Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see doc/LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #define OPMPHM_TEST
10 : #include <opmphm.c>
11 : #include <tests_internal.h>
12 :
13 : // dummy for testing
14 0 : static const char * test_opmphm_getName (void * data ELEKTRA_UNUSED)
15 : {
16 0 : return "Test Key Name";
17 : }
18 :
19 : const size_t maxComponentSize = 273;
20 : const uint8_t minRUniPar = 2;
21 : const uint8_t maxRUniPar = 10;
22 :
23 2 : static void test_basic (void)
24 : {
25 2 : Opmphm * opmphm = opmphmNew ();
26 2 : exit_if_fail (opmphm, "opmphmNew");
27 4 : succeed_if (!opmphmIsBuild (opmphm), "opmphm is build but should be not build");
28 2 : succeed_if (!opmphmIsBuild (NULL), "isBuild NULL returned true");
29 : opmphm->size = 1;
30 2 : succeed_if (opmphmIsBuild (opmphm), "opmphm is not build but should be build");
31 2 : opmphm->size = 0;
32 2 : opmphmDel (opmphm);
33 2 : }
34 :
35 2 : static void test_opmphmGraphNew (void)
36 : {
37 20 : for (uint8_t rUniPar = minRUniPar; rUniPar <= maxRUniPar; ++rUniPar)
38 : {
39 4896 : for (size_t componentSize = 1; componentSize < maxComponentSize; ++componentSize)
40 : {
41 : // find max n for this p
42 : size_t n;
43 4004928 : for (n = 1; ((n + 1) / rUniPar) + 1 <= componentSize; ++n)
44 : ;
45 :
46 : // prep
47 4896 : Opmphm * opmphm = opmphmNew ();
48 4896 : exit_if_fail (opmphm, "opmphmNew");
49 : // check opmphm
50 4896 : succeed_if (opmphm->rUniPar == 0, "check opmphm->rUniPar");
51 4896 : succeed_if (opmphm->size == 0, "check opmphm->size");
52 4896 : succeed_if (opmphm->componentSize == 0, "check opmphm->componentSize");
53 4896 : OpmphmGraph * graph = opmphmGraphNew (opmphm, rUniPar, n, 1);
54 4896 : exit_if_fail (graph, "opmphmGraphNew");
55 : // check opmphm
56 4896 : succeed_if (opmphm->rUniPar == rUniPar, "check opmphm->rUniPar");
57 4896 : succeed_if (opmphm->componentSize == componentSize, "check opmphm->componentSize");
58 : // check access Opmphm->hashFunctionSeeds
59 29376 : for (uint8_t r = 0; r < rUniPar; ++r)
60 : {
61 29376 : opmphm->hashFunctionSeeds[r] = 0;
62 29376 : succeed_if (opmphm->hashFunctionSeeds[r] == 0, "check access opmphm->hashFunctionSeeds");
63 : }
64 : // check access OpmphmEdge->vertices ,OpmphmEdge->nextEdge and graph->removeSequence
65 4004928 : for (size_t i = 0; i < n; ++i)
66 : {
67 28484928 : for (uint8_t r = 0; r < rUniPar; ++r)
68 : {
69 28484928 : graph->edges[i].vertices[r] = i * r;
70 28484928 : graph->edges[i].nextEdge[r] = i * r;
71 : }
72 4004928 : graph->removeSequence[i] = i;
73 : }
74 4004928 : for (size_t i = 0; i < n; ++i)
75 : {
76 28484928 : for (uint8_t r = 0; r < rUniPar; ++r)
77 : {
78 28484928 : succeed_if (graph->edges[i].vertices[r] == i * r, "check access OpmphmEdge->vertices");
79 28484928 : succeed_if (graph->edges[i].nextEdge[r] == i * r, "check access OpmphmEdge->nextEdge");
80 : }
81 4004928 : succeed_if (graph->removeSequence[i] == i, "check access graph->removeSequence");
82 : }
83 : // check vertices initialization
84 4009824 : for (size_t i = 0; i < componentSize * rUniPar; ++i)
85 : {
86 4009824 : succeed_if (graph->vertices[i].firstEdge == 0, "check vertices initialization");
87 4009824 : succeed_if (graph->vertices[i].degree == 0, "check vertices initialization");
88 : }
89 :
90 : // cleanup
91 4896 : opmphmDel (opmphm);
92 4896 : opmphmGraphDel (graph);
93 : }
94 : }
95 2 : }
96 2 : static void test_minComponentSize (void)
97 : {
98 20 : for (uint8_t rUniPar = minRUniPar; rUniPar <= maxRUniPar; ++rUniPar)
99 : {
100 18 : Opmphm * opmphm = opmphmNew ();
101 18 : exit_if_fail (opmphm, "opmphmNew");
102 18 : OpmphmGraph * graph = opmphmGraphNew (opmphm, rUniPar, 1, 1);
103 18 : exit_if_fail (graph, "opmphmGraphNew");
104 : // check
105 18 : succeed_if (1 == opmphm->componentSize, "min componentSize is not 1");
106 : // cleanup
107 18 : opmphmDel (opmphm);
108 18 : opmphmGraphDel (graph);
109 : }
110 2 : }
111 :
112 :
113 2 : static void test_cyclicMultipleEdges (void)
114 : {
115 : /**
116 : * Test multiple edges, there is at least one edge multiple times
117 : */
118 20 : for (uint8_t rUniPar = minRUniPar; rUniPar <= maxRUniPar; ++rUniPar)
119 : {
120 4878 : for (size_t componentSize = 2; componentSize < maxComponentSize; ++componentSize)
121 : {
122 : // find max n for this p
123 : size_t n;
124 4004838 : for (n = 1; ((n + 1) / rUniPar) + 1 <= componentSize; ++n)
125 : ;
126 : // prep
127 4878 : Opmphm * opmphm = opmphmNew ();
128 4878 : exit_if_fail (opmphm, "opmphmNew");
129 4878 : OpmphmGraph * graph = opmphmGraphNew (opmphm, rUniPar, n, 1);
130 4878 : exit_if_fail (graph, "opmphmGraphNew");
131 : OpmphmInit opmphmInit;
132 : // dummy data
133 4878 : opmphmInit.getName = test_opmphm_getName;
134 4878 : opmphmInit.initSeed = (int32_t) 1;
135 4878 : opmphmInit.data = (void **) 1;
136 : // fill
137 4009716 : for (size_t i = 0; i < n; ++i)
138 : {
139 28484268 : for (uint8_t r = 0; r < rUniPar; ++r)
140 : {
141 28484268 : graph->edges[i].vertices[r] = i % componentSize;
142 : }
143 : }
144 : // check
145 4878 : succeed_if (opmphmMapping (opmphm, graph, &opmphmInit, n), "graph with cycles marked as acyclic");
146 : // cleanup
147 4878 : opmphmDel (opmphm);
148 4878 : opmphmGraphDel (graph);
149 : }
150 : }
151 2 : }
152 2 : static void test_cyclicCountUpEdges (void)
153 : {
154 : /**
155 : * Test cycles, fill up edge.h[] with all possible edges, starting from (0,...,0), no multiple edges.
156 : */
157 20 : for (uint8_t rUniPar = minRUniPar; rUniPar <= maxRUniPar; ++rUniPar)
158 : {
159 4860 : for (size_t componentSize = 3; componentSize < maxComponentSize; ++componentSize)
160 : {
161 : // find max n for this p
162 : size_t n;
163 4004640 : for (n = 1; ((n + 1) / rUniPar) + 1 <= componentSize; ++n)
164 : ;
165 : // prep
166 4860 : Opmphm * opmphm = opmphmNew ();
167 4860 : exit_if_fail (opmphm, "opmphmNew");
168 4860 : OpmphmGraph * graph = opmphmGraphNew (opmphm, rUniPar, n, 1);
169 4860 : exit_if_fail (graph, "opmphmGraphNew");
170 : OpmphmInit opmphmInit;
171 : // dummy data
172 4860 : opmphmInit.getName = test_opmphm_getName;
173 4860 : opmphmInit.initSeed = (int32_t) 1;
174 4860 : opmphmInit.data = (void **) 1;
175 : // fill
176 4860 : uint32_t data[rUniPar];
177 34020 : for (uint8_t r = 0; r < rUniPar; ++r)
178 : {
179 29160 : data[r] = 0;
180 : }
181 4004640 : for (size_t i = 0; i < n; ++i)
182 : {
183 28482840 : for (uint8_t r = 0; r < rUniPar; ++r)
184 : {
185 28482840 : graph->edges[i].vertices[r] = data[r];
186 : }
187 : // count up data
188 : uint8_t r = rUniPar;
189 : do
190 : {
191 4029012 : --r;
192 4029012 : data[r] = (data[r] + 1) % componentSize;
193 4029012 : } while (data[r] == 0);
194 : }
195 : // check
196 4860 : succeed_if (opmphmMapping (opmphm, graph, &opmphmInit, n), "graph with cycles marked as acyclic");
197 : // cleanup
198 4860 : opmphmDel (opmphm);
199 4860 : opmphmGraphDel (graph);
200 : }
201 : }
202 2 : }
203 2 : static void test_cyclicCountDownEdges (void)
204 : {
205 : /**
206 : * Test cycles, fill up edge.h[] with all possible edges, starting from (p - 1,...,p - 1), no multiple edges.
207 : */
208 20 : for (uint8_t rUniPar = minRUniPar; rUniPar <= maxRUniPar; ++rUniPar)
209 : {
210 4860 : for (size_t componentSize = 3; componentSize < maxComponentSize; ++componentSize)
211 : {
212 : // find max n for this p
213 : size_t n;
214 4004640 : for (n = 1; ((n + 1) / rUniPar) + 1 <= componentSize; ++n)
215 : ;
216 : // prep
217 4860 : Opmphm * opmphm = opmphmNew ();
218 4860 : exit_if_fail (opmphm, "opmphmNew");
219 4860 : OpmphmGraph * graph = opmphmGraphNew (opmphm, rUniPar, n, 1);
220 4860 : exit_if_fail (graph, "opmphmGraphNew");
221 : OpmphmInit opmphmInit;
222 : // dummy data
223 4860 : opmphmInit.getName = test_opmphm_getName;
224 4860 : opmphmInit.initSeed = (int32_t) 1;
225 4860 : opmphmInit.data = (void **) 1;
226 : // fill
227 4860 : int32_t data[rUniPar];
228 34020 : for (uint8_t r = 0; r < rUniPar; ++r)
229 : {
230 29160 : data[r] = componentSize - 1;
231 : }
232 4004640 : for (size_t i = 0; i < n; ++i)
233 : {
234 28482840 : for (uint8_t r = 0; r < rUniPar; ++r)
235 : {
236 28482840 : graph->edges[i].vertices[r] = data[r];
237 : }
238 : // count down data
239 : uint8_t r = rUniPar;
240 : do
241 : {
242 4029012 : --r;
243 4029012 : --data[r];
244 4029012 : if (data[r] < 0)
245 : {
246 24372 : data[r] = componentSize - 1;
247 : }
248 4029012 : } while (data[r] == (int32_t) componentSize - 1);
249 : }
250 : // check
251 4860 : succeed_if (opmphmMapping (opmphm, graph, &opmphmInit, n), "graph with cycles marked as acyclic");
252 : // cleanup
253 4860 : opmphmDel (opmphm);
254 4860 : opmphmGraphDel (graph);
255 : }
256 : }
257 2 : }
258 :
259 :
260 2 : static void test_acyclicDefaultOrder (void)
261 : {
262 : /**
263 : * Test:
264 : * * Empty and Clear
265 : * * reuse of mapping
266 : * * assignment (default order)
267 : * * lookup
268 : */
269 20 : for (uint8_t rUniPar = minRUniPar; rUniPar <= maxRUniPar; ++rUniPar)
270 : {
271 4860 : for (size_t componentSize = 3; componentSize < maxComponentSize; ++componentSize)
272 : {
273 : // find max n for this p
274 4860 : size_t n = componentSize - 1;
275 : // prep
276 4860 : Opmphm * opmphm = opmphmNew ();
277 4860 : exit_if_fail (opmphm, "opmphmNew");
278 4860 : OpmphmGraph * graph = opmphmGraphNew (opmphm, rUniPar, n, rUniPar);
279 4860 : exit_if_fail (graph, "opmphmGraphNew");
280 : OpmphmInit opmphmInit;
281 : // dummy data
282 4860 : opmphmInit.getName = test_opmphm_getName;
283 4860 : opmphmInit.initSeed = (int32_t) 1;
284 4860 : opmphmInit.data = (void **) 1;
285 : // fill
286 668250 : for (size_t i = 0; i < n; ++i)
287 : {
288 3980340 : for (uint8_t r = 0; r < rUniPar; ++r)
289 : {
290 3980340 : graph->edges[i].vertices[r] = (i + r) % componentSize;
291 : }
292 : }
293 : // save element last and create multiple edge
294 4860 : uint32_t data[rUniPar];
295 34020 : for (uint8_t r = 0; r < rUniPar; ++r)
296 : {
297 29160 : data[r] = graph->edges[n - 1].vertices[r];
298 29160 : graph->edges[n - 1].vertices[r] = graph->edges[0].vertices[r];
299 : }
300 : // check
301 4860 : succeed_if (opmphmMapping (opmphm, graph, &opmphmInit, n), "graph with cycles marked as acyclic");
302 : // restore last element
303 29160 : for (uint8_t r = 0; r < rUniPar; ++r)
304 : {
305 29160 : graph->edges[n - 1].vertices[r] = data[r];
306 : }
307 4860 : succeed_if (!opmphmMapping (opmphm, graph, &opmphmInit, n), "acyclic graph marked as cyclic");
308 4860 : exit_if_fail (opmphmAssignment (opmphm, graph, n, 1) == 0, "opmphmAssignment");
309 663390 : for (size_t i = 0; i < n; ++i)
310 : {
311 663390 : succeed_if (opmphmLookup (opmphm, n, graph->edges[i].vertices) == i, "lookup");
312 : }
313 : // cleanup
314 4860 : opmphmDel (opmphm);
315 4860 : opmphmGraphDel (graph);
316 : }
317 : }
318 2 : }
319 2 : static void test_acyclicReverseOrder (void)
320 : {
321 : /**
322 : * Test:
323 : * * Empty and Clear
324 : * * reuse of mapping
325 : * * assignment (reverse order)
326 : * * lookup
327 : */
328 20 : for (uint8_t rUniPar = minRUniPar; rUniPar <= maxRUniPar; ++rUniPar)
329 : {
330 4860 : for (size_t componentSize = 3; componentSize < maxComponentSize; ++componentSize)
331 : {
332 : // find max n for this p
333 4860 : size_t n = componentSize - 1;
334 : // prep
335 4860 : Opmphm * opmphm = opmphmNew ();
336 4860 : exit_if_fail (opmphm, "opmphmNew");
337 4860 : OpmphmGraph * graph = opmphmGraphNew (opmphm, rUniPar, n, rUniPar);
338 4860 : exit_if_fail (graph, "opmphmGraphNew");
339 : OpmphmInit opmphmInit;
340 : // dummy data
341 4860 : opmphmInit.getName = test_opmphm_getName;
342 4860 : opmphmInit.initSeed = (int32_t) 1;
343 4860 : opmphmInit.data = (void **) 1;
344 : // fill
345 668250 : for (size_t i = 0; i < n; ++i)
346 : {
347 3980340 : for (uint8_t r = 0; r < rUniPar; ++r)
348 : {
349 3980340 : graph->edges[i].vertices[r] = (i + r) % componentSize;
350 : }
351 663390 : graph->edges[i].order = n - 1 - i;
352 : }
353 : // save element last and create multiple edge
354 4860 : uint32_t data[rUniPar];
355 34020 : for (uint8_t r = 0; r < rUniPar; ++r)
356 : {
357 29160 : data[r] = graph->edges[n - 1].vertices[r];
358 29160 : graph->edges[n - 1].vertices[r] = graph->edges[0].vertices[r];
359 : }
360 : // check
361 4860 : succeed_if (opmphmMapping (opmphm, graph, &opmphmInit, n), "graph with cycles marked as acyclic");
362 : // restore last element
363 29160 : for (uint8_t r = 0; r < rUniPar; ++r)
364 : {
365 29160 : graph->edges[n - 1].vertices[r] = data[r];
366 : }
367 4860 : succeed_if (!opmphmMapping (opmphm, graph, &opmphmInit, n), "acyclic graph marked as cyclic");
368 4860 : exit_if_fail (opmphmAssignment (opmphm, graph, n, 0) == 0, "opmphmAssignment");
369 663390 : for (size_t i = 0; i < n; ++i)
370 : {
371 663390 : succeed_if (opmphmLookup (opmphm, n, graph->edges[i].vertices) == n - 1 - i, "lookup");
372 : }
373 : // cleanup
374 4860 : opmphmDel (opmphm);
375 4860 : opmphmGraphDel (graph);
376 : }
377 : }
378 2 : }
379 :
380 :
381 2 : int main (int argc, char ** argv)
382 : {
383 2 : printf ("OPMPHM TESTS\n");
384 2 : printf ("==================\n\n");
385 :
386 2 : init (argc, argv);
387 :
388 2 : test_basic ();
389 2 : test_opmphmGraphNew ();
390 2 : test_minComponentSize ();
391 2 : test_cyclicMultipleEdges ();
392 2 : test_cyclicCountUpEdges ();
393 2 : test_cyclicCountDownEdges ();
394 2 : test_acyclicDefaultOrder ();
395 2 : test_acyclicReverseOrder ();
396 :
397 2 : print_result ("test_opmphm");
398 :
399 2 : return nbError;
400 : }
|