Line data Source code
1 : #define BOOST_TEST_DYN_LINK
2 : #define BOOST_TEST_MODULE (ReverseLookup test)
3 :
4 : #include <boost/test/unit_test.hpp>
5 :
6 : #include <algorithm>
7 : #include <chrono>
8 : #include <iostream>
9 : #include <iterator>
10 : #include <memory>
11 : #include <set>
12 : #include <string>
13 :
14 : #include "../DatabaseConfigurationInterface.h"
15 :
16 : using namespace ots;
17 :
18 : struct ReverseLookupTestData {
19 2 : ReverseLookupTestData() {
20 2 : srand(time(nullptr));
21 2 : baseVersion = rand() % 99999 + 100000;
22 2 : std::cout << "=== REVERSE LOOKUP TEST SUITE ===\n";
23 2 : std::cout << "Base version: " << baseVersion << "\n\n";
24 2 : }
25 :
26 2 : ~ReverseLookupTestData() { std::cout << "\n=== TEST SUITE COMPLETE ===\n"; }
27 :
28 : int baseVersion;
29 : };
30 :
31 : ReverseLookupTestData fixture;
32 :
33 : BOOST_AUTO_TEST_SUITE(reverse_lookup_test)
34 :
35 4 : BOOST_AUTO_TEST_CASE(basic_reverse_lookup) {
36 2 : std::cout << "\n=== TEST 1: Basic reverse lookup ===\n";
37 :
38 2 : auto ifc = DatabaseConfigurationInterface();
39 :
40 2 : int version1 = fixture.baseVersion;
41 2 : int version2 = fixture.baseVersion + 1;
42 :
43 2 : std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
44 2 : cfg1->getView().version = version1;
45 2 : auto result1 = ifc.saveActiveVersion(cfg1.get());
46 2 : BOOST_CHECK_EQUAL(result1, 0);
47 :
48 2 : std::shared_ptr<ConfigurationBase> cfg2 = std::make_shared<TestConfiguration002>();
49 2 : cfg2->getView().version = version2;
50 2 : auto result2 = ifc.saveActiveVersion(cfg2.get());
51 2 : BOOST_CHECK_EQUAL(result2, 0);
52 :
53 2 : std::cout << "Created versions: " << version1 << ", " << version2 << "\n";
54 :
55 2 : auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
56 2 : compositionMap[cfg1->getConfigurationName()] = version1;
57 2 : compositionMap[cfg2->getConfigurationName()] = version2;
58 :
59 6 : std::string compositionName = std::string{"TestComp_"} + std::to_string(fixture.baseVersion);
60 :
61 2 : ifc.storeGlobalConfiguration(compositionMap, compositionName);
62 2 : std::cout << "Created composition: " << compositionName << "\n";
63 :
64 2 : std::cout << "Performing reverse lookup for " << cfg1->getConfigurationName() << " v" << version1 << "\n";
65 :
66 2 : auto foundCompositions = ifc.findCompositionsContaining(cfg1->getConfigurationName(), std::to_string(version1));
67 :
68 2 : std::cout << "Found " << foundCompositions.size() << " composition(s)\n";
69 4 : for (auto const& comp : foundCompositions) {
70 2 : std::cout << " - " << comp << "\n";
71 : }
72 :
73 2 : bool found = (foundCompositions.find(compositionName) != foundCompositions.end());
74 :
75 2 : BOOST_CHECK_EQUAL(found, true);
76 2 : std::cout << " Verified: Composition found via reverse lookup\n";
77 2 : }
78 :
79 4 : BOOST_AUTO_TEST_CASE(multiple_compositions_same_version) {
80 2 : std::cout << "\n=== TEST 2: Multiple compositions same version ===\n";
81 :
82 2 : auto ifc = DatabaseConfigurationInterface();
83 :
84 2 : int sharedVersion = fixture.baseVersion + 10;
85 :
86 2 : std::shared_ptr<ConfigurationBase> cfgShared = std::make_shared<TestConfiguration001>();
87 2 : cfgShared->getView().version = sharedVersion;
88 2 : ifc.saveActiveVersion(cfgShared.get());
89 :
90 2 : std::cout << "Created shared version: " << sharedVersion << "\n";
91 :
92 2 : auto map1 = DatabaseConfigurationInterface::config_version_map_t{};
93 2 : map1[cfgShared->getConfigurationName()] = sharedVersion;
94 :
95 6 : std::string comp1Name = std::string{"Comp1_"} + std::to_string(fixture.baseVersion);
96 2 : ifc.storeGlobalConfiguration(map1, comp1Name);
97 2 : std::cout << "Created composition 1: " << comp1Name << "\n";
98 :
99 2 : auto map2 = DatabaseConfigurationInterface::config_version_map_t{};
100 2 : map2[cfgShared->getConfigurationName()] = sharedVersion;
101 :
102 6 : std::string comp2Name = std::string{"Comp2_"} + std::to_string(fixture.baseVersion);
103 2 : ifc.storeGlobalConfiguration(map2, comp2Name);
104 2 : std::cout << "Created composition 2: " << comp2Name << "\n";
105 :
106 2 : auto foundCompositions = ifc.findCompositionsContaining(cfgShared->getConfigurationName(), std::to_string(sharedVersion));
107 :
108 2 : std::cout << "Reverse lookup found " << foundCompositions.size() << " compositions\n";
109 :
110 2 : BOOST_CHECK_EQUAL(foundCompositions.size(), 2);
111 :
112 2 : bool found1 = (foundCompositions.find(comp1Name) != foundCompositions.end());
113 2 : bool found2 = (foundCompositions.find(comp2Name) != foundCompositions.end());
114 :
115 2 : BOOST_CHECK_EQUAL(found1, true);
116 2 : BOOST_CHECK_EQUAL(found2, true);
117 :
118 2 : std::cout << " Verified: Both compositions found\n";
119 2 : }
120 :
121 4 : BOOST_AUTO_TEST_CASE(reverse_lookup_no_matches) {
122 2 : std::cout << "\n=== TEST 3: Reverse lookup no matches ===\n";
123 :
124 2 : auto ifc = DatabaseConfigurationInterface();
125 :
126 2 : int orphanVersion = fixture.baseVersion + 100;
127 :
128 2 : std::shared_ptr<ConfigurationBase> cfgOrphan = std::make_shared<TestConfiguration001>();
129 2 : cfgOrphan->getView().version = orphanVersion;
130 2 : ifc.saveActiveVersion(cfgOrphan.get());
131 :
132 2 : std::cout << "Created orphan version (not in any composition): " << orphanVersion << "\n";
133 :
134 2 : auto foundCompositions = ifc.findCompositionsContaining(cfgOrphan->getConfigurationName(), std::to_string(orphanVersion));
135 :
136 2 : std::cout << "Reverse lookup found " << foundCompositions.size() << " compositions\n";
137 :
138 2 : BOOST_CHECK_EQUAL(foundCompositions.size(), 0);
139 2 : std::cout << " Verified: No compositions found (as expected)\n";
140 2 : }
141 :
142 4 : BOOST_AUTO_TEST_CASE(version_multiple_positions_same_composition) {
143 2 : std::cout << "\n=== TEST 4: Version multiple positions same composition ===\n";
144 :
145 2 : auto ifc = DatabaseConfigurationInterface();
146 :
147 2 : int version1 = fixture.baseVersion + 200;
148 2 : int version2 = fixture.baseVersion + 201;
149 :
150 2 : std::shared_ptr<ConfigurationBase> cfg1a = std::make_shared<TestConfiguration001>();
151 2 : cfg1a->getView().version = version1;
152 2 : ifc.saveActiveVersion(cfg1a.get());
153 :
154 2 : std::shared_ptr<ConfigurationBase> cfg1b = std::make_shared<TestConfiguration001>();
155 2 : cfg1b->getView().version = version2;
156 2 : ifc.saveActiveVersion(cfg1b.get());
157 :
158 2 : auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
159 2 : compositionMap[cfg1a->getConfigurationName()] = version1;
160 :
161 6 : std::string compName = std::string{"SingleTypeComp_"} + std::to_string(fixture.baseVersion);
162 :
163 2 : ifc.storeGlobalConfiguration(compositionMap, compName);
164 :
165 2 : auto found1 = ifc.findCompositionsContaining(cfg1a->getConfigurationName(), std::to_string(version1));
166 :
167 2 : BOOST_CHECK_EQUAL(found1.size(), 1);
168 :
169 2 : auto found2 = ifc.findCompositionsContaining(cfg1b->getConfigurationName(), std::to_string(version2));
170 :
171 2 : BOOST_CHECK_EQUAL(found2.size(), 0);
172 :
173 2 : std::cout << " Verified: Only the stored version is found\n";
174 2 : }
175 :
176 4 : BOOST_AUTO_TEST_CASE(performance_many_compositions) {
177 2 : std::cout << "\n=== TEST 5: Performance many compositions ===\n";
178 :
179 2 : auto ifc = DatabaseConfigurationInterface();
180 :
181 2 : int targetVersion = fixture.baseVersion + 500;
182 :
183 2 : std::shared_ptr<ConfigurationBase> cfgTarget = std::make_shared<TestConfiguration001>();
184 2 : cfgTarget->getView().version = targetVersion;
185 2 : ifc.saveActiveVersion(cfgTarget.get());
186 :
187 2 : std::string targetCompName;
188 :
189 22 : for (int i = 0; i < 10; ++i) {
190 20 : int otherVersion = fixture.baseVersion + 600 + i;
191 :
192 20 : std::shared_ptr<ConfigurationBase> cfgOther = std::make_shared<TestConfiguration002>();
193 20 : cfgOther->getView().version = otherVersion;
194 20 : ifc.saveActiveVersion(cfgOther.get());
195 :
196 20 : auto map = DatabaseConfigurationInterface::config_version_map_t{};
197 :
198 20 : if (i == 5) {
199 2 : map[cfgTarget->getConfigurationName()] = targetVersion;
200 2 : map[cfgOther->getConfigurationName()] = otherVersion;
201 6 : targetCompName = std::string{"PerfComp_"} + std::to_string(i) + "_" + std::to_string(fixture.baseVersion);
202 : } else {
203 18 : map[cfgOther->getConfigurationName()] = otherVersion;
204 : }
205 :
206 60 : std::string compName = std::string{"PerfComp_"} + std::to_string(i) + "_" + std::to_string(fixture.baseVersion);
207 20 : ifc.storeGlobalConfiguration(map, compName);
208 20 : }
209 :
210 2 : std::cout << "Created 10 compositions, target is in: " << targetCompName << "\n";
211 :
212 2 : auto start = std::chrono::high_resolution_clock::now();
213 :
214 2 : auto foundCompositions = ifc.findCompositionsContaining(cfgTarget->getConfigurationName(), std::to_string(targetVersion));
215 :
216 2 : auto end = std::chrono::high_resolution_clock::now();
217 2 : auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
218 :
219 2 : std::cout << "Reverse lookup completed in " << duration.count() << "ms\n";
220 :
221 2 : BOOST_CHECK_EQUAL(foundCompositions.size(), 1);
222 :
223 2 : bool foundTarget = (foundCompositions.find(targetCompName) != foundCompositions.end());
224 2 : BOOST_CHECK_EQUAL(foundTarget, true);
225 :
226 2 : std::cout << " Verified: Correct composition found efficiently\n";
227 :
228 2 : BOOST_CHECK_LT(duration.count(), 5000);
229 2 : }
230 :
231 : BOOST_AUTO_TEST_SUITE_END()
|