common_test.cpp revision 1.1 1 1.1 jmmv // Copyright 2011 Google Inc.
2 1.1 jmmv // All rights reserved.
3 1.1 jmmv //
4 1.1 jmmv // Redistribution and use in source and binary forms, with or without
5 1.1 jmmv // modification, are permitted provided that the following conditions are
6 1.1 jmmv // met:
7 1.1 jmmv //
8 1.1 jmmv // * Redistributions of source code must retain the above copyright
9 1.1 jmmv // notice, this list of conditions and the following disclaimer.
10 1.1 jmmv // * Redistributions in binary form must reproduce the above copyright
11 1.1 jmmv // notice, this list of conditions and the following disclaimer in the
12 1.1 jmmv // documentation and/or other materials provided with the distribution.
13 1.1 jmmv // * Neither the name of Google Inc. nor the names of its contributors
14 1.1 jmmv // may be used to endorse or promote products derived from this software
15 1.1 jmmv // without specific prior written permission.
16 1.1 jmmv //
17 1.1 jmmv // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 1.1 jmmv // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 1.1 jmmv // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 1.1 jmmv // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 1.1 jmmv // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 1.1 jmmv // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 1.1 jmmv // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.1 jmmv // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.1 jmmv // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.1 jmmv // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 1.1 jmmv // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 jmmv
29 1.1 jmmv #include "cli/common.hpp"
30 1.1 jmmv
31 1.1 jmmv #include <fstream>
32 1.1 jmmv
33 1.1 jmmv #include <atf-c++.hpp>
34 1.1 jmmv
35 1.1 jmmv #include "engine/exceptions.hpp"
36 1.1 jmmv #include "engine/filters.hpp"
37 1.1 jmmv #include "engine/test_case.hpp"
38 1.1 jmmv #include "engine/test_program.hpp"
39 1.1 jmmv #include "engine/test_result.hpp"
40 1.1 jmmv #include "utils/cmdline/exceptions.hpp"
41 1.1 jmmv #include "utils/cmdline/globals.hpp"
42 1.1 jmmv #include "utils/cmdline/parser.ipp"
43 1.1 jmmv #include "utils/cmdline/ui_mock.hpp"
44 1.1 jmmv #include "utils/datetime.hpp"
45 1.1 jmmv #include "utils/env.hpp"
46 1.1 jmmv #include "utils/fs/exceptions.hpp"
47 1.1 jmmv #include "utils/fs/operations.hpp"
48 1.1 jmmv #include "utils/fs/path.hpp"
49 1.1 jmmv #include "utils/optional.ipp"
50 1.1 jmmv #include "utils/sanity.hpp"
51 1.1 jmmv
52 1.1 jmmv namespace cmdline = utils::cmdline;
53 1.1 jmmv namespace config = utils::config;
54 1.1 jmmv namespace datetime = utils::datetime;
55 1.1 jmmv namespace fs = utils::fs;
56 1.1 jmmv
57 1.1 jmmv using utils::optional;
58 1.1 jmmv
59 1.1 jmmv
60 1.1 jmmv namespace {
61 1.1 jmmv
62 1.1 jmmv
63 1.1 jmmv /// Syntactic sugar to instantiate engine::test_filter objects.
64 1.1 jmmv inline engine::test_filter
65 1.1 jmmv mkfilter(const char* test_program, const char* test_case)
66 1.1 jmmv {
67 1.1 jmmv return engine::test_filter(fs::path(test_program), test_case);
68 1.1 jmmv }
69 1.1 jmmv
70 1.1 jmmv
71 1.1 jmmv } // anonymous namespace
72 1.1 jmmv
73 1.1 jmmv
74 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(build_root_path__default);
75 1.1 jmmv ATF_TEST_CASE_BODY(build_root_path__default)
76 1.1 jmmv {
77 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
78 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
79 1.1 jmmv
80 1.1 jmmv ATF_REQUIRE(!cli::build_root_path(mock_cmdline));
81 1.1 jmmv }
82 1.1 jmmv
83 1.1 jmmv
84 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(build_root_path__explicit);
85 1.1 jmmv ATF_TEST_CASE_BODY(build_root_path__explicit)
86 1.1 jmmv {
87 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
88 1.1 jmmv options["build-root"].push_back("/my//path");
89 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
90 1.1 jmmv
91 1.1 jmmv ATF_REQUIRE(cli::build_root_path(mock_cmdline));
92 1.1 jmmv ATF_REQUIRE_EQ("/my/path", cli::build_root_path(mock_cmdline).get().str());
93 1.1 jmmv }
94 1.1 jmmv
95 1.1 jmmv
96 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(get_home__ok);
97 1.1 jmmv ATF_TEST_CASE_BODY(get_home__ok)
98 1.1 jmmv {
99 1.1 jmmv const fs::path home("/foo/bar");
100 1.1 jmmv utils::setenv("HOME", home.str());
101 1.1 jmmv const optional< fs::path > computed = cli::get_home();
102 1.1 jmmv ATF_REQUIRE(computed);
103 1.1 jmmv ATF_REQUIRE_EQ(home, computed.get());
104 1.1 jmmv }
105 1.1 jmmv
106 1.1 jmmv
107 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(get_home__missing);
108 1.1 jmmv ATF_TEST_CASE_BODY(get_home__missing)
109 1.1 jmmv {
110 1.1 jmmv utils::unsetenv("HOME");
111 1.1 jmmv ATF_REQUIRE(!cli::get_home());
112 1.1 jmmv }
113 1.1 jmmv
114 1.1 jmmv
115 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(get_home__invalid);
116 1.1 jmmv ATF_TEST_CASE_BODY(get_home__invalid)
117 1.1 jmmv {
118 1.1 jmmv utils::setenv("HOME", "");
119 1.1 jmmv ATF_REQUIRE(!cli::get_home());
120 1.1 jmmv }
121 1.1 jmmv
122 1.1 jmmv
123 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(kyuafile_path__default);
124 1.1 jmmv ATF_TEST_CASE_BODY(kyuafile_path__default)
125 1.1 jmmv {
126 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
127 1.1 jmmv options["kyuafile"].push_back(cli::kyuafile_option.default_value());
128 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
129 1.1 jmmv
130 1.1 jmmv ATF_REQUIRE_EQ(cli::kyuafile_option.default_value(),
131 1.1 jmmv cli::kyuafile_path(mock_cmdline).str());
132 1.1 jmmv }
133 1.1 jmmv
134 1.1 jmmv
135 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(kyuafile_path__explicit);
136 1.1 jmmv ATF_TEST_CASE_BODY(kyuafile_path__explicit)
137 1.1 jmmv {
138 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
139 1.1 jmmv options["kyuafile"].push_back("/my//path");
140 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
141 1.1 jmmv
142 1.1 jmmv ATF_REQUIRE_EQ("/my/path", cli::kyuafile_path(mock_cmdline).str());
143 1.1 jmmv }
144 1.1 jmmv
145 1.1 jmmv
146 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(store_path__default__create_directory__ok);
147 1.1 jmmv ATF_TEST_CASE_BODY(store_path__default__create_directory__ok)
148 1.1 jmmv {
149 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
150 1.1 jmmv options["store"].push_back(cli::store_option.default_value());
151 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
152 1.1 jmmv
153 1.1 jmmv const fs::path home("homedir");
154 1.1 jmmv utils::setenv("HOME", home.str());
155 1.1 jmmv
156 1.1 jmmv ATF_REQUIRE(!fs::exists(home / ".kyua"));
157 1.1 jmmv ATF_REQUIRE_EQ(home / ".kyua/store.db", cli::store_path(mock_cmdline));
158 1.1 jmmv ATF_REQUIRE(fs::exists(home / ".kyua"));
159 1.1 jmmv }
160 1.1 jmmv
161 1.1 jmmv
162 1.1 jmmv ATF_TEST_CASE(store_path__default__create_directory__fail);
163 1.1 jmmv ATF_TEST_CASE_HEAD(store_path__default__create_directory__fail)
164 1.1 jmmv {
165 1.1 jmmv set_md_var("require.user", "unprivileged");
166 1.1 jmmv }
167 1.1 jmmv ATF_TEST_CASE_BODY(store_path__default__create_directory__fail)
168 1.1 jmmv {
169 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
170 1.1 jmmv options["store"].push_back(cli::store_option.default_value());
171 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
172 1.1 jmmv
173 1.1 jmmv const fs::path home("homedir");
174 1.1 jmmv utils::setenv("HOME", home.str());
175 1.1 jmmv fs::mkdir(home, 0555);
176 1.1 jmmv
177 1.1 jmmv ATF_REQUIRE_THROW(fs::error, cli::store_path(mock_cmdline).str());
178 1.1 jmmv ATF_REQUIRE(!fs::exists(home / ".kyua"));
179 1.1 jmmv }
180 1.1 jmmv
181 1.1 jmmv
182 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(store_path__default__no_home);
183 1.1 jmmv ATF_TEST_CASE_BODY(store_path__default__no_home)
184 1.1 jmmv {
185 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
186 1.1 jmmv options["store"].push_back(cli::store_option.default_value());
187 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
188 1.1 jmmv
189 1.1 jmmv utils::unsetenv("HOME");
190 1.1 jmmv
191 1.1 jmmv ATF_REQUIRE_EQ("kyua-store.db", cli::store_path(mock_cmdline).str());
192 1.1 jmmv }
193 1.1 jmmv
194 1.1 jmmv
195 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(store_path__explicit);
196 1.1 jmmv ATF_TEST_CASE_BODY(store_path__explicit)
197 1.1 jmmv {
198 1.1 jmmv std::map< std::string, std::vector< std::string > > options;
199 1.1 jmmv options["store"].push_back("/my//path");
200 1.1 jmmv const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
201 1.1 jmmv
202 1.1 jmmv const fs::path home("homedir");
203 1.1 jmmv ATF_REQUIRE_EQ("/my/path", cli::store_path(mock_cmdline).str());
204 1.1 jmmv ATF_REQUIRE(!fs::exists(home / ".kyua"));
205 1.1 jmmv }
206 1.1 jmmv
207 1.1 jmmv
208 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(parse_filters__none);
209 1.1 jmmv ATF_TEST_CASE_BODY(parse_filters__none)
210 1.1 jmmv {
211 1.1 jmmv const cmdline::args_vector args;
212 1.1 jmmv const std::set< engine::test_filter > filters = cli::parse_filters(args);
213 1.1 jmmv ATF_REQUIRE(filters.empty());
214 1.1 jmmv }
215 1.1 jmmv
216 1.1 jmmv
217 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(parse_filters__ok);
218 1.1 jmmv ATF_TEST_CASE_BODY(parse_filters__ok)
219 1.1 jmmv {
220 1.1 jmmv cmdline::args_vector args;
221 1.1 jmmv args.push_back("foo");
222 1.1 jmmv args.push_back("bar/baz");
223 1.1 jmmv args.push_back("other:abc");
224 1.1 jmmv args.push_back("other:bcd");
225 1.1 jmmv const std::set< engine::test_filter > filters = cli::parse_filters(args);
226 1.1 jmmv
227 1.1 jmmv std::set< engine::test_filter > exp_filters;
228 1.1 jmmv exp_filters.insert(mkfilter("foo", ""));
229 1.1 jmmv exp_filters.insert(mkfilter("bar/baz", ""));
230 1.1 jmmv exp_filters.insert(mkfilter("other", "abc"));
231 1.1 jmmv exp_filters.insert(mkfilter("other", "bcd"));
232 1.1 jmmv
233 1.1 jmmv ATF_REQUIRE(exp_filters == filters);
234 1.1 jmmv }
235 1.1 jmmv
236 1.1 jmmv
237 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(parse_filters__duplicate);
238 1.1 jmmv ATF_TEST_CASE_BODY(parse_filters__duplicate)
239 1.1 jmmv {
240 1.1 jmmv cmdline::args_vector args;
241 1.1 jmmv args.push_back("foo/bar//baz");
242 1.1 jmmv args.push_back("hello/world:yes");
243 1.1 jmmv args.push_back("foo//bar/baz");
244 1.1 jmmv ATF_REQUIRE_THROW_RE(cmdline::error, "Duplicate.*'foo/bar/baz'",
245 1.1 jmmv cli::parse_filters(args));
246 1.1 jmmv }
247 1.1 jmmv
248 1.1 jmmv
249 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(parse_filters__nondisjoint);
250 1.1 jmmv ATF_TEST_CASE_BODY(parse_filters__nondisjoint)
251 1.1 jmmv {
252 1.1 jmmv cmdline::args_vector args;
253 1.1 jmmv args.push_back("foo/bar");
254 1.1 jmmv args.push_back("hello/world:yes");
255 1.1 jmmv args.push_back("foo/bar:baz");
256 1.1 jmmv ATF_REQUIRE_THROW_RE(cmdline::error, "'foo/bar'.*'foo/bar:baz'.*disjoint",
257 1.1 jmmv cli::parse_filters(args));
258 1.1 jmmv }
259 1.1 jmmv
260 1.1 jmmv
261 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(report_unused_filters__none);
262 1.1 jmmv ATF_TEST_CASE_BODY(report_unused_filters__none)
263 1.1 jmmv {
264 1.1 jmmv std::set< engine::test_filter > unused;
265 1.1 jmmv
266 1.1 jmmv cmdline::ui_mock ui;
267 1.1 jmmv ATF_REQUIRE(!cli::report_unused_filters(unused, &ui));
268 1.1 jmmv ATF_REQUIRE(ui.out_log().empty());
269 1.1 jmmv ATF_REQUIRE(ui.err_log().empty());
270 1.1 jmmv }
271 1.1 jmmv
272 1.1 jmmv
273 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(report_unused_filters__some);
274 1.1 jmmv ATF_TEST_CASE_BODY(report_unused_filters__some)
275 1.1 jmmv {
276 1.1 jmmv std::set< engine::test_filter > unused;
277 1.1 jmmv unused.insert(mkfilter("a/b", ""));
278 1.1 jmmv unused.insert(mkfilter("hey/d", "yes"));
279 1.1 jmmv
280 1.1 jmmv cmdline::ui_mock ui;
281 1.1 jmmv cmdline::init("progname");
282 1.1 jmmv ATF_REQUIRE(cli::report_unused_filters(unused, &ui));
283 1.1 jmmv ATF_REQUIRE(ui.out_log().empty());
284 1.1 jmmv ATF_REQUIRE_EQ(2, ui.err_log().size());
285 1.1 jmmv ATF_REQUIRE( atf::utils::grep_collection("No.*matched.*'a/b'",
286 1.1 jmmv ui.err_log()));
287 1.1 jmmv ATF_REQUIRE( atf::utils::grep_collection("No.*matched.*'hey/d:yes'",
288 1.1 jmmv ui.err_log()));
289 1.1 jmmv }
290 1.1 jmmv
291 1.1 jmmv
292 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(format_delta);
293 1.1 jmmv ATF_TEST_CASE_BODY(format_delta)
294 1.1 jmmv {
295 1.1 jmmv ATF_REQUIRE_EQ("0.000s", cli::format_delta(datetime::delta()));
296 1.1 jmmv ATF_REQUIRE_EQ("0.012s", cli::format_delta(datetime::delta(0, 12300)));
297 1.1 jmmv ATF_REQUIRE_EQ("0.999s", cli::format_delta(datetime::delta(0, 999000)));
298 1.1 jmmv ATF_REQUIRE_EQ("51.321s", cli::format_delta(datetime::delta(51, 321000)));
299 1.1 jmmv }
300 1.1 jmmv
301 1.1 jmmv
302 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(format_result__no_reason);
303 1.1 jmmv ATF_TEST_CASE_BODY(format_result__no_reason)
304 1.1 jmmv {
305 1.1 jmmv ATF_REQUIRE_EQ("passed", cli::format_result(
306 1.1 jmmv engine::test_result(engine::test_result::passed)));
307 1.1 jmmv ATF_REQUIRE_EQ("failed", cli::format_result(
308 1.1 jmmv engine::test_result(engine::test_result::failed)));
309 1.1 jmmv }
310 1.1 jmmv
311 1.1 jmmv
312 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(format_result__with_reason);
313 1.1 jmmv ATF_TEST_CASE_BODY(format_result__with_reason)
314 1.1 jmmv {
315 1.1 jmmv ATF_REQUIRE_EQ("broken: Something", cli::format_result(
316 1.1 jmmv engine::test_result(engine::test_result::broken, "Something")));
317 1.1 jmmv ATF_REQUIRE_EQ("expected_failure: A B C", cli::format_result(
318 1.1 jmmv engine::test_result(engine::test_result::expected_failure, "A B C")));
319 1.1 jmmv ATF_REQUIRE_EQ("failed: More text", cli::format_result(
320 1.1 jmmv engine::test_result(engine::test_result::failed, "More text")));
321 1.1 jmmv ATF_REQUIRE_EQ("skipped: Bye", cli::format_result(
322 1.1 jmmv engine::test_result(engine::test_result::skipped, "Bye")));
323 1.1 jmmv }
324 1.1 jmmv
325 1.1 jmmv
326 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(format_test_case_id__test_case);
327 1.1 jmmv ATF_TEST_CASE_BODY(format_test_case_id__test_case)
328 1.1 jmmv {
329 1.1 jmmv const engine::test_program test_program(
330 1.1 jmmv "mock", fs::path("foo/bar/baz"), fs::path("unused-root"),
331 1.1 jmmv "unused-suite-name", engine::metadata_builder().build());
332 1.1 jmmv const engine::test_case test_case("mock", test_program, "abc",
333 1.1 jmmv engine::metadata_builder().build());
334 1.1 jmmv ATF_REQUIRE_EQ("foo/bar/baz:abc", cli::format_test_case_id(test_case));
335 1.1 jmmv }
336 1.1 jmmv
337 1.1 jmmv
338 1.1 jmmv ATF_TEST_CASE_WITHOUT_HEAD(format_test_case_id__test_filter);
339 1.1 jmmv ATF_TEST_CASE_BODY(format_test_case_id__test_filter)
340 1.1 jmmv {
341 1.1 jmmv const engine::test_filter filter(fs::path("foo/bar"), "baz");
342 1.1 jmmv ATF_REQUIRE_EQ("foo/bar:baz", cli::format_test_case_id(filter));
343 1.1 jmmv }
344 1.1 jmmv
345 1.1 jmmv
346 1.1 jmmv ATF_INIT_TEST_CASES(tcs)
347 1.1 jmmv {
348 1.1 jmmv ATF_ADD_TEST_CASE(tcs, build_root_path__default);
349 1.1 jmmv ATF_ADD_TEST_CASE(tcs, build_root_path__explicit);
350 1.1 jmmv
351 1.1 jmmv ATF_ADD_TEST_CASE(tcs, get_home__ok);
352 1.1 jmmv ATF_ADD_TEST_CASE(tcs, get_home__missing);
353 1.1 jmmv ATF_ADD_TEST_CASE(tcs, get_home__invalid);
354 1.1 jmmv
355 1.1 jmmv ATF_ADD_TEST_CASE(tcs, kyuafile_path__default);
356 1.1 jmmv ATF_ADD_TEST_CASE(tcs, kyuafile_path__explicit);
357 1.1 jmmv
358 1.1 jmmv ATF_ADD_TEST_CASE(tcs, store_path__default__create_directory__ok);
359 1.1 jmmv ATF_ADD_TEST_CASE(tcs, store_path__default__create_directory__fail);
360 1.1 jmmv ATF_ADD_TEST_CASE(tcs, store_path__default__no_home);
361 1.1 jmmv ATF_ADD_TEST_CASE(tcs, store_path__explicit);
362 1.1 jmmv
363 1.1 jmmv ATF_ADD_TEST_CASE(tcs, parse_filters__none);
364 1.1 jmmv ATF_ADD_TEST_CASE(tcs, parse_filters__ok);
365 1.1 jmmv ATF_ADD_TEST_CASE(tcs, parse_filters__duplicate);
366 1.1 jmmv ATF_ADD_TEST_CASE(tcs, parse_filters__nondisjoint);
367 1.1 jmmv
368 1.1 jmmv ATF_ADD_TEST_CASE(tcs, report_unused_filters__none);
369 1.1 jmmv ATF_ADD_TEST_CASE(tcs, report_unused_filters__some);
370 1.1 jmmv
371 1.1 jmmv ATF_ADD_TEST_CASE(tcs, format_delta);
372 1.1 jmmv
373 1.1 jmmv ATF_ADD_TEST_CASE(tcs, format_result__no_reason);
374 1.1 jmmv ATF_ADD_TEST_CASE(tcs, format_result__with_reason);
375 1.1 jmmv
376 1.1 jmmv ATF_ADD_TEST_CASE(tcs, format_test_case_id__test_case);
377 1.1 jmmv ATF_ADD_TEST_CASE(tcs, format_test_case_id__test_filter);
378 1.1 jmmv }
379