1 /* Copyright (c) 2014, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <stdio.h>
16 #include <string.h>
17 
18 #include <openssl/pqueue.h>
19 #include <openssl/ssl.h>
20 
21 
clear_and_free_queue(pqueue q)22 static void clear_and_free_queue(pqueue q) {
23   for (;;) {
24     pitem *item = pqueue_pop(q);
25     if (item == NULL) {
26       break;
27     }
28     pitem_free(item);
29   }
30   pqueue_free(q);
31 }
32 
trivial(void)33 static int trivial(void) {
34   pqueue q = pqueue_new();
35   if (q == NULL) {
36     return 0;
37   }
38   int32_t data = 0xdeadbeef;
39   uint8_t priority[8] = {0};
40   pitem *item = pitem_new(priority, &data);
41   if (item == NULL ||
42       pqueue_insert(q, item) != item ||
43       pqueue_size(q) != 1 ||
44       pqueue_peek(q) != item ||
45       pqueue_pop(q) != item ||
46       pqueue_size(q) != 0 ||
47       pqueue_pop(q) != NULL) {
48     return 0;
49   }
50   pitem_free(item);
51   clear_and_free_queue(q);
52   return 1;
53 }
54 
55 #define NUM_ITEMS 10
56 
fixed_random(void)57 static int fixed_random(void) {
58   /* Random order of 10 elements, chosen by
59    * random.choice(list(itertools.permutations(range(10)))) */
60   int ordering[NUM_ITEMS] = {9, 6, 3, 4, 0, 2, 7, 1, 8, 5};
61   int i;
62   pqueue q = pqueue_new();
63   uint8_t priority[8] = {0};
64   piterator iter;
65   pitem *curr, *item;
66 
67   if (q == NULL) {
68     return 0;
69   }
70 
71   /* Insert the elements */
72   for (i = 0; i < NUM_ITEMS; i++) {
73     priority[7] = ordering[i];
74     item = pitem_new(priority, &ordering[i]);
75     if (item == NULL || pqueue_insert(q, item) != item) {
76       return 0;
77     }
78   }
79 
80   /* Insert the elements again. This inserts duplicates and should
81    * fail. */
82   for (i = 0; i < NUM_ITEMS; i++) {
83     priority[7] = ordering[i];
84     item = pitem_new(priority, &ordering[i]);
85     if (item == NULL || pqueue_insert(q, item) != NULL) {
86       return 0;
87     }
88     pitem_free(item);
89   }
90 
91   if (pqueue_size(q) != NUM_ITEMS) {
92     return 0;
93   }
94 
95   /* Iterate over the elements. */
96   iter = pqueue_iterator(q);
97   curr = pqueue_next(&iter);
98   if (curr == NULL) {
99     return 0;
100   }
101   while (1) {
102     pitem *next = pqueue_next(&iter);
103     int *curr_data, *next_data;
104 
105     if (next == NULL) {
106       break;
107     }
108     curr_data = (int*)curr->data;
109     next_data = (int*)next->data;
110     if (*curr_data >= *next_data) {
111       return 0;
112     }
113     curr = next;
114   }
115   clear_and_free_queue(q);
116   return 1;
117 }
118 
main(void)119 int main(void) {
120   SSL_library_init();
121 
122   if (!trivial() || !fixed_random()) {
123     return 1;
124   }
125 
126   printf("PASS\n");
127   return 0;
128 }
129