Under which circumstances a redis.call(command, ...args) invocation can fail if both commandis valid and args are valid arguments to command?
Related
I want to test that an app is both exiting with a non-zero code AND outputting a particular string. I set the properties like this:
set_tests_properties(
myapp-test-foobar
PROPERTIES
WILL_FAIL TRUE
FAIL_REGULAR_EXPRESSION "^Usage: myapp"
)
But the test passes even if the app's exit code is 0. Although WILL_FAIL is necessary, otherwise the test will fail when the FRE is matched, the exit code is ignored. I searched the cmake docs for an answer to no avail.
EDIT: It turns out that ctest (I'm using v3.19.2) does not check the exit code if either PASS_REGULAR_EXPRESSION or FAIL_REGULAR_EXPRESSION is set. The pass or fail condition is met solely by the RE matching.
A nasty bug has escaped into the wild in one of my apps because of this.
EDIT: The answer suggested in comments below is for handling an app that aborts, i.e. crashes, on the error condition being tested and so is different from my case. Please see my comment below for further reasoning and solution.
The fix I described in my comment above does not work. As I recently discovered a mismatched FAIL_REGULAR_EXPRESSION will not cause the test to fail. See this question.
This is because when FAIL_REGULAR_EXPRESSION and WILL_FAIL are set ctest does
if (match FAIL_REGULAR_EXPRESSION || exit_code != 0)
For clarity here are the other cases. When only WILL_FAIL is set, ctest does
if (exit_code != 0)
When PASS_REGULAR_EXPRESSION is set, ctest does
if (match PASS_REGULAR_EXPRESSION)
and when none of the 3 are set, ctest does
if (exit_code == 0)
You can test for both the correct error code and error message by abusing PASS_REGULAR_EXPRESSION as in the following
add_test( NAME myapp-test-ktx2-in-exit-code
COMMAND myapp -o foo infile.ktx2
WORKING_DIRECTORY ${MY_WORK_DIR}
)
set_tests_properties(
myapp-test-ktx2-in-exit-code
PROPERTIES
WILL_FAIL TRUE
)
add_test( NAME myapp-test-ktx2-in
COMMAND myapp -o foo input.ktx2
WORKING_DIRECTORY ${MY_WORK_DIR}
)
set_tests_properties(
myapp-test-ktx2-in
PROPERTIES
PASS_REGULAR_EXPRESSION ".* is not a KTX v1 file."
)
If both tests pass we are guaranteed that we have a non-zero exit code and the error message matches PASS_REGULAR_EXPRESSION.
If you want to test both for the correct PASS_REGULAR_EXPRESSION and exit_code == 0 you will similarly need two tests: one to test PASS_REGULAR_EXPRESSION and one without it set.
There is a function named myfunc defined as
function (myfunc var1 var2 var3)
...
endfunction()
Then, I see a function call
myfunc(custom hahaha platform ALL
COMMAND echo "hello world"
SOURCES ${some_var} )
My question is
The function myfunc takes 3 variables. In the above function call, which are the 3 variables? Also, how can there be additional commands COMMAND and SOURCES within the function call?
3 variables will be the first 3 arguments.
If your function was defined as follows:
function (myfunc var1 var2 var3)
message ("var1: ${var1}")
message ("var2: ${var2}")
message ("var3: ${var3}")
message ("number of arguments sent to function: ${ARGC}")
message ("all function arguments: ${ARGV}")
message ("all arguments beyond defined: ${ARGN}")
endfunction()
after calling it as you stated:
set (some_var "some var")
myfunc(custom hahaha platform ALL
COMMAND echo "hello world"
SOURCES ${some_var} )
the outuput will be:
var1: custom
var2: hahaha
var3: platform
number of arguments sent to function: 9
all function arguments: custom;hahaha;platform;ALL;COMMAND;echo;hello world;SOURCES;some var
all arguments beyond defined: ALL;COMMAND;echo;hello world;SOURCES;some var
so you have called your function with 9 arguments, that are referenced with ${ARGV}, all arguments that are not defined can also be referenced using variable ${ARGN}.
Note that when calling function, ALL, COMMAND, and SOURCES are just arguments to the function, nothing else.
In the end, here is the full documentation about cmake functions and arguments
To complement #gordan.sikic answer, you also might be interested in cmake_parse_arguments command.
It allows you to define named parameters to your function, like COMMAND ... and WORKING_DIRECTORY ... in add_custom_command. See example in the documentation page.
In CMakeLists.txt I write:
INCLUDE(CheckLibraryExists)
check_library_exists("libcurl" "" "" HAVE_CURL)
HAVE_CURL is always false, even if libcurl installed, and this function not causes fatal errors.
To check why a a try-compile fails, you can run CMake with the --debug-trycompile option, which will leave behind the buildsystem for the last try_compile command (these are used internally by all the Check... modules).
I didn't run the check, but I looked at the code of CheckLibraryExists, and it is apparently mandatory to specify a function to look for in that library (the second argument to check_library_exists).
function(print2Args arg1 arg2)
message(STATUS ${arg1} " " ${arg2})
endfunction(print2Args)
Is it possible to update user defined function print2Args s.t. it will accept options like the built-in CMake function execute_process?
CMake offers this via the CMakeParseArguments. You do not specify the arguments in the function signature as you did in your example.
CMake accepts more arguments then given in the function signature. You define options, one-valued arguments and pairs of arguments in variables and pass these to cmake_parse_arguments. This command sets several variables which you can use to check what arguments where set.
Documentation and an example:
https://cmake.org/cmake/help/latest/module/CMakeParseArguments.html
In my continuous integration testing for my emacs package fsharp-mode, I am adding byte-compilation to the tests, in order to have immediate feedback. I am roughly using:
emasc -batch batch-byte-compile *.el
This returns non-zero if there is an error, but not if it is just a warning. I would like to be alerted also if there are any warnings, as this may include calls to undefined functions (which has happened before thanks to a typo).
So: how can I obtain a non-zero return code in case of compilation warnings?
You can set byte-compile-error-on-warn to a non-nil value, as in:
$ emacs -Q --batch \
--eval '(setq byte-compile-error-on-warn t)' \
-f batch-byte-compile *.el
The byte compiler now stops at the first warning, though, so you should make this setting optional in your Makefile, and only use it in your CI setup.
If you need more sophisticated control than that, you have to write your own post-processor, e.g. a Python script that parses the output of the byte compiler and adjusts the exit code and/or output accordingly, or write your own batch-byte-compile variant that does more sophisticated processing.