1 // Copyright 2012 Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include <stdlib.h> 30 31 #include <atf-c.h> 32 33 #define INTERFACE "plain" 34 #include "common_inttest.h" 35 36 37 /// Sets up a particular helper. 38 /// 39 /// \param tc The test case calling this function. 40 /// \param helper_name Name of the desired helper. 41 /// 42 /// \return The return value of helpers_path(). 43 static char* 44 select_helper(const atf_tc_t* tc, const char* helper_name) 45 { 46 ATF_REQUIRE(setenv("HELPER", helper_name, 1) != -1); 47 return helpers_path(tc); 48 } 49 50 51 ATF_TC(list__ok); 52 ATF_TC_HEAD(list__ok, tc) { setup(tc, false); } 53 ATF_TC_BODY(list__ok, tc) 54 { 55 check(EXIT_SUCCESS, "test_case{name='main'}\n", "", 56 "list", "irrelevant-program", NULL); 57 } 58 59 60 ATF_TC(test__pass); 61 ATF_TC_HEAD(test__pass, tc) { setup(tc, true); } 62 ATF_TC_BODY(test__pass, tc) 63 { 64 char* helpers = select_helper(tc, "pass"); 65 check(EXIT_SUCCESS, 66 "First line to stdout\nSecond line to stdout\n", 67 "First line to stderr\nSecond line to stderr\n", 68 "test", helpers, "main", "test-result", NULL); 69 free(helpers); 70 71 ATF_REQUIRE(atf_utils_compare_file("test-result", "passed\n")); 72 } 73 74 75 ATF_TC(test__fail); 76 ATF_TC_HEAD(test__fail, tc) { setup(tc, true); } 77 ATF_TC_BODY(test__fail, tc) 78 { 79 char* helpers = select_helper(tc, "fail"); 80 check(EXIT_FAILURE, "First line to stdout\n", "First line to stderr\n", 81 "test", helpers, "main", "test-result", NULL); 82 free(helpers); 83 84 ATF_REQUIRE(atf_utils_compare_file("test-result", 85 "failed: Returned non-success exit status 78\n")); 86 } 87 88 89 ATF_TC(test__crash); 90 ATF_TC_HEAD(test__crash, tc) { setup(tc, true); } 91 ATF_TC_BODY(test__crash, tc) 92 { 93 char* helpers = select_helper(tc, "signal"); 94 check(EXIT_FAILURE, "", "save:crash.err", 95 "test", helpers, "main", "test-result", NULL); 96 free(helpers); 97 98 ATF_REQUIRE(atf_utils_compare_file("test-result", 99 "broken: Received signal 6\n")); 100 101 ATF_REQUIRE(atf_utils_grep_file("About to die due to SIGABRT!", 102 "crash.err")); 103 ATF_REQUIRE(atf_utils_grep_file("attempting to gather stack trace", 104 "crash.err")); 105 } 106 107 108 ATF_TC(test__timeout); 109 ATF_TC_HEAD(test__timeout, tc) { setup(tc, true); } 110 ATF_TC_BODY(test__timeout, tc) 111 { 112 char* helpers = select_helper(tc, "sleep"); 113 check(EXIT_FAILURE, "", "Subprocess timed out; sending KILL signal...\n", 114 "-t1", "test", helpers, "main", "test-result", NULL); 115 free(helpers); 116 117 ATF_REQUIRE(atf_utils_compare_file("test-result", "broken: Test case " 118 "timed out\n")); 119 } 120 121 122 ATF_TC(test__config_ignored); 123 ATF_TC_HEAD(test__config_ignored, tc) { setup(tc, true); } 124 ATF_TC_BODY(test__config_ignored, tc) 125 { 126 char* helpers = select_helper(tc, "pass"); 127 check(EXIT_SUCCESS, 128 "First line to stdout\nSecond line to stdout\n", 129 "save:stderr.txt", 130 "test", "-va=b", "-vfoo=a b c", helpers, "main", "test-result", NULL); 131 free(helpers); 132 133 ATF_REQUIRE(atf_utils_grep_file("ignoring 'a=b'", "stderr.txt")); 134 ATF_REQUIRE(atf_utils_grep_file("ignoring 'foo=a b c'", "stderr.txt")); 135 ATF_REQUIRE(atf_utils_compare_file("test-result", "passed\n")); 136 } 137 138 139 ATF_TC(test__missing_test_program); 140 ATF_TC_HEAD(test__missing_test_program, tc) { setup(tc, false); } 141 ATF_TC_BODY(test__missing_test_program, tc) 142 { 143 check(EXIT_INTERNAL_ERROR, "", 144 "kyua-plain-tester: execvp failed: No such file or directory\n", 145 "test", "./non-existent", "main", "test-result", NULL); 146 147 ATF_REQUIRE(!atf_utils_file_exists("test-result")); 148 } 149 150 151 ATF_TC(test__invalid_test_case_name); 152 ATF_TC_HEAD(test__invalid_test_case_name, tc) { setup(tc, false); } 153 ATF_TC_BODY(test__invalid_test_case_name, tc) 154 { 155 check(EXIT_INTERNAL_ERROR, "", 156 "kyua-plain-tester: Unknown test case 'foo'\n", 157 "test", "./non-existent", "foo", "test-result", NULL); 158 159 ATF_REQUIRE(!atf_utils_file_exists("test-result")); 160 } 161 162 163 ATF_TP_ADD_TCS(tp) 164 { 165 ATF_TP_ADD_TC(tp, top__missing_command); 166 ATF_TP_ADD_TC(tp, top__unknown_command); 167 168 ATF_TP_ADD_TC(tp, list__ok); 169 170 ATF_TP_ADD_TC(tp, test__pass); 171 ATF_TP_ADD_TC(tp, test__fail); 172 ATF_TP_ADD_TC(tp, test__crash); 173 ATF_TP_ADD_TC(tp, test__timeout); 174 ATF_TP_ADD_TC(tp, test__config_ignored); 175 ATF_TP_ADD_TC(tp, test__missing_test_program); 176 ATF_TP_ADD_TC(tp, test__invalid_test_case_name); 177 178 return atf_no_error(); 179 } 180