add a Makefile for gnu make
[libdht.git] / regress / put.c
blobca873676c128e61f64d4e964faf1b752962d092f
1 /*
2 * Copyright (c) 2016 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 2
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, 2,
42 {"hello", "world"},
43 {"world", "hello"}
45 {"B", "127.0.0.1", 5001, 2,
46 {"1hello", "world1"},
47 {"world", "hello"}
49 {"C", "127.0.0.1", 5002, 2,
50 {"12hello", "world12"},
51 {"world", "hello"}
55 #define MAX_RKEYS 5
56 struct result {
57 int n;
58 char *keys[MAX_RKEYS];
59 char *vals[MAX_RKEYS];
60 int visited[MAX_RKEYS];
63 static struct result results[] = {
66 {"hello", "1hello", "12hello", "world1", "world12"},
67 {"world", "world", "world", "hello", "hello"},
68 {0, 0, 0, 0, 0}
72 {"1hello", "world", "world1"},
73 {"world", "hello", "hello"},
74 {0, 0, 0}
78 {"hello", "12hello", "world", "world12"},
79 {"world", "world", "hello", "hello"},
80 {0, 0, 0, 0}
84 struct args {
85 int nidx;
86 struct dht_node *node;
90 int
91 lfind(const char *key, const char *val, struct result *r)
93 int i;
95 for (i = 0 ; i < r->n ; i++) {
96 if (!strcmp(key, r->keys[i]) && !strcmp(val, r->vals[i]) && !r->visited[i]) {
97 r->visited[i] = 1;
98 return 1;
101 return 0;
104 void *
105 test_thread(void *arg)
107 int i, fail = 0;
108 int me = ((struct args *)arg)->nidx;
109 struct dht_node *n = ((struct args *)arg)->node;
110 struct hashtab *ht = (struct hashtab *)n->ht;
111 char *key, *val;
112 size_t key_size, val_size;
113 size_t iter;
115 while (!n->ready);
117 sleep(5);
118 for (i = 0 ; i < vnodes[me].n_keys ; i++) {
119 if (!dht_put_tunable(n, vnodes[me].keys[i], vnodes[me].vals[i], N_REPLICAS))
120 printf("FAILED [%s] dht_put_tunable.\n", n->id);
123 sleep(5);
124 HASHTAB_FOREACH(*ht, iter, key, key_size, val, val_size) {
125 if (lfind(key, val, &results[me])) {
126 printf("OK\n");
127 } else {
128 fail++;
129 printf("FAILED [%s] %s -> %s\n", n->id, key, val);
133 _exit(fail);
134 /* NOTREACHED */
135 return NULL;
139 node(int me)
141 int i;
142 struct dht_node *n;
143 struct args *a;
144 pthread_t tp, tt;
146 n = malloc(sizeof(struct dht_node));
147 if (!dht_init(n, vnodes[me].id, vnodes[me].port, N_REPLICAS, 0, NULL))
148 err(1, "dht_init");
150 for (i = 0 ; i < N_NODES ; i++)
151 if (i != me)
152 dht_add_peer(n, vnodes[i].id, vnodes[i].ip, vnodes[i].port);
154 a = malloc(sizeof(struct args));
155 a->node = n;
156 a->nidx = me;
157 if (pthread_create(&tt, NULL, test_thread, a))
158 err(1, "pthread_create");
160 dht_event_loop(n);
161 errx(1, "should not reach here!");
162 return 0;
166 main(int argc, char **argv)
168 int i, status, fail = 0;
169 pid_t pid;
171 for (i = 0 ; i < N_NODES ; i++) {
172 if (!fork()) {
173 node(i);
174 return 0;
177 while (1) {
178 pid = wait(&status);
179 if (pid == -1) {
180 if (errno == ECHILD)
181 break;
182 else
183 err(1, "wait");
184 } else {
185 if (WIFEXITED(status) && WEXITSTATUS(status))
186 fail++;
189 sleep(5);
190 return fail;