implement get tunable and add get regression
[libdht.git] / regress / get.c
blobef3fc64e44b23bc4e9db491e09cffa91bad32cf7
1 /*
2 * Copyright (c) 2017 Mohamed Aslan <maslan@sce.carleton.ca>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <dht.h>
20 #include <hashtab.h>
21 #include <pthread.h>
22 #include <err.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <sys/wait.h>
27 #define N_REPLICAS 2
29 #define MAX_KEYS 5
30 struct v_node {
31 char *id;
32 char *ip;
33 int port;
34 int n_keys;
35 char *keys[MAX_KEYS];
36 char *vals[MAX_KEYS];
39 #define N_NODES 3
40 static struct v_node vnodes[] = {
41 {"A", "127.0.0.1", 5000, 5,
42 {"hello", "1hello", "12hello", "world1", "world12"},
43 {"world", "world", "world", "hello", "hello"},
45 {"B", "127.0.0.1", 5001, 3,
46 {"1hello", "world", "world1", NULL, NULL},
47 {"world", "hello", "hello", NULL, NULL},
49 {"C", "127.0.0.1", 5002, 4,
50 {"hello", "12hello", "world", "world12", NULL},
51 {"world", "world", "hello", "hello", NULL},
55 #define N_KV 6
56 char *keys[N_KV] = {
57 "hello", "world", "1hello",
58 "world1", "12hello", "world12"
60 char *vals[N_KV] = {
61 "world", "hello", "world",
62 "hello", "world", "hello"
65 struct args {
66 int nidx;
67 struct dht_node *node;
71 void *
72 test_thread(void *arg)
74 int i, fail = 0;
75 struct dht_node *n = ((struct args *)arg)->node;
76 char *val;
78 while (!n->ready);
80 sleep(5);
81 /* read all keys/vals */
82 for (i = 0 ; i < N_KV ; i++) {
83 if (!dht_get_tunable(n, keys[i], &val, N_REPLICAS)) {
84 printf("FAILED [%s] dht_get_tunable.\n", n->id);
85 printf("for %s:%s\n", keys[i], vals[i]);
86 fail++;
87 continue;
89 if (strcmp(vals[i], val)) {
90 printf("FAILED [%s] dht_get_tunable, received bad val.\n", n->id);
91 fail++;
94 printf("OK\n");
95 sleep(5);
97 _exit(fail);
98 /* NOTREACHED */
99 return NULL;
103 node(int me)
105 int i;
106 struct dht_node *n;
107 struct args *a;
108 struct hashtab *ht;
109 struct timespec ts;
110 pthread_t tp, tt;
112 n = malloc(sizeof(struct dht_node));
113 if (!dht_init(n, vnodes[me].id, vnodes[me].port, N_REPLICAS, 0, NULL))
114 err(1, "dht_init");
116 /* populate hashtable */
117 ht = (struct hashtab *)n->ht;
118 (void)clock_gettime(CLOCK_REALTIME, &ts);
119 for (i = 0 ; i < vnodes[me].n_keys ; i++) {
120 n->opts->ht_put(ht, vnodes[me].keys[i], vnodes[me].vals[i], &ts);
123 for (i = 0 ; i < N_NODES ; i++)
124 if (i != me)
125 dht_add_peer(n, vnodes[i].id, vnodes[i].ip, vnodes[i].port);
127 a = malloc(sizeof(struct args));
128 a->node = n;
129 a->nidx = me;
130 if (pthread_create(&tt, NULL, test_thread, a))
131 err(1, "pthread_create");
133 dht_event_loop(n);
134 errx(1, "should not reach here!");
135 return 0;
139 main(int argc, char **argv)
141 int i, status, fail = 0;
142 pid_t pid;
144 for (i = 0 ; i < N_NODES ; i++) {
145 if (!fork()) {
146 node(i);
147 return 0;
150 while (1) {
151 pid = wait(&status);
152 if (pid == -1) {
153 if (errno == ECHILD)
154 break;
155 else
156 err(1, "wait");
157 } else {
158 if (WIFEXITED(status) && WEXITSTATUS(status))
159 fail++;
162 sleep(5);
163 return fail;