Line data Source code
1 : #define BOOST_TEST_DYN_LINK
2 : #define BOOST_TEST_MODULE (ThreeVersionsBug test)
3 :
4 : #include <boost/test/unit_test.hpp>
5 :
6 : #include <iostream>
7 : #include <memory>
8 : #include <string>
9 :
10 : #include "../DatabaseConfigurationInterface.h"
11 :
12 : using namespace ots;
13 :
14 : struct BugTestData {
15 2 : BugTestData() {
16 2 : srand(time(nullptr));
17 2 : baseVersion = rand() % 99999 + 100000;
18 2 : std::cout << "=== INVESTIGATING THREE VERSIONS BUG ===\n";
19 2 : std::cout << "Base version: " << baseVersion << "\n\n";
20 2 : }
21 :
22 2 : ~BugTestData() { std::cout << "\n=== INVESTIGATION COMPLETE ===\n"; }
23 :
24 : int baseVersion;
25 : };
26 :
27 : BugTestData fixture;
28 :
29 : BOOST_AUTO_TEST_SUITE(three_versions_bug_test)
30 :
31 4 : BOOST_AUTO_TEST_CASE(attempt_three_versions_same_type) {
32 2 : std::cout << "\n=== TEST 1: Attempting to add three versions ===\n";
33 :
34 2 : auto ifc = DatabaseConfigurationInterface();
35 :
36 2 : int version1 = fixture.baseVersion;
37 2 : int version2 = fixture.baseVersion + 1;
38 2 : int version3 = fixture.baseVersion + 2;
39 :
40 2 : std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
41 2 : cfg1->getView().version = version1;
42 2 : ifc.saveActiveVersion(cfg1.get());
43 2 : std::cout << "Created version 1: " << version1 << "\n";
44 :
45 2 : std::shared_ptr<ConfigurationBase> cfg2 = std::make_shared<TestConfiguration001>();
46 2 : cfg2->getView().version = version2;
47 2 : ifc.saveActiveVersion(cfg2.get());
48 2 : std::cout << "Created version 2: " << version2 << "\n";
49 :
50 2 : std::shared_ptr<ConfigurationBase> cfg3 = std::make_shared<TestConfiguration001>();
51 2 : cfg3->getView().version = version3;
52 2 : ifc.saveActiveVersion(cfg3.get());
53 2 : std::cout << "Created version 3: " << version3 << "\n";
54 :
55 2 : std::cout << "\nAttempt 1: Using std::map...\n";
56 2 : auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
57 :
58 2 : compositionMap[cfg1->getConfigurationName()] = version1;
59 2 : std::cout << " Added version1, map size: " << compositionMap.size() << "\n";
60 :
61 2 : compositionMap[cfg2->getConfigurationName()] = version2;
62 2 : std::cout << " Added version2, map size: " << compositionMap.size() << " (should still be 1)\n";
63 :
64 2 : compositionMap[cfg3->getConfigurationName()] = version3;
65 2 : std::cout << " Added version3, map size: " << compositionMap.size() << " (should still be 1)\n";
66 :
67 2 : BOOST_CHECK_EQUAL(compositionMap.size(), 1);
68 2 : BOOST_CHECK_EQUAL(compositionMap[cfg1->getConfigurationName()], version3);
69 :
70 2 : std::cout << " Result: Map correctly contains only last version: " << version3 << "\n";
71 :
72 6 : std::string compName = std::string{"BugTest1_"} + std::to_string(fixture.baseVersion);
73 :
74 2 : ifc.storeGlobalConfiguration(compositionMap, compName);
75 2 : std::cout << " Created composition: " << compName << "\n";
76 :
77 2 : auto loadedMap = ifc.loadGlobalConfiguration(compName);
78 2 : BOOST_CHECK_EQUAL(loadedMap.size(), 1);
79 :
80 2 : std::cout << " Verified: Composition has " << loadedMap.size() << " member (correct)\n";
81 2 : }
82 :
83 4 : BOOST_AUTO_TEST_CASE(inspect_database_storage_format) {
84 2 : std::cout << "\n=== TEST 2: Inspecting database storage format ===\n";
85 :
86 2 : auto ifc = DatabaseConfigurationInterface();
87 :
88 2 : int version1 = fixture.baseVersion + 10;
89 2 : int version2 = fixture.baseVersion + 11;
90 :
91 2 : std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
92 2 : cfg1->getView().version = version1;
93 2 : ifc.saveActiveVersion(cfg1.get());
94 :
95 2 : std::shared_ptr<ConfigurationBase> cfg2 = std::make_shared<TestConfiguration002>();
96 2 : cfg2->getView().version = version2;
97 2 : ifc.saveActiveVersion(cfg2.get());
98 :
99 2 : auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
100 2 : compositionMap[cfg1->getConfigurationName()] = version1;
101 2 : compositionMap[cfg2->getConfigurationName()] = version2;
102 :
103 6 : std::string compName = std::string{"BugTest2_"} + std::to_string(fixture.baseVersion);
104 :
105 2 : ifc.storeGlobalConfiguration(compositionMap, compName);
106 :
107 2 : auto loadedMap = ifc.loadGlobalConfiguration(compName);
108 :
109 2 : std::cout << "Composition '" << compName << "' contains:\n";
110 6 : for (auto const& entry : loadedMap) {
111 4 : std::cout << " " << entry.first << " -> version " << entry.second << "\n";
112 : }
113 :
114 2 : BOOST_CHECK_EQUAL(loadedMap.size(), 2);
115 :
116 2 : int count001 = loadedMap.count(cfg1->getConfigurationName());
117 2 : int count002 = loadedMap.count(cfg2->getConfigurationName());
118 :
119 2 : BOOST_CHECK_EQUAL(count001, 1);
120 2 : BOOST_CHECK_EQUAL(count002, 1);
121 :
122 2 : std::cout << " Verified: Each configuration type appears exactly once\n";
123 2 : }
124 :
125 4 : BOOST_AUTO_TEST_CASE(scan_database_for_duplicates) {
126 2 : std::cout << "\n=== TEST 3: Scanning database for duplicate entries ===\n";
127 :
128 2 : auto ifc = DatabaseConfigurationInterface();
129 :
130 2 : auto allCompositions = ifc.findAllGlobalConfigurations();
131 :
132 2 : std::cout << "Scanning " << allCompositions.size() << " compositions for duplicates...\n";
133 :
134 2 : int duplicatesFound = 0;
135 :
136 6 : for (auto const& compName : allCompositions) {
137 : try {
138 4 : auto members = ifc.loadGlobalConfiguration(compName);
139 :
140 4 : if (members.size() > 10) {
141 0 : std::cout << " " << compName << ": " << members.size() << " members\n";
142 : }
143 :
144 4 : } catch (std::exception const& e) {
145 0 : std::cout << " Error loading " << compName << ": " << e.what() << "\n";
146 0 : }
147 : }
148 :
149 2 : std::cout << "\nSummary: Found " << duplicatesFound << " compositions with duplicate detection issues\n";
150 2 : }
151 :
152 4 : BOOST_AUTO_TEST_CASE(map_interface_prevents_duplicates) {
153 2 : std::cout << "\n=== TEST 4: Map interface prevents duplicates ===\n";
154 :
155 2 : auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
156 :
157 2 : std::string typeName = "TestConfiguration001";
158 :
159 2 : compositionMap[typeName] = 100;
160 2 : std::cout << "Added version 100, map size: " << compositionMap.size() << "\n";
161 2 : BOOST_CHECK_EQUAL(compositionMap.size(), 1);
162 2 : BOOST_CHECK_EQUAL(compositionMap[typeName], 100);
163 :
164 2 : compositionMap[typeName] = 200;
165 2 : std::cout << "Added version 200, map size: " << compositionMap.size() << "\n";
166 2 : BOOST_CHECK_EQUAL(compositionMap.size(), 1);
167 2 : BOOST_CHECK_EQUAL(compositionMap[typeName], 200);
168 :
169 2 : compositionMap[typeName] = 300;
170 2 : std::cout << "Added version 300, map size: " << compositionMap.size() << "\n";
171 2 : BOOST_CHECK_EQUAL(compositionMap.size(), 1);
172 2 : BOOST_CHECK_EQUAL(compositionMap[typeName], 300);
173 :
174 2 : std::cout << " Verified: std::map automatically prevents duplicates\n";
175 2 : std::cout << " Final value: " << compositionMap[typeName] << " (should be 300)\n";
176 2 : }
177 :
178 : BOOST_AUTO_TEST_SUITE_END()
|