d2e382690a1cc2d3dff968284e7186ad2b33bffc
[trust_router.git] / trp / test / rtbl_test.c
1 #include <stdio.h>
2 #include <talloc.h>
3 #include <string.h>
4 #include <assert.h>
5
6 #include <trust_router/tr_name.h>
7 #include <trp_rtable.h>
8
9 char *apc[]={"apc1", "apc2", "apc3"};
10 size_t n_apc=sizeof(apc)/sizeof(apc[0]);
11 char *realm[]={"realm1", "realm2", "realm3"};
12 size_t n_realm=sizeof(realm)/sizeof(realm[0]);
13 char *peer[]={"peer1", "peer2", "peer3"};
14 size_t n_peer=sizeof(peer)/sizeof(peer[0]);
15
16 static unsigned int metric1(size_t a, size_t b, size_t c)
17 {
18   return a+b+c;
19 }
20
21 static unsigned int metric2(size_t a, size_t b, size_t c)
22 {
23   return a+b+c+25;
24 }
25
26 static unsigned int metric3(size_t a, size_t b, size_t c)
27 {
28   return a*(b+c)+b*c;
29 }
30
31 static void populate_rtable(TRP_RTABLE *table, unsigned int (*metric)(size_t, size_t, size_t))
32 {
33   TRP_RENTRY *entry=NULL;
34   size_t ii=0, jj=0, kk=0;
35   struct timespec ts={0,0};
36
37   for (ii=0; ii<n_apc; ii++) {
38     for (jj=0; jj<n_realm; jj++) {
39       for (kk=0; kk<n_peer; kk++) {
40         entry=trp_rentry_new(NULL);
41         trp_rentry_set_apc(entry, tr_new_name(apc[ii]));
42         trp_rentry_set_realm(entry, tr_new_name(realm[jj]));
43         trp_rentry_set_trust_router(entry, tr_new_name(realm[jj]));
44         trp_rentry_set_peer(entry, tr_new_name(peer[kk]));
45         trp_rentry_set_metric(entry, metric(ii,jj,kk));
46         trp_rentry_set_next_hop(entry, tr_new_name(peer[kk]));
47         ts=(struct timespec){jj+1,ii+kk+1};
48         trp_rentry_set_expiry(entry, &ts);
49         trp_rtable_add(table, entry);
50         entry=NULL; /* entry belongs to the table now */
51       }
52     }
53   }
54 }
55
56 static void verify_rtable(TRP_RTABLE *table, unsigned int (*metric)(size_t, size_t, size_t))
57 {
58   TRP_RENTRY *entry=NULL;
59   size_t ii=0, jj=0, kk=0;
60   size_t len=0;
61   TR_NAME *apc_n, *realm_n, *peer_n;
62
63   for (ii=0; ii<n_apc; ii++) {
64     for (jj=0; jj<n_realm; jj++) {
65       for (kk=0; kk<n_peer; kk++) {
66         apc_n=tr_new_name(apc[ii]);
67         realm_n=tr_new_name(realm[jj]);
68         peer_n=tr_new_name(peer[kk]);
69         entry=trp_rtable_get_entry(table, apc_n, realm_n, peer_n);
70         tr_free_name(apc_n);
71         tr_free_name(realm_n);
72         tr_free_name(peer_n);
73
74         assert(entry!=NULL);
75
76         len=trp_rentry_get_apc(entry)->len;
77         assert(len==strlen(apc[ii]));
78         assert(0==strncmp(trp_rentry_get_apc(entry)->buf, apc[ii], len));
79
80         len=trp_rentry_get_realm(entry)->len;
81         assert(len==strlen(realm[jj]));
82         assert(0==strncmp(trp_rentry_get_realm(entry)->buf, realm[jj], len));
83         
84         len=trp_rentry_get_peer(entry)->len;
85         assert(len==strlen(peer[kk]));
86         assert(0==strncmp(trp_rentry_get_peer(entry)->buf, peer[kk], len));
87         
88         len=trp_rentry_get_trust_router(entry)->len;
89         assert(len==strlen(realm[jj]));
90         assert(0==strncmp(trp_rentry_get_trust_router(entry)->buf, realm[jj], len));
91
92         assert(trp_rentry_get_metric(entry)==metric(ii,jj,kk));
93
94         len=trp_rentry_get_next_hop(entry)->len;
95         assert(len==strlen(peer[kk]));
96         assert(0==strncmp(trp_rentry_get_next_hop(entry)->buf, peer[kk], len));
97
98         assert(trp_rentry_get_selected(entry)==0);
99         assert(trp_rentry_get_expiry(entry)->tv_sec==jj+1);
100         assert(trp_rentry_get_expiry(entry)->tv_nsec==ii+kk+1);
101
102         printf("{%s %s %s} entry OK!\n", apc[ii], realm[jj], peer[kk]);
103       }
104     }
105   }
106 }
107
108 static int is_in(char *a, char *b[], size_t n_b)
109 {
110   size_t count=0;
111
112   while (n_b--) {
113     if (0==strcmp(a, b[n_b]))
114       count++;
115   }
116   return count;
117 }
118 static void verify_apc_list(TRP_RTABLE *table)
119 {
120   size_t n=0;
121   TR_NAME **apcs_found=trp_rtable_get_apcs(table, &n);
122   assert(n==n_apc);
123   while(n--)
124     assert(1==is_in(apcs_found[n]->buf, apc, n_apc));
125 }
126
127 static void verify_apc_realm_lists(TRP_RTABLE *table)
128 {
129   size_t n=0, ii=0;
130   TR_NAME *apc_n=NULL, **realms_found=NULL;
131
132   for (ii=0; ii<n_apc; ii++) {
133     apc_n=tr_new_name(apc[ii]);
134     realms_found=trp_rtable_get_apc_realms(table, apc_n, &n);
135     tr_free_name(apc_n);
136     assert(n==n_realm);
137     while (n--)
138       assert(1==is_in(realms_found[n]->buf, realm, n_realm));
139     talloc_free(realms_found);
140     printf("APC %s ok!\n", apc[ii]);
141   }
142 }
143
144 static void verify_get_apc_entries(TRP_RTABLE *table)
145 {
146   size_t n=0, ii=0;
147   TRP_RENTRY **apc_entries=NULL;
148   TR_NAME *apc_n=NULL;
149
150   for (ii=0; ii<n_apc; ii++) {
151     apc_n=tr_new_name(apc[ii]);
152     apc_entries=trp_rtable_get_apc_entries(table, apc_n, &n);
153     tr_free_name(apc_n);
154     assert(n==n_realm*n_peer);
155     while (n--) {
156       assert(0==strncmp(trp_rentry_get_apc(apc_entries[n])->buf,
157                         apc[ii],
158                         trp_rentry_get_apc(apc_entries[n])->len));
159       assert(1==is_in(trp_rentry_get_realm(apc_entries[n])->buf, realm, n_realm));
160       assert(1==is_in(trp_rentry_get_peer(apc_entries[n])->buf, peer, n_peer));
161     }
162     printf("APC %s ok!\n", apc[ii]);
163     talloc_free(apc_entries);
164   }
165 }
166
167 static void verify_get_realm_entries(TRP_RTABLE *table)
168 {
169   size_t n=0, ii=0, jj=0;
170   TRP_RENTRY **realm_entries=NULL;
171   TR_NAME *apc_n=NULL, *realm_n=NULL;
172
173   for (ii=0; ii<n_apc; ii++) {
174     for (jj=0; jj<n_realm; jj++) {
175       apc_n=tr_new_name(apc[ii]);
176       realm_n=tr_new_name(realm[jj]);
177       realm_entries=trp_rtable_get_realm_entries(table, apc_n, realm_n, &n);
178       tr_free_name(apc_n);
179       tr_free_name(realm_n);
180       assert(n==n_peer);
181       while (n--) {
182         assert(0==strncmp(trp_rentry_get_apc(realm_entries[n])->buf,
183                           apc[ii],
184                           trp_rentry_get_apc(realm_entries[n])->len));
185         assert(0==strncmp(trp_rentry_get_realm(realm_entries[n])->buf,
186                           realm[jj],
187                           trp_rentry_get_realm(realm_entries[n])->len));
188         assert(1==is_in(trp_rentry_get_peer(realm_entries[n])->buf, peer, n_peer));
189       }
190       printf("APC %s realm %s ok!\n", apc[ii], realm[jj]);
191       talloc_free(realm_entries);
192     }
193   }
194 }
195
196 /* doesn't work if c not in a */
197 static size_t get_index(char *c, char **a, size_t n_a)
198 {
199   while(n_a--) {
200     if (0==strcmp(c, a[n_a]))
201       return n_a;
202   }
203   return 0;
204 }
205
206 static void update_metric(TRP_RTABLE *table, unsigned int (*new_metric)(size_t, size_t, size_t))
207 {
208   TRP_RENTRY **entries=NULL;
209   size_t n=0, ii=0,jj=0,kk=0;
210
211   entries=trp_rtable_get_entries(table, &n);
212   while (n--) {
213     ii=get_index(trp_rentry_get_apc(entries[n])->buf, apc, n_apc);
214     jj=get_index(trp_rentry_get_realm(entries[n])->buf, realm, n_realm);
215     kk=get_index(trp_rentry_get_peer(entries[n])->buf, peer, n_peer);
216     trp_rentry_set_metric(entries[n],
217                           new_metric(ii,jj,kk));
218   }
219   talloc_free(entries);
220 }
221
222 static void remove_entries(TRP_RTABLE *table)
223 {
224   size_t n=trp_rtable_size(table);
225   size_t ii,jj,kk;
226   TR_NAME *apc_n, *realm_n, *peer_n;
227   TRP_RENTRY *entry=NULL;
228
229   for (ii=0; ii<n_apc; ii++) {
230     for (jj=0; jj<n_realm; jj++) {
231       for (kk=0; kk<n_realm; kk++) {
232         apc_n=tr_new_name(apc[ii]);
233         realm_n=tr_new_name(realm[jj]);
234         peer_n=tr_new_name(peer[kk]);
235         entry=trp_rtable_get_entry(table, apc_n, realm_n, peer_n);
236         assert(entry !=NULL);
237         tr_free_name(apc_n);
238         tr_free_name(realm_n);
239         tr_free_name(peer_n);
240         trp_rtable_remove(table, entry);
241         entry=NULL;
242         assert(trp_rtable_size(table)==--n);
243       }
244     }
245   }
246 }
247
248
249 static void print_rtable(TRP_RTABLE *table)
250 {
251   char *s=trp_rtable_to_str(NULL, table, NULL, NULL);
252   printf(s);
253   talloc_free(s);
254 }
255
256 int main(void)
257 {
258   TRP_RTABLE *table=NULL;
259   table=trp_rtable_new();
260   populate_rtable(table, metric1);
261   print_rtable(table);
262
263   printf("\nVerifying routing table...\n");
264   verify_rtable(table, metric1);
265   printf("                         ...success!\n");
266
267   printf("\nVerifying APC list...\n");
268   verify_apc_list(table);
269   printf("                    ...success!\n");
270
271   printf("\nVerifying APC realm lists...\n");
272   verify_apc_realm_lists(table);
273   printf("                    ...success!\n");
274
275   printf("\nVerifying APC entry lists...\n");
276   verify_get_apc_entries(table);
277   printf("                           ...success!\n");
278
279   printf("\nVerifying realm entry lists...\n");
280   verify_get_realm_entries(table);
281   printf("                              ...success!\n");
282
283   printf("\nVerifying table value update...\n");
284   update_metric(table, metric2); /* changes the metric value in each element in-place */
285   verify_rtable(table, metric2);
286   printf("                              ...success!\n");
287
288   printf("\nVerifying element replacement...\n");
289   populate_rtable(table, metric3); /* replaces all the elements with new ones */
290   verify_rtable(table, metric3);
291   printf("                               ...success!\n");
292
293   printf("\nVerifying element removal...\n");
294   remove_entries(table);
295   print_rtable(table);
296   printf("                           ...success!\n");
297
298   printf("\nRepopulating table...\n");
299   populate_rtable(table, metric3);
300   verify_rtable(table, metric3);
301   printf("                               ...success!\n");
302
303   trp_rtable_free(table);
304   return 0;
305 }