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 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 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 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 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