source: tags/arb-6.0/TEMPLATES/command_output.h

Last change on this file was 9455, checked in by westram, 11 years ago
  • tests for multiprobe-loaddesignresult
    • test designoutput of current ptserver vs hardcoded designoutput
      • need to update whenever designoutput changes
      • enforces load-test for most recent output-format
File size: 6.7 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : command_output.h                                //
4//   Purpose   :                                                 //
5//                                                               //
6//   Coded by Ralf Westram (coder@reallysoft.de) in March 2012   //
7//   Institute of Microbiology (Technical University Munich)     //
8//   http://www.arb-home.de/                                     //
9//                                                               //
10// ============================================================= //
11
12#ifndef COMMAND_OUTPUT_H
13#define COMMAND_OUTPUT_H
14
15#ifndef UNIT_TESTS
16#error currently only used inside unittest-code. need refactoring to be used generally
17#endif
18
19#ifndef ARB_FILE_H
20#include <arb_file.h>
21#endif
22#ifndef ARBDBT_H
23#include <arbdbt.h>
24#endif
25#ifndef UT_VALGRINDED_H
26#include <ut_valgrinded.h>
27#endif
28#ifndef _UNISTD_H
29#include <unistd.h>
30#endif
31
32// --------------------------------------------------------------------------------
33
34class CommandOutput : virtual Noncopyable {
35    // support class to test CLI of arb-tools
36
37    char     *stdoutput; // output from command
38    char     *stderrput;
39    GB_ERROR  error;
40
41    void appendError(GB_ERROR err) {
42        if (!error) error = err;
43        else error = GBS_global_string("%s\n%s", error, err);
44    }
45
46    char *readAndUnlink(const char *file) {
47        char *content = GB_read_file(file);
48        if (!content) appendError(GB_await_error());
49        int res = GB_unlink(file);
50        if (res == -1) appendError(GB_await_error());
51        return content;
52    }
53public:
54    CommandOutput(const char *command, bool try_valgrind)
55        : stdoutput(NULL), stderrput(NULL), error(NULL)
56    {
57        char *escaped = GBS_string_eval(command, "'=\\\\'", NULL);
58        if (!escaped) {
59            appendError(GB_await_error());
60        }
61        else {
62            if (try_valgrind) make_valgrinded_call(escaped);
63
64            pid_t pid = getpid();
65
66            char *stdout_log = GBS_global_string_copy("stdout_%i.log", pid);
67            char *stderr_log = GBS_global_string_copy("stderr_%i.log", pid);
68
69            char *cmd = GBS_global_string_copy("bash -c '%s >%s 2>%s'", escaped, stdout_log, stderr_log);
70
71            appendError(GBK_system(cmd));
72            free(cmd);
73            free(escaped);
74
75            stdoutput = readAndUnlink(stdout_log);
76            stderrput = readAndUnlink(stderr_log);
77
78            free(stderr_log);
79            free(stdout_log);
80        }
81        if (error) {
82            printf("command '%s'\n"
83                   "escaped command '%s'\n"
84                   "stdout='%s'\n"
85                   "stderr='%s'\n", 
86                   command, escaped, stdoutput, stderrput);
87        }
88    }
89    ~CommandOutput() {
90        free(stderrput);
91        free(stdoutput);
92    }
93
94    const char *get_stdoutput() const { return stdoutput; }
95    const char *get_stderrput() const { return stderrput; }
96    GB_ERROR get_error() const { return error; }
97
98    arb_test::match_expectation Equals(const char *expected_std, const char *expected_err) {
99        using namespace arb_test;
100        expectation_group expected(that(error).is_equal_to_NULL());
101        if (expected_std) expected.add(that(stdoutput).is_equal_to(expected_std));
102        if (expected_err) expected.add(that(stderrput).is_equal_to(expected_err));
103        return all().ofgroup(expected);
104    }
105    arb_test::match_expectation Contains(const char *expected_std, const char *expected_err) {
106        using namespace arb_test;
107        expectation_group expected(that(error).is_equal_to_NULL());
108        if (expected_std) expected.add(that(stdoutput).does_contain(expected_std));
109        if (expected_err) expected.add(that(stderrput).does_contain(expected_err));
110        return all().ofgroup(expected);
111    }
112    arb_test::match_expectation has_checksum(uint32_t expected_checksum) {
113        uint32_t css      = GBS_checksum(stdoutput, false, "");
114        uint32_t cse      = GBS_checksum(stderrput, false, "");
115        uint32_t checksum = css^cse;
116        using namespace arb_test;
117        return all().of(that(error).is_equal_to_NULL(),
118                        that(checksum).is_equal_to(expected_checksum));
119    }
120};
121
122// --------------------------------------------------------------------------------
123
124#define TEST_OUTPUT_EQUALS(cmd, expected_std, expected_err)                                             \
125    do {                                                                                                \
126        bool try_valgrind = (expected_err == NULL);                                                     \
127        TEST_EXPECTATION(CommandOutput(cmd, try_valgrind).Equals(expected_std, expected_err));               \
128    } while(0)
129
130#define TEST_OUTPUT_EQUALS__BROKEN(cmd, expected_std, expected_err)                                     \
131    do {                                                                                                \
132        bool try_valgrind = (expected_err == NULL);                                                     \
133        TEST_EXPECTATION__BROKEN(CommandOutput(cmd, try_valgrind).Equals(expected_std, expected_err));       \
134    } while(0)
135
136#define TEST_OUTPUT_CONTAINS(cmd, expected_std, expected_err)                                           \
137    do {                                                                                                \
138        bool try_valgrind = (expected_err == NULL);                                                     \
139        TEST_EXPECTATION(CommandOutput(cmd, try_valgrind).Contains(expected_std, expected_err));             \
140    } while(0)
141
142#define TEST_OUTPUT_CONTAINS__BROKEN(cmd, expected_std, expected_err)                                   \
143    do {                                                                                                \
144        bool try_valgrind = (expected_err == NULL);                                                     \
145        TEST_EXPECTATION__BROKEN(CommandOutput(cmd, try_valgrind).Contains(expected_std, expected_err));     \
146    } while(0)
147
148#define TEST_OUTPUT_HAS_CHECKSUM(cmd,checksum)         TEST_EXPECTATION        (CommandOutput(cmd, false).has_checksum(checksum))
149#define TEST_OUTPUT_HAS_CHECKSUM__BROKEN(cmd,checksum) TEST_EXPECTATION__BROKEN(CommandOutput(cmd, false).has_checksum(checksum))
150
151#define TEST_STDOUT_EQUALS(cmd, expected_std) TEST_OUTPUT_EQUALS(cmd, expected_std, (const char *)NULL)
152#define TEST_STDERR_EQUALS(cmd, expected_err) TEST_OUTPUT_EQUALS(cmd, (const char *)NULL, expected_err)
153
154#define TEST_STDOUT_CONTAINS(cmd, part) TEST_OUTPUT_CONTAINS(cmd, part, "")
155
156#else
157#error command_output.h included twice
158#endif // COMMAND_OUTPUT_H
Note: See TracBrowser for help on using the repository browser.