Reduced timeouts by 10x
[invirt/third/libt4.git] / lock_tester.cc
1 //
2 // Lock server tester
3 //
4
5 #include "lock_client.h"
6 #include <arpa/inet.h>
7 #include <sys/types.h>
8 #include <unistd.h>
9
10 char log_thread_prefix = 'c';
11
12 // must be >= 2
13 const int nt = 6; //XXX: lab1's rpc handlers are blocking. Since rpcs uses a thread pool of 10 threads, we cannot test more than 10 blocking rpc.
14 string dst;
15 lock_client **lc = new lock_client * [nt];
16 lock_protocol::lockid_t a = "1";
17 lock_protocol::lockid_t b = "2";
18 lock_protocol::lockid_t c = "3";
19
20 // check_grant() and check_release() check that the lock server
21 // doesn't grant the same lock to both clients.
22 // it assumes that lock names are distinct in the first byte.
23 int ct[256];
24 mutex count_mutex;
25
26 void check_grant(lock_protocol::lockid_t lid) {
27     lock ml(count_mutex);
28     int x = lid[0] & 0x0f;
29     if (ct[x] != 0) {
30         cout << "error: server granted " << lid << " twice" << endl;
31         cerr << "error: server granted " << lid << " twice" << endl;
32         exit(1);
33     }
34     ct[x] += 1;
35 }
36
37 void check_release(lock_protocol::lockid_t lid) {
38     lock ml(count_mutex);
39     int x = lid[0] & 0x0f;
40     if (ct[x] != 1) {
41         cerr << "error: client released un-held lock " << lid << endl;
42         exit(1);
43     }
44     ct[x] -= 1;
45 }
46
47 void test1(void) {
48     LOG_NONMEMBER("acquire a release a acquire a release a");
49     lc[0]->acquire(a);
50     check_grant(a);
51     lc[0]->release(a);
52     check_release(a);
53     lc[0]->acquire(a);
54     check_grant(a);
55     lc[0]->release(a);
56     check_release(a);
57
58     LOG_NONMEMBER("acquire a acquire b release b release a");
59     lc[0]->acquire(a);
60     check_grant(a);
61     lc[0]->acquire(b);
62     check_grant(b);
63     lc[0]->release(b);
64     check_release(b);
65     lc[0]->release(a);
66     check_release(a);
67 }
68
69 void test2(int i) {
70     LOG_NONMEMBER("test2: client " << i << " acquire a release a");
71     lc[i]->acquire(a);
72     LOG_NONMEMBER("test2: client " << i << " acquire done");
73     check_grant(a);
74     usleep(100000);
75     LOG_NONMEMBER("test2: client " << i << " release");
76     check_release(a);
77     lc[i]->release(a);
78     LOG_NONMEMBER("test2: client " << i << " release done");
79 }
80
81 void test3(int i) {
82     LOG_NONMEMBER("test3: client " << i << " acquire a release a concurrent");
83     for (int j = 0; j < 10; j++) {
84         lc[i]->acquire(a);
85         check_grant(a);
86         LOG_NONMEMBER("test3: client " << i << " got lock");
87         check_release(a);
88         lc[i]->release(a);
89     }
90 }
91
92 void test4(int i) {
93     LOG_NONMEMBER("test4: thread " << i << " acquire a release a concurrent; same clnt");
94     for (int j = 0; j < 10; j++) {
95         lc[0]->acquire(a);
96         check_grant(a);
97         LOG_NONMEMBER("test4: thread " << i << " on client 0 got lock");
98         check_release(a);
99         lc[0]->release(a);
100     }
101 }
102
103 void test5(int i) {
104     LOG_NONMEMBER("test5: client " << i << " acquire a release a concurrent; same and diff clnt");
105     for (int j = 0; j < 10; j++) {
106         if (i < 5)  lc[0]->acquire(a);
107         else  lc[1]->acquire(a);
108         check_grant(a);
109         LOG_NONMEMBER("test5: client " << i << " got lock");
110         check_release(a);
111         if (i < 5) lc[0]->release(a);
112         else lc[1]->release(a);
113     }
114 }
115
116 int
117 main(int argc, char *argv[])
118 {
119     thread th[nt];
120     int test = 0;
121
122     setvbuf(stdout, NULL, _IONBF, 0);
123     setvbuf(stderr, NULL, _IONBF, 0);
124     srandom((uint32_t)getpid());
125
126     if (argc < 2) {
127         cerr << "Usage: " << argv[0] << " [host:]port [test]" << endl;
128         exit(1);
129     }
130
131     dst = argv[1]; 
132
133     if (argc > 2) {
134         test = atoi(argv[2]);
135         if (test < 1 || test > 5) {
136             LOG_NONMEMBER("Test number must be between 1 and 5");
137             exit(1);
138         }
139     }
140
141     LOG_NONMEMBER("cache lock client");
142     for (int i = 0; i < nt; i++) lc[i] = new lock_client(dst);
143
144     if (!test || test == 1) {
145         test1();
146     }
147
148     if (!test || test == 2) {
149         // test2
150         for (int i = 0; i < nt; i++)
151             th[i] = thread(test2, i);
152         for (int i = 0; i < nt; i++)
153             th[i].join();
154     }
155
156     if (!test || test == 3) {
157         LOG_NONMEMBER("test 3");
158
159         for (int i = 0; i < nt; i++)
160             th[i] = thread(test3, i);
161         for (int i = 0; i < nt; i++)
162             th[i].join();
163     }
164
165     if (!test || test == 4) {
166         LOG_NONMEMBER("test 4");
167
168         for (int i = 0; i < 2; i++)
169             th[i] = thread(test4, i);
170         for (int i = 0; i < 2; i++)
171             th[i].join();
172     }
173
174     if (!test || test == 5) {
175         LOG_NONMEMBER("test 5");
176
177         for (int i = 0; i < nt; i++)
178             th[i] = thread(test5, i);
179         for (int i = 0; i < nt; i++)
180             th[i].join();
181     }
182
183     LOG_NONMEMBER(argv[0] << ": passed all tests successfully");
184
185 }