test: update tests to use new API
							parent
							
								
									50ebf86589
								
							
						
					
					
						commit
						a153c4e22d
					
				|  | @ -26,9 +26,17 @@ TrieExitCode trie_init(Trie **trie_ptr, const char *file_path) { | |||
|   // Allocate & initialize trie
 | ||||
|   Trie *trie = calloc(1, sizeof(Trie)); | ||||
|   trie->root = tnode_init(); | ||||
|   trie->file_path = strdup(file_path); | ||||
|   pthread_rwlock_init(&trie->lock, NULL); | ||||
| 
 | ||||
|   *trie_ptr = trie; | ||||
| 
 | ||||
|   if (file_path == NULL) { | ||||
|     trie->file_path = NULL; | ||||
|     return Ok; | ||||
|   } | ||||
| 
 | ||||
|   trie->file_path = strdup(file_path); | ||||
| 
 | ||||
|   // Populate trie with data from file
 | ||||
|   FILE *fp = fopen(file_path, "r"); | ||||
| 
 | ||||
|  | @ -75,8 +83,6 @@ TrieExitCode trie_init(Trie **trie_ptr, const char *file_path) { | |||
| 
 | ||||
|   fclose(fp); | ||||
| 
 | ||||
|   *trie_ptr = trie; | ||||
| 
 | ||||
|   return Ok; | ||||
| } | ||||
| 
 | ||||
|  | @ -265,28 +271,30 @@ TrieExitCode trie_add_no_lock(Trie *trie, const char *string, Entry *entry) { | |||
| } | ||||
| 
 | ||||
| TrieExitCode trie_add(Trie *trie, const char *key, Entry *entry) { | ||||
|   // Easiest way to make sure we don't add duplicate entries
 | ||||
|   // We use an internal function that doesn't require a read lock, as we're
 | ||||
|   // already inside a write lock
 | ||||
|   if (trie_search_node(trie, key).child != NULL) { | ||||
|     return AlreadyPresent; | ||||
|   if (trie->file_path != NULL) { | ||||
|     // Easiest way to make sure we don't add duplicate entries
 | ||||
|     // We use an internal function that doesn't require a read lock, as we're
 | ||||
|     // already inside a write lock
 | ||||
|     if (trie_search_node(trie, key).child != NULL) { | ||||
|       return AlreadyPresent; | ||||
|     } | ||||
| 
 | ||||
|     FILE *fp = fopen(trie->file_path, "a"); | ||||
| 
 | ||||
|     if (fp == NULL) { | ||||
|       return FileError; | ||||
|     } | ||||
| 
 | ||||
|     fputs(key, fp); | ||||
|     fputs(" ", fp); | ||||
|     fputc(entry_type_to_char(entry->type), fp); | ||||
|     fputs(" ", fp); | ||||
|     fputs(entry->string, fp); | ||||
|     fputs("\n", fp); | ||||
| 
 | ||||
|     fclose(fp); | ||||
|   } | ||||
| 
 | ||||
|   FILE *fp = fopen(trie->file_path, "a"); | ||||
| 
 | ||||
|   if (fp == NULL) { | ||||
|     return FileError; | ||||
|   } | ||||
| 
 | ||||
|   fputs(key, fp); | ||||
|   fputs(" ", fp); | ||||
|   fputc(entry_type_to_char(entry->type), fp); | ||||
|   fputs(" ", fp); | ||||
|   fputs(entry->string, fp); | ||||
|   fputs("\n", fp); | ||||
| 
 | ||||
|   fclose(fp); | ||||
| 
 | ||||
|   // This function *should* always return Ok. Otherwise, the function would've
 | ||||
|   // exited because the string was found in the trie.
 | ||||
|   return trie_add_no_lock(trie, key, entry); | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <stdbool.h> | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| #include "trie.h" | ||||
| 
 | ||||
| typedef struct fuzzyconfig { | ||||
|     int seed; | ||||
|  | @ -74,7 +75,7 @@ char** init_string_matrix(int count, int len) { | |||
|  * @param size_func function to get the size of the given trie | ||||
|  * @return exit code describing failures, if any | ||||
|  */ | ||||
| int fuzzy_test_trie_seed(FuzzyConfig conf, void* (*init_func) (), void (*free_func) (void*), bool (*add_func) (void*, char*, void*), bool (*remove_func) (void*, char*), size_t (*size_func) (void*)) { | ||||
| int fuzzy_test_trie_seed(FuzzyConfig conf) { | ||||
|     srand(conf.seed); | ||||
| 
 | ||||
|     char** matrix = init_string_matrix(conf.word_count, conf.word_length); | ||||
|  | @ -100,9 +101,11 @@ int fuzzy_test_trie_seed(FuzzyConfig conf, void* (*init_func) (), void (*free_fu | |||
|     // also correct
 | ||||
|     size_t size = 0; | ||||
| 
 | ||||
|     void* ct = init_func(); | ||||
|     Trie *ct; | ||||
|     trie_init(&ct, NULL); | ||||
| 
 | ||||
|     bool changed; | ||||
|     TrieExitCode status; | ||||
| 
 | ||||
|     // 0: success
 | ||||
|     // 1: invalid add
 | ||||
|  | @ -113,13 +116,13 @@ int fuzzy_test_trie_seed(FuzzyConfig conf, void* (*init_func) (), void (*free_fu | |||
| 
 | ||||
|     // Add all strings to trie, checking for duplicates
 | ||||
|     for (int i = 0; i < conf.word_count; i++) { | ||||
|       changed = add_func(ct, matrix[i], NULL); | ||||
|       status = trie_add(ct, matrix[i], NULL); | ||||
| 
 | ||||
|       // if changed is false, *contains_dedupped[i] should be true, as changed
 | ||||
|       // can only be false if the string is already contained in the trie. if
 | ||||
|       // changed is true, *contains_dedupped[i] should be false, as the string
 | ||||
|       // cannot be in the trie yet.
 | ||||
|       if (changed == *contains_dedupped[i]) { | ||||
|       if (status == Ok && *contains_dedupped[i]) { | ||||
|         exit_code = 1; | ||||
|         goto END; | ||||
|       } | ||||
|  | @ -131,8 +134,8 @@ int fuzzy_test_trie_seed(FuzzyConfig conf, void* (*init_func) (), void (*free_fu | |||
|     } | ||||
| 
 | ||||
|     // Ensure size is correct
 | ||||
|     if (size_func(ct) != size) { | ||||
|       printf("%i %i\n", size_func(ct), size); | ||||
|     if (trie_size(ct) != size) { | ||||
|       printf("%i %i\n", trie_size(ct), size); | ||||
|       exit_code = 3; | ||||
|       goto END; | ||||
|     } | ||||
|  | @ -160,7 +163,7 @@ int fuzzy_test_trie_seed(FuzzyConfig conf, void* (*init_func) (), void (*free_fu | |||
|     /* } */ | ||||
| 
 | ||||
| END: | ||||
|     free_func(ct); | ||||
|     trie_free(ct); | ||||
| 
 | ||||
|     // Even testing functions should properly free memory
 | ||||
|     free(contains); | ||||
|  |  | |||
|  | @ -5,64 +5,106 @@ | |||
| #define TEST_SIZE(ct, size) \ | ||||
|     TEST_CHECK(trie_size(ct) == size); \ | ||||
|     TEST_MSG("Size: %zu", trie_size(ct)) | ||||
|                                 \ | ||||
| 
 | ||||
| # define TRIE_INIT() \ | ||||
|   Trie *ct; \ | ||||
|   trie_init(&ct, NULL); \ | ||||
|   TEST_CHECK(ct != NULL) | ||||
| 
 | ||||
| void test_init() { | ||||
|     Trie* ct = trie_init(); | ||||
|     TEST_CHECK(ct != NULL); | ||||
|     TEST_SIZE(ct, 0); | ||||
|     trie_free(ct); | ||||
|   TRIE_INIT(); | ||||
|   TEST_SIZE(ct, 0); | ||||
|   trie_free(ct); | ||||
| } | ||||
| 
 | ||||
| void test_add_one() { | ||||
|     Trie* ct = trie_init(); | ||||
|     TEST_CHECK(ct != NULL); | ||||
|   TRIE_INIT(); | ||||
| 
 | ||||
|     Entry *entry = entry_new(Redirect, ""); | ||||
|     const char* string = "this is a test"; | ||||
|   Entry *entry = entry_new(Redirect, ""); | ||||
|   const char* string = "this is a test"; | ||||
| 
 | ||||
|     TEST_CHECK(trie_add(ct, string, entry)); | ||||
|     TEST_CHECK(trie_search(ct, string) == entry); | ||||
|     TEST_SIZE(ct, 1); | ||||
|     trie_free(ct); | ||||
|   TEST_CHECK(trie_add(ct, string, entry) == Ok); | ||||
|   Entry *entry2; | ||||
|   TEST_CHECK(trie_search(ct, &entry2, string) == Ok); | ||||
|   TEST_CHECK(entry == entry2); | ||||
|   TEST_SIZE(ct, 1); | ||||
|   trie_free(ct); | ||||
| } | ||||
| 
 | ||||
| void test_add_prefix() { | ||||
|   TRIE_INIT(); | ||||
| 
 | ||||
|   const char *s1 = "halloween-2022"; | ||||
|   const char *s2 = "halloween-202"; | ||||
| 
 | ||||
|   Entry *entry1 = entry_new(Redirect, ""); | ||||
|   Entry *entry2 = entry_new(Redirect, ""); | ||||
| 
 | ||||
|   TEST_CHECK(trie_add(ct, s1, entry1) == Ok); | ||||
|   TEST_CHECK(trie_add(ct, s2, entry2) == Ok); | ||||
| 
 | ||||
|   Entry *entry3; | ||||
| 
 | ||||
|   TEST_CHECK(trie_search(ct, &entry3, s1) == Ok); | ||||
|   TEST_CHECK(entry3 == entry1); | ||||
|   entry2 = NULL; | ||||
| 
 | ||||
|   TEST_CHECK(trie_search(ct, &entry3, s2) == Ok); | ||||
|   TEST_CHECK(entry3 == entry2); | ||||
| 
 | ||||
|   trie_free(ct); | ||||
| } | ||||
| 
 | ||||
| void test_search_not_present() { | ||||
|     Trie* ct = trie_init(); | ||||
|     TEST_CHECK(ct != NULL); | ||||
|   TRIE_INIT(); | ||||
| 
 | ||||
|     TEST_CHECK(trie_add(ct, "this string exists", NULL)); | ||||
|     TEST_CHECK(trie_search(ct, "this string does not exist") == NULL); | ||||
|     trie_free(ct); | ||||
|   TEST_CHECK(trie_add(ct, "this string exists", NULL) == Ok); | ||||
|   Entry *entry; | ||||
|   TEST_CHECK(trie_search(ct, &entry, "this string does not exist") == NotFound); | ||||
| 
 | ||||
|   trie_free(ct); | ||||
| } | ||||
| 
 | ||||
| void test_add_more() { | ||||
|     Trie* ct = trie_init(); | ||||
|     TEST_CHECK(ct != NULL); | ||||
|   TRIE_INIT(); | ||||
| 
 | ||||
|     const char* one = "one"; | ||||
|     const char* two = "two"; | ||||
|     const char* twenty = "twenty"; | ||||
|     const char* twentytwo = "twentytwo"; | ||||
|     Entry *entry = entry_new(Redirect, ""); | ||||
|   const char* one = "one"; | ||||
|   const char* two = "two"; | ||||
|   const char* twenty = "twenty"; | ||||
|   const char* twentytwo = "twentytwo"; | ||||
| 
 | ||||
|     TEST_CHECK(trie_add(ct, one, entry)); | ||||
|     TEST_CHECK(trie_add(ct, two, entry)); | ||||
|     TEST_CHECK(trie_add(ct, twenty, entry)); | ||||
|     TEST_CHECK(trie_add(ct, twentytwo, entry)); | ||||
|   Entry *entry = entry_new(Redirect, ""); | ||||
| 
 | ||||
|     TEST_SIZE(ct, 4); | ||||
|   TEST_CHECK(trie_add(ct, one, entry) == Ok); | ||||
|   TEST_CHECK(trie_add(ct, two, entry) == Ok); | ||||
|   TEST_CHECK(trie_add(ct, twenty, entry) == Ok); | ||||
|   TEST_CHECK(trie_add(ct, twentytwo, entry) == Ok); | ||||
| 
 | ||||
|     TEST_CHECK(trie_search(ct, one) == entry); | ||||
|     TEST_CHECK(trie_search(ct, two) == entry); | ||||
|     TEST_CHECK(trie_search(ct, twenty) == entry); | ||||
|     TEST_CHECK(trie_search(ct, twentytwo) == entry); | ||||
|   TEST_SIZE(ct, 4); | ||||
| 
 | ||||
|     TEST_CHECK(!trie_add(ct, one, NULL)); | ||||
|     TEST_CHECK(!trie_add(ct, two, NULL)); | ||||
|     TEST_CHECK(!trie_add(ct, twenty, NULL)); | ||||
|     TEST_CHECK(!trie_add(ct, twentytwo, NULL)); | ||||
|   Entry *entry2; | ||||
|   TEST_CHECK(trie_search(ct, &entry2, one) == Ok); | ||||
|   TEST_CHECK(entry2 == entry); | ||||
|   entry2 = NULL; | ||||
| 
 | ||||
|     trie_free(ct); | ||||
|   TEST_CHECK(trie_search(ct, &entry2, two) == Ok); | ||||
|   TEST_CHECK(entry2 == entry); | ||||
|   entry2 = NULL; | ||||
| 
 | ||||
|   TEST_CHECK(trie_search(ct, &entry2, twenty) == Ok); | ||||
|   TEST_CHECK(entry2 == entry); | ||||
|   entry2 = NULL; | ||||
| 
 | ||||
|   TEST_CHECK(trie_search(ct, &entry2, twentytwo) == Ok); | ||||
|   TEST_CHECK(entry2 == entry); | ||||
|   entry2 = NULL; | ||||
| 
 | ||||
|   TEST_CHECK(trie_add(ct, one, NULL) == AlreadyPresent); | ||||
|   TEST_CHECK(trie_add(ct, two, NULL) == AlreadyPresent); | ||||
|   TEST_CHECK(trie_add(ct, twenty, NULL) == AlreadyPresent); | ||||
|   TEST_CHECK(trie_add(ct, twentytwo, NULL) == AlreadyPresent); | ||||
| 
 | ||||
|   trie_free(ct); | ||||
| } | ||||
| 
 | ||||
| /* void test_remove_one() { */ | ||||
|  | @ -127,9 +169,7 @@ void test_fuzzy_set() { | |||
|   int res; | ||||
| 
 | ||||
|   for (int i = 0; i < count; i++) { | ||||
| res = fuzzy_test_trie_seed(configs[i], trie_init, | ||||
|                                      trie_free, trie_add_no_lock, | ||||
|                                      NULL, trie_size); | ||||
| res = fuzzy_test_trie_seed(configs[i]); | ||||
|     TEST_CHECK_(res == 0, | ||||
|                 "Failed config, seed = %i, len = %i, count = %i, code=%i", configs[i].seed, configs[i].word_length, configs[i].word_count, res); | ||||
|     } | ||||
|  |  | |||
|  | @ -19,9 +19,7 @@ void test_fuzzy() { | |||
|           config.word_length = len; | ||||
|           config.word_count = count; | ||||
| 
 | ||||
| res = fuzzy_test_trie_seed(config, trie_init, | ||||
|                                      trie_free, trie_add_no_lock, | ||||
|                                      NULL, trie_size); | ||||
| res = fuzzy_test_trie_seed(config); | ||||
|     TEST_CHECK_(res == 0, | ||||
|                 "Failed config, seed = %i, len = %i, count = %i, code = %i", config.seed, config.word_length, config.word_count, res); | ||||
|         } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue