1// Copyright 2014 The Kyua Authors. 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 "store/layout.hpp" 30 31extern "C" { 32#include <unistd.h> 33} 34 35#include <iostream> 36 37#include <atf-c++.hpp> 38 39#include "store/exceptions.hpp" 40#include "store/layout.hpp" 41#include "utils/datetime.hpp" 42#include "utils/env.hpp" 43#include "utils/fs/operations.hpp" 44#include "utils/fs/path.hpp" 45 46namespace datetime = utils::datetime; 47namespace fs = utils::fs; 48namespace layout = store::layout; 49 50 51ATF_TEST_CASE_WITHOUT_HEAD(find_results__latest); 52ATF_TEST_CASE_BODY(find_results__latest) 53{ 54 const fs::path store_dir = layout::query_store_dir(); 55 fs::mkdir_p(store_dir, 0755); 56 57 const std::string test_suite = layout::test_suite_for_path( 58 fs::current_path()); 59 const std::string base = (store_dir / ( 60 "results." + test_suite + ".")).str(); 61 62 atf::utils::create_file(base + "20140613-194515-000000.db", ""); 63 ATF_REQUIRE_EQ(base + "20140613-194515-000000.db", 64 layout::find_results("LATEST").str()); 65 66 atf::utils::create_file(base + "20140614-194515-123456.db", ""); 67 ATF_REQUIRE_EQ(base + "20140614-194515-123456.db", 68 layout::find_results("LATEST").str()); 69 70 atf::utils::create_file(base + "20130614-194515-999999.db", ""); 71 ATF_REQUIRE_EQ(base + "20140614-194515-123456.db", 72 layout::find_results("LATEST").str()); 73} 74 75 76ATF_TEST_CASE_WITHOUT_HEAD(find_results__directory); 77ATF_TEST_CASE_BODY(find_results__directory) 78{ 79 const fs::path store_dir = layout::query_store_dir(); 80 fs::mkdir_p(store_dir, 0755); 81 82 const fs::path dir1("dir1/foo"); 83 fs::mkdir_p(dir1, 0755); 84 const fs::path dir2("dir1/bar"); 85 fs::mkdir_p(dir2, 0755); 86 87 const std::string base1 = (store_dir / ( 88 "results." + layout::test_suite_for_path(dir1) + ".")).str(); 89 const std::string base2 = (store_dir / ( 90 "results." + layout::test_suite_for_path(dir2) + ".")).str(); 91 92 atf::utils::create_file(base1 + "20140613-194515-000000.db", ""); 93 ATF_REQUIRE_EQ(base1 + "20140613-194515-000000.db", 94 layout::find_results(dir1.str()).str()); 95 96 atf::utils::create_file(base2 + "20140615-111111-000000.db", ""); 97 ATF_REQUIRE_EQ(base2 + "20140615-111111-000000.db", 98 layout::find_results(dir2.str()).str()); 99 100 atf::utils::create_file(base1 + "20140614-194515-123456.db", ""); 101 ATF_REQUIRE_EQ(base1 + "20140614-194515-123456.db", 102 layout::find_results(dir1.str()).str()); 103 104 atf::utils::create_file(base1 + "20130614-194515-999999.db", ""); 105 ATF_REQUIRE_EQ(base1 + "20140614-194515-123456.db", 106 layout::find_results(dir1.str()).str()); 107} 108 109 110ATF_TEST_CASE_WITHOUT_HEAD(find_results__file); 111ATF_TEST_CASE_BODY(find_results__file) 112{ 113 const fs::path store_dir = layout::query_store_dir(); 114 fs::mkdir_p(store_dir, 0755); 115 116 atf::utils::create_file("a-file.db", ""); 117 ATF_REQUIRE_EQ(fs::path("a-file.db").to_absolute(), 118 layout::find_results("a-file.db")); 119} 120 121 122ATF_TEST_CASE_WITHOUT_HEAD(find_results__id); 123ATF_TEST_CASE_BODY(find_results__id) 124{ 125 const fs::path store_dir = layout::query_store_dir(); 126 fs::mkdir_p(store_dir, 0755); 127 128 const fs::path dir1("dir1/foo"); 129 fs::mkdir_p(dir1, 0755); 130 const fs::path dir2("dir1/bar"); 131 fs::mkdir_p(dir2, 0755); 132 133 const std::string id1 = layout::test_suite_for_path(dir1); 134 const std::string base1 = (store_dir / ("results." + id1 + ".")).str(); 135 const std::string id2 = layout::test_suite_for_path(dir2); 136 const std::string base2 = (store_dir / ("results." + id2 + ".")).str(); 137 138 atf::utils::create_file(base1 + "20140613-194515-000000.db", ""); 139 ATF_REQUIRE_EQ(base1 + "20140613-194515-000000.db", 140 layout::find_results(id1).str()); 141 142 atf::utils::create_file(base2 + "20140615-111111-000000.db", ""); 143 ATF_REQUIRE_EQ(base2 + "20140615-111111-000000.db", 144 layout::find_results(id2).str()); 145 146 atf::utils::create_file(base1 + "20140614-194515-123456.db", ""); 147 ATF_REQUIRE_EQ(base1 + "20140614-194515-123456.db", 148 layout::find_results(id1).str()); 149 150 atf::utils::create_file(base1 + "20130614-194515-999999.db", ""); 151 ATF_REQUIRE_EQ(base1 + "20140614-194515-123456.db", 152 layout::find_results(id1).str()); 153} 154 155 156ATF_TEST_CASE_WITHOUT_HEAD(find_results__id_with_timestamp); 157ATF_TEST_CASE_BODY(find_results__id_with_timestamp) 158{ 159 const fs::path store_dir = layout::query_store_dir(); 160 fs::mkdir_p(store_dir, 0755); 161 162 const fs::path dir1("dir1/foo"); 163 fs::mkdir_p(dir1, 0755); 164 const fs::path dir2("dir1/bar"); 165 fs::mkdir_p(dir2, 0755); 166 167 const std::string id1 = layout::test_suite_for_path(dir1); 168 const std::string base1 = (store_dir / ("results." + id1 + ".")).str(); 169 const std::string id2 = layout::test_suite_for_path(dir2); 170 const std::string base2 = (store_dir / ("results." + id2 + ".")).str(); 171 172 atf::utils::create_file(base1 + "20140613-194515-000000.db", ""); 173 atf::utils::create_file(base2 + "20140615-111111-000000.db", ""); 174 atf::utils::create_file(base1 + "20140614-194515-123456.db", ""); 175 atf::utils::create_file(base1 + "20130614-194515-999999.db", ""); 176 177 ATF_REQUIRE_MATCH( 178 "_dir1_foo.20140613-194515-000000.db$", 179 layout::find_results(id1 + ".20140613-194515-000000").str()); 180 181 ATF_REQUIRE_MATCH( 182 "_dir1_foo.20140614-194515-123456.db$", 183 layout::find_results(id1 + ".20140614-194515-123456").str()); 184 185 ATF_REQUIRE_MATCH( 186 "_dir1_bar.20140615-111111-000000.db$", 187 layout::find_results(id2 + ".20140615-111111-000000").str()); 188} 189 190 191ATF_TEST_CASE_WITHOUT_HEAD(find_results__not_found); 192ATF_TEST_CASE_BODY(find_results__not_found) 193{ 194 ATF_REQUIRE_THROW_RE( 195 store::error, 196 "No previous results file found for test suite foo_bar", 197 layout::find_results("foo_bar")); 198 199 const fs::path store_dir = layout::query_store_dir(); 200 fs::mkdir_p(store_dir, 0755); 201 ATF_REQUIRE_THROW_RE( 202 store::error, 203 "No previous results file found for test suite foo_bar", 204 layout::find_results("foo_bar")); 205 206 const char* candidates[] = { 207 "results.foo.20140613-194515-012345.db", // Bad test suite. 208 "results.foo_bar.20140613-194515-012345", // Missing extension. 209 "foo_bar.20140613-194515-012345.db", // Missing prefix. 210 "results.foo_bar.2010613-194515-012345.db", // Bad date. 211 "results.foo_bar.20140613-19515-012345.db", // Bad time. 212 "results.foo_bar.20140613-194515-01245.db", // Bad microseconds. 213 NULL, 214 }; 215 for (const char** candidate = candidates; *candidate != NULL; ++candidate) { 216 std::cout << "Current candidate: " << *candidate << '\n'; 217 atf::utils::create_file((store_dir / *candidate).str(), ""); 218 ATF_REQUIRE_THROW_RE( 219 store::error, 220 "No previous results file found for test suite foo_bar", 221 layout::find_results("foo_bar")); 222 } 223 224 atf::utils::create_file( 225 (store_dir / "results.foo_bar.20140613-194515-012345.db").str(), ""); 226 layout::find_results("foo_bar"); // Expected not to throw. 227} 228 229 230ATF_TEST_CASE_WITHOUT_HEAD(new_db__new); 231ATF_TEST_CASE_BODY(new_db__new) 232{ 233 datetime::set_mock_now(2014, 6, 13, 19, 45, 15, 5000); 234 ATF_REQUIRE(!fs::exists(fs::path(".kyua/store"))); 235 const layout::results_id_file_pair results = layout::new_db( 236 "NEW", fs::path("/some/path/to/the/suite")); 237 ATF_REQUIRE( fs::exists(fs::path(".kyua/store"))); 238 ATF_REQUIRE( fs::is_directory(fs::path(".kyua/store"))); 239 240 const std::string id = "some_path_to_the_suite.20140613-194515-005000"; 241 ATF_REQUIRE_EQ(id, results.first); 242 ATF_REQUIRE_EQ(layout::query_store_dir() / ("results." + id + ".db"), 243 results.second); 244} 245 246 247ATF_TEST_CASE_WITHOUT_HEAD(new_db__explicit); 248ATF_TEST_CASE_BODY(new_db__explicit) 249{ 250 ATF_REQUIRE(!fs::exists(fs::path(".kyua/store"))); 251 const layout::results_id_file_pair results = layout::new_db( 252 "foo/results-file.db", fs::path("unused")); 253 ATF_REQUIRE(!fs::exists(fs::path(".kyua/store"))); 254 ATF_REQUIRE(!fs::exists(fs::path("foo"))); 255 256 ATF_REQUIRE(results.first.empty()); 257 ATF_REQUIRE_EQ(fs::path("foo/results-file.db"), results.second); 258} 259 260 261ATF_TEST_CASE_WITHOUT_HEAD(new_db_for_migration); 262ATF_TEST_CASE_BODY(new_db_for_migration) 263{ 264 ATF_REQUIRE(!fs::exists(fs::path(".kyua/store"))); 265 const fs::path results_file = layout::new_db_for_migration( 266 fs::path("/some/root"), 267 datetime::timestamp::from_values(2014, 7, 30, 10, 5, 20, 76500)); 268 ATF_REQUIRE( fs::exists(fs::path(".kyua/store"))); 269 ATF_REQUIRE( fs::is_directory(fs::path(".kyua/store"))); 270 271 ATF_REQUIRE_EQ( 272 layout::query_store_dir() / 273 "results.some_root.20140730-100520-076500.db", 274 results_file); 275} 276 277 278ATF_TEST_CASE_WITHOUT_HEAD(query_store_dir__home_absolute); 279ATF_TEST_CASE_BODY(query_store_dir__home_absolute) 280{ 281 const fs::path home = fs::current_path() / "homedir"; 282 utils::setenv("HOME", home.str()); 283 const fs::path store_dir = layout::query_store_dir(); 284 ATF_REQUIRE(store_dir.is_absolute()); 285 ATF_REQUIRE_EQ(home / ".kyua/store", store_dir); 286} 287 288 289ATF_TEST_CASE_WITHOUT_HEAD(query_store_dir__home_relative); 290ATF_TEST_CASE_BODY(query_store_dir__home_relative) 291{ 292 const fs::path home("homedir"); 293 utils::setenv("HOME", home.str()); 294 const fs::path store_dir = layout::query_store_dir(); 295 ATF_REQUIRE(store_dir.is_absolute()); 296 ATF_REQUIRE_MATCH((home / ".kyua/store").str(), store_dir.str()); 297} 298 299 300ATF_TEST_CASE_WITHOUT_HEAD(query_store_dir__no_home); 301ATF_TEST_CASE_BODY(query_store_dir__no_home) 302{ 303 utils::unsetenv("HOME"); 304 ATF_REQUIRE_EQ(fs::current_path(), layout::query_store_dir()); 305} 306 307 308ATF_TEST_CASE_WITHOUT_HEAD(test_suite_for_path__absolute); 309ATF_TEST_CASE_BODY(test_suite_for_path__absolute) 310{ 311 ATF_REQUIRE_EQ("dir1_dir2_dir3", 312 layout::test_suite_for_path(fs::path("/dir1/dir2/dir3"))); 313 ATF_REQUIRE_EQ("dir1", 314 layout::test_suite_for_path(fs::path("/dir1"))); 315 ATF_REQUIRE_EQ("dir1_dir2", 316 layout::test_suite_for_path(fs::path("/dir1///dir2"))); 317} 318 319 320ATF_TEST_CASE_WITHOUT_HEAD(test_suite_for_path__relative); 321ATF_TEST_CASE_BODY(test_suite_for_path__relative) 322{ 323 const std::string test_suite = layout::test_suite_for_path( 324 fs::path("foo/bar")); 325 ATF_REQUIRE_MATCH("_foo_bar$", test_suite); 326 ATF_REQUIRE_MATCH("^[^_]", test_suite); 327} 328 329 330ATF_INIT_TEST_CASES(tcs) 331{ 332 ATF_ADD_TEST_CASE(tcs, find_results__latest); 333 ATF_ADD_TEST_CASE(tcs, find_results__directory); 334 ATF_ADD_TEST_CASE(tcs, find_results__file); 335 ATF_ADD_TEST_CASE(tcs, find_results__id); 336 ATF_ADD_TEST_CASE(tcs, find_results__id_with_timestamp); 337 ATF_ADD_TEST_CASE(tcs, find_results__not_found); 338 339 ATF_ADD_TEST_CASE(tcs, new_db__new); 340 ATF_ADD_TEST_CASE(tcs, new_db__explicit); 341 342 ATF_ADD_TEST_CASE(tcs, new_db_for_migration); 343 344 ATF_ADD_TEST_CASE(tcs, query_store_dir__home_absolute); 345 ATF_ADD_TEST_CASE(tcs, query_store_dir__home_relative); 346 ATF_ADD_TEST_CASE(tcs, query_store_dir__no_home); 347 348 ATF_ADD_TEST_CASE(tcs, test_suite_for_path__absolute); 349 ATF_ADD_TEST_CASE(tcs, test_suite_for_path__relative); 350} 351