Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Tests for KDB
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include <keysetio.hpp>
11 :
12 : #include <gtest/gtest-elektra.h>
13 :
14 : #include <list>
15 : #include <stdio.h>
16 :
17 24 : class Error : public ::testing::Test
18 : {
19 : protected:
20 : static const std::string testRoot;
21 : static const std::string configFileRoot;
22 :
23 :
24 : testing::Namespaces namespaces;
25 : testing::MountpointPtr mpRoot;
26 :
27 24 : Error () : namespaces ()
28 : {
29 12 : }
30 :
31 12 : virtual void SetUp () override
32 : {
33 60 : mpRoot.reset (new testing::Mountpoint (testRoot, configFileRoot));
34 12 : }
35 :
36 12 : virtual void TearDown () override
37 : {
38 24 : mpRoot.reset ();
39 12 : }
40 : };
41 :
42 6 : const std::string Error::testRoot = "/tests/kdb/";
43 6 : const std::string Error::configFileRoot = "kdbFileError.dump";
44 :
45 :
46 20 : TEST_F (Error, Simple)
47 : {
48 : using namespace kdb;
49 4 : KDB kdb;
50 4 : KeySet ks;
51 :
52 10 : ks.append (Key ("system" + testRoot + "key", KEY_META, "trigger/error", "C01310", KEY_END));
53 :
54 6 : ASSERT_EQ (kdb.get (ks, testRoot), 0) << "should be nothing to update";
55 8 : ASSERT_EQ (ks.size (), 1) << "did not keep key at get" << ks;
56 :
57 6 : Key parentKey (testRoot, KEY_END);
58 4 : EXPECT_THROW (kdb.set (ks, parentKey), kdb::KDBException) << "could not trigger error";
59 : struct stat buf;
60 12 : ASSERT_EQ (stat (mpRoot->systemConfigFile.c_str (), &buf), -1) << "found wrong file";
61 :
62 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error"));
63 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error/number"));
64 14 : EXPECT_EQ (parentKey.getMeta<std::string> ("error/number"), "C01310");
65 :
66 8 : ASSERT_EQ (ks.size (), 1) << "did not keep key at set" << ks;
67 : }
68 :
69 20 : TEST_F (Error, Again)
70 : {
71 : using namespace kdb;
72 4 : KDB kdb;
73 4 : KeySet ks;
74 :
75 10 : ks.append (Key ("system" + testRoot + "key", KEY_META, "trigger/error", "C01310", KEY_END));
76 :
77 6 : ASSERT_EQ (kdb.get (ks, testRoot), 0) << "should be nothing to update";
78 :
79 6 : Key parentKey (testRoot, KEY_END);
80 4 : EXPECT_THROW (kdb.set (ks, parentKey), kdb::KDBException) << "could not trigger error";
81 :
82 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error"));
83 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error/number"));
84 14 : EXPECT_EQ (parentKey.getMeta<std::string> ("error/number"), "C01310");
85 :
86 10 : ks.append (Key ("system" + testRoot + "key", KEY_META, "trigger/error", "C01110", KEY_END));
87 :
88 4 : EXPECT_THROW (kdb.set (ks, parentKey), kdb::KDBException) << "could not trigger error (again)";
89 :
90 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error"));
91 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error/number"));
92 14 : EXPECT_EQ (parentKey.getMeta<std::string> ("error/number"), "C01110");
93 :
94 8 : ASSERT_EQ (ks.size (), 1) << "did not keep key at set (again)" << ks;
95 : }
96 :
97 : // The following test requires a filesystem that supports sub-second timestamps.
98 : // The default filesystem on macOS, HFS+ does not support such precise timestamps.
99 : #if !defined(__APPLE__)
100 20 : TEST_F (Error, AgainRepeat)
101 : {
102 : using namespace kdb;
103 4 : KDB kdb;
104 4 : KeySet ks;
105 :
106 10 : ks.append (Key ("system" + testRoot + "key", KEY_META, "trigger/error", "C01310", KEY_END));
107 :
108 6 : ASSERT_EQ (kdb.get (ks, testRoot), 0) << "should be nothing to update";
109 :
110 6 : Key parentKey (testRoot, KEY_END);
111 4 : EXPECT_THROW (kdb.set (ks, parentKey), kdb::KDBException) << "could not trigger error";
112 :
113 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error"));
114 16 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error/number"));
115 14 : EXPECT_EQ (parentKey.getMeta<std::string> ("error/number"), "C01310");
116 :
117 46 : std::list<std::string> errorCodes{ "C01110", "C01100", "C01200", "C01310", "C01320", "C01330", "C02000", "C03100", "C03200" };
118 :
119 24 : for (auto code = errorCodes.begin (); code != errorCodes.end (); ++code)
120 : {
121 90 : ks.append (Key ("system" + testRoot + "key", KEY_END));
122 :
123 18 : EXPECT_NO_THROW (kdb.set (ks, parentKey)) << "no error trigger?";
124 :
125 90 : ks.append (Key ("system" + testRoot + "key", KEY_META, "trigger/error", code->c_str (), KEY_END));
126 :
127 36 : EXPECT_THROW (kdb.set (ks, parentKey), kdb::KDBException) << "could not trigger error (again)";
128 :
129 144 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error"));
130 144 : EXPECT_TRUE (parentKey.getMeta<const kdb::Key> ("error/number"));
131 108 : EXPECT_EQ (parentKey.getMeta<std::string> ("error/number"), code->c_str ())
132 0 : << " with reason: " << parentKey.getMeta<std::string> ("error/reason");
133 :
134 72 : ASSERT_EQ (ks.size (), 1) << "did not keep key at set (again)" << ks;
135 : }
136 : }
137 : #endif
138 :
139 18 : TEST_F (Error, CSimple)
140 : {
141 : using namespace ckdb;
142 2 : Key * parentKey = keyNew (testRoot.c_str (), KEY_END);
143 2 : KDB * kdb = kdbOpen (parentKey);
144 2 : KeySet * ks = ksNew (20, KS_END);
145 :
146 8 : ksAppendKey (ks, keyNew (("system" + testRoot + "key").c_str (), KEY_META, "trigger/error", "C01310", KEY_END));
147 :
148 6 : ASSERT_EQ (kdbGet (kdb, ks, parentKey), 0) << "should be nothing to update";
149 6 : ASSERT_EQ (ksGetSize (ks), 1) << "did not keep key at get" << ks;
150 :
151 6 : EXPECT_EQ (kdbSet (kdb, ks, parentKey), -1) << "could not trigger error";
152 :
153 6 : EXPECT_TRUE (ckdb::keyGetMeta (parentKey, "error"));
154 4 : EXPECT_STREQ (keyString (ckdb::keyGetMeta (parentKey, "error/number")), "C01310");
155 :
156 2 : kdbClose (kdb, parentKey);
157 2 : keyDel (parentKey);
158 2 : ksDel (ks);
159 : }
160 :
161 20 : TEST_F (Error, ToWarning)
162 : {
163 : using namespace ckdb;
164 2 : Key * parentKey = keyNew (testRoot.c_str (), KEY_END);
165 2 : KDB * kdb = kdbOpen (parentKey);
166 2 : KeySet * ks = ksNew (20, KS_END);
167 :
168 8 : ksAppendKey (ks, keyNew (("system" + testRoot + "key1").c_str (), KEY_META, "trigger/error/nofail", "C01310", KEY_END));
169 8 : ksAppendKey (ks, keyNew (("system" + testRoot + "key2").c_str (), KEY_META, "trigger/error", "C01110", KEY_END));
170 :
171 6 : ASSERT_EQ (kdbGet (kdb, ks, parentKey), 0) << "should be nothing to update";
172 6 : ASSERT_EQ (ksGetSize (ks), 2) << "did not keep key at get" << ks;
173 :
174 6 : EXPECT_EQ (kdbSet (kdb, ks, parentKey), -1) << "could not trigger error";
175 :
176 6 : EXPECT_TRUE (ckdb::keyGetMeta (parentKey, "error"));
177 4 : EXPECT_STREQ (keyString (ckdb::keyGetMeta (parentKey, "error/number")), "C01310");
178 :
179 6 : EXPECT_TRUE (ckdb::keyGetMeta (parentKey, "warnings/#00"));
180 4 : EXPECT_STREQ (keyString (ckdb::keyGetMeta (parentKey, "warnings/#00/number")), "C01110");
181 :
182 :
183 2 : kdbClose (kdb, parentKey);
184 2 : keyDel (parentKey);
185 2 : ksDel (ks);
186 : }
187 :
188 20 : TEST_F (Error, Persists)
189 : {
190 : using namespace ckdb;
191 2 : Key * parentKey = keyNew (testRoot.c_str (), KEY_END);
192 2 : KDB * kdb = kdbOpen (parentKey);
193 2 : KeySet * ks = ksNew (20, KS_END);
194 :
195 8 : ksAppendKey (ks, keyNew (("system" + testRoot + "key").c_str (), KEY_META, "trigger/error", "C01310", KEY_END));
196 :
197 6 : ASSERT_EQ (kdbGet (kdb, ks, parentKey), 0) << "should be nothing to update";
198 6 : ASSERT_EQ (ksGetSize (ks), 1) << "did not keep key at get" << ks;
199 :
200 6 : EXPECT_EQ (kdbSet (kdb, ks, parentKey), -1) << "could not trigger error";
201 :
202 6 : EXPECT_TRUE (ckdb::keyGetMeta (parentKey, "error"));
203 4 : EXPECT_STREQ (keyString (ckdb::keyGetMeta (parentKey, "error/number")), "C01310");
204 :
205 :
206 8 : keyDel (ksLookup (ks, keyNew (("system" + testRoot + "key").c_str (), KEY_END), KDB_O_POP | KDB_O_DEL));
207 :
208 6 : EXPECT_EQ (kdbSet (kdb, ks, parentKey), 0) << "kdbSet failed";
209 6 : EXPECT_TRUE (ckdb::keyGetMeta (parentKey, "error"));
210 4 : EXPECT_STREQ (keyString (ckdb::keyGetMeta (parentKey, "error/number")), "C01310");
211 :
212 :
213 2 : kdbClose (kdb, parentKey);
214 2 : keyDel (parentKey);
215 2 : ksDel (ks);
216 6 : }
|