1 /* Tests for persistence.
2 *
3 * FIXME - these need to be aggressive about finding failures, at the moment
4 * they are just confirming that good behaviour works. */
5
6 #include <CUnit/CUnit.h>
7 #include <CUnit/Basic.h>
8
9 #define WITH_BROKER
10 #define WITH_PERSISTENCE
11
12 #include "mosquitto_broker_internal.h"
13 #include "persist.h"
14 #include "property_mosq.h"
15
16 uint64_t last_retained;
17 char *last_sub = NULL;
18 int last_qos;
19 uint32_t last_identifier;
20
TEST_persistence_disabled(void)21 static void TEST_persistence_disabled(void)
22 {
23 struct mosquitto_db db;
24 struct mosquitto__config config;
25 int rc;
26
27 memset(&db, 0, sizeof(struct mosquitto_db));
28 memset(&config, 0, sizeof(struct mosquitto__config));
29 db.config = &config;
30
31 rc = persist__restore(&db);
32 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
33 }
34
35
TEST_empty_file(void)36 static void TEST_empty_file(void)
37 {
38 struct mosquitto_db db;
39 struct mosquitto__config config;
40 int rc;
41
42 memset(&db, 0, sizeof(struct mosquitto_db));
43 memset(&config, 0, sizeof(struct mosquitto__config));
44 db.config = &config;
45
46 config.persistence = true;
47
48 config.persistence_filepath = "files/persist_read/empty.test-db";
49 rc = persist__restore(&db);
50 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
51 }
52
53
TEST_corrupt_header(void)54 static void TEST_corrupt_header(void)
55 {
56 struct mosquitto_db db;
57 struct mosquitto__config config;
58 int rc;
59
60 memset(&db, 0, sizeof(struct mosquitto_db));
61 memset(&config, 0, sizeof(struct mosquitto__config));
62 db.config = &config;
63
64 config.persistence = true;
65
66 config.persistence_filepath = "files/persist_read/corrupt-header-short.test-db";
67 rc = persist__restore(&db);
68 CU_ASSERT_EQUAL(rc, 1);
69
70 config.persistence_filepath = "files/persist_read/corrupt-header-long.test-db";
71 rc = persist__restore(&db);
72 CU_ASSERT_EQUAL(rc, 1);
73 }
74
TEST_unsupported_version(void)75 static void TEST_unsupported_version(void)
76 {
77 struct mosquitto_db db;
78 struct mosquitto__config config;
79 int rc;
80
81 memset(&db, 0, sizeof(struct mosquitto_db));
82 memset(&config, 0, sizeof(struct mosquitto__config));
83 db.config = &config;
84
85 config.persistence = true;
86 config.persistence_filepath = "files/persist_read/unsupported-version.test-db";
87
88 rc = persist__restore(&db);
89 CU_ASSERT_EQUAL(rc, 1);
90 }
91
92
TEST_v3_config_ok(void)93 static void TEST_v3_config_ok(void)
94 {
95 struct mosquitto_db db;
96 struct mosquitto__config config;
97 int rc;
98
99 memset(&db, 0, sizeof(struct mosquitto_db));
100 memset(&config, 0, sizeof(struct mosquitto__config));
101 db.config = &config;
102
103 config.persistence = true;
104 config.persistence_filepath = "files/persist_read/v3-cfg.test-db";
105
106 rc = persist__restore(&db);
107 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
108 CU_ASSERT_EQUAL(db.last_db_id, 0x7856341200000000);
109 }
110
111
TEST_v4_config_ok(void)112 static void TEST_v4_config_ok(void)
113 {
114 struct mosquitto_db db;
115 struct mosquitto__config config;
116 int rc;
117
118 memset(&db, 0, sizeof(struct mosquitto_db));
119 memset(&config, 0, sizeof(struct mosquitto__config));
120 db.config = &config;
121
122 config.persistence = true;
123 config.persistence_filepath = "files/persist_read/v4-cfg.test-db";
124
125 rc = persist__restore(&db);
126 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
127 CU_ASSERT_EQUAL(db.last_db_id, 0x7856341200000000);
128 }
129
130
TEST_v3_config_truncated(void)131 static void TEST_v3_config_truncated(void)
132 {
133 struct mosquitto_db db;
134 struct mosquitto__config config;
135 int rc;
136
137 memset(&db, 0, sizeof(struct mosquitto_db));
138 memset(&config, 0, sizeof(struct mosquitto__config));
139 db.config = &config;
140
141 config.persistence = true;
142 config.persistence_filepath = "files/persist_read/v3-cfg-truncated.test-db";
143
144 rc = persist__restore(&db);
145 CU_ASSERT_EQUAL(rc, 1);
146 CU_ASSERT_EQUAL(db.last_db_id, 0);
147 }
148
149
TEST_v3_config_bad_dbid(void)150 static void TEST_v3_config_bad_dbid(void)
151 {
152 struct mosquitto_db db;
153 struct mosquitto__config config;
154 int rc;
155
156 memset(&db, 0, sizeof(struct mosquitto_db));
157 memset(&config, 0, sizeof(struct mosquitto__config));
158 db.config = &config;
159
160 config.persistence = true;
161 config.persistence_filepath = "files/persist_read/v3-cfg-bad-dbid.test-db";
162
163 rc = persist__restore(&db);
164 CU_ASSERT_EQUAL(rc, 1);
165 CU_ASSERT_EQUAL(db.last_db_id, 0);
166 }
167
168
TEST_v3_bad_chunk(void)169 static void TEST_v3_bad_chunk(void)
170 {
171 struct mosquitto_db db;
172 struct mosquitto__config config;
173 int rc;
174
175 memset(&db, 0, sizeof(struct mosquitto_db));
176 memset(&config, 0, sizeof(struct mosquitto__config));
177 db.config = &config;
178
179 config.persistence = true;
180 config.persistence_filepath = "files/persist_read/v3-bad-chunk.test-db";
181
182 rc = persist__restore(&db);
183 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
184 CU_ASSERT_EQUAL(db.last_db_id, 0x17);
185 }
186
187
TEST_v3_message_store(void)188 static void TEST_v3_message_store(void)
189 {
190 struct mosquitto_db db;
191 struct mosquitto__config config;
192 int rc;
193
194 memset(&db, 0, sizeof(struct mosquitto_db));
195 memset(&config, 0, sizeof(struct mosquitto__config));
196 db.config = &config;
197
198 config.persistence = true;
199 config.persistence_filepath = "files/persist_read/v3-message-store.test-db";
200
201 rc = persist__restore(&db);
202 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
203 CU_ASSERT_EQUAL(db.msg_store_count, 1);
204 CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
205 CU_ASSERT_PTR_NOT_NULL(db.msg_store);
206 if(db.msg_store){
207 CU_ASSERT_EQUAL(db.msg_store->db_id, 1);
208 CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
209 CU_ASSERT_EQUAL(db.msg_store->source_mid, 2);
210 CU_ASSERT_EQUAL(db.msg_store->mid, 0);
211 CU_ASSERT_EQUAL(db.msg_store->qos, 2);
212 CU_ASSERT_EQUAL(db.msg_store->retain, 1);
213 CU_ASSERT_PTR_NOT_NULL(db.msg_store->topic);
214 if(db.msg_store->topic){
215 CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
216 }
217 CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
218 if(db.msg_store->payloadlen == 7){
219 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
220 }
221 }
222 }
223
TEST_v3_client(void)224 static void TEST_v3_client(void)
225 {
226 struct mosquitto_db db;
227 struct mosquitto__config config;
228 struct mosquitto *context;
229 int rc;
230
231 memset(&db, 0, sizeof(struct mosquitto_db));
232 memset(&config, 0, sizeof(struct mosquitto__config));
233 db.config = &config;
234
235 config.persistence = true;
236 config.persistence_filepath = "files/persist_read/v3-client.test-db";
237
238 rc = persist__restore(&db);
239 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
240
241 CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
242 HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
243 CU_ASSERT_PTR_NOT_NULL(context);
244 if(context){
245 CU_ASSERT_PTR_NULL(context->msgs_in.inflight);
246 CU_ASSERT_PTR_NULL(context->msgs_out.inflight);
247 CU_ASSERT_EQUAL(context->last_mid, 0x5287);
248 }
249 }
250
TEST_v3_client_message(void)251 static void TEST_v3_client_message(void)
252 {
253 struct mosquitto_db db;
254 struct mosquitto__config config;
255 struct mosquitto *context;
256 int rc;
257
258 memset(&db, 0, sizeof(struct mosquitto_db));
259 memset(&config, 0, sizeof(struct mosquitto__config));
260 db.config = &config;
261
262 config.persistence = true;
263 config.persistence_filepath = "files/persist_read/v3-client-message.test-db";
264 config.max_inflight_messages = 20;
265
266 rc = persist__restore(&db);
267 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
268
269 CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
270 HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
271 CU_ASSERT_PTR_NOT_NULL(context);
272 if(context){
273 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight);
274 if(context->msgs_out.inflight){
275 CU_ASSERT_PTR_NULL(context->msgs_out.inflight->next);
276 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight->store);
277 if(context->msgs_out.inflight->store){
278 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->ref_count, 1);
279 CU_ASSERT_STRING_EQUAL(context->msgs_out.inflight->store->source_id, "source_id");
280 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->source_mid, 2);
281 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->mid, 0);
282 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->qos, 2);
283 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->retain, 1);
284 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight->store->topic);
285 if(context->msgs_out.inflight->store->topic){
286 CU_ASSERT_STRING_EQUAL(context->msgs_out.inflight->store->topic, "topic");
287 }
288 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->payloadlen, 7);
289 if(context->msgs_out.inflight->store->payloadlen == 7){
290 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(context->msgs_out.inflight->store), "payload", 7);
291 }
292 }
293 CU_ASSERT_EQUAL(context->msgs_out.inflight->mid, 0x73);
294 CU_ASSERT_EQUAL(context->msgs_out.inflight->qos, 1);
295 CU_ASSERT_EQUAL(context->msgs_out.inflight->retain, 0);
296 CU_ASSERT_EQUAL(context->msgs_out.inflight->direction, mosq_md_out);
297 CU_ASSERT_EQUAL(context->msgs_out.inflight->state, mosq_ms_wait_for_puback);
298 CU_ASSERT_EQUAL(context->msgs_out.inflight->dup, 0);
299 CU_ASSERT_PTR_NULL(context->msgs_out.inflight->properties);
300 }
301 }
302 }
303
TEST_v3_retain(void)304 static void TEST_v3_retain(void)
305 {
306 struct mosquitto_db db;
307 struct mosquitto__config config;
308 int rc;
309
310 last_retained = 0;
311
312 memset(&db, 0, sizeof(struct mosquitto_db));
313 memset(&config, 0, sizeof(struct mosquitto__config));
314 db.config = &config;
315
316 config.persistence = true;
317 config.persistence_filepath = "files/persist_read/v3-retain.test-db";
318
319 rc = persist__restore(&db);
320 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
321 CU_ASSERT_EQUAL(db.msg_store_count, 1);
322 CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
323 CU_ASSERT_PTR_NOT_NULL(db.msg_store);
324 if(db.msg_store){
325 CU_ASSERT_EQUAL(db.msg_store->db_id, 0x54);
326 CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
327 CU_ASSERT_EQUAL(db.msg_store->source_mid, 2);
328 CU_ASSERT_EQUAL(db.msg_store->mid, 0);
329 CU_ASSERT_EQUAL(db.msg_store->qos, 2);
330 CU_ASSERT_EQUAL(db.msg_store->retain, 1);
331 CU_ASSERT_PTR_NOT_NULL(db.msg_store->topic);
332 if(db.msg_store->topic){
333 CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
334 }
335 CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
336 if(db.msg_store->payloadlen == 7){
337 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
338 }
339 }
340 CU_ASSERT_EQUAL(last_retained, 0x54);
341 }
342
TEST_v3_sub(void)343 static void TEST_v3_sub(void)
344 {
345 struct mosquitto_db db;
346 struct mosquitto__config config;
347 struct mosquitto *context;
348 int rc;
349
350 last_sub = NULL;
351 last_qos = -1;
352
353 memset(&db, 0, sizeof(struct mosquitto_db));
354 memset(&config, 0, sizeof(struct mosquitto__config));
355 db.config = &config;
356
357 config.persistence = true;
358 config.persistence_filepath = "files/persist_read/v3-sub.test-db";
359
360 rc = persist__restore(&db);
361 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
362
363 CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
364 HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
365 CU_ASSERT_PTR_NOT_NULL(context);
366 if(context){
367 CU_ASSERT_PTR_NOT_NULL(last_sub);
368 if(last_sub){
369 CU_ASSERT_STRING_EQUAL(last_sub, "subscription")
370 free(last_sub);
371 }
372 CU_ASSERT_EQUAL(last_qos, 1);
373 }
374 }
375
TEST_v4_message_store(void)376 static void TEST_v4_message_store(void)
377 {
378 struct mosquitto_db db;
379 struct mosquitto__config config;
380 int rc;
381
382 memset(&db, 0, sizeof(struct mosquitto_db));
383 memset(&config, 0, sizeof(struct mosquitto__config));
384 db.config = &config;
385
386 config.persistence = true;
387 config.persistence_filepath = "files/persist_read/v4-message-store.test-db";
388
389 rc = persist__restore(&db);
390 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
391 CU_ASSERT_EQUAL(db.msg_store_count, 1);
392 CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
393 CU_ASSERT_PTR_NOT_NULL(db.msg_store);
394 if(db.msg_store){
395 CU_ASSERT_EQUAL(db.msg_store->db_id, 0xFEDCBA9876543210);
396 CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
397 CU_ASSERT_EQUAL(db.msg_store->source_mid, 0x88);
398 CU_ASSERT_EQUAL(db.msg_store->mid, 0);
399 CU_ASSERT_EQUAL(db.msg_store->qos, 1);
400 CU_ASSERT_EQUAL(db.msg_store->retain, 0);
401 CU_ASSERT_PTR_NOT_NULL(db.msg_store->topic);
402 if(db.msg_store->topic){
403 CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
404 }
405 CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
406 if(db.msg_store->payloadlen == 7){
407 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
408 }
409 }
410 }
411
TEST_v5_config_ok(void)412 static void TEST_v5_config_ok(void)
413 {
414 struct mosquitto_db db;
415 struct mosquitto__config config;
416 int rc;
417
418 memset(&db, 0, sizeof(struct mosquitto_db));
419 memset(&config, 0, sizeof(struct mosquitto__config));
420 db.config = &config;
421
422 config.persistence = true;
423 config.persistence_filepath = "files/persist_read/v5-cfg.test-db";
424
425 rc = persist__restore(&db);
426 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
427 CU_ASSERT_EQUAL(db.last_db_id, 0x7856341200000000);
428 }
429
430
TEST_v5_config_truncated(void)431 static void TEST_v5_config_truncated(void)
432 {
433 struct mosquitto_db db;
434 struct mosquitto__config config;
435 int rc;
436
437 memset(&db, 0, sizeof(struct mosquitto_db));
438 memset(&config, 0, sizeof(struct mosquitto__config));
439 db.config = &config;
440
441 config.persistence = true;
442 config.persistence_filepath = "files/persist_read/v5-cfg-truncated.test-db";
443
444 rc = persist__restore(&db);
445 CU_ASSERT_EQUAL(rc, 1);
446 CU_ASSERT_EQUAL(db.last_db_id, 0);
447 }
448
449
TEST_v5_bad_chunk(void)450 static void TEST_v5_bad_chunk(void)
451 {
452 struct mosquitto_db db;
453 struct mosquitto__config config;
454 int rc;
455
456 memset(&db, 0, sizeof(struct mosquitto_db));
457 memset(&config, 0, sizeof(struct mosquitto__config));
458 db.config = &config;
459
460 config.persistence = true;
461 config.persistence_filepath = "files/persist_read/v5-bad-chunk.test-db";
462
463 rc = persist__restore(&db);
464 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
465 CU_ASSERT_EQUAL(db.last_db_id, 0x17);
466 }
467
468
TEST_v5_message_store(void)469 static void TEST_v5_message_store(void)
470 {
471 struct mosquitto_db db;
472 struct mosquitto__config config;
473 int rc;
474
475 memset(&db, 0, sizeof(struct mosquitto_db));
476 memset(&config, 0, sizeof(struct mosquitto__config));
477 db.config = &config;
478
479 config.persistence = true;
480 config.persistence_filepath = "files/persist_read/v5-message-store.test-db";
481
482 rc = persist__restore(&db);
483 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
484 CU_ASSERT_EQUAL(db.msg_store_count, 1);
485 CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
486 CU_ASSERT_PTR_NOT_NULL(db.msg_store);
487 if(db.msg_store){
488 CU_ASSERT_EQUAL(db.msg_store->db_id, 1);
489 CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
490 CU_ASSERT_EQUAL(db.msg_store->source_mid, 2);
491 CU_ASSERT_EQUAL(db.msg_store->mid, 0);
492 CU_ASSERT_EQUAL(db.msg_store->qos, 2);
493 CU_ASSERT_EQUAL(db.msg_store->retain, 1);
494 CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
495 CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
496 if(db.msg_store->payloadlen == 7){
497 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
498 }
499 CU_ASSERT_PTR_NULL(db.msg_store->properties);
500 }
501 }
502
503
TEST_v5_message_store_props(void)504 static void TEST_v5_message_store_props(void)
505 {
506 struct mosquitto_db db;
507 struct mosquitto__config config;
508 struct mosquitto__listener listener;
509 int rc;
510
511 memset(&db, 0, sizeof(struct mosquitto_db));
512 memset(&config, 0, sizeof(struct mosquitto__config));
513 memset(&listener, 0, sizeof(struct mosquitto__listener));
514 db.config = &config;
515
516 listener.port = 1883;
517 config.listeners = &listener;
518 config.listener_count = 1;
519
520 config.persistence = true;
521 config.persistence_filepath = "files/persist_read/v5-message-store-props.test-db";
522
523 rc = persist__restore(&db);
524 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
525 CU_ASSERT_EQUAL(db.msg_store_count, 1);
526 CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
527 CU_ASSERT_PTR_NOT_NULL(db.msg_store);
528 if(db.msg_store){
529 CU_ASSERT_EQUAL(db.msg_store->db_id, 1);
530 CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
531 CU_ASSERT_EQUAL(db.msg_store->source_mid, 2);
532 CU_ASSERT_EQUAL(db.msg_store->mid, 0);
533 CU_ASSERT_EQUAL(db.msg_store->qos, 2);
534 CU_ASSERT_EQUAL(db.msg_store->retain, 1);
535 CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
536 CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
537 if(db.msg_store->payloadlen == 7){
538 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
539 }
540 CU_ASSERT_PTR_NOT_NULL(db.msg_store->properties);
541 if(db.msg_store->properties){
542 CU_ASSERT_EQUAL(db.msg_store->properties->identifier, 1);
543 CU_ASSERT_EQUAL(db.msg_store->properties->value.i8, 1);
544 }
545 CU_ASSERT_PTR_NOT_NULL(db.msg_store->source_listener);
546 }
547 }
548
TEST_v5_client(void)549 static void TEST_v5_client(void)
550 {
551 struct mosquitto_db db;
552 struct mosquitto__config config;
553 struct mosquitto *context;
554 int rc;
555
556 memset(&db, 0, sizeof(struct mosquitto_db));
557 memset(&config, 0, sizeof(struct mosquitto__config));
558 db.config = &config;
559
560 config.persistence = true;
561 config.persistence_filepath = "files/persist_read/v5-client.test-db";
562
563 rc = persist__restore(&db);
564 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
565
566 CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
567 HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
568 CU_ASSERT_PTR_NOT_NULL(context);
569 if(context){
570 CU_ASSERT_PTR_NULL(context->msgs_in.inflight);
571 CU_ASSERT_PTR_NULL(context->msgs_out.inflight);
572 CU_ASSERT_EQUAL(context->last_mid, 0x5287);
573 }
574 }
575
TEST_v5_client_message(void)576 static void TEST_v5_client_message(void)
577 {
578 struct mosquitto_db db;
579 struct mosquitto__config config;
580 struct mosquitto *context;
581 int rc;
582
583 memset(&db, 0, sizeof(struct mosquitto_db));
584 memset(&config, 0, sizeof(struct mosquitto__config));
585 db.config = &config;
586
587 config.persistence = true;
588 config.persistence_filepath = "files/persist_read/v5-client-message.test-db";
589
590 rc = persist__restore(&db);
591 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
592
593 CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
594 HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
595 CU_ASSERT_PTR_NOT_NULL(context);
596 if(context){
597 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight);
598 if(context->msgs_out.inflight){
599 CU_ASSERT_PTR_NULL(context->msgs_out.inflight->next);
600 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight->store);
601 if(context->msgs_out.inflight->store){
602 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->ref_count, 1);
603 CU_ASSERT_STRING_EQUAL(context->msgs_out.inflight->store->source_id, "source_id");
604 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->source_mid, 2);
605 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->mid, 0);
606 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->qos, 2);
607 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->retain, 1);
608 CU_ASSERT_STRING_EQUAL(context->msgs_out.inflight->store->topic, "topic");
609 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->payloadlen, 7);
610 if(context->msgs_out.inflight->store->payloadlen == 7){
611 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(context->msgs_out.inflight->store), "payload", 7);
612 }
613 }
614 CU_ASSERT_EQUAL(context->msgs_out.inflight->mid, 0x73);
615 CU_ASSERT_EQUAL(context->msgs_out.inflight->qos, 1);
616 CU_ASSERT_EQUAL(context->msgs_out.inflight->retain, 0);
617 CU_ASSERT_EQUAL(context->msgs_out.inflight->direction, mosq_md_out);
618 CU_ASSERT_EQUAL(context->msgs_out.inflight->state, mosq_ms_wait_for_puback);
619 CU_ASSERT_EQUAL(context->msgs_out.inflight->dup, 0);
620 CU_ASSERT_PTR_NULL(context->msgs_out.inflight->properties);
621 }
622 }
623 }
624
TEST_v5_client_message_props(void)625 static void TEST_v5_client_message_props(void)
626 {
627 struct mosquitto_db db;
628 struct mosquitto__config config;
629 struct mosquitto *context;
630 int rc;
631
632 memset(&db, 0, sizeof(struct mosquitto_db));
633 memset(&config, 0, sizeof(struct mosquitto__config));
634 db.config = &config;
635
636 config.persistence = true;
637 config.persistence_filepath = "files/persist_read/v5-client-message-props.test-db";
638
639 rc = persist__restore(&db);
640 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
641
642 CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
643 HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
644 CU_ASSERT_PTR_NOT_NULL(context);
645 if(context){
646 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight);
647 if(context->msgs_out.inflight){
648 CU_ASSERT_PTR_NULL(context->msgs_out.inflight->next);
649 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight->store);
650 if(context->msgs_out.inflight->store){
651 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->ref_count, 1);
652 CU_ASSERT_STRING_EQUAL(context->msgs_out.inflight->store->source_id, "source_id");
653 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->source_mid, 2);
654 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->mid, 0);
655 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->qos, 2);
656 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->retain, 1);
657 CU_ASSERT_STRING_EQUAL(context->msgs_out.inflight->store->topic, "topic");
658 CU_ASSERT_EQUAL(context->msgs_out.inflight->store->payloadlen, 7);
659 if(context->msgs_out.inflight->store->payloadlen == 7){
660 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(context->msgs_out.inflight->store), "payload", 7);
661 }
662 }
663 CU_ASSERT_EQUAL(context->msgs_out.inflight->mid, 0x73);
664 CU_ASSERT_EQUAL(context->msgs_out.inflight->qos, 1);
665 CU_ASSERT_EQUAL(context->msgs_out.inflight->retain, 0);
666 CU_ASSERT_EQUAL(context->msgs_out.inflight->direction, mosq_md_out);
667 CU_ASSERT_EQUAL(context->msgs_out.inflight->state, mosq_ms_wait_for_puback);
668 CU_ASSERT_EQUAL(context->msgs_out.inflight->dup, 0);
669 CU_ASSERT_PTR_NOT_NULL(context->msgs_out.inflight->properties);
670 if(context->msgs_out.inflight->properties){
671 CU_ASSERT_EQUAL(context->msgs_out.inflight->properties->identifier, 1);
672 CU_ASSERT_EQUAL(context->msgs_out.inflight->properties->value.i8, 1);
673 }
674 }
675 }
676 }
677
TEST_v5_retain(void)678 static void TEST_v5_retain(void)
679 {
680 struct mosquitto_db db;
681 struct mosquitto__config config;
682 int rc;
683
684 last_retained = 0;
685
686 memset(&db, 0, sizeof(struct mosquitto_db));
687 memset(&config, 0, sizeof(struct mosquitto__config));
688 db.config = &config;
689
690 config.persistence = true;
691 config.persistence_filepath = "files/persist_read/v5-retain.test-db";
692
693 rc = persist__restore(&db);
694 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
695 CU_ASSERT_EQUAL(db.msg_store_count, 1);
696 CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
697 CU_ASSERT_PTR_NOT_NULL(db.msg_store);
698 if(db.msg_store){
699 CU_ASSERT_EQUAL(db.msg_store->db_id, 0x54);
700 CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
701 CU_ASSERT_EQUAL(db.msg_store->source_mid, 2);
702 CU_ASSERT_EQUAL(db.msg_store->mid, 0);
703 CU_ASSERT_EQUAL(db.msg_store->qos, 2);
704 CU_ASSERT_EQUAL(db.msg_store->retain, 1);
705 CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
706 CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
707 if(db.msg_store->payloadlen == 7){
708 CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
709 }
710 }
711 CU_ASSERT_EQUAL(last_retained, 0x54);
712 }
713
TEST_v5_sub(void)714 static void TEST_v5_sub(void)
715 {
716 struct mosquitto_db db;
717 struct mosquitto__config config;
718 struct mosquitto *context;
719 int rc;
720
721 last_sub = NULL;
722 last_qos = -1;
723
724 memset(&db, 0, sizeof(struct mosquitto_db));
725 memset(&config, 0, sizeof(struct mosquitto__config));
726 db.config = &config;
727
728 config.persistence = true;
729 config.persistence_filepath = "files/persist_read/v5-sub.test-db";
730
731 rc = persist__restore(&db);
732 CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
733
734 CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
735 HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
736 CU_ASSERT_PTR_NOT_NULL(context);
737 if(context){
738 CU_ASSERT_PTR_NOT_NULL(last_sub);
739 if(last_sub){
740 CU_ASSERT_STRING_EQUAL(last_sub, "subscription")
741 free(last_sub);
742 }
743 CU_ASSERT_EQUAL(last_qos, 1);
744 CU_ASSERT_EQUAL(last_identifier, 0x7623);
745 }
746 }
747
748 /* ========================================================================
749 * TEST SUITE SETUP
750 * ======================================================================== */
751
init_persist_read_tests(void)752 int init_persist_read_tests(void)
753 {
754 CU_pSuite test_suite = NULL;
755
756 test_suite = CU_add_suite("Persist read", NULL, NULL);
757 if(!test_suite){
758 printf("Error adding CUnit persist read test suite.\n");
759 return 1;
760 }
761
762 if(0
763 || !CU_add_test(test_suite, "Persistence disabled", TEST_persistence_disabled)
764 || !CU_add_test(test_suite, "Empty file", TEST_empty_file)
765 || !CU_add_test(test_suite, "Corrupt header", TEST_corrupt_header)
766 || !CU_add_test(test_suite, "Unsupported version", TEST_unsupported_version)
767 || !CU_add_test(test_suite, "v3 config ok", TEST_v3_config_ok)
768 || !CU_add_test(test_suite, "v3 config bad truncated", TEST_v3_config_truncated)
769 || !CU_add_test(test_suite, "v3 config bad dbid", TEST_v3_config_bad_dbid)
770 || !CU_add_test(test_suite, "v3 bad chunk", TEST_v3_bad_chunk)
771 || !CU_add_test(test_suite, "v3 message store", TEST_v3_message_store)
772 || !CU_add_test(test_suite, "v3 client", TEST_v3_client)
773 || !CU_add_test(test_suite, "v3 client message", TEST_v3_client_message)
774 || !CU_add_test(test_suite, "v3 retain", TEST_v3_retain)
775 || !CU_add_test(test_suite, "v3 sub", TEST_v3_sub)
776 || !CU_add_test(test_suite, "v4 config ok", TEST_v4_config_ok)
777 || !CU_add_test(test_suite, "v4 message store", TEST_v4_message_store)
778 || !CU_add_test(test_suite, "v5 config ok", TEST_v5_config_ok)
779 || !CU_add_test(test_suite, "v5 config bad truncated", TEST_v5_config_truncated)
780 || !CU_add_test(test_suite, "v5 bad chunk", TEST_v5_bad_chunk)
781 || !CU_add_test(test_suite, "v5 message store", TEST_v5_message_store)
782 || !CU_add_test(test_suite, "v5 message store+props", TEST_v5_message_store_props)
783 || !CU_add_test(test_suite, "v5 client", TEST_v5_client)
784 || !CU_add_test(test_suite, "v5 client message", TEST_v5_client_message)
785 || !CU_add_test(test_suite, "v5 client message+props", TEST_v5_client_message_props)
786 || !CU_add_test(test_suite, "v5 retain", TEST_v5_retain)
787 || !CU_add_test(test_suite, "v5 sub", TEST_v5_sub)
788 ){
789
790 printf("Error adding persist CUnit tests.\n");
791 return 1;
792 }
793
794 return 0;
795 }
796
main(int argc,char * argv[])797 int main(int argc, char *argv[])
798 {
799 int fails;
800
801 if(CU_initialize_registry() != CUE_SUCCESS){
802 printf("Error initializing CUnit registry.\n");
803 return 1;
804 }
805
806 if(0
807 || init_persist_read_tests()
808 ){
809
810 CU_cleanup_registry();
811 return 1;
812 }
813
814 CU_basic_set_mode(CU_BRM_VERBOSE);
815 CU_basic_run_tests();
816 fails = CU_get_number_of_failures();
817 CU_cleanup_registry();
818
819 return (int)fails;
820 }
821