X-Git-Url: https://www.flypig.org.uk/git/?p=libcontrac.git;a=blobdiff_plain;f=tests%2Ftest_contrac.c;h=ffa09c17ac1f1c44ffc8b3ef8da929cad32390cb;hp=aa81384c8166e1a6e8b56a74eaa1d075ff2f121f;hb=8515bbba069347de07a452586d7e49a2e8bdf151;hpb=79942abab927241b65a29a8a30d71b8efe6b6d94 diff --git a/tests/test_contrac.c b/tests/test_contrac.c index aa81384..ffa09c1 100644 --- a/tests/test_contrac.c +++ b/tests/test_contrac.c @@ -17,8 +17,16 @@ // Includes #include +#include #include "contrac/contrac.h" +#include "contrac/contrac_private.h" +#include "contrac/utils.h" +#include "contrac/dtk.h" +#include "contrac/rpi.h" +#include "contrac/dtk_list.h" +#include "contrac/rpi_list.h" +#include "contrac/match.h" // Defines @@ -28,8 +36,312 @@ // Function definitions +START_TEST (check_base64) { + //bool result; + //int pos; + char *string[4] = { + "This is a string", // 16 + "Maybe upon a time", // 17 + "And then there was", // 18 + "In the end there is", // 19 + }; + char *base64[4] = { + "VGhpcyBpcyBhIHN0cmluZw==", // 24 + "TWF5YmUgdXBvbiBhIHRpbWU=", // 24 + "QW5kIHRoZW4gdGhlcmUgd2Fz", // 24 + "SW4gdGhlIGVuZCB0aGVyZSBpcw==", // 24 + }; + size_t size; + char * output; + int pos; + + for (pos = 0; pos < 4; ++pos) { + // Encode + size = base64_encode_size(strlen(string[pos])); + + ck_assert(size == (strlen(base64[pos]) + 1)); + output = calloc(sizeof(char), size); + + base64_encode_binary_to_base64((unsigned char *)string[pos], strlen(string[pos]), (unsigned char *)output, &size); + + ck_assert(size == (strlen(base64[pos]) + 1)); + ck_assert_str_eq(output, base64[pos]); + + // Decode + size = base64_decode_size(strlen(base64[pos])); + + ck_assert(size >= (strlen(string[pos]) + 1)); + ck_assert(size < (strlen(string[pos]) + 4)); + output = calloc(sizeof(char), size + 1); + + base64_decode_base64_to_binary((unsigned char *)base64[pos], strlen(base64[pos]), (unsigned char *)output, &size); + + ck_assert(size >= (strlen(string[pos]) + 1)); + ck_assert(size < (strlen(string[pos]) + 4)); + ck_assert_str_eq(output, string[pos]); + } +} +END_TEST + START_TEST (check_contrac) { + bool result; + unsigned char const *tk; + int pos; + + // Generate some keys, check the results + Contrac * contrac; + + contrac = contrac_new(); + ck_assert(contrac != NULL); + + result = contrac_get_initialised(contrac); + ck_assert(result == false); + + tk = contrac_get_tracing_key(contrac); + // The tracing key will initialise to zero by default + for (pos = 0; pos < TK_SIZE; ++pos) { + ck_assert(tk[pos] == 0); + } + + result = contrac_generate_tracing_key(contrac); + ck_assert(result == true); + + result = contrac_get_initialised(contrac); + ck_assert(result == false); + + // The random generator could generate all zeros, but we'll take the risk + tk = contrac_get_tracing_key(contrac); + result = false; + for (pos = 0; pos < TK_SIZE; ++pos) { + if (tk[pos] != 0) { + result = true; + } + } + ck_assert(result == true); + + result = contrac_get_initialised(contrac); + ck_assert(result == false); + + result = contrac_set_day_number(contrac, 23); + ck_assert(result == true); + + result = contrac_get_initialised(contrac); + ck_assert(result == false); + + result = contrac_set_time_interval_number(contrac, 76); + ck_assert(result == true); + + result = contrac_get_initialised(contrac); + ck_assert(result == true); + + // Clean up + contrac_delete(contrac); +} +END_TEST + +START_TEST (check_dtk) { + bool result; + char const *tracing_key_base64 = "3UmKrtcQ2tfLE8UPSXHb4PtgRfE0E2xdSs+PGVIS8cc="; + char tk_base64[TK_SIZE_BASE64 + 1]; + char dtk_base64[DTK_SIZE_BASE64 + 1]; + + // Generate some keys, check the results + Contrac * contrac; + + contrac = contrac_new(); + ck_assert(contrac != NULL); + + contrac_set_tracing_key_base64(contrac, tracing_key_base64); + + contrac_get_tracing_key_base64(contrac, tk_base64); + ck_assert_int_eq(strlen(tk_base64), TK_SIZE_BASE64); + ck_assert_str_eq(tracing_key_base64, tk_base64); + + // Check the Daily Tracing Keys are generated correctly + // Should use the standard test vectors when they're available + + result = contrac_set_day_number(contrac, 12); + ck_assert(result); + contrac_get_daily_key_base64(contrac, dtk_base64); + ck_assert_int_eq(strlen(dtk_base64), DTK_SIZE_BASE64); + ck_assert_str_eq(dtk_base64, "AzZ389DsGecAjZqby1sLNQ=="); + + + result = contrac_set_day_number(contrac, 0); + ck_assert(result); + contrac_get_daily_key_base64(contrac, dtk_base64); + ck_assert_int_eq(strlen(dtk_base64), DTK_SIZE_BASE64); + ck_assert_str_eq(dtk_base64, "p7LrsTReTw3k721eIWDjRw=="); + + result = contrac_set_day_number(contrac, 143); + ck_assert(result); + contrac_get_daily_key_base64(contrac, dtk_base64); + ck_assert_int_eq(strlen(dtk_base64), DTK_SIZE_BASE64); + ck_assert_str_eq(dtk_base64, "f6RZL/2wGCzxSBzZc9xVNQ=="); + + // Clean up + contrac_delete(contrac); +} +END_TEST + +START_TEST (check_rpi) { + bool result; + char const *tracing_key_base64[2] = { + "3UmKrtcQ2tfLE8UPSXHb4PtgRfE0E2xdSs+PGVIS8cc=", + "U3CgpSjF0qFW8DNSTHVWF99few5FOW7RV7kA9j6LFTc=", + }; + char rpi_base64[RPI_SIZE_BASE64 + 1]; + + // Generate some keys, check the results + Contrac * contrac; + + contrac = contrac_new(); + ck_assert(contrac != NULL); + + contrac_set_tracing_key_base64(contrac, tracing_key_base64[0]); + + result = contrac_set_day_number(contrac, 9); + ck_assert(result); + + // Check the Rolling Proximity Identifiers are generated correctly + // Should use the standard test vectors when they're available + + result = contrac_set_time_interval_number(contrac, 0); + ck_assert(result); + contrac_get_proximity_id_base64(contrac, rpi_base64); + ck_assert_int_eq(strlen(rpi_base64), RPI_SIZE_BASE64); + ck_assert_str_eq(rpi_base64, "++ucH9hoIkGwCzM+J09faQ=="); + + result = contrac_set_time_interval_number(contrac, 82); + ck_assert(result); + contrac_get_proximity_id_base64(contrac, rpi_base64); + ck_assert_int_eq(strlen(rpi_base64), RPI_SIZE_BASE64); + ck_assert_str_eq(rpi_base64, "GrqeroryZQ+Uvhx10zfKWw=="); + + result = contrac_set_time_interval_number(contrac, 143); + ck_assert(result); + contrac_get_proximity_id_base64(contrac, rpi_base64); + ck_assert_int_eq(strlen(rpi_base64), RPI_SIZE_BASE64); + ck_assert_str_eq(rpi_base64, "+9eL1UlYZ9buUCFF5qRDUA=="); + + contrac_set_tracing_key_base64(contrac, tracing_key_base64[1]); + + result = contrac_set_day_number(contrac, 500); + ck_assert(result); + + result = contrac_set_time_interval_number(contrac, 1); + ck_assert(result); + contrac_get_proximity_id_base64(contrac, rpi_base64); + ck_assert_int_eq(strlen(rpi_base64), RPI_SIZE_BASE64); + ck_assert_str_eq(rpi_base64, "XmePWi0HlgHyBcVUb0KhjQ=="); + + result = contrac_set_time_interval_number(contrac, 27); + ck_assert(result); + contrac_get_proximity_id_base64(contrac, rpi_base64); + ck_assert_int_eq(strlen(rpi_base64), RPI_SIZE_BASE64); + ck_assert_str_eq(rpi_base64, "LlPznz6D044ZKYsY3sHJew=="); + + result = contrac_set_time_interval_number(contrac, 143); + ck_assert(result); + contrac_get_proximity_id_base64(contrac, rpi_base64); + ck_assert_int_eq(strlen(rpi_base64), RPI_SIZE_BASE64); + ck_assert_str_eq(rpi_base64, "QDG50cy9NTXZ3zDAUGkePQ=="); + + // Clean up + contrac_delete(contrac); +} +END_TEST + +START_TEST (check_match) { + bool result; + char const *tracing_key_base64 = "3UmKrtcQ2tfLE8UPSXHb4PtgRfE0E2xdSs+PGVIS8cc="; + RpiList * beacon_list; + DtkList * diagnosis_list; + // There are four matches in amongst this lot + // (day, time) = (12, 15), (1175, 142), (1175, 67), (12, 93) + uint32_t beacon_days[8] = {55, 12, 0, 8787, 1175, 1175, 187, 12}; + uint8_t beacon_times[8] = {1, 15, 5, 101, 142, 67, 51, 93}; + uint32_t diagnosis_days[2] = {1175, 12}; + // Summarise the four matches + uint32_t match_days[4] = {12, 1175, 1175, 12}; + uint8_t match_times[4] = {15, 142, 67, 93}; + int pos; + const unsigned char * rpi_bytes; + const unsigned char * dtk_bytes; + Rpi * rpi; + Dtk * dtk; + MatchList * matches; + MatchListItem const * match; + int match_count; + + // Generate some keys, check the results + Contrac * contrac; + + contrac = contrac_new(); + ck_assert(contrac != NULL); + + contrac_set_tracing_key_base64(contrac, tracing_key_base64); + + // Generate some beacons (as if collected over BlueTooth) + + beacon_list = rpi_list_new(); + + for (pos = 0; pos < 8; ++pos) { + result = contrac_set_day_number(contrac, beacon_days[pos]); + ck_assert(result); + + result = contrac_set_time_interval_number(contrac, beacon_times[pos]); + ck_assert(result); + + rpi_bytes = contrac_get_proximity_id(contrac); + rpi = rpi_new(); + rpi_assign(rpi, rpi_bytes, beacon_times[pos]); + + rpi_list_append(beacon_list, rpi); + } + + // Generate some diagnosis data (as if provided by a diagnosis server) + + diagnosis_list = dtk_list_new(); + for (pos = 0; pos < 2; ++pos) { + result = contrac_set_day_number(contrac, diagnosis_days[pos]); + ck_assert(result); + + dtk_bytes = contrac_get_daily_key(contrac); + dtk = dtk_new(); + dtk_assign(dtk, dtk_bytes, diagnosis_days[pos]); + + dtk_list_append(diagnosis_list, dtk); + } + + // Check that the matching algorithm identifies the beacons that match + + matches = match_list_new(); + match_list_find_matches(matches, beacon_list, diagnosis_list); + + match = match_list_first(matches); + + match_count = 0; + while (match) { + result = false; + for (pos = 0; pos < 4; ++pos) { + if ((match_list_get_day_number(match) == match_days[pos]) && (match_list_get_time_interval_number(match) == match_times[pos])) { + result = true; + } + } + + ck_assert(result); + + match_count++; + match = match_list_next(match); + } + ck_assert_int_eq(match_count, 4); + // Clean up + match_list_delete(matches); + rpi_list_delete(beacon_list); + dtk_list_delete(diagnosis_list); + contrac_delete(contrac); } END_TEST @@ -42,7 +354,11 @@ int main(void) { s = suite_create("libcontrac"); tc = tcase_create("Contrac"); + tcase_add_test(tc, check_base64); tcase_add_test(tc, check_contrac); + tcase_add_test(tc, check_dtk); + tcase_add_test(tc, check_rpi); + tcase_add_test(tc, check_match); suite_add_tcase(s, tc); sr = srunner_create(s);