xref: /src/crypto/openssl/test/sparse_array_test.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
19dd13e84SCy Schubert /*
29dd13e84SCy Schubert  * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
39dd13e84SCy Schubert  * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
49dd13e84SCy Schubert  *
59dd13e84SCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
69dd13e84SCy Schubert  * this file except in compliance with the License.  You can obtain a copy
79dd13e84SCy Schubert  * in the file LICENSE in the source distribution or at
89dd13e84SCy Schubert  * https://www.openssl.org/source/license.html
99dd13e84SCy Schubert  */
109dd13e84SCy Schubert 
119dd13e84SCy Schubert #include <stdio.h>
129dd13e84SCy Schubert #include <string.h>
139dd13e84SCy Schubert #include <limits.h>
149dd13e84SCy Schubert 
159dd13e84SCy Schubert #include <openssl/crypto.h>
169dd13e84SCy Schubert #include "internal/nelem.h"
179dd13e84SCy Schubert #include "crypto/sparse_array.h"
189dd13e84SCy Schubert #include "testutil.h"
199dd13e84SCy Schubert 
209dd13e84SCy Schubert /* The macros below generate unused functions which error out one of the clang
219dd13e84SCy Schubert  * builds.  We disable this check here.
229dd13e84SCy Schubert  */
239dd13e84SCy Schubert #ifdef __clang__
249dd13e84SCy Schubert #pragma clang diagnostic ignored "-Wunused-function"
259dd13e84SCy Schubert #endif
269dd13e84SCy Schubert 
279dd13e84SCy Schubert DEFINE_SPARSE_ARRAY_OF(char);
289dd13e84SCy Schubert 
test_sparse_array(void)299dd13e84SCy Schubert static int test_sparse_array(void)
309dd13e84SCy Schubert {
319dd13e84SCy Schubert     static const struct {
329dd13e84SCy Schubert         ossl_uintmax_t n;
339dd13e84SCy Schubert         char *v;
349dd13e84SCy Schubert     } cases[] = {
359dd13e84SCy Schubert         { 22, "a" }, { 0, "z" }, { 1, "b" }, { 290, "c" },
369dd13e84SCy Schubert         { INT_MAX, "m" }, { 6666666, "d" }, { (ossl_uintmax_t)-1, "H" },
379dd13e84SCy Schubert         { 99, "e" }
389dd13e84SCy Schubert     };
399dd13e84SCy Schubert     SPARSE_ARRAY_OF(char) * sa;
409dd13e84SCy Schubert     size_t i, j;
419dd13e84SCy Schubert     int res = 0;
429dd13e84SCy Schubert 
439dd13e84SCy Schubert     if (!TEST_ptr(sa = ossl_sa_char_new())
449dd13e84SCy Schubert         || !TEST_ptr_null(ossl_sa_char_get(sa, 3))
459dd13e84SCy Schubert         || !TEST_ptr_null(ossl_sa_char_get(sa, 0))
469dd13e84SCy Schubert         || !TEST_ptr_null(ossl_sa_char_get(sa, UINT_MAX)))
479dd13e84SCy Schubert         goto err;
489dd13e84SCy Schubert 
499dd13e84SCy Schubert     for (i = 0; i < OSSL_NELEM(cases); i++) {
509dd13e84SCy Schubert         if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) {
519dd13e84SCy Schubert             TEST_note("iteration %zu", i + 1);
529dd13e84SCy Schubert             goto err;
539dd13e84SCy Schubert         }
549dd13e84SCy Schubert         for (j = 0; j <= i; j++)
559dd13e84SCy Schubert             if (!TEST_str_eq(ossl_sa_char_get(sa, cases[j].n), cases[j].v)) {
569dd13e84SCy Schubert                 TEST_note("iteration %zu / %zu", i + 1, j + 1);
579dd13e84SCy Schubert                 goto err;
589dd13e84SCy Schubert             }
599dd13e84SCy Schubert     }
609dd13e84SCy Schubert 
619dd13e84SCy Schubert     res = 1;
629dd13e84SCy Schubert err:
639dd13e84SCy Schubert     ossl_sa_char_free(sa);
649dd13e84SCy Schubert     return res;
659dd13e84SCy Schubert }
669dd13e84SCy Schubert 
test_sparse_array_num(void)679dd13e84SCy Schubert static int test_sparse_array_num(void)
689dd13e84SCy Schubert {
699dd13e84SCy Schubert     static const struct {
709dd13e84SCy Schubert         size_t num;
719dd13e84SCy Schubert         ossl_uintmax_t n;
729dd13e84SCy Schubert         char *v;
739dd13e84SCy Schubert     } cases[] = {
749dd13e84SCy Schubert         { 1, 22, "a" }, { 2, 1021, "b" }, { 3, 3, "c" }, { 2, 22, NULL },
759dd13e84SCy Schubert         { 2, 3, "d" }, { 3, 22, "e" }, { 3, 666, NULL }, { 4, 666, "f" },
769dd13e84SCy Schubert         { 3, 3, NULL }, { 2, 22, NULL }, { 1, 666, NULL }, { 2, 64000, "g" },
779dd13e84SCy Schubert         { 1, 1021, NULL }, { 0, 64000, NULL }, { 1, 23, "h" }, { 0, 23, NULL }
789dd13e84SCy Schubert     };
799dd13e84SCy Schubert     SPARSE_ARRAY_OF(char) *sa = NULL;
809dd13e84SCy Schubert     size_t i;
819dd13e84SCy Schubert     int res = 0;
829dd13e84SCy Schubert 
839dd13e84SCy Schubert     if (!TEST_size_t_eq(ossl_sa_char_num(NULL), 0)
849dd13e84SCy Schubert         || !TEST_ptr(sa = ossl_sa_char_new())
859dd13e84SCy Schubert         || !TEST_size_t_eq(ossl_sa_char_num(sa), 0))
869dd13e84SCy Schubert         goto err;
879dd13e84SCy Schubert     for (i = 0; i < OSSL_NELEM(cases); i++)
889dd13e84SCy Schubert         if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))
899dd13e84SCy Schubert             || !TEST_size_t_eq(ossl_sa_char_num(sa), cases[i].num))
909dd13e84SCy Schubert             goto err;
919dd13e84SCy Schubert     res = 1;
929dd13e84SCy Schubert err:
939dd13e84SCy Schubert     ossl_sa_char_free(sa);
949dd13e84SCy Schubert     return res;
959dd13e84SCy Schubert }
969dd13e84SCy Schubert 
979dd13e84SCy Schubert struct index_cases_st {
989dd13e84SCy Schubert     ossl_uintmax_t n;
999dd13e84SCy Schubert     char *v;
1009dd13e84SCy Schubert     int del;
1019dd13e84SCy Schubert };
1029dd13e84SCy Schubert 
1039dd13e84SCy Schubert struct doall_st {
1049dd13e84SCy Schubert     SPARSE_ARRAY_OF(char) * sa;
1059dd13e84SCy Schubert     size_t num_cases;
1069dd13e84SCy Schubert     const struct index_cases_st *cases;
1079dd13e84SCy Schubert     int res;
1089dd13e84SCy Schubert     int all;
1099dd13e84SCy Schubert };
1109dd13e84SCy Schubert 
leaf_check_all(ossl_uintmax_t n,char * value,void * arg)1119dd13e84SCy Schubert static void leaf_check_all(ossl_uintmax_t n, char *value, void *arg)
1129dd13e84SCy Schubert {
1139dd13e84SCy Schubert     struct doall_st *doall_data = (struct doall_st *)arg;
1149dd13e84SCy Schubert     const struct index_cases_st *cases = doall_data->cases;
1159dd13e84SCy Schubert     size_t i;
1169dd13e84SCy Schubert 
1179dd13e84SCy Schubert     doall_data->res = 0;
1189dd13e84SCy Schubert     for (i = 0; i < doall_data->num_cases; i++)
1199dd13e84SCy Schubert         if ((doall_data->all || !cases[i].del)
1209dd13e84SCy Schubert             && n == cases[i].n && strcmp(value, cases[i].v) == 0) {
1219dd13e84SCy Schubert             doall_data->res = 1;
1229dd13e84SCy Schubert             return;
1239dd13e84SCy Schubert         }
1249dd13e84SCy Schubert     TEST_error("Index %ju with value %s not found", n, value);
1259dd13e84SCy Schubert }
1269dd13e84SCy Schubert 
leaf_delete(ossl_uintmax_t n,char * value,void * arg)1279dd13e84SCy Schubert static void leaf_delete(ossl_uintmax_t n, char *value, void *arg)
1289dd13e84SCy Schubert {
1299dd13e84SCy Schubert     struct doall_st *doall_data = (struct doall_st *)arg;
1309dd13e84SCy Schubert     const struct index_cases_st *cases = doall_data->cases;
1319dd13e84SCy Schubert     size_t i;
1329dd13e84SCy Schubert 
1339dd13e84SCy Schubert     doall_data->res = 0;
1349dd13e84SCy Schubert     for (i = 0; i < doall_data->num_cases; i++)
1359dd13e84SCy Schubert         if (n == cases[i].n && strcmp(value, cases[i].v) == 0) {
1369dd13e84SCy Schubert             doall_data->res = 1;
1379dd13e84SCy Schubert             ossl_sa_char_set(doall_data->sa, n, NULL);
1389dd13e84SCy Schubert             return;
1399dd13e84SCy Schubert         }
1409dd13e84SCy Schubert     TEST_error("Index %ju with value %s not found", n, value);
1419dd13e84SCy Schubert }
1429dd13e84SCy Schubert 
test_sparse_array_doall(void)1439dd13e84SCy Schubert static int test_sparse_array_doall(void)
1449dd13e84SCy Schubert {
1459dd13e84SCy Schubert     static const struct index_cases_st cases[] = {
146808413daSEnji Cooper         { 22, "A", 1 },
147808413daSEnji Cooper         { 1021, "b", 0 },
148808413daSEnji Cooper         { 3, "c", 0 },
149808413daSEnji Cooper         { INT_MAX, "d", 1 },
150808413daSEnji Cooper         { (ossl_uintmax_t)-1, "H", 0 },
151808413daSEnji Cooper         { (ossl_uintmax_t)-2, "i", 1 },
152808413daSEnji Cooper         { 666666666, "s", 1 },
153808413daSEnji Cooper         { 1234567890, "t", 0 },
1549dd13e84SCy Schubert     };
1559dd13e84SCy Schubert     struct doall_st doall_data;
1569dd13e84SCy Schubert     size_t i;
1579dd13e84SCy Schubert     SPARSE_ARRAY_OF(char) *sa = NULL;
1589dd13e84SCy Schubert     int res = 0;
1599dd13e84SCy Schubert 
1609dd13e84SCy Schubert     if (!TEST_ptr(sa = ossl_sa_char_new()))
1619dd13e84SCy Schubert         goto err;
1629dd13e84SCy Schubert     doall_data.num_cases = OSSL_NELEM(cases);
1639dd13e84SCy Schubert     doall_data.cases = cases;
1649dd13e84SCy Schubert     doall_data.all = 1;
1659dd13e84SCy Schubert     doall_data.sa = NULL;
1669dd13e84SCy Schubert     for (i = 0; i < OSSL_NELEM(cases); i++)
1679dd13e84SCy Schubert         if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) {
1689dd13e84SCy Schubert             TEST_note("failed at iteration %zu", i + 1);
1699dd13e84SCy Schubert             goto err;
1709dd13e84SCy Schubert         }
1719dd13e84SCy Schubert 
1729dd13e84SCy Schubert     ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data);
1739dd13e84SCy Schubert     if (doall_data.res == 0) {
1749dd13e84SCy Schubert         TEST_info("while checking all elements");
1759dd13e84SCy Schubert         goto err;
1769dd13e84SCy Schubert     }
1779dd13e84SCy Schubert     doall_data.all = 0;
1789dd13e84SCy Schubert     doall_data.sa = sa;
1799dd13e84SCy Schubert     ossl_sa_char_doall_arg(sa, &leaf_delete, &doall_data);
1809dd13e84SCy Schubert     if (doall_data.res == 0) {
1819dd13e84SCy Schubert         TEST_info("while deleting selected elements");
1829dd13e84SCy Schubert         goto err;
1839dd13e84SCy Schubert     }
1849dd13e84SCy Schubert     ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data);
1859dd13e84SCy Schubert     if (doall_data.res == 0) {
1869dd13e84SCy Schubert         TEST_info("while checking for deleted elements");
1879dd13e84SCy Schubert         goto err;
1889dd13e84SCy Schubert     }
1899dd13e84SCy Schubert     res = 1;
1909dd13e84SCy Schubert 
1919dd13e84SCy Schubert err:
1929dd13e84SCy Schubert     ossl_sa_char_free(sa);
1939dd13e84SCy Schubert     return res;
1949dd13e84SCy Schubert }
1959dd13e84SCy Schubert 
setup_tests(void)1969dd13e84SCy Schubert int setup_tests(void)
1979dd13e84SCy Schubert {
1989dd13e84SCy Schubert     ADD_TEST(test_sparse_array);
1999dd13e84SCy Schubert     ADD_TEST(test_sparse_array_num);
2009dd13e84SCy Schubert     ADD_TEST(test_sparse_array_doall);
2019dd13e84SCy Schubert     return 1;
2029dd13e84SCy Schubert }
203