END_TEST START_TEST(test_mgr_clear) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "dub2", NULL); fail_unless(res == 0); res = filtmgr_unmap_filter(mgr, "dub2"); fail_unless(res == 0); // Should be not proxied still res = filtmgr_clear_filter(mgr, "dub2"); fail_unless(res == 0); // Force a vacuum filtmgr_vacuum(mgr); res = filtmgr_create_filter(mgr, "dub2", NULL); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "dub2"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_list_cold) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab6", NULL); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab7", NULL); fail_unless(res == 0); bloom_filter_list_head *head; res = filtmgr_list_cold_filters(mgr, &head); fail_unless(res == 0); fail_unless(head->size == 0); // Check the keys in one, so that it stays hot char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab6", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); // Check cold again res = filtmgr_list_cold_filters(mgr, &head); fail_unless(res == 0); fail_unless(head->size == 1); int has_zab6 = 0; int has_zab7 = 0; bloom_filter_list *node = head->head; while (node) { if (strcmp(node->filter_name, "zab6") == 0) has_zab6 = 1; else if (strcmp(node->filter_name, "zab7") == 0) has_zab7 = 1; node = node->next; } fail_unless(!has_zab6); fail_unless(has_zab7); res = filtmgr_drop_filter(mgr, "zab6"); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "zab7"); fail_unless(res == 0); filtmgr_cleanup_list(head); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_clear_reload) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab9", NULL); fail_unless(res == 0); // Try to add keys now char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab9", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_unmap_filter(mgr, "zab9"); fail_unless(res == 0); // F*****G annoying umask permissions bullshit // Cused by the Check test framework fail_unless(chmod("/tmp/bloomd/bloomd.zab9/config.ini", 0777) == 0); fail_unless(chmod("/tmp/bloomd/bloomd.zab9/data.000.mmap", 0777) == 0); res = filtmgr_clear_filter(mgr, "zab9"); fail_unless(res == 0); // Force a vacuum filtmgr_vacuum(mgr); // This should rediscover res = filtmgr_create_filter(mgr, "zab9", NULL); fail_unless(res == 0); // Try to check keys now res = filtmgr_check_keys(mgr, "zab9", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "zab9"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_list_prefix) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, 0, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "bar1", NULL); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "bar2", NULL); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zyx", NULL); fail_unless(res == 0); bloom_filter_list_head *head; res = filtmgr_list_filters(mgr, "bar", &head); fail_unless(res == 0); fail_unless(head->size == 2); int has_bar1 = 0; int has_bar2 = 0; bloom_filter_list *node = head->head; while (node) { if (strcmp(node->filter_name, "bar1") == 0) has_bar1 = 1; else if (strcmp(node->filter_name, "bar2") == 0) has_bar2 = 1; node = node->next; } fail_unless(has_bar1); fail_unless(has_bar2); res = filtmgr_drop_filter(mgr, "bar1"); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "bar2"); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "zyx"); fail_unless(res == 0); filtmgr_cleanup_list(head); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Scale up */ START_TEST(test_mgr_grow) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); config.in_memory = 1; config.initial_capacity = 10000; bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "scale1", NULL); fail_unless(res == 0); // Try to add keys now char *keys[10]; char result[10]; for (int iter=0;iter<10000;iter++) { // Generate the keys for (int i=0;i<10;i++) asprintf(&keys[i], "test_key_%d", i*iter); res = filtmgr_set_keys(mgr, "scale1", (char**)&keys, 10, (char*)&result); fail_unless(res == 0); for (int i=0;i<10;i++) free(keys[i]); } res = filtmgr_drop_filter(mgr, "scale1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Custom config */ START_TEST(test_mgr_create_custom_config) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); // Custom config bloom_config *custom = malloc(sizeof(bloom_config)); memcpy(custom, &config, sizeof(bloom_config)); custom->in_memory = 1; res = filtmgr_create_filter(mgr, "custom1", custom); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "custom1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_check_no_keys) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab2", NULL); fail_unless(res == 0); char *keys[] = {"hey","there","person"}; char result[] = {1, 1, 1}; res = filtmgr_check_keys(mgr, "zab2", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(!result[0]); fail_unless(!result[1]); fail_unless(!result[2]); res = filtmgr_drop_filter(mgr, "zab2"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Close & Restore */ START_TEST(test_mgr_restore) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab8", NULL); fail_unless(res == 0); char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab8", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); // Shutdown res = destroy_filter_manager(mgr); fail_unless(res == 0); // F*****G annoying umask permissions bullshit // Cused by the Check test framework fail_unless(chmod("/tmp/bloomd/bloomd.zab8/config.ini", 0777) == 0); fail_unless(chmod("/tmp/bloomd/bloomd.zab8/data.000.mmap", 0777) == 0); // Restrore res = init_filter_manager(&config, &mgr); fail_unless(res == 0); for (int i=0;i<3;i++) result[i] = 0; res = filtmgr_check_keys(mgr, "zab8", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "zab8"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Unmap in memory */ START_TEST(test_mgr_unmap_in_mem) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); config.in_memory = 1; bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "mem1", NULL); fail_unless(res == 0); // Try to add keys now char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "mem1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_unmap_filter(mgr, "mem1"); fail_unless(res == 0); // Try to add keys now for (int i=0;i<3;i++) result[i] = 0; res = filtmgr_check_keys(mgr, "mem1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "mem1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_create_drop) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "foo1", NULL); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "foo1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_add_check_keys) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, 0, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab1", NULL); fail_unless(res == 0); char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); for (int i=0;i<3;i++) result[i] = 0; res = filtmgr_check_keys(mgr, "zab1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "zab1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
/** * Internal command used to handle filter creation. */ static void handle_create_cmd(bloom_conn_handler *handle, char *args, int args_len) { // If we have no args, complain. if (!args) { handle_client_err(handle->conn, (char*)&FILT_NEEDED, FILT_NEEDED_LEN); return; } // Scan for options after the filter name char *options; int options_len; int res = buffer_after_terminator(args, args_len, ' ', &options, &options_len); // Verify the filter name is valid char *filter_name = args; if (regexec(&VALID_FILTER_NAMES_RE, filter_name, 0, NULL, 0) != 0) { handle_client_err(handle->conn, (char*)&BAD_FILT_NAME, BAD_FILT_NAME_LEN); return; } // Parse the options bloom_config *config = NULL; int err = 0; if (res == 0) { // Make a new config store, copy the current config = malloc(sizeof(bloom_config)); memcpy(config, handle->config, sizeof(bloom_config)); // Parse any options char *param = options; while (param) { // Adds a zero terminator to the current param, scans forward buffer_after_terminator(options, options_len, ' ', &options, &options_len); // Check for the custom params int match = 0; match |= sscanf(param, "capacity=%llu", (unsigned long long*)&config->initial_capacity); match |= sscanf(param, "prob=%lf", &config->default_probability); match |= sscanf(param, "in_memory=%d", &config->in_memory); // Check if there was no match if (!match) { err = 1; handle_client_err(handle->conn, (char*)&BAD_ARGS, BAD_ARGS_LEN); break; } // Advance to the next param param = options; } // Validate the params int invalid_config = 0; invalid_config |= sane_initial_capacity(config->initial_capacity); invalid_config |= sane_default_probability(config->default_probability); invalid_config |= sane_in_memory(config->in_memory); // Barf if the configs are bad if (invalid_config) { err = 1; handle_client_err(handle->conn, (char*)&BAD_ARGS, BAD_ARGS_LEN); } } // Clean up an leave on errors if (err) { if (config) free(config); return; } // Create a new filter res = filtmgr_create_filter(handle->mgr, filter_name, config); switch (res) { case 0: handle_client_resp(handle->conn, (char*)DONE_RESP, DONE_RESP_LEN); break; case -1: handle_client_resp(handle->conn, (char*)EXISTS_RESP, EXISTS_RESP_LEN); if (config) free(config); break; case -3: handle_client_resp(handle->conn, (char*)DELETE_IN_PROGRESS, DELETE_IN_PROGRESS_LEN); if (config) free(config); break; default: INTERNAL_ERROR(); if (config) free(config); break; } }