| 1 | |
| 2 | #include "tests.h"
|
| 3 | #include "util/blake2s.h"
|
| 4 | #include "util/debug.h"
|
| 5 |
|
| 6 | #include <linux/compiler.h>
|
| 7 | #include <stdlib.h>
|
| 8 | #include <string2.h>
|
| 9 |
|
| 10 | static int test_strreplace(char needle, const char *haystack,
|
| 11 | const char *replace, const char *expected)
|
| 12 | {
|
| 13 | char *new = strreplace_chars(needle, haystack, replace);
|
| 14 | int ret = strcmp(new, expected);
|
| 15 |
|
| 16 | free(new);
|
| 17 | return ret == 0;
|
| 18 | }
|
| 19 |
|
| 20 |
|
| 21 | #define MAX_DATA_LEN 512
|
| 22 |
|
| 23 | |
| 24 | * Hash length tested by test_blake2s(). BLAKE2s supports variable-length
|
| 25 | * hashes. However, the only user of BLAKE2s in 'perf' uses 20-byte hashes,
|
| 26 | * matching the length of the ELF build ID field. So that's the length we test.
|
| 27 |
|
| 28 | #define HASH_LEN 20
|
| 29 |
|
| 30 |
|
| 31 | static int test_blake2s(void)
|
| 32 | {
|
| 33 | u8 data[MAX_DATA_LEN];
|
| 34 | u8 hash[HASH_LEN];
|
| 35 | u8 hash2[HASH_LEN];
|
| 36 | struct blake2s_ctx main_ctx;
|
| 37 | |
| 38 | * This value was generated by the following Python code:
|
| 39 | *
|
| 40 | * import hashlib
|
| 41 | *
|
| 42 | * data = bytes(i % 256 for i in range(513))
|
| 43 | * h = hashlib.blake2s(digest_size=20)
|
| 44 | * for i in range(513):
|
| 45 | * h.update(hashlib.blake2s(data=data[:i], digest_size=20).digest())
|
| 46 | * print(h.hexdigest())
|
| 47 |
|
| 48 | static const u8 expected_hash_of_hashes[20] = {
|
| 49 | 0xef, 0x9b, 0x13, 0x98, 0x78, 0x8e, 0x74, 0x59, 0x9c, 0xd5,
|
| 50 | 0x0c, 0xf0, 0x33, 0x97, 0x79, 0x3d, 0x3e, 0xd0, 0x95, 0xa6
|
| 51 | };
|
| 52 | size_t i;
|
| 53 |
|
| 54 |
|
| 55 | for (i = 0; i < MAX_DATA_LEN; i++)
|
| 56 | data[i] = i;
|
| 57 |
|
| 58 | blake2s_init(&main_ctx, sizeof(hash));
|
| 59 | for (i = 0; i <= MAX_DATA_LEN; i++) {
|
| 60 | struct blake2s_ctx ctx;
|
| 61 |
|
| 62 |
|
| 63 | blake2s_init(&ctx, HASH_LEN);
|
| 64 | blake2s_update(&ctx, data, i);
|
| 65 | blake2s_final(&ctx, hash);
|
| 66 |
|
| 67 |
|
| 68 | blake2s_init(&ctx, HASH_LEN);
|
| 69 | blake2s_update(&ctx, data, i / 2);
|
| 70 | blake2s_update(&ctx, &data[i / 2], i - (i / 2));
|
| 71 | blake2s_final(&ctx, hash2);
|
| 72 | TEST_ASSERT_VAL("inconsistent BLAKE2s hashes",
|
| 73 | memcmp(hash, hash2, HASH_LEN) == 0);
|
| 74 |
|
| 75 | |
| 76 | * Pass the hash to another BLAKE2s context, so that we
|
| 77 | * incrementally compute the hash of all the hashes.
|
| 78 |
|
| 79 | blake2s_update(&main_ctx, hash, HASH_LEN);
|
| 80 | }
|
| 81 |
|
| 82 |
|
| 83 | blake2s_final(&main_ctx, hash);
|
| 84 | TEST_ASSERT_VAL("wrong BLAKE2s hashes",
|
| 85 | memcmp(hash, expected_hash_of_hashes, HASH_LEN) == 0);
|
| 86 | return 0;
|
| 87 | }
|
| 88 |
|
| 89 | static int test__blake2s_case(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
|
| 90 | {
|
| 91 | return test_blake2s();
|
| 92 | }
|
| 93 |
|
| 94 | static int test__strreplace(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
|
| 95 | {
|
| 96 | TEST_ASSERT_VAL("empty string", test_strreplace(' ', "", "123", ""));
|
| 97 | TEST_ASSERT_VAL("no match", test_strreplace('5', "123", "4", "123"));
|
| 98 | TEST_ASSERT_VAL("replace 1", test_strreplace('3', "123", "4", "124"));
|
| 99 | TEST_ASSERT_VAL("replace 2", test_strreplace('a', "abcabc", "ef", "efbcefbc"));
|
| 100 | TEST_ASSERT_VAL("replace long", test_strreplace('a', "abcabc", "longlong",
|
| 101 | "longlongbclonglongbc"));
|
| 102 |
|
| 103 | return 0;
|
| 104 | }
|
| 105 |
|
| 106 | static struct test_case tests__util[] = {
|
| 107 | TEST_CASE("String replacement", strreplace),
|
| 108 | TEST_CASE("BLAKE2s hash", blake2s_case),
|
| 109 | { .name = NULL, }
|
| 110 | };
|
| 111 |
|
| 112 | struct test_suite suite__util = {
|
| 113 | .desc = "util",
|
| 114 | .test_cases = tests__util,
|
| 115 | };
|