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