Charm Queue and its tests: Increase coverage, and cleanup
[charm.git] / tests / charm++ / queue / pgm.C
1 #include <iostream>
2 #include <cstdlib>
3
4 using std::cerr;
5 using std::endl;
6 using std::sprintf;
7
8 #include "queueing.h"
9 #include "main.decl.h"
10
11 #define RUN_TEST(f) do { \
12   ++tests; \
13   if (f()) { \
14     ++success; \
15   } else { \
16     ++fail; \
17     cerr << "Test \"" #f "\" failed" << endl; \
18   } \
19 } while (0)
20
21 // A newly created Queue should be empty, which corresponds to a
22 // length of 0
23 bool test_empty()
24 {
25   Queue q = CqsCreate();
26   bool result = (0 == CqsLength(q)) && (1 == CqsEmpty(q));
27   CqsDelete(q);
28   return result;
29 }
30
31 // Enqueueing an element should show that there is an element
32 // present. We should get the same thing back when we dequeue
33 //
34 // The queue is not allowed to dereference the void* we give it
35 bool test_one()
36 {
37   Queue q = CqsCreate();
38   void *p = 0;
39   CqsEnqueue(q, p);
40   bool result = (1 == CqsLength(q)) && (0 == CqsEmpty(q));
41   void *r;
42   CqsDequeue(q, &r);
43   result &= (r == p) 
44     && (0 == CqsLength(q)) 
45     && (1 == CqsEmpty(q));
46   CqsDelete(q);
47   return result;
48 }
49
50 // Put two in, see if we get the same two back. Order unspecified
51 bool test_two()
52 {
53   Queue q = CqsCreate();
54   void *i = 0, *j = (char *)1;
55   void *r, *s;
56   CqsEnqueue(q, i);
57   CqsEnqueue(q, j);
58   bool result = (2 == CqsLength(q));
59   CqsDequeue(q, &r);
60   CqsDequeue(q, &s);
61   result &= (r == i && s == j) || (r == j && s == i);
62   result &= 1 == CqsEmpty(q);
63   CqsDelete(q);
64   return result;
65 }
66
67 bool test_fifo()
68 {
69   Queue q = CqsCreate();
70   void *i = (char *)1, *j = (char *)2, *k = (char *)3;
71   void *r, *s, *t;
72   CqsEnqueueFifo(q, i);
73   CqsEnqueueFifo(q, j);
74   CqsEnqueueFifo(q, k);
75   CqsDequeue(q, &r);
76   CqsDequeue(q, &s);
77   CqsDequeue(q, &t);
78   bool result = (r == i) && (s == j) && (t == k);
79   CqsDelete(q);
80   return result;
81 }
82
83 bool test_lifo()
84 {
85   Queue q = CqsCreate();
86   void *i = (char *)1, *j = (char *)2, *k = (char *)3;
87   void *r, *s, *t;
88   CqsEnqueueLifo(q, i);
89   CqsEnqueueLifo(q, j);
90   CqsEnqueueLifo(q, k);
91   CqsDequeue(q, &r);
92   CqsDequeue(q, &s);
93   CqsDequeue(q, &t);
94   bool result = (r == k) && (s == j) && (t == i);
95   CqsDelete(q);
96   return result;
97 }
98
99 bool test_enqueue_mixed()
100 {
101   Queue q = CqsCreate();
102   void *i = (char *)1, *j = (char *)2, *k = (char *)3;
103   void *r, *s, *t;
104   CqsEnqueueFifo(q, i);
105   CqsEnqueueFifo(q, j);
106   CqsEnqueueLifo(q, k);
107   CqsDequeue(q, &r);
108   CqsDequeue(q, &s);
109   CqsDequeue(q, &t);
110   bool result = (r == k) && (s == i) && (t == j);
111   CqsDelete(q);
112   return result;
113 }
114
115 static bool findEntry(void ** const e, int num, void * const t)
116 {
117     for (int i = 0; i < num; ++i)
118     {
119         if (e[i] == t)
120             return true;
121     }
122     return false;
123 }
124
125 bool test_enumerate()
126 {
127   Queue q = CqsCreate();
128   void *i = (char *)1, *j = (char *)2, *k = (char *)3;
129   void **e;
130   CqsEnqueueFifo(q, i);
131   CqsEnqueueFifo(q, j);
132   CqsEnqueueLifo(q, k);
133   CqsEnumerateQueue(q, &e);
134   int n = CqsLength(q);
135   bool result = findEntry(e, n, i) && findEntry(e, n, j) && findEntry(e, n, k);
136   CmiFree(e);
137   CqsDelete(q);
138   return result;
139 }
140
141 bool test_general_fifo()
142 {
143   Queue q = CqsCreate();
144   void *i = (char *)1, *j = (char *)2, *k = (char *)3;
145   void **e;
146   CqsEnqueueGeneral(q, i, CQS_QUEUEING_FIFO, 1, 0);
147   CqsEnqueueGeneral(q, j, CQS_QUEUEING_FIFO, 2, 0);
148   CqsEnqueueGeneral(q, k, CQS_QUEUEING_FIFO, 42, 0);
149   void *r, *s, *t;
150   CqsDequeue(q, &r);
151   CqsDequeue(q, &s);
152   CqsDequeue(q, &t);
153   bool result = (r == i) && (s == j) && (t == k);
154   cerr << "r s t" << r << s << t;
155   CqsDelete(q);
156   return result;
157 }
158
159 bool test_general_ififo()
160 {
161   Queue q = CqsCreate();
162   void *i = (char *)1, *j = (char *)2, *k = (char *)3;
163   void **e;
164   unsigned int a = -1, b = 0, c = 1;
165   CqsEnqueueGeneral(q, i, CQS_QUEUEING_IFIFO, 8*sizeof(int), &c);
166   CqsEnqueueGeneral(q, j, CQS_QUEUEING_IFIFO, 8*sizeof(int), &b);
167   CqsEnqueueGeneral(q, k, CQS_QUEUEING_IFIFO, 8*sizeof(int), &a);
168   void *r, *s, *t;
169   CqsDequeue(q, &r);
170   CqsDequeue(q, &s);
171   CqsDequeue(q, &t);
172   bool result = (r == k) && (s == j) && (t == i);
173   cerr << "r s t" << r << s << t;
174   CqsDelete(q);
175   return result;
176 }
177
178 #if 0
179 // Template for new harness-driven tests
180 bool test_foo()
181 {
182   Queue q = CqsCreate();
183   
184   bool result = ;
185   CqsDelete(q);
186   return result;
187 }
188 #endif
189
190 struct main : public CBase_main
191 {
192   main(CkArgMsg *)
193   {
194     int tests = 0, success = 0, fail = 0;
195     char message[100];
196
197     RUN_TEST(test_empty);
198     RUN_TEST(test_one);
199     RUN_TEST(test_two);
200     RUN_TEST(test_fifo);
201     RUN_TEST(test_lifo);
202     RUN_TEST(test_enqueue_mixed);
203     RUN_TEST(test_enumerate);
204     RUN_TEST(test_general_fifo);
205     RUN_TEST(test_general_ififo);
206
207     if (fail) {
208       sprintf(message, "%d/%d tests failed\n", fail, tests);
209       CkAbort(message);
210     }
211     else {
212       CkPrintf("All %d tests passed\n", tests);
213       CkExit();
214     }
215   }
216
217 };
218
219 #include "main.def.h"