-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow dynamic configuration of maximal assertion message size. #128
Conversation
src/check_pack.c
Outdated
} | ||
|
||
static int get_max_msg_size(void) { | ||
if (ck_max_msg_size <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be consistent with the behavior of the other environment variables, the order of precedence should be:
- environment variable
- check_set_max_msg_size()
- default value
See CK_DEFAULT_TIMEOUT as an example of this.
src/check_pack.c
Outdated
ck_max_msg_size = atoi(env); | ||
|
||
if (ck_max_msg_size <= 0) | ||
ck_max_msg_size = 4096; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could 4096 still be a variable or #define
above, so it is not a magic number?
I think it would be valuable to document this new API call in the manual, maybe somewhere in this section. Also mention that the environment variable can override the value. There is an section which shows all the environment variables here. Also mention the new environment variable there. Finally, I think it would be valuable to have a new test for this, which shows that if the value is set too low Check does cause an error but if it is set high enough Check continues with the test. Many unit tests in Check run using Check itself, which verifies that certain errors occur when they are expected. The tests themselves are defined up to this point, they are added to the test suite (with whatever environment variables are used) here, and the table which says what the output of the tests should be is here. Try adding a test or so to verify the behavior of the new API and environment variable. |
Thanks for the review pointers. I fixed the code to give precedence to the environment variable, and updated the TexInfo documentation. I have difficulty with creating a test though. A too-long message invokes |
Hm, seems that the normal test setup will not work for this. I may suggest the following then. First, add a test which checks that using the API is OK, and that the value returned from the getter is as expected (e.g the env var takes precedence). For exercising the feature, the test could be put into another program and run independently. The example of this is the memory leak test test_mem_leaks.sh, which captures Valgrind output. That executes the program compiled from check_mem_leaks.c. If having another executable for the test is needed along with another script to run it, that is OK. The test would need to be added to the configure.ac and the correct CMake file, though. |
doc/check.texi
Outdated
(up to 4GB allocations were seen in the wild). | ||
To prevent this, a limit is placed on the assertion message size. | ||
This limit is 4K bytes by default. | ||
It can be modified by setting the @code(CK_MAX_MSG_SIZE) environment variable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that you may need {}
around @code
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is:
@code{CK_MAX_MSG_SIZE}
Working on the tests; I see test/check_mem_leaks in the Edit: I see Edit 2: Added to both CMake and Automake tests. |
tests/check_env_max_msg_size.c
Outdated
*/ | ||
|
||
/** | ||
* The purpose of this test is to be used by valgrind to check for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May need to update this comment
tests/check_set_max_msg_size.c
Outdated
*/ | ||
|
||
/** | ||
* The purpose of this test is to be used by valgrind to check for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, the comment needs to be updated
tests/check_set_max_msg_size.c
Outdated
* Run the test suite. This is intended to trigger the "Message is too long" error. | ||
* Actual success/failure is determined by examining the output. | ||
*/ | ||
check_set_max_msg_size(32); // This will have an effect due to no environment variable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two test programs could be collapsed by passing in a value over the command line, as I think that is the only difference, correct?
tests/test_env_max_msg_size.sh
Outdated
@@ -0,0 +1,22 @@ | |||
#!/usr/bin/env sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two test scripts could be collapsed, and simply run the unit test executable multiple times and check the result.
@@ -993,6 +993,17 @@ repetitive code that is hard to read. For your convenience Check | |||
provides a set of functions (actually macros) for testing often used | |||
conditions. | |||
|
|||
@findex check_set_max_msg_size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be moved to the end of the section, as it would not be expected to be called as frequently as the others. Or, do you disagree?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that placing it at the end would make it "disappear" for someone who would say "ah, a list of all kind of assertions, I'll skip to the next section and come back here if I want to locate a specific assertion function". The other option is to make it an explicit section of its own but that seems an overkill for a single simple function.
Jenkins: ok to test |
The valgrind test is specific to Linux. The original intention of CMake was to support Windows targets, so it did not make much sense to add it. It turns out that some users on Linux do want to use CMake as well. Regardless, the unit tests are really to help protect the quality of the project. As long as the project still runs the tests on changes, I think being supported in one or the other build system should not be that important. |
Fixed everything (except for moving the documentation paragraph). Edit: Oops, didn't push the latest. Did now. |
Ready to merge - or is there anything else? |
src/check_pack.c
Outdated
* The usual size for a message is less than 80 bytes. | ||
* All this is done instead of the previous approach to allocate (actually | ||
* continuously reallocate) one big chunk for the whole message stream. | ||
* Problems were seen in the wild with up to 4 GB reallocations. | ||
*/ | ||
|
||
void check_set_max_msg_size(int max_msg_size) { | ||
if (ck_max_msg_size <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it that once the value has been set it cannot be changed? The comment in the prototype says this is the intent: "if used... must be called once...". I am fine with the behavior, just curious as to the rationale.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was probably too focused on a specific use case. Fixed.
src/check_pack.c
Outdated
* The usual size for a message is less than 80 bytes. | ||
* All this is done instead of the previous approach to allocate (actually | ||
* continuously reallocate) one big chunk for the whole message stream. | ||
* Problems were seen in the wild with up to 4 GB reallocations. | ||
*/ | ||
|
||
void check_set_max_msg_size(int max_msg_size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small thing, but can you match the style of the { in this file, namely:
void check_set_max_msg_size(int max_msg_size()
{
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/check_pack.c
Outdated
} | ||
|
||
static int get_max_msg_size(void) { | ||
if (ck_max_msg_size <= 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary? Should not the setter verify that the value is sane?
Is there a reason that ck_max_msg_size must be signed? Is it valid for it to be negative? Could it be unsigned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed type to size_t
, which is probably the "right" type for a size.
Changed type of argument to |
src/check_pack.c
Outdated
check_set_max_msg_size(0); | ||
static size_t get_max_msg_size(void) | ||
{ | ||
if (ck_max_msg_size == 0) // If check_set_max_msg_size was not called, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not the getter be making the decision as to if the environment variable exists or not, and let the setter only set the value passed? This way, if the environment variable changed since when the setter was called and the getter was called the correct value would be returned? e.g.:
void check_set_max_msg_size(size_t max_msg_size)
{
ck_max_msg_size = max_msg_size;
}
void get_max_msg_size()
{
size_t value = 0;
char *env = getenv("CK_MAX_MSG_SIZE");
if (env)
value = (size_t)strtoul(env, NULL, 10); // Cast in case size_t != unsigned long.
if(value == 0)
value = ck_max_msg_size;
if (value == 0)
value = DEFAULT_MAX_MSG_SIZE;
return value;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the environment variable at run time seems strange, but I guess it could happen. Also, I guess performance isn't an issue, as this is only used when an assertion fails...
…environment variable.
Fixed. |
Thanks for the changeset! I've merge it in. If you would like, you can submit a merge request adding an entry into the AUTHORS file for yourself. |
Resolve issue #127.
The new function is annotated as
@since 0.12.0
under the assumption that would be the next released version.