diff options
| author | 刘畅 <[email protected]> | 2023-12-06 08:52:47 +0000 |
|---|---|---|
| committer | 刘畅 <[email protected]> | 2023-12-06 08:52:47 +0000 |
| commit | fe477349056d0797a5b1ca29556ee7689826b332 (patch) | |
| tree | 6ef77e9a4b8c54a515928bc7f5c19fd5527e775f | |
| parent | a5923348e98e0a312826d12c92beef20f702a0ca (diff) | |
| parent | 29cd6942c133fad7c38a75e22e1cadea726ec89f (diff) | |
Merge branch 'fixbug_fairness_profile_unlimited_token' into 'rel'
修复fairness类型profile限不住速并添加相应测试例
See merge request tango/shaping-engine!58
| -rw-r--r-- | shaping/src/shaper.cpp | 39 | ||||
| -rw-r--r-- | shaping/test/gtest_shaper.cpp | 81 | ||||
| -rw-r--r-- | shaping/test/stub.cpp | 7 | ||||
| -rw-r--r-- | shaping/test/stub.h | 1 |
4 files changed, 119 insertions, 9 deletions
diff --git a/shaping/src/shaper.cpp b/shaping/src/shaper.cpp index 170a235..55f32fb 100644 --- a/shaping/src/shaper.cpp +++ b/shaping/src/shaper.cpp @@ -465,13 +465,36 @@ END: return; } -static void shaper_deposit_token_sub(struct shaping_profile_hash_node *pf_hash_node, int req_token_bits, unsigned char direction, int priority) +static void shaper_deposit_token_sub(struct shaping_profile_info *profile, int req_token_bits, unsigned char direction, int priority) { - if (direction == SHAPING_DIR_IN) { - pf_hash_node->in_deposit_token_bits[priority] -= req_token_bits; - } else { - pf_hash_node->out_deposit_token_bits[priority] -= req_token_bits; + int *deposit_token; + struct shaping_profile_hash_node *pf_hash_node = profile->hash_node; + + switch (profile->type) { + case PROFILE_TYPE_GENERIC: + if (direction == SHAPING_DIR_IN) { + deposit_token = &pf_hash_node->in_deposit_token_bits[priority]; + } else { + deposit_token = &pf_hash_node->out_deposit_token_bits[priority]; + } + break; + case PROFILE_TYPE_HOST_FARINESS: + case PROFILE_TYPE_MAX_MIN_HOST_FAIRNESS: + case PROFILE_TYPE_SPLIT_BY_LOCAL_HOST: + if (direction == SHAPING_DIR_IN) { + deposit_token = &profile->in_deposit_token_bits; + } else { + deposit_token = &profile->out_deposit_token_bits; + } + break; + default: + LOG_ERROR("%s: invalid profile type %d, profile id %d", LOG_TAG_SHAPING, profile->type, profile->id); + return; } + + *deposit_token -= req_token_bits; + + return; } static int shaper_deposit_token_is_enough(struct shaping_profile_info *profile, int req_token_bits, unsigned char direction, int priority) @@ -551,7 +574,7 @@ static int shaper_token_get_from_profile(struct shaping_thread_ctx *ctx, struct } if (shaper_deposit_token_is_enough(pf_info, req_token_bits, direction, pf_info->priority)) { - shaper_deposit_token_sub(pf_info->hash_node, req_token_bits, direction, pf_info->priority); + shaper_deposit_token_sub(pf_info, req_token_bits, direction, pf_info->priority); return SHAPER_TOKEN_GET_SUCCESS; } @@ -695,7 +718,7 @@ static int shaper_token_consume(struct shaping_thread_ctx *ctx, struct shaping_f shaper_profile_hash_node_update(profile); if (shaper_deposit_token_is_enough(profile, req_token_bytes * 8, direction, profile->priority)) { - shaper_deposit_token_sub(profile->hash_node, req_token_bytes * 8, direction, profile->priority); + shaper_deposit_token_sub(profile, req_token_bytes * 8, direction, profile->priority); return SHAPER_TOKEN_GET_SUCCESS; } @@ -962,7 +985,7 @@ static void shaper_token_consume_force(struct shaping_flow *sf, struct metadata for (int i = 0; i < sf->rule_num; i++) { rule = &sf->matched_rule_infos[i]; shaper_profile_hash_node_update(&rule->primary); - shaper_deposit_token_sub(rule->primary.hash_node, meta->raw_len * 8, meta->dir, rule->primary.priority); + shaper_deposit_token_sub(&rule->primary, meta->raw_len * 8, meta->dir, rule->primary.priority); } return; diff --git a/shaping/test/gtest_shaper.cpp b/shaping/test/gtest_shaper.cpp index 8196ed2..8c120d9 100644 --- a/shaping/test/gtest_shaper.cpp +++ b/shaping/test/gtest_shaper.cpp @@ -303,6 +303,85 @@ TEST(single_session, udp_tx_in_order) /*session1 match rule1 rule1: profile: limit 1000*/ +TEST(max_min_host_fairness_profile, udp_tx_in_order) +{ + struct stub_pkt_queue expec_tx_queue; + struct stub_pkt_queue *actual_tx_queue; + struct shaping_ctx *ctx = NULL; + struct shaping_flow *sf = NULL; + long long rule_id[] = {0}; + int priority[] = {1}; + int profile_num[] = {1}; + int profile_id[][MAX_REF_PROFILE] = {{0}}; + + TAILQ_INIT(&expec_tx_queue); + stub_init(); + ctx = shaping_engine_init(); + ASSERT_TRUE(ctx != NULL); + sf = shaping_flow_new(&ctx->thread_ctx[0]); + ASSERT_TRUE(sf != NULL); + + stub_set_matched_shaping_rules(1, rule_id, priority, profile_num, profile_id); + stub_set_token_bucket_avl_per_sec(0, 1000, SHAPING_DIR_OUT); + stub_set_profile_type(0, PROFILE_TYPE_MAX_MIN_HOST_FAIRNESS); + actual_tx_queue = stub_get_tx_queue(); + shaper_rules_update(&ctx->thread_ctx[0], sf, rule_id, 1); + + + /**********send packets*********************/ + send_packets(&ctx->thread_ctx[0], sf, 100, 100, SHAPING_DIR_OUT, &expec_tx_queue, 1, 0); + /*******************************************/ + + //first 10 packets + ASSERT_EQ(0, judge_packet_eq(&expec_tx_queue, actual_tx_queue, 10)); + ASSERT_TRUE(TAILQ_EMPTY(actual_tx_queue)); + + while (!TAILQ_EMPTY(&expec_tx_queue)) {//last 90 delay packets + stub_refresh_token_bucket(0); + for (int i = 0; i < 20; i++) {//even though invoke polling more than 10 times, there should be only 10 pkts be sent + polling_entry(ctx->thread_ctx[0].sp, ctx->thread_ctx[0].stat, &ctx->thread_ctx[0]); + stub_curr_time_ns_inc(STUB_TIME_INC_FOR_PACKET); + } + ASSERT_EQ(0, judge_packet_eq(&expec_tx_queue, actual_tx_queue, 10)); + ASSERT_TRUE(TAILQ_EMPTY(actual_tx_queue)); + } + + shaping_flow_free(&ctx->thread_ctx[0], sf); + fieldstat_global_disable_prometheus_endpoint(); + + /***********send stat data here********************/ + fieldstat_dynamic_passive_output(ctx->stat->instance);//send metric manualy + shaper_global_stat_refresh(ctx->global_stat); + + shaper_thread_resource_clear(); + shaping_engine_destroy(ctx); + + stub_clear_matched_shaping_rules(); + + /*******test statistics***********/ + sleep(2);//wait telegraf to output + FILE *stat_file; + + //judge shaping metric + stat_file = fopen(SHAPING_STAT_FILE_NAME, "r"); + memset(line, 0, sizeof(line)); + ASSERT_TRUE(NULL != fgets(line, sizeof(line), stat_file)); + shaping_stat_judge(line, 0, 0, 1, 100, 10000, 0, 0, 170000, SHAPING_DIR_OUT, profile_type_primary);//max latency is last 10 pkts + fclose(stat_file); + stat_file = fopen(SHAPING_STAT_FILE_NAME, "w");//clear stat file + fclose(stat_file); + + //judge shaping global metric + stat_file = fopen(SHAPING_GLOBAL_STAT_FILE_NAME, "r"); + memset(line, 0, sizeof(line)); + ASSERT_TRUE(NULL != fgets(line, sizeof(line), stat_file)); + shaping_global_stat_judge(line, 100, 10000, 0, 0, 0, 0); + fclose(stat_file); +} + +/*session1 match rule1 + rule1: + profile: limit 1000*/ TEST(single_session, tcp_tx_in_order) { struct stub_pkt_queue expec_tx_queue; @@ -1595,6 +1674,6 @@ TEST(statistics, udp_queueing_pkt) int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); - //testing::GTEST_FLAG(filter) = "single_session.tcp_tx_in_order"; + //testing::GTEST_FLAG(filter) = "max_min_host_fairness_profile.udp_tx_in_order"; return RUN_ALL_TESTS(); }
\ No newline at end of file diff --git a/shaping/test/stub.cpp b/shaping/test/stub.cpp index 293ef3c..f3c89e5 100644 --- a/shaping/test/stub.cpp +++ b/shaping/test/stub.cpp @@ -84,6 +84,12 @@ void stub_refresh_token_bucket(int profile_id) return; } +void stub_set_profile_type(int profile_id, enum shaping_profile_type type) +{ + pf_array[profile_id].type = type; + return; +} + void stub_set_async_token_get_times(int profile_id, int times) { pf_async_times[profile_id] = times; @@ -419,6 +425,7 @@ void swarmkv_tconsume(struct swarmkv * db, const char * key, size_t keylen, long void swarmkv_ftconsume(struct swarmkv * db, const char * key, size_t keylen, const char * member, size_t member_len, long long weight, long long tokens, swarmkv_on_reply_callback_t *cb, void *cb_arg) { + swarmkv_tconsume(db, key, keylen, tokens, cb, cb_arg); return; } diff --git a/shaping/test/stub.h b/shaping/test/stub.h index 48b9b0b..f7119d2 100644 --- a/shaping/test/stub.h +++ b/shaping/test/stub.h @@ -31,6 +31,7 @@ TAILQ_HEAD(stub_pkt_queue, stub_packet_node); void stub_set_token_bucket_avl_per_sec(int profile_id, unsigned int tokens, unsigned char direction); void stub_refresh_token_bucket(int profile_id); +void stub_set_profile_type(int profile_id, enum shaping_profile_type type); void stub_set_async_token_get_times(int profile_id, int times); void stub_set_matched_shaping_rules(int rule_num, long long *rule_id, const int *priority, const int *profile_num, int profile_id[][MAX_REF_PROFILE]); |
