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/crypto.h>
19 #include <openssl/pqueue.h>
20 #include <openssl/ssl.h>
21
22
clear_and_free_queue(pqueue q)23 static void clear_and_free_queue(pqueue q) {
24 for (;;) {
25 pitem *item = pqueue_pop(q);
26 if (item == NULL) {
27 break;
28 }
29 pitem_free(item);
30 }
31 pqueue_free(q);
32 }
33
trivial(void)34 static int trivial(void) {
35 pqueue q = pqueue_new();
36 if (q == NULL) {
37 return 0;
38 }
39 int32_t data = 0xdeadbeef;
40 uint8_t priority[8] = {0};
41 pitem *item = pitem_new(priority, &data);
42 if (item == NULL ||
43 pqueue_insert(q, item) != item ||
44 pqueue_size(q) != 1 ||
45 pqueue_peek(q) != item ||
46 pqueue_pop(q) != item ||
47 pqueue_size(q) != 0 ||
48 pqueue_pop(q) != NULL) {
49 return 0;
50 }
51 pitem_free(item);
52 clear_and_free_queue(q);
53 return 1;
54 }
55
56 #define NUM_ITEMS 10
57
fixed_random(void)58 static int fixed_random(void) {
59 /* Random order of 10 elements, chosen by
60 * random.choice(list(itertools.permutations(range(10)))) */
61 int ordering[NUM_ITEMS] = {9, 6, 3, 4, 0, 2, 7, 1, 8, 5};
62 int i;
63 pqueue q = pqueue_new();
64 uint8_t priority[8] = {0};
65 piterator iter;
66 pitem *curr, *item;
67
68 if (q == NULL) {
69 return 0;
70 }
71
72 /* Insert the elements */
73 for (i = 0; i < NUM_ITEMS; i++) {
74 priority[7] = ordering[i];
75 item = pitem_new(priority, &ordering[i]);
76 if (item == NULL || pqueue_insert(q, item) != item) {
77 return 0;
78 }
79 }
80
81 /* Insert the elements again. This inserts duplicates and should
82 * fail. */
83 for (i = 0; i < NUM_ITEMS; i++) {
84 priority[7] = ordering[i];
85 item = pitem_new(priority, &ordering[i]);
86 if (item == NULL || pqueue_insert(q, item) != NULL) {
87 return 0;
88 }
89 pitem_free(item);
90 }
91
92 if (pqueue_size(q) != NUM_ITEMS) {
93 return 0;
94 }
95
96 /* Iterate over the elements. */
97 iter = pqueue_iterator(q);
98 curr = pqueue_next(&iter);
99 if (curr == NULL) {
100 return 0;
101 }
102 while (1) {
103 pitem *next = pqueue_next(&iter);
104 int *curr_data, *next_data;
105
106 if (next == NULL) {
107 break;
108 }
109 curr_data = (int*)curr->data;
110 next_data = (int*)next->data;
111 if (*curr_data >= *next_data) {
112 return 0;
113 }
114 curr = next;
115 }
116 clear_and_free_queue(q);
117 return 1;
118 }
119
main(void)120 int main(void) {
121 CRYPTO_library_init();
122
123 if (!trivial() || !fixed_random()) {
124 return 1;
125 }
126
127 printf("PASS\n");
128 return 0;
129 }
130