1 #include <ccan/tdb2/tdb.c>
2 #include <ccan/tdb2/open.c>
3 #include <ccan/tdb2/free.c>
4 #include <ccan/tdb2/lock.c>
5 #include <ccan/tdb2/io.c>
6 #include <ccan/tdb2/hash.c>
7 #include <ccan/tdb2/check.c>
8 #include <ccan/tdb2/transaction.c>
9 #include <ccan/tdb2/traverse.c>
10 #include <ccan/tap/tap.h>
13 static int mylock(int fd, int rw, off_t off, off_t len, bool waitflag,
19 static int myunlock(int fd, int rw, off_t off, off_t len, void *unused)
24 static uint64_t hash_fn(const void *key, size_t len, uint64_t seed,
30 int main(int argc, char *argv[])
33 struct tdb_context *tdb;
34 int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
35 TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT };
36 union tdb_attribute seed_attr;
37 union tdb_attribute hash_attr;
38 union tdb_attribute lock_attr;
40 hash_attr.base.attr = TDB_ATTRIBUTE_HASH;
41 hash_attr.base.next = &seed_attr;
42 hash_attr.hash.fn = hash_fn;
43 hash_attr.hash.data = &hash_attr;
45 seed_attr.base.attr = TDB_ATTRIBUTE_SEED;
46 seed_attr.base.next = &lock_attr;
47 seed_attr.seed.seed = 100;
49 lock_attr.base.attr = TDB_ATTRIBUTE_FLOCK;
50 lock_attr.base.next = &tap_log_attr;
51 lock_attr.flock.lock = mylock;
52 lock_attr.flock.unlock = myunlock;
53 lock_attr.flock.data = &lock_attr;
55 plan_tests(sizeof(flags) / sizeof(flags[0]) * 50);
57 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
58 union tdb_attribute attr;
60 /* First open with no attributes. */
61 tdb = tdb_open("run-90-get-set-attributes.tdb", flags[i],
62 O_RDWR|O_CREAT|O_TRUNC, 0600, NULL);
65 /* Get log on no attributes will fail */
66 attr.base.attr = TDB_ATTRIBUTE_LOG;
67 ok1(tdb_get_attribute(tdb, &attr) == TDB_ERR_NOEXIST);
68 /* These always work. */
69 attr.base.attr = TDB_ATTRIBUTE_HASH;
70 ok1(tdb_get_attribute(tdb, &attr) == 0);
71 ok1(attr.base.attr == TDB_ATTRIBUTE_HASH);
72 ok1(attr.hash.fn == jenkins_hash);
73 attr.base.attr = TDB_ATTRIBUTE_FLOCK;
74 ok1(tdb_get_attribute(tdb, &attr) == 0);
75 ok1(attr.base.attr == TDB_ATTRIBUTE_FLOCK);
76 ok1(attr.flock.lock == tdb_fcntl_lock);
77 ok1(attr.flock.unlock == tdb_fcntl_unlock);
78 attr.base.attr = TDB_ATTRIBUTE_SEED;
79 ok1(tdb_get_attribute(tdb, &attr) == 0);
80 ok1(attr.base.attr == TDB_ATTRIBUTE_SEED);
81 /* This is possible, just astronomically unlikely. */
82 ok1(attr.seed.seed != 0);
84 /* Unset attributes. */
85 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_LOG);
86 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_FLOCK);
89 ok1(tdb_set_attribute(tdb, &tap_log_attr) == 0);
90 ok1(tdb_set_attribute(tdb, &lock_attr) == 0);
91 /* These should fail. */
92 ok1(tdb_set_attribute(tdb, &seed_attr) == TDB_ERR_EINVAL);
93 ok1(tap_log_messages == 1);
94 ok1(tdb_set_attribute(tdb, &hash_attr) == TDB_ERR_EINVAL);
95 ok1(tap_log_messages == 2);
98 /* Getting them should work as expected. */
99 attr.base.attr = TDB_ATTRIBUTE_LOG;
100 ok1(tdb_get_attribute(tdb, &attr) == 0);
101 ok1(attr.base.attr == TDB_ATTRIBUTE_LOG);
102 ok1(attr.log.fn == tap_log_attr.log.fn);
103 ok1(attr.log.data == tap_log_attr.log.data);
105 attr.base.attr = TDB_ATTRIBUTE_FLOCK;
106 ok1(tdb_get_attribute(tdb, &attr) == 0);
107 ok1(attr.base.attr == TDB_ATTRIBUTE_FLOCK);
108 ok1(attr.flock.lock == mylock);
109 ok1(attr.flock.unlock == myunlock);
110 ok1(attr.flock.data == &lock_attr);
112 /* Unset them again. */
113 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_FLOCK);
114 ok1(tap_log_messages == 0);
115 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_LOG);
116 ok1(tap_log_messages == 0);
119 ok1(tap_log_messages == 0);
121 /* Now open with all attributes. */
122 tdb = tdb_open("run-90-get-set-attributes.tdb", flags[i],
123 O_RDWR|O_CREAT|O_TRUNC, 0600, &hash_attr);
126 /* Get will succeed */
127 attr.base.attr = TDB_ATTRIBUTE_LOG;
128 ok1(tdb_get_attribute(tdb, &attr) == 0);
129 ok1(attr.base.attr == TDB_ATTRIBUTE_LOG);
130 ok1(attr.log.fn == tap_log_attr.log.fn);
131 ok1(attr.log.data == tap_log_attr.log.data);
133 attr.base.attr = TDB_ATTRIBUTE_HASH;
134 ok1(tdb_get_attribute(tdb, &attr) == 0);
135 ok1(attr.base.attr == TDB_ATTRIBUTE_HASH);
136 ok1(attr.hash.fn == hash_fn);
137 ok1(attr.hash.data == &hash_attr);
139 attr.base.attr = TDB_ATTRIBUTE_FLOCK;
140 ok1(tdb_get_attribute(tdb, &attr) == 0);
141 ok1(attr.base.attr == TDB_ATTRIBUTE_FLOCK);
142 ok1(attr.flock.lock == mylock);
143 ok1(attr.flock.unlock == myunlock);
144 ok1(attr.flock.data == &lock_attr);
146 attr.base.attr = TDB_ATTRIBUTE_SEED;
147 ok1(tdb_get_attribute(tdb, &attr) == 0);
148 ok1(attr.base.attr == TDB_ATTRIBUTE_SEED);
149 ok1(attr.seed.seed == seed_attr.seed.seed);
151 /* Unset attributes. */
152 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_HASH);
153 ok1(tap_log_messages == 1);
154 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_SEED);
155 ok1(tap_log_messages == 2);
156 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_FLOCK);
157 tdb_unset_attribute(tdb, TDB_ATTRIBUTE_LOG);
158 ok1(tap_log_messages == 2);
159 tap_log_messages = 0;
164 return exit_status();