xref: /netbsd-src/external/bsd/kyua-cli/dist/store/backend_test.cpp (revision 6b3a42af15b5e090c339512c790dd68f3d11a9d8)
1*6b3a42afSjmmv // Copyright 2011 Google Inc.
2*6b3a42afSjmmv // All rights reserved.
3*6b3a42afSjmmv //
4*6b3a42afSjmmv // Redistribution and use in source and binary forms, with or without
5*6b3a42afSjmmv // modification, are permitted provided that the following conditions are
6*6b3a42afSjmmv // met:
7*6b3a42afSjmmv //
8*6b3a42afSjmmv // * Redistributions of source code must retain the above copyright
9*6b3a42afSjmmv //   notice, this list of conditions and the following disclaimer.
10*6b3a42afSjmmv // * Redistributions in binary form must reproduce the above copyright
11*6b3a42afSjmmv //   notice, this list of conditions and the following disclaimer in the
12*6b3a42afSjmmv //   documentation and/or other materials provided with the distribution.
13*6b3a42afSjmmv // * Neither the name of Google Inc. nor the names of its contributors
14*6b3a42afSjmmv //   may be used to endorse or promote products derived from this software
15*6b3a42afSjmmv //   without specific prior written permission.
16*6b3a42afSjmmv //
17*6b3a42afSjmmv // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*6b3a42afSjmmv // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*6b3a42afSjmmv // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*6b3a42afSjmmv // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*6b3a42afSjmmv // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*6b3a42afSjmmv // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*6b3a42afSjmmv // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*6b3a42afSjmmv // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*6b3a42afSjmmv // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*6b3a42afSjmmv // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*6b3a42afSjmmv // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*6b3a42afSjmmv 
29*6b3a42afSjmmv #include "store/backend.hpp"
30*6b3a42afSjmmv 
31*6b3a42afSjmmv extern "C" {
32*6b3a42afSjmmv #include <sys/stat.h>
33*6b3a42afSjmmv }
34*6b3a42afSjmmv 
35*6b3a42afSjmmv #include <atf-c++.hpp>
36*6b3a42afSjmmv 
37*6b3a42afSjmmv #include "store/exceptions.hpp"
38*6b3a42afSjmmv #include "store/metadata.hpp"
39*6b3a42afSjmmv #include "utils/datetime.hpp"
40*6b3a42afSjmmv #include "utils/env.hpp"
41*6b3a42afSjmmv #include "utils/fs/operations.hpp"
42*6b3a42afSjmmv #include "utils/fs/path.hpp"
43*6b3a42afSjmmv #include "utils/logging/operations.hpp"
44*6b3a42afSjmmv #include "utils/sqlite/database.hpp"
45*6b3a42afSjmmv #include "utils/sqlite/statement.ipp"
46*6b3a42afSjmmv 
47*6b3a42afSjmmv namespace datetime = utils::datetime;
48*6b3a42afSjmmv namespace fs = utils::fs;
49*6b3a42afSjmmv namespace logging = utils::logging;
50*6b3a42afSjmmv namespace sqlite = utils::sqlite;
51*6b3a42afSjmmv 
52*6b3a42afSjmmv 
53*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__backup_database__ok);
ATF_TEST_CASE_BODY(detail__backup_database__ok)54*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__backup_database__ok)
55*6b3a42afSjmmv {
56*6b3a42afSjmmv     atf::utils::create_file("test.db", "The DB\n");
57*6b3a42afSjmmv     store::detail::backup_database(fs::path("test.db"), 13);
58*6b3a42afSjmmv     ATF_REQUIRE(fs::exists(fs::path("test.db")));
59*6b3a42afSjmmv     ATF_REQUIRE(fs::exists(fs::path("test.db.v13.backup")));
60*6b3a42afSjmmv     ATF_REQUIRE(atf::utils::compare_file("test.db.v13.backup", "The DB\n"));
61*6b3a42afSjmmv }
62*6b3a42afSjmmv 
63*6b3a42afSjmmv 
64*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__backup_database__ok_overwrite);
ATF_TEST_CASE_BODY(detail__backup_database__ok_overwrite)65*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__backup_database__ok_overwrite)
66*6b3a42afSjmmv {
67*6b3a42afSjmmv     atf::utils::create_file("test.db", "Original contents");
68*6b3a42afSjmmv     atf::utils::create_file("test.db.v1.backup", "Overwrite me");
69*6b3a42afSjmmv     store::detail::backup_database(fs::path("test.db"), 1);
70*6b3a42afSjmmv     ATF_REQUIRE(fs::exists(fs::path("test.db")));
71*6b3a42afSjmmv     ATF_REQUIRE(fs::exists(fs::path("test.db.v1.backup")));
72*6b3a42afSjmmv     ATF_REQUIRE(atf::utils::compare_file("test.db.v1.backup",
73*6b3a42afSjmmv                                          "Original contents"));
74*6b3a42afSjmmv }
75*6b3a42afSjmmv 
76*6b3a42afSjmmv 
77*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__backup_database__fail_open);
ATF_TEST_CASE_BODY(detail__backup_database__fail_open)78*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__backup_database__fail_open)
79*6b3a42afSjmmv {
80*6b3a42afSjmmv     ATF_REQUIRE_THROW_RE(store::error, "Cannot open.*foo.db",
81*6b3a42afSjmmv                          store::detail::backup_database(fs::path("foo.db"), 5));
82*6b3a42afSjmmv }
83*6b3a42afSjmmv 
84*6b3a42afSjmmv 
85*6b3a42afSjmmv ATF_TEST_CASE(detail__backup_database__fail_create);
ATF_TEST_CASE_HEAD(detail__backup_database__fail_create)86*6b3a42afSjmmv ATF_TEST_CASE_HEAD(detail__backup_database__fail_create)
87*6b3a42afSjmmv {
88*6b3a42afSjmmv     set_md_var("require.user", "unprivileged");
89*6b3a42afSjmmv }
ATF_TEST_CASE_BODY(detail__backup_database__fail_create)90*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__backup_database__fail_create)
91*6b3a42afSjmmv {
92*6b3a42afSjmmv     ATF_REQUIRE(::mkdir("dir", 0755) != -1);
93*6b3a42afSjmmv     atf::utils::create_file("dir/test.db", "Does not need to be valid");
94*6b3a42afSjmmv     ATF_REQUIRE(::chmod("dir", 0111) != -1);
95*6b3a42afSjmmv     ATF_REQUIRE_THROW_RE(
96*6b3a42afSjmmv         store::error, "Cannot create.*dir/test.db.v13.backup",
97*6b3a42afSjmmv         store::detail::backup_database(fs::path("dir/test.db"), 13));
98*6b3a42afSjmmv }
99*6b3a42afSjmmv 
100*6b3a42afSjmmv 
101*6b3a42afSjmmv ATF_TEST_CASE(detail__initialize__ok);
ATF_TEST_CASE_HEAD(detail__initialize__ok)102*6b3a42afSjmmv ATF_TEST_CASE_HEAD(detail__initialize__ok)
103*6b3a42afSjmmv {
104*6b3a42afSjmmv     logging::set_inmemory();
105*6b3a42afSjmmv     set_md_var("require.files", store::detail::schema_file().c_str());
106*6b3a42afSjmmv }
ATF_TEST_CASE_BODY(detail__initialize__ok)107*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__initialize__ok)
108*6b3a42afSjmmv {
109*6b3a42afSjmmv     sqlite::database db = sqlite::database::in_memory();
110*6b3a42afSjmmv     const datetime::timestamp before = datetime::timestamp::now();
111*6b3a42afSjmmv     const store::metadata md = store::detail::initialize(db);
112*6b3a42afSjmmv     const datetime::timestamp after = datetime::timestamp::now();
113*6b3a42afSjmmv 
114*6b3a42afSjmmv     ATF_REQUIRE(md.timestamp() >= before.to_seconds());
115*6b3a42afSjmmv     ATF_REQUIRE(md.timestamp() <= after.to_microseconds());
116*6b3a42afSjmmv     ATF_REQUIRE_EQ(store::detail::current_schema_version, md.schema_version());
117*6b3a42afSjmmv 
118*6b3a42afSjmmv     // Query some known tables to ensure they were created.
119*6b3a42afSjmmv     db.exec("SELECT * FROM metadata");
120*6b3a42afSjmmv 
121*6b3a42afSjmmv     // And now query some know values.
122*6b3a42afSjmmv     sqlite::statement stmt = db.create_statement(
123*6b3a42afSjmmv         "SELECT COUNT(*) FROM metadata");
124*6b3a42afSjmmv     ATF_REQUIRE(stmt.step());
125*6b3a42afSjmmv     ATF_REQUIRE_EQ(1, stmt.column_int(0));
126*6b3a42afSjmmv     ATF_REQUIRE(!stmt.step());
127*6b3a42afSjmmv }
128*6b3a42afSjmmv 
129*6b3a42afSjmmv 
130*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__initialize__missing_schema);
ATF_TEST_CASE_BODY(detail__initialize__missing_schema)131*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__initialize__missing_schema)
132*6b3a42afSjmmv {
133*6b3a42afSjmmv     utils::setenv("KYUA_STOREDIR", "/non-existent");
134*6b3a42afSjmmv     store::detail::current_schema_version = 712;
135*6b3a42afSjmmv 
136*6b3a42afSjmmv     sqlite::database db = sqlite::database::in_memory();
137*6b3a42afSjmmv     ATF_REQUIRE_THROW_RE(store::error,
138*6b3a42afSjmmv                          "Cannot open.*'/non-existent/schema_v712.sql'",
139*6b3a42afSjmmv                          store::detail::initialize(db));
140*6b3a42afSjmmv }
141*6b3a42afSjmmv 
142*6b3a42afSjmmv 
143*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__initialize__sqlite_error);
ATF_TEST_CASE_BODY(detail__initialize__sqlite_error)144*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__initialize__sqlite_error)
145*6b3a42afSjmmv {
146*6b3a42afSjmmv     utils::setenv("KYUA_STOREDIR", ".");
147*6b3a42afSjmmv     store::detail::current_schema_version = 712;
148*6b3a42afSjmmv 
149*6b3a42afSjmmv     atf::utils::create_file("schema_v712.sql", "foo_bar_baz;\n");
150*6b3a42afSjmmv 
151*6b3a42afSjmmv     sqlite::database db = sqlite::database::in_memory();
152*6b3a42afSjmmv     ATF_REQUIRE_THROW_RE(store::error, "Failed to initialize.*:.*foo_bar_baz",
153*6b3a42afSjmmv                          store::detail::initialize(db));
154*6b3a42afSjmmv }
155*6b3a42afSjmmv 
156*6b3a42afSjmmv 
157*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__migration_file__builtin);
ATF_TEST_CASE_BODY(detail__migration_file__builtin)158*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__migration_file__builtin)
159*6b3a42afSjmmv {
160*6b3a42afSjmmv     utils::unsetenv("KYUA_STOREDIR");
161*6b3a42afSjmmv     ATF_REQUIRE_EQ(fs::path(KYUA_STOREDIR) / "migrate_v5_v9.sql",
162*6b3a42afSjmmv                    store::detail::migration_file(5, 9));
163*6b3a42afSjmmv }
164*6b3a42afSjmmv 
165*6b3a42afSjmmv 
166*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__migration_file__overriden);
ATF_TEST_CASE_BODY(detail__migration_file__overriden)167*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__migration_file__overriden)
168*6b3a42afSjmmv {
169*6b3a42afSjmmv     utils::setenv("KYUA_STOREDIR", "/tmp/test");
170*6b3a42afSjmmv     ATF_REQUIRE_EQ(fs::path("/tmp/test/migrate_v5_v9.sql"),
171*6b3a42afSjmmv                    store::detail::migration_file(5, 9));
172*6b3a42afSjmmv }
173*6b3a42afSjmmv 
174*6b3a42afSjmmv 
175*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__schema_file__builtin);
ATF_TEST_CASE_BODY(detail__schema_file__builtin)176*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__schema_file__builtin)
177*6b3a42afSjmmv {
178*6b3a42afSjmmv     utils::unsetenv("KYUA_STOREDIR");
179*6b3a42afSjmmv     ATF_REQUIRE_EQ(fs::path(KYUA_STOREDIR) / "schema_v2.sql",
180*6b3a42afSjmmv                    store::detail::schema_file());
181*6b3a42afSjmmv }
182*6b3a42afSjmmv 
183*6b3a42afSjmmv 
184*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(detail__schema_file__overriden);
ATF_TEST_CASE_BODY(detail__schema_file__overriden)185*6b3a42afSjmmv ATF_TEST_CASE_BODY(detail__schema_file__overriden)
186*6b3a42afSjmmv {
187*6b3a42afSjmmv     utils::setenv("KYUA_STOREDIR", "/tmp/test");
188*6b3a42afSjmmv     store::detail::current_schema_version = 123;
189*6b3a42afSjmmv     ATF_REQUIRE_EQ(fs::path("/tmp/test/schema_v123.sql"),
190*6b3a42afSjmmv                    store::detail::schema_file());
191*6b3a42afSjmmv }
192*6b3a42afSjmmv 
193*6b3a42afSjmmv 
194*6b3a42afSjmmv ATF_TEST_CASE(backend__open_ro__ok);
ATF_TEST_CASE_HEAD(backend__open_ro__ok)195*6b3a42afSjmmv ATF_TEST_CASE_HEAD(backend__open_ro__ok)
196*6b3a42afSjmmv {
197*6b3a42afSjmmv     logging::set_inmemory();
198*6b3a42afSjmmv     set_md_var("require.files", store::detail::schema_file().c_str());
199*6b3a42afSjmmv }
ATF_TEST_CASE_BODY(backend__open_ro__ok)200*6b3a42afSjmmv ATF_TEST_CASE_BODY(backend__open_ro__ok)
201*6b3a42afSjmmv {
202*6b3a42afSjmmv     {
203*6b3a42afSjmmv         sqlite::database db = sqlite::database::open(
204*6b3a42afSjmmv             fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create);
205*6b3a42afSjmmv         store::detail::initialize(db);
206*6b3a42afSjmmv     }
207*6b3a42afSjmmv     store::backend backend = store::backend::open_ro(fs::path("test.db"));
208*6b3a42afSjmmv     backend.database().exec("SELECT * FROM metadata");
209*6b3a42afSjmmv }
210*6b3a42afSjmmv 
211*6b3a42afSjmmv 
212*6b3a42afSjmmv ATF_TEST_CASE_WITHOUT_HEAD(backend__open_ro__missing_file);
ATF_TEST_CASE_BODY(backend__open_ro__missing_file)213*6b3a42afSjmmv ATF_TEST_CASE_BODY(backend__open_ro__missing_file)
214*6b3a42afSjmmv {
215*6b3a42afSjmmv     ATF_REQUIRE_THROW_RE(store::error, "Cannot open 'missing.db': ",
216*6b3a42afSjmmv                          store::backend::open_ro(fs::path("missing.db")));
217*6b3a42afSjmmv     ATF_REQUIRE(!fs::exists(fs::path("missing.db")));
218*6b3a42afSjmmv }
219*6b3a42afSjmmv 
220*6b3a42afSjmmv 
221*6b3a42afSjmmv ATF_TEST_CASE(backend__open_ro__integrity_error);
ATF_TEST_CASE_HEAD(backend__open_ro__integrity_error)222*6b3a42afSjmmv ATF_TEST_CASE_HEAD(backend__open_ro__integrity_error)
223*6b3a42afSjmmv {
224*6b3a42afSjmmv     logging::set_inmemory();
225*6b3a42afSjmmv     set_md_var("require.files", store::detail::schema_file().c_str());
226*6b3a42afSjmmv }
ATF_TEST_CASE_BODY(backend__open_ro__integrity_error)227*6b3a42afSjmmv ATF_TEST_CASE_BODY(backend__open_ro__integrity_error)
228*6b3a42afSjmmv {
229*6b3a42afSjmmv     {
230*6b3a42afSjmmv         sqlite::database db = sqlite::database::open(
231*6b3a42afSjmmv             fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create);
232*6b3a42afSjmmv         store::detail::initialize(db);
233*6b3a42afSjmmv         db.exec("DELETE FROM metadata");
234*6b3a42afSjmmv     }
235*6b3a42afSjmmv     ATF_REQUIRE_THROW_RE(store::integrity_error, "metadata.*empty",
236*6b3a42afSjmmv                          store::backend::open_ro(fs::path("test.db")));
237*6b3a42afSjmmv }
238*6b3a42afSjmmv 
239*6b3a42afSjmmv 
240*6b3a42afSjmmv ATF_TEST_CASE(backend__open_rw__ok);
ATF_TEST_CASE_HEAD(backend__open_rw__ok)241*6b3a42afSjmmv ATF_TEST_CASE_HEAD(backend__open_rw__ok)
242*6b3a42afSjmmv {
243*6b3a42afSjmmv     logging::set_inmemory();
244*6b3a42afSjmmv     set_md_var("require.files", store::detail::schema_file().c_str());
245*6b3a42afSjmmv }
ATF_TEST_CASE_BODY(backend__open_rw__ok)246*6b3a42afSjmmv ATF_TEST_CASE_BODY(backend__open_rw__ok)
247*6b3a42afSjmmv {
248*6b3a42afSjmmv     {
249*6b3a42afSjmmv         sqlite::database db = sqlite::database::open(
250*6b3a42afSjmmv             fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create);
251*6b3a42afSjmmv         store::detail::initialize(db);
252*6b3a42afSjmmv     }
253*6b3a42afSjmmv     store::backend backend = store::backend::open_rw(fs::path("test.db"));
254*6b3a42afSjmmv     backend.database().exec("SELECT * FROM metadata");
255*6b3a42afSjmmv }
256*6b3a42afSjmmv 
257*6b3a42afSjmmv 
258*6b3a42afSjmmv ATF_TEST_CASE(backend__open_rw__create_missing);
ATF_TEST_CASE_HEAD(backend__open_rw__create_missing)259*6b3a42afSjmmv ATF_TEST_CASE_HEAD(backend__open_rw__create_missing)
260*6b3a42afSjmmv {
261*6b3a42afSjmmv     logging::set_inmemory();
262*6b3a42afSjmmv     set_md_var("require.files", store::detail::schema_file().c_str());
263*6b3a42afSjmmv }
ATF_TEST_CASE_BODY(backend__open_rw__create_missing)264*6b3a42afSjmmv ATF_TEST_CASE_BODY(backend__open_rw__create_missing)
265*6b3a42afSjmmv {
266*6b3a42afSjmmv     store::backend backend = store::backend::open_rw(fs::path("test.db"));
267*6b3a42afSjmmv     backend.database().exec("SELECT * FROM metadata");
268*6b3a42afSjmmv }
269*6b3a42afSjmmv 
270*6b3a42afSjmmv 
271*6b3a42afSjmmv ATF_TEST_CASE(backend__open_rw__integrity_error);
ATF_TEST_CASE_HEAD(backend__open_rw__integrity_error)272*6b3a42afSjmmv ATF_TEST_CASE_HEAD(backend__open_rw__integrity_error)
273*6b3a42afSjmmv {
274*6b3a42afSjmmv     logging::set_inmemory();
275*6b3a42afSjmmv     set_md_var("require.files", store::detail::schema_file().c_str());
276*6b3a42afSjmmv }
ATF_TEST_CASE_BODY(backend__open_rw__integrity_error)277*6b3a42afSjmmv ATF_TEST_CASE_BODY(backend__open_rw__integrity_error)
278*6b3a42afSjmmv {
279*6b3a42afSjmmv     {
280*6b3a42afSjmmv         sqlite::database db = sqlite::database::open(
281*6b3a42afSjmmv             fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create);
282*6b3a42afSjmmv         store::detail::initialize(db);
283*6b3a42afSjmmv         db.exec("DELETE FROM metadata");
284*6b3a42afSjmmv     }
285*6b3a42afSjmmv     ATF_REQUIRE_THROW_RE(store::integrity_error, "metadata.*empty",
286*6b3a42afSjmmv                          store::backend::open_rw(fs::path("test.db")));
287*6b3a42afSjmmv }
288*6b3a42afSjmmv 
289*6b3a42afSjmmv 
ATF_INIT_TEST_CASES(tcs)290*6b3a42afSjmmv ATF_INIT_TEST_CASES(tcs)
291*6b3a42afSjmmv {
292*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__backup_database__ok);
293*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__backup_database__ok_overwrite);
294*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__backup_database__fail_open);
295*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__backup_database__fail_create);
296*6b3a42afSjmmv 
297*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__initialize__ok);
298*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__initialize__missing_schema);
299*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__initialize__sqlite_error);
300*6b3a42afSjmmv 
301*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__migration_file__builtin);
302*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__migration_file__overriden);
303*6b3a42afSjmmv 
304*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__schema_file__builtin);
305*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, detail__schema_file__overriden);
306*6b3a42afSjmmv 
307*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, backend__open_ro__ok);
308*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, backend__open_ro__missing_file);
309*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, backend__open_ro__integrity_error);
310*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, backend__open_rw__ok);
311*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, backend__open_rw__create_missing);
312*6b3a42afSjmmv     ATF_ADD_TEST_CASE(tcs, backend__open_rw__integrity_error);
313*6b3a42afSjmmv 
314*6b3a42afSjmmv     // Tests for migrate_schema are in schema_inttest.  This is because, for
315*6b3a42afSjmmv     // such tests to be meaningful, they need to be integration tests and don't
316*6b3a42afSjmmv     // really fit the goal of this unit-test module.
317*6b3a42afSjmmv }
318