sparse_array_test.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <limits.h>
  13. #include <openssl/crypto.h>
  14. #include "internal/nelem.h"
  15. #include "crypto/sparse_array.h"
  16. #include "testutil.h"
  17. /* The macros below generate unused functions which error out one of the clang
  18. * builds. We disable this check here.
  19. */
  20. #ifdef __clang__
  21. #pragma clang diagnostic ignored "-Wunused-function"
  22. #endif
  23. DEFINE_SPARSE_ARRAY_OF(char);
  24. static int test_sparse_array(void)
  25. {
  26. static const struct {
  27. ossl_uintmax_t n;
  28. char *v;
  29. } cases[] = {
  30. { 22, "a" }, { 0, "z" }, { 1, "b" }, { 290, "c" },
  31. { INT_MAX, "m" }, { 6666666, "d" }, { (ossl_uintmax_t)-1, "H" },
  32. { 99, "e" }
  33. };
  34. SPARSE_ARRAY_OF(char) *sa;
  35. size_t i, j;
  36. int res = 0;
  37. if (!TEST_ptr(sa = ossl_sa_char_new())
  38. || !TEST_ptr_null(ossl_sa_char_get(sa, 3))
  39. || !TEST_ptr_null(ossl_sa_char_get(sa, 0))
  40. || !TEST_ptr_null(ossl_sa_char_get(sa, UINT_MAX)))
  41. goto err;
  42. for (i = 0; i < OSSL_NELEM(cases); i++) {
  43. if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) {
  44. TEST_note("iteration %zu", i + 1);
  45. goto err;
  46. }
  47. for (j = 0; j <= i; j++)
  48. if (!TEST_str_eq(ossl_sa_char_get(sa, cases[j].n), cases[j].v)) {
  49. TEST_note("iteration %zu / %zu", i + 1, j + 1);
  50. goto err;
  51. }
  52. }
  53. res = 1;
  54. err:
  55. ossl_sa_char_free(sa);
  56. return res;
  57. }
  58. static int test_sparse_array_num(void)
  59. {
  60. static const struct {
  61. size_t num;
  62. ossl_uintmax_t n;
  63. char *v;
  64. } cases[] = {
  65. { 1, 22, "a" }, { 2, 1021, "b" }, { 3, 3, "c" }, { 2, 22, NULL },
  66. { 2, 3, "d" }, { 3, 22, "e" }, { 3, 666, NULL }, { 4, 666, "f" },
  67. { 3, 3, NULL }, { 2, 22, NULL }, { 1, 666, NULL }, { 2, 64000, "g" },
  68. { 1, 1021, NULL }, { 0, 64000, NULL }, { 1, 23, "h" }, { 0, 23, NULL }
  69. };
  70. SPARSE_ARRAY_OF(char) *sa = NULL;
  71. size_t i;
  72. int res = 0;
  73. if (!TEST_size_t_eq(ossl_sa_char_num(NULL), 0)
  74. || !TEST_ptr(sa = ossl_sa_char_new())
  75. || !TEST_size_t_eq(ossl_sa_char_num(sa), 0))
  76. goto err;
  77. for (i = 0; i < OSSL_NELEM(cases); i++)
  78. if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))
  79. || !TEST_size_t_eq(ossl_sa_char_num(sa), cases[i].num))
  80. goto err;
  81. res = 1;
  82. err:
  83. ossl_sa_char_free(sa);
  84. return res;
  85. }
  86. struct index_cases_st {
  87. ossl_uintmax_t n;
  88. char *v;
  89. int del;
  90. };
  91. struct doall_st {
  92. SPARSE_ARRAY_OF(char) *sa;
  93. size_t num_cases;
  94. const struct index_cases_st *cases;
  95. int res;
  96. int all;
  97. };
  98. static void leaf_check_all(ossl_uintmax_t n, char *value, void *arg)
  99. {
  100. struct doall_st *doall_data = (struct doall_st *)arg;
  101. const struct index_cases_st *cases = doall_data->cases;
  102. size_t i;
  103. doall_data->res = 0;
  104. for (i = 0; i < doall_data->num_cases; i++)
  105. if ((doall_data->all || !cases[i].del)
  106. && n == cases[i].n && strcmp(value, cases[i].v) == 0) {
  107. doall_data->res = 1;
  108. return;
  109. }
  110. TEST_error("Index %ju with value %s not found", n, value);
  111. }
  112. static void leaf_delete(ossl_uintmax_t n, char *value, void *arg)
  113. {
  114. struct doall_st *doall_data = (struct doall_st *)arg;
  115. const struct index_cases_st *cases = doall_data->cases;
  116. size_t i;
  117. doall_data->res = 0;
  118. for (i = 0; i < doall_data->num_cases; i++)
  119. if (n == cases[i].n && strcmp(value, cases[i].v) == 0) {
  120. doall_data->res = 1;
  121. ossl_sa_char_set(doall_data->sa, n, NULL);
  122. return;
  123. }
  124. TEST_error("Index %ju with value %s not found", n, value);
  125. }
  126. static int test_sparse_array_doall(void)
  127. {
  128. static const struct index_cases_st cases[] = {
  129. { 22, "A", 1 }, { 1021, "b", 0 }, { 3, "c", 0 }, { INT_MAX, "d", 1 },
  130. { (ossl_uintmax_t)-1, "H", 0 }, { (ossl_uintmax_t)-2, "i", 1 },
  131. { 666666666, "s", 1 }, { 1234567890, "t", 0 },
  132. };
  133. struct doall_st doall_data;
  134. size_t i;
  135. SPARSE_ARRAY_OF(char) *sa = NULL;
  136. int res = 0;
  137. if (!TEST_ptr(sa = ossl_sa_char_new()))
  138. goto err;
  139. doall_data.num_cases = OSSL_NELEM(cases);
  140. doall_data.cases = cases;
  141. doall_data.all = 1;
  142. doall_data.sa = NULL;
  143. for (i = 0; i < OSSL_NELEM(cases); i++)
  144. if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) {
  145. TEST_note("failed at iteration %zu", i + 1);
  146. goto err;
  147. }
  148. ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data);
  149. if (doall_data.res == 0) {
  150. TEST_info("while checking all elements");
  151. goto err;
  152. }
  153. doall_data.all = 0;
  154. doall_data.sa = sa;
  155. ossl_sa_char_doall_arg(sa, &leaf_delete, &doall_data);
  156. if (doall_data.res == 0) {
  157. TEST_info("while deleting selected elements");
  158. goto err;
  159. }
  160. ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data);
  161. if (doall_data.res == 0) {
  162. TEST_info("while checking for deleted elements");
  163. goto err;
  164. }
  165. res = 1;
  166. err:
  167. ossl_sa_char_free(sa);
  168. return res;
  169. }
  170. int setup_tests(void)
  171. {
  172. ADD_TEST(test_sparse_array);
  173. ADD_TEST(test_sparse_array_num);
  174. ADD_TEST(test_sparse_array_doall);
  175. return 1;
  176. }