1
+#include "test-lib.h"
2
+#include "lib-oid.h"
3
+#include "oidmap.h"
4
+#include "hash.h"
5
+#include "hex.h"
6
+
7
+/*
8
+ * Elements we will put in oidmap structs are made of a key: the entry.oid
9
+ * field, which is of type struct object_id, and a value: the name field (could
10
+ * be a refname for example).
11
+ */
12
+struct test_entry {
13
+ struct oidmap_entry entry;
14
+ char name[FLEX_ARRAY];
15
+};
16
+
17
+static const char *const key_val[][2] = { { "11", "one" },
18
+ { "22", "two" },
19
+ { "33", "three" } };
20
+
21
+static void setup(void (*f)(struct oidmap *map))
22
+{
23
+ struct oidmap map = OIDMAP_INIT;
24
+ int ret = 0;
25
+
26
+ for (size_t i = 0; i < ARRAY_SIZE(key_val); i++){
27
+ struct test_entry *entry;
28
+
29
+ FLEX_ALLOC_STR(entry, name, key_val[i][1]);
30
+ if ((ret = get_oid_arbitrary_hex(key_val[i][0], &entry->entry.oid))) {
31
+ free(entry);
32
+ break;
33
+ }
34
+ entry = oidmap_put(&map, entry);
35
+ if (!check(entry == NULL))
36
+ free(entry);
37
+ }
38
+
39
+ if (!ret)
40
+ f(&map);
41
+ oidmap_free(&map, 1);
42
+}
43
+
44
+static void t_replace(struct oidmap *map)
45
+{
46
+ struct test_entry *entry, *prev;
47
+
48
+ FLEX_ALLOC_STR(entry, name, "un");
49
+ if (get_oid_arbitrary_hex("11", &entry->entry.oid))
50
+ return;
51
+ prev = oidmap_put(map, entry);
52
+ if (!check(prev != NULL))
53
+ return;
54
+ check_str(prev->name, "one");
55
+ free(prev);
56
+
57
+ FLEX_ALLOC_STR(entry, name, "deux");
58
+ if (get_oid_arbitrary_hex("22", &entry->entry.oid))
59
+ return;
60
+ prev = oidmap_put(map, entry);
61
+ if (!check(prev != NULL))
62
+ return;
63
+ check_str(prev->name, "two");
64
+ free(prev);
65
+}
66
+
67
+static void t_get(struct oidmap *map)
68
+{
69
+ struct test_entry *entry;
70
+ struct object_id oid;
71
+
72
+ if (get_oid_arbitrary_hex("22", &oid))
73
+ return;
74
+ entry = oidmap_get(map, &oid);
75
+ if (!check(entry != NULL))
76
+ return;
77
+ check_str(entry->name, "two");
78
+
79
+ if (get_oid_arbitrary_hex("44", &oid))
80
+ return;
81
+ check(oidmap_get(map, &oid) == NULL);
82
+
83
+ if (get_oid_arbitrary_hex("11", &oid))
84
+ return;
85
+ entry = oidmap_get(map, &oid);
86
+ if (!check(entry != NULL))
87
+ return;
88
+ check_str(entry->name, "one");
89
+}
90
+
91
+static void t_remove(struct oidmap *map)
92
+{
93
+ struct test_entry *entry;
94
+ struct object_id oid;
95
+
96
+ if (get_oid_arbitrary_hex("11", &oid))
97
+ return;
98
+ entry = oidmap_remove(map, &oid);
99
+ if (!check(entry != NULL))
100
+ return;
101
+ check_str(entry->name, "one");
102
+ check(oidmap_get(map, &oid) == NULL);
103
+ free(entry);
104
+
105
+ if (get_oid_arbitrary_hex("22", &oid))
106
+ return;
107
+ entry = oidmap_remove(map, &oid);
108
+ if (!check(entry != NULL))
109
+ return;
110
+ check_str(entry->name, "two");
111
+ check(oidmap_get(map, &oid) == NULL);
112
+ free(entry);
113
+
114
+ if (get_oid_arbitrary_hex("44", &oid))
115
+ return;
116
+ check(oidmap_remove(map, &oid) == NULL);
117
+}
118
+
119
+static int key_val_contains(struct test_entry *entry, char seen[])
120
+{
121
+ for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) {
122
+ struct object_id oid;
123
+
124
+ if (get_oid_arbitrary_hex(key_val[i][0], &oid))
125
+ return -1;
126
+
127
+ if (oideq(&entry->entry.oid, &oid)) {
128
+ if (seen[i])
129
+ return 2;
130
+ seen[i] = 1;
131
+ return 0;
132
+ }
133
+ }
134
+ return 1;
135
+}
136
+
137
+static void t_iterate(struct oidmap *map)
138
+{
139
+ struct oidmap_iter iter;
140
+ struct test_entry *entry;
141
+ char seen[ARRAY_SIZE(key_val)] = { 0 };
142
+ int count = 0;
143
+
144
+ oidmap_iter_init(map, &iter);
145
+ while ((entry = oidmap_iter_next(&iter))) {
146
+ int ret;
147
+ if (!check_int((ret = key_val_contains(entry, seen)), ==, 0)) {
148
+ switch (ret) {
149
+ case -1:
150
+ break; /* error message handled by get_oid_arbitrary_hex() */
151
+ case 1:
152
+ test_msg("obtained entry was not given in the input\n"
153
+ " name: %s\n oid: %s\n",
154
+ entry->name, oid_to_hex(&entry->entry.oid));
155
+ break;
156
+ case 2:
157
+ test_msg("duplicate entry detected\n"
158
+ " name: %s\n oid: %s\n",
159
+ entry->name, oid_to_hex(&entry->entry.oid));
160
+ break;
161
+ default:
162
+ test_msg("BUG: invalid return value (%d) from key_val_contains()",
163
+ ret);
164
+ break;
165
+ }
166
+ } else {
167
+ count++;
168
+ }
169
+ }
170
+ check_int(count, ==, ARRAY_SIZE(key_val));
171
+ check_int(hashmap_get_size(&map->map), ==, ARRAY_SIZE(key_val));
172
+}
173
+
174
+int cmd_main(int argc UNUSED, const char **argv UNUSED)
175
+{
176
+ TEST(setup(t_replace), "replace works");
177
+ TEST(setup(t_get), "get works");
178
+ TEST(setup(t_remove), "remove works");
179
+ TEST(setup(t_iterate), "iterate works");
180
+ return test_done();
181
+}