Skip to content

Supporting test with non-zero exit code #86

@yairlenga

Description

@yairlenga

This is another attempt to address #31 and #84

I've recently started using acutest, after finding a VSCode extension for it. Simplicity is refreshing vs other tools - but I hit the same issue - some C test should fail with signal. Instead of trying the setjmp/longjmp - would it be possible to consider an approach where specific it will be possible to specify the expected exit condition on the test. 2 ideas, which I believe are relatively easiy to implement:

  1. Add extra indication to each test (in the TEST_LIST) about expected return code
  2. Possibly simpler - add a new macro to each test, which will specify expected signal, default (0) is no signal.

Option 1 will extend the acutest_test with an extra member - 'signo'. Taking advantage of the fact that unspecified values default to 0.

struct acutest_test_ {
    const char* name;
    void (*func)(void);
    int signo ;
};

Users can specify the expected signal in the test list:

TEST_LIST = {
    { "mytest", test_func},

        // Expecting SIGSEGV
    { "SEGVtest", segv_test_func, .signo = SIGSEGV },
    ...
}

Option 2 takes different approach - It adds an helper to run a function in a forked process, and return the exit code exit status/signal number (suggesting using the shell conventions where exit_code = 128+signal). Users can integrate this as a test that they use, with simple macro as helper.

// Linux only - I'm do not have experience with Windows
#define SIGNAL_EXIT_STATUS(sig) (sig+128)
static int acutest_run_forked(func)
{
    pid_t pid = fork() ;
    if ( pid < 0 ) {
        // Error
        return -1 ;

    } else if ( !pid ) {
        // Child
        func() ;
        exit(0) ;
    } ;

   // Parent
  int status ;
  pid_t done = waitpid(pid, &status, 0) ;
  if ( done != pid ) return -2 ;
  if ( WIFEXITED(status) ) return WEXITSTATUS(status) ;
  if ( WIFSIGNALED(status) ) return SIGNAL_EXIT_STATUS(WIFTERMSIG(status)) ;
  // Other error in 'waitpid'
  return -3 ;
}

#define TEST_SIGNAL(func, expected_signo) {
    int extat = acutest_run_forked(func) ;
    TEST_CHECK_(exstat == SIGNAL_EXIT_STATUS(signo),  "Expected signal %d from function %s, got status=%d", expected_signo, ##func, exstat) ;
}

Usage is:

    TEST_SIGNAL(func, SIGHUP) ;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions