/* * Copyright 2014 (c) Anna Schumaker. * Test a Database */ #include #include static void test_entry() { const struct db_ops *index_ops = test_index_ops(); struct index_entry *ie; struct set_iter it; unsigned int i; struct file f; ie = INDEX_ENTRY(index_ops->dbe_alloc("Link")); test_equal(index_ops->dbe_key(&ie->ie_dbe), "Link"); set_insert(&ie->ie_set, 0); set_insert(&ie->ie_set, 1); set_insert(&ie->ie_set, 2); i = 0; set_for_each(&ie->ie_set, &it) { test_loop_equal(it.it_val, i, i); i++; } test_loop_passed(); file_init(&f, "index_entry", 0, 0); file_open(&f, OPEN_WRITE); file_writef(&f, "Zelda\n0 \n"); index_ops->dbe_write(&f, &ie->ie_dbe); file_close(&f); g_free(ie->ie_key); index_ops->dbe_free(&ie->ie_dbe); file_open(&f, OPEN_READ); ie = INDEX_ENTRY(index_ops->dbe_read(&f)); test_equal(index_ops->dbe_key(&ie->ie_dbe), "Zelda"); test_equal(set_size(&ie->ie_set), 0); g_free(ie->ie_key); index_ops->dbe_free(&ie->ie_dbe); ie = INDEX_ENTRY(index_ops->dbe_read(&f)); test_equal(ie->ie_key, "Link"); test_equal(index_ops->dbe_key(&ie->ie_dbe), "Link"); test_equal(set_size(&ie->ie_set), 3); file_close(&f); i = 0; set_for_each(&ie->ie_set, &it) { test_loop_equal(it.it_val, i, i); i++; } test_loop_passed(); g_free(ie->ie_key); index_ops->dbe_free(&ie->ie_dbe); } static void __test_stress(unsigned int N) { const struct db_ops *index_ops = test_index_ops(); struct index_entry *ie, *ie2; struct database index; unsigned int i; gchar key[2] = ""; char c; index_init(&index, "stress.idx", false); /* index_insert() */ for (c = 'a'; c <= 'z'; c++) { g_strlcpy(key, &c, 2); ie = index_insert(&index, key, 0); test_loop_not_equal((void *)ie, NULL, c - 'a'); test_loop_equal(index_ops->dbe_key(&ie->ie_dbe), key, c - 'a'); for (i = 0; i < N; i++) ie2 = index_insert(&index, key, i); test_loop_equal((void *)ie, (void *)ie2, c - 'a'); test_loop_equal(set_size(&ie->ie_set), N, c - 'a'); test_loop_equal(index.db_size, c - 'a' + 1, c - 'a'); } test_loop_passed(); test_equal(index.db_size, 26); /* index_has() */ for (c = 'a'; c <= 'z'; c += 4) { g_strlcpy(key, &c, 2); for (i = 0; i < N; i++) test_loop_equal(index_has(&index, key, i), (bool)true, i); test_loop_equal(index_has(&index, key, N), (bool)false, c - 'a'); } test_loop_passed(); /* index_remove() */ for (c = 'a'; c <= 'z'; c += 4) { g_strlcpy(key, &c, 2); for (i = 0; i < N; i++) index_remove(&index, key, i); ie = INDEX_ENTRY(db_find(&index, key)); test_loop_not_equal((void *)ie, NULL, c - 'a'); test_loop_equal(set_size(&ie->ie_set), 0, c - 'a'); } test_loop_passed(); index_remove(&index, "ZZ", 42); test_equal(index.db_size, 26); db_deinit(&index); } static void test_basics() { __test_stress(10); } static void test_stress() { __test_stress(100000); } DECLARE_UNIT_TESTS( UNIT_TEST("Index Entry", test_entry), UNIT_TEST("Index Basics (N = 10)", test_basics), UNIT_TEST("Index Stress (N = 100,000)", test_stress), );