Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Tests for the Backend builder class
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include <gtest/gtest-elektra.h>
11 : #include <kdb.hpp>
12 :
13 : #include <regex>
14 :
15 32 : class Ensure : public ::testing::Test
16 : {
17 : protected:
18 : static const char * testRoot;
19 : static const char * configFileRoot;
20 : std::string specRoot;
21 : std::string userRoot;
22 :
23 : testing::Namespaces namespaces;
24 : testing::MountpointPtr mpRoot;
25 :
26 64 : Ensure () : specRoot (std::string ("spec") + testRoot), userRoot (std::string ("user") + testRoot), namespaces ()
27 : {
28 8 : }
29 :
30 8 : virtual void SetUp () override
31 : {
32 64 : mpRoot.reset (new testing::Mountpoint (testRoot, configFileRoot));
33 :
34 : using namespace kdb;
35 16 : KDB kdb;
36 :
37 16 : KeySet ks;
38 32 : kdb.get (ks, testRoot);
39 :
40 32 : ks.append (Key (specRoot + "/speckey/#", KEY_META, "mymeta", "1", KEY_END));
41 32 : ks.append (Key (userRoot + "/speckey", KEY_META, "array", "#0", KEY_END));
42 32 : ks.append (Key (userRoot + "/speckey/#0", KEY_VALUE, "", KEY_END));
43 32 : ks.append (Key (userRoot + "/errorkey", KEY_META, "trigger/warnings", "3", KEY_END));
44 :
45 32 : kdb.set (ks, testRoot);
46 8 : }
47 :
48 8 : virtual void TearDown () override
49 : {
50 16 : mpRoot.reset ();
51 8 : }
52 :
53 : static bool checkTracerOutput (const std::string & capture);
54 : };
55 :
56 : const char * Ensure::testRoot = "/tests/kdb/ensure";
57 : const char * Ensure::configFileRoot = "kdbFileEnsure.dump";
58 :
59 :
60 20 : TEST_F (Ensure, GlobalUnmount)
61 : {
62 : using namespace kdb;
63 4 : KDB kdb;
64 :
65 : {
66 4 : KeySet ks;
67 8 : kdb.get (ks, testRoot);
68 :
69 20 : EXPECT_EQ (ks.lookup (userRoot + "/speckey/#0", 0).getMeta<std::string> ("mymeta"), "1") << "spec plugin didn't run";
70 : }
71 :
72 : {
73 4 : KeySet contract;
74 6 : contract.append (Key ("system/elektra/ensure/plugins/global/spec", KEY_VALUE, "unmounted", KEY_END));
75 8 : Key root (specRoot, KEY_END);
76 2 : kdb.ensure (contract, root);
77 :
78 4 : KeySet ks;
79 8 : kdb.get (ks, testRoot);
80 :
81 18 : EXPECT_FALSE (ks.lookup (userRoot + "/speckey/#0", 0).hasMeta ("mymeta")) << "spec plugin shouldn't have run";
82 :
83 2 : kdb.ensure (contract, root);
84 8 : kdb.get (ks, testRoot);
85 :
86 18 : EXPECT_FALSE (ks.lookup (userRoot + "/speckey/#0", 0).hasMeta ("mymeta")) << "global unmount should be idempotent";
87 : }
88 2 : }
89 :
90 20 : TEST_F (Ensure, GlobalRemount)
91 : {
92 : using namespace kdb;
93 : {
94 4 : KDB kdb;
95 4 : KeySet ks;
96 8 : kdb.get (ks, testRoot);
97 :
98 8 : ks.append (Key (specRoot + "/otherspeckey", KEY_META, "require", "", KEY_END));
99 8 : kdb.set (ks, testRoot);
100 : }
101 :
102 : {
103 4 : KDB kdb;
104 4 : KeySet contract;
105 6 : contract.append (Key ("system/elektra/ensure/plugins/global/spec", KEY_VALUE, "remount", KEY_END));
106 6 : contract.append (Key ("system/elektra/ensure/plugins/global/spec/config/conflict/get", KEY_VALUE, "ERROR", KEY_END));
107 6 : contract.append (Key ("system/elektra/ensure/plugins/global/spec/config/conflict/set", KEY_VALUE, "ERROR", KEY_END));
108 8 : Key root (specRoot, KEY_END);
109 2 : kdb.ensure (contract, root);
110 :
111 :
112 4 : Key newRoot (testRoot, KEY_END);
113 4 : KeySet ks;
114 4 : EXPECT_THROW (kdb.get (ks, newRoot), KDBException);
115 :
116 14 : EXPECT_EQ (newRoot.getMeta<std::string> ("error/number"), "C03200") << "spec plugin should have produced error";
117 : }
118 2 : }
119 :
120 20 : TEST_F (Ensure, Unmount)
121 : {
122 : using namespace kdb;
123 4 : KDB kdb;
124 :
125 : {
126 4 : KeySet ks;
127 4 : Key root (testRoot, KEY_END);
128 2 : kdb.get (ks, root);
129 2 : kdb.set (ks, root);
130 :
131 12 : EXPECT_EQ (root.getMeta<std::string> ("warnings/#00/number"), "C01310") << "error plugin didn't run";
132 : }
133 :
134 : {
135 4 : KeySet contract;
136 6 : contract.append (Key ("system/elektra/ensure/plugins/parent/error", KEY_VALUE, "unmounted", KEY_END));
137 8 : Key uroot (userRoot, KEY_END);
138 2 : kdb.ensure (contract, uroot);
139 :
140 4 : KeySet ks;
141 4 : Key root (testRoot, KEY_END);
142 2 : kdb.get (ks, root);
143 2 : kdb.set (ks, root);
144 :
145 12 : EXPECT_FALSE (root.hasMeta ("warnings")) << "error plugin shouldn't have run";
146 :
147 10 : root.delMeta ("warnings");
148 :
149 2 : kdb.ensure (contract, uroot);
150 2 : kdb.get (ks, root);
151 2 : kdb.set (ks, root);
152 :
153 12 : EXPECT_FALSE (root.hasMeta ("warnings")) << "unmount should be idempotent";
154 : }
155 2 : }
156 :
157 4 : bool Ensure::checkTracerOutput (const std::string & capture)
158 : {
159 12 : EXPECT_FALSE (capture.empty ()) << "tracer plugin not run";
160 :
161 8 : std::istringstream lines (capture);
162 8 : std::string line;
163 4 : size_t i = 0;
164 4 : bool success = true;
165 44 : while (std::getline (lines, line))
166 : {
167 48 : std::smatch match;
168 24 : success = success && std::regex_match (line, match, std::regex (R"(^tracer: .*$)"));
169 24 : EXPECT_TRUE (success) << "A line didn't match the expected tracer output:" << std::endl << "line: " << line << std::endl;
170 12 : ++i;
171 : }
172 :
173 8 : return success;
174 : }
175 :
176 20 : TEST_F (Ensure, GlobalMount)
177 : {
178 : using namespace kdb;
179 4 : KDB kdb;
180 4 : Key parent (testRoot, KEY_META, "debugGlobalPositions", "", KEY_END);
181 :
182 : {
183 2 : testing::internal::CaptureStdout ();
184 4 : KeySet ks;
185 2 : kdb.get (ks, parent);
186 :
187 10 : EXPECT_TRUE (testing::internal::GetCapturedStdout ().empty ()) << "there should be no output on stdout";
188 : }
189 :
190 : {
191 4 : KeySet contract;
192 6 : contract.append (Key ("system/elektra/ensure/plugins/global/tracer", KEY_VALUE, "mounted", KEY_END));
193 8 : Key root (specRoot, KEY_END);
194 2 : kdb.ensure (contract, root);
195 :
196 2 : testing::internal::CaptureStdout ();
197 4 : KeySet ks;
198 2 : kdb.get (ks, parent);
199 :
200 : {
201 4 : SCOPED_TRACE ("first ensure");
202 8 : EXPECT_TRUE (checkTracerOutput (testing::internal::GetCapturedStdout ())) << "tracer output didn't match";
203 : }
204 :
205 2 : kdb.ensure (contract, root);
206 :
207 2 : testing::internal::CaptureStdout ();
208 2 : kdb.get (ks, parent);
209 :
210 : {
211 4 : SCOPED_TRACE ("second ensure");
212 8 : EXPECT_TRUE (checkTracerOutput (testing::internal::GetCapturedStdout ())) << "global mount should be idempotent";
213 : }
214 : }
215 8 : }
|