1 /*  Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 
3     This program is free software: you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation, either version 3 of the License, or
6     (at your option) any later version.
7 
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12 
13     You should have received a copy of the GNU General Public License
14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
15  */
16 
17 #include <assert.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <tap/basic.h>
21 #include <tap/files.h>
22 
23 #include "knot/zone/timers.h"
24 #include "libknot/db/db_lmdb.h"
25 #include "libknot/dname.h"
26 #include "libknot/error.h"
27 
28 static const zone_timers_t MOCK_TIMERS = {
29 	.soa_expire = 3600,
30 	.last_refresh = 1474559950,
31 	.next_refresh = 1474559960,
32 	.last_notified_serial = 0,
33 	.last_flush = 1,
34 	.last_resalt = 2,
35 	.next_ds_check = 1474559961,
36 	.next_ds_push = 1474559962,
37 	.catalog_member = 1474559963,
38 };
39 
timers_eq(const zone_timers_t * a,const zone_timers_t * b)40 static bool timers_eq(const zone_timers_t *a, const zone_timers_t *b)
41 {
42 	return a->soa_expire == b->soa_expire &&
43 	       a->last_refresh == b->last_refresh &&
44 	       a->next_refresh == b->next_refresh &&
45 	       a->last_notified_serial == b->last_notified_serial &&
46 	       a->last_flush == b->last_flush &&
47 	       a->last_resalt == b->last_resalt &&
48 	       a->next_ds_check == b->next_ds_check &&
49 	       a->next_ds_push == b->next_ds_push &&
50 	       a->catalog_member == b->catalog_member;
51 }
52 
keep_all(const knot_dname_t * zone,void * data)53 static bool keep_all(const knot_dname_t *zone, void *data)
54 {
55 	return true;
56 }
57 
remove_all(const knot_dname_t * zone,void * data)58 static bool remove_all(const knot_dname_t *zone, void *data)
59 {
60 	return false;
61 }
62 
main(int argc,char * argv[])63 int main(int argc, char *argv[])
64 {
65 	plan_lazy();
66 	assert(knot_db_lmdb_api());
67 
68 	char *dbid = test_mkdtemp();
69 	if (!dbid) {
70 		return EXIT_FAILURE;
71 	}
72 
73 	const knot_dname_t *zone = (uint8_t *)"\x7""example""\x3""com";
74 	struct zone_timers timers = MOCK_TIMERS;
75 
76 	// Create database
77 	knot_lmdb_db_t _db = { 0 }, *db = &_db;
78 	knot_lmdb_init(db, dbid, 1024 * 1024, 0, NULL);
79 	int ret = knot_lmdb_open(db);
80 	ok(ret == KNOT_EOK && db != NULL, "open timers");
81 
82 	// Lookup nonexistent
83 	ret = zone_timers_read(db, zone, &timers);
84 	is_int(KNOT_ENOENT, ret, "zone_timer_read() nonexistent");
85 
86 	// Write timers
87 	ret = zone_timers_write(db, zone, &timers);
88 	is_int(KNOT_EOK, ret, "zone_timers_write()");
89 
90 	// Read timers
91 	memset(&timers, 0, sizeof(timers));
92 	ret = zone_timers_read(db, zone, &timers);
93 	ok(ret == KNOT_EOK, "zone_timers_read()");
94 	ok(timers_eq(&timers, &MOCK_TIMERS), "inconsistent timers");
95 
96 	// Sweep none
97 	ret = zone_timers_sweep(db, keep_all, NULL);
98 	is_int(KNOT_EOK, ret, "zone_timers_sweep() none");
99 	ret = zone_timers_read(db, zone, &timers);
100 	is_int(KNOT_EOK, ret, "zone_timers_read()");
101 
102 	// Sweep all
103 	ret = zone_timers_sweep(db, remove_all, NULL);
104 	is_int(KNOT_EOK, ret, "zone_timers_sweep() all");
105 	ret = zone_timers_read(db, zone, &timers);
106 	is_int(KNOT_ENOENT, ret, "zone_timers_read() nonexistent");
107 
108 	// Clean up.
109 	knot_lmdb_deinit(db);
110 	test_rm_rf(dbid);
111 	free(dbid);
112 
113 	return EXIT_SUCCESS;
114 }
115