static void http_dd_free(LogPipe *s) { HTTPDestinationDriver *self = (HTTPDestinationDriver *)s; log_template_options_destroy(&self->template_options); g_string_free(self->delimiter, TRUE); g_string_free(self->body_prefix, TRUE); g_string_free(self->body_suffix, TRUE); log_template_unref(self->body_template); curl_global_cleanup(); g_free(self->user); g_free(self->password); g_free(self->user_agent); g_free(self->ca_dir); g_free(self->ca_file); g_free(self->cert_file); g_free(self->key_file); g_free(self->ciphers); g_list_free_full(self->headers, g_free); http_auth_header_free(self->auth_header); g_mutex_free(self->workers_lock); http_load_balancer_free(self->load_balancer); log_threaded_dest_driver_free(s); }
Test(http_loadbalancer, failed_servers_are_reattempted_after_recovery_time) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc[NUM_CLIENTS]; HTTPLoadBalancerTarget *target; http_load_balancer_set_recovery_timeout(lb, 1); _setup_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); http_load_balancer_set_target_failed(lb, &lb->targets[0]); for (gint i = 0; i < G_N_ELEMENTS(lbc); i++) { target = http_load_balancer_choose_target(lb, &lbc[i]); cr_assert(target->state == HTTP_TARGET_OPERATIONAL, "As it seems the test lost its race against the load" "balancer's 1 seconds recovery timeout. You can always bump" "the timeout a bit higher, but hey this loop is 16 iterations" "long, that should be doable in 1 second."); } sleep(1); target = http_load_balancer_choose_target(lb, &lbc[0]); cr_assert(target->state == HTTP_TARGET_FAILED); _teardown_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); http_load_balancer_free(lb); }
Test(http_loadbalancer, number_of_failed_targets_is_tracked_even_if_the_same_target_is_failed_multiple_times) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc; _setup_lb_clients(lb, &lbc, 1); /* make all targets to the failed state */ for (gint i = 0; i < NUM_TARGETS; i++) { HTTPLoadBalancerTarget *target = &lb->targets[i]; http_load_balancer_set_target_failed(lb, target); cr_assert(lb->num_failed_targets == i + 1); http_load_balancer_set_target_failed(lb, target); cr_assert(lb->num_failed_targets == i + 1); http_load_balancer_set_target_successful(lb, target); cr_assert(lb->num_failed_targets == i); http_load_balancer_set_target_successful(lb, target); cr_assert(lb->num_failed_targets == i); http_load_balancer_set_target_failed(lb, target); cr_assert(lb->num_failed_targets == i + 1); } _teardown_lb_clients(lb, &lbc, 1); http_load_balancer_free(lb); }
Test(http_loadbalancer, choose_target_balances_clients_to_targets) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc[NUM_CLIENTS]; gint target_counts[NUM_TARGETS] = {0}; _setup_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); /* count number of workers on each target */ for (gint i = 0; i < G_N_ELEMENTS(lbc); i++) { HTTPLoadBalancerTarget *target = http_load_balancer_choose_target(lb, &lbc[i]); target_counts[target->index]++; } for (gint i = 0; i < NUM_TARGETS; i++) { gint expected_number_of_workers = NUM_CLIENTS / NUM_TARGETS; /* we might have one more client, if the number of workers is not * divisible by the number of targets. The load balancer allocates * the first couple of targets for the excess. */ cr_expect(target_counts[i] - expected_number_of_workers <= 1 && target_counts[i] - expected_number_of_workers >= 0, "The target %d is not balanced, expected_number_of_workers=%d, actual=%d", i, expected_number_of_workers, target_counts[i]); } _teardown_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); http_load_balancer_free(lb); }
Test(http_loadbalancer, target_index_is_set_as_urls_are_added_to_the_array_index) { HTTPLoadBalancer *lb = _construct_load_balancer(); for (gint i = 0; i < lb->num_targets; i++) cr_assert(lb->targets[i].index == i); http_load_balancer_free(lb); }
Test(http_loadbalancer, drop_targets_resets_the_target_list) { HTTPLoadBalancer *lb = _construct_load_balancer(); cr_assert(lb->num_targets != 0); http_load_balancer_drop_all_targets(lb); cr_assert(lb->num_targets == 0); http_load_balancer_free(lb); }
Test(http_loadbalancer, failed_target_is_taken_out_of_rotation) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc[NUM_CLIENTS]; gint target_counts[NUM_TARGETS] = {0}; gint failing_targets = 0; _setup_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); for (gint i = 0; i < G_N_ELEMENTS(lbc); i++) { HTTPLoadBalancerTarget *target = http_load_balancer_choose_target(lb, &lbc[i]); cr_assert(target != NULL); /* fail every second */ if (_should_fail_this_target(target)) { http_load_balancer_set_target_failed(lb, target); failing_targets++; } else http_load_balancer_set_target_successful(lb, target); } /* check that our lbc's still get operational targets */ for (gint i = 0; i < G_N_ELEMENTS(lbc); i++) { HTTPLoadBalancerTarget *target = http_load_balancer_choose_target(lb, &lbc[i]); cr_assert(_should_fail_this_target(target) == FALSE, "HTTPLoadBalancer returned a target that was marked as failed, index=%d", target->index); cr_assert(target->state == HTTP_TARGET_OPERATIONAL); target_counts[target->index]++; } /* check that we balance the load on the remaining targets properly */ for (gint i = 0; i < NUM_TARGETS; i++) { if (_should_fail_this_target(&lb->targets[i])) { cr_expect(lb->targets[i].state == HTTP_TARGET_FAILED); } else { gint expected_number_of_workers = NUM_CLIENTS / (NUM_TARGETS - failing_targets); cr_expect(target_counts[i] - expected_number_of_workers <= 1 && target_counts[i] - expected_number_of_workers >= 0, "The target %d is not balanced, expected_number_of_workers=%d, actual=%d", i, expected_number_of_workers, target_counts[i]); } } _teardown_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); http_load_balancer_free(lb); }
Test(http_loadbalancer, number_of_clients_is_tracked_in_num_clients) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc[NUM_CLIENTS]; for (gint i = 0; i < G_N_ELEMENTS(lbc); i++) { http_lb_client_init(&lbc[i], lb); cr_assert(lb->num_clients == i + 1); } http_load_balancer_free(lb); }
Test(http_loadbalancer, choose_target_selects_the_first_operational_target) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc; http_lb_client_init(&lbc, lb); HTTPLoadBalancerTarget *target = http_load_balancer_choose_target(lb, &lbc); cr_assert(target->url, "http://localhost:8000"); cr_assert(target->state == HTTP_TARGET_OPERATIONAL); http_lb_client_deinit(&lbc); http_load_balancer_free(lb); }
Test(http_loadbalancer, choose_target_tries_to_stay_affine_to_the_current_target) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc[NUM_CLIENTS]; _setup_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); for (gint i = 0; i < G_N_ELEMENTS(lbc); i++) { HTTPLoadBalancerTarget *initial_target = http_load_balancer_choose_target(lb, &lbc[i]); for (gint n = 0; n < 100; n++) { HTTPLoadBalancerTarget *target = http_load_balancer_choose_target(lb, &lbc[i]); cr_assert(initial_target == target); } } _teardown_lb_clients(lb, lbc, G_N_ELEMENTS(lbc)); http_load_balancer_free(lb); }
Test(http_loadbalancer, if_all_targets_fail_the_least_recently_failed_one_is_tried) { HTTPLoadBalancer *lb = _construct_load_balancer(); HTTPLoadBalancerClient lbc; _setup_lb_clients(lb, &lbc, 1); /* make all targets to the failed state */ for (gint i = NUM_TARGETS - 1; i >= 0; i--) { HTTPLoadBalancerTarget *target = &lb->targets[i]; http_load_balancer_set_target_failed(lb, target); sleep(1); } /* check that we get the least recently failed target */ HTTPLoadBalancerTarget *target = http_load_balancer_choose_target(lb, &lbc); cr_assert(target->state != HTTP_TARGET_OPERATIONAL); cr_assert(target->index == NUM_TARGETS - 1); http_load_balancer_set_target_failed(lb, target); target = http_load_balancer_choose_target(lb, &lbc); cr_assert(target->state != HTTP_TARGET_OPERATIONAL); cr_assert(target->index == NUM_TARGETS - 2); http_load_balancer_set_target_failed(lb, target); target = http_load_balancer_choose_target(lb, &lbc); cr_assert(target->state != HTTP_TARGET_OPERATIONAL); cr_assert(target->index == NUM_TARGETS - 3); _teardown_lb_clients(lb, &lbc, 1); http_load_balancer_free(lb); }
Test(http_loadbalancer, construct_and_free) { HTTPLoadBalancer *lb = _construct_load_balancer(); http_load_balancer_free(lb); }