source: tags/ms_r18q1/UNIT_TESTER/test_runtool.h

Last change on this file was 16763, checked in by westram, 6 years ago
File size: 4.2 KB
Line 
1// ============================================================ //
2//                                                              //
3//   File      : test_runtool.h                                 //
4//   Purpose   : provides tests for external tools (CLI)        //
5//                                                              //
6//   Coded by Ralf Westram (coder@reallysoft.de) in June 2017   //
7//   http://www.arb-home.de/                                    //
8//                                                              //
9// ============================================================ //
10
11#ifndef TEST_RUNTOOL_H
12#define TEST_RUNTOOL_H
13
14#ifndef UT_VALGRINDED_H
15#include <ut_valgrinded.h>
16#endif
17#ifndef ARB_STRARRAY_H
18#include <arb_strarray.h>
19#endif
20#ifndef ARB_STRBUF_H
21#include <arb_strbuf.h>
22#endif
23
24namespace test_runtool {
25
26    inline char *make_checked_piped_command(const char *piped_command, int pipeSymbolCount) {
27        // append pipe-check to 'piped_command'
28        // ('piped_command' has to contain 'pipeSymbolCount' pipe symbols)
29        // - wrap command in call to bash (PIPESTATUS is bash-specific)
30
31        arb_assert(pipeSymbolCount>0);
32
33        GBS_strstruct cmd_list(500);
34        cmd_list.cat(piped_command);
35        // append bash-expression to check result of each part of the pipe
36        cmd_list.cat(";exit $((");
37        for (int i = 0; i<=pipeSymbolCount; ++i) {
38            if (i) cmd_list.cat(" | ");
39            cmd_list.nprintf(30, "${PIPESTATUS[%i]}", i);
40        }
41        cmd_list.cat("))");
42
43        // explicitely use bash to execute:
44        char *quotedCommand = GBK_singlequote(cmd_list.get_data());
45        char *checked_cmd   = GBS_global_string_copy("bash -c %s", quotedCommand);
46        free(quotedCommand);
47        return checked_cmd;
48    }
49
50    inline void add_valgrinded_cmd(StrArray& array, char *cmd) {
51        make_valgrinded_call(cmd);
52        array.put(cmd);
53    }
54
55    inline char *valgrinded_pipe_command(const char *piped_command, const char *first_pipe) {
56        if (will_valgrind_calls()) {
57            StrArray pipe_cmds;
58
59            while (first_pipe) {
60                add_valgrinded_cmd(pipe_cmds, ARB_strpartdup(piped_command, first_pipe-1));
61                piped_command = first_pipe+1;
62                first_pipe    = find_pipe_symbol(piped_command);
63            }
64            add_valgrinded_cmd(pipe_cmds, strdup(piped_command)); // rest
65
66            char *repiped_cmd         = GBT_join_strings(pipe_cmds, '|');
67            char *checked_repiped_cmd = make_checked_piped_command(repiped_cmd, pipe_cmds.size()-1);
68            free(repiped_cmd);
69
70            return checked_repiped_cmd;
71        }
72
73        int pipeCount = 0;
74        while (first_pipe) {
75            ++pipeCount;
76            first_pipe = find_pipe_symbol(first_pipe+1);
77        }
78        return make_checked_piped_command(piped_command, pipeCount);
79    }
80
81    inline GB_ERROR valgrinded_system(const char *cmdline) { // @@@ rename later (does more)
82        // basically does two things:
83        // - if current binary runs valgrinded => use valgrind to run 'cmdline' (can handle pipes)
84        // - if 'cmdline' is a pipe => check exitcodes of all parts of the pipe
85
86        char       *cmddup     = NULp;
87        const char *first_pipe = find_pipe_symbol(cmdline);
88
89        if (first_pipe) {
90            cmddup = valgrinded_pipe_command(cmdline, first_pipe);
91        }
92        else {
93            cmddup = ARB_strdup(cmdline);
94            make_valgrinded_call(cmddup);
95        }
96
97        GB_ERROR error = GBK_system(cmddup);
98        free(cmddup);
99        return error;
100    }
101
102};
103
104#define RUN_TOOL(cmdline)                test_runtool::valgrinded_system(cmdline)
105#define RUN_TOOL_NEVER_VALGRIND(cmdline) GBK_system(cmdline)
106
107// expect success or failure running CLI-tool:
108
109#define TEST_RUN_TOOL(cmdline)                TEST_EXPECT_NO_ERROR(RUN_TOOL(cmdline))
110#define TEST_RUN_TOOL_NEVER_VALGRIND(cmdline) TEST_EXPECT_NO_ERROR(RUN_TOOL_NEVER_VALGRIND(cmdline))
111#define TEST_RUN_TOOL_FAILS(cmdline)          TEST_EXPECT_ERROR_CONTAINS(RUN_TOOL(cmdline), "System call failed")
112
113// Note: more detailed tests are available using TEST_OUTPUT_CONTAINS, TEST_FAILURE_OUTPUT_CONTAINS and related macros
114
115#else
116#error test_runtool.h included twice
117#endif // TEST_RUNTOOL_H
Note: See TracBrowser for help on using the repository browser.