#ifndef _GTEST_UTILS_H #define _GTEST_UTILS_H #include #ifdef __cplusplus extern "C" { #endif #include #include "sce.h" #include "log.h" #include "vxlan.h" #include "packet_io.h" #include "sf_metrics.h" #include "health_check.h" #include "global_metrics.h" #include "gmock_marsio.h" #define set_metadata(meta, id, offset, is_ctrl, is_decrypt) \ { \ memset(&meta, 0, sizeof(meta)); \ meta.session_id = id; \ meta.raw_data = NULL; \ meta.raw_len = 0; \ meta.l7offset = offset; \ meta.direction = 0; \ meta.is_ctrl_pkt = is_ctrl; \ meta.is_decrypted = is_decrypt; \ memset(&meta.sids.elems, 1, sizeof(meta.sids.elems)); \ meta.sids.num = 8; \ memset(&meta.route_ctx.data, 1, 64); \ meta.route_ctx.len = 64; \ } #define build_mbuf_for_inject_pkt(mbuf, data, len) \ { \ marsio_buff_malloc_global(NULL, &mbuf, 1, 0, 0); \ char *ptr = marsio_buff_append(mbuf, len); \ EXPECT_TRUE(ptr != nullptr); \ memcpy(ptr, data, len); \ } #define build_mbuf_for_data_pkt(mbuf, data, len, id, is_decrypt) \ { \ struct metadata meta; \ set_metadata(meta, id, 0, 0, is_decrypt); \ marsio_buff_malloc_global(NULL, &mbuf, 1, 0, 0); \ EXPECT_TRUE(mbuff_set_metadata(mbuf, &meta) == 0); \ char *ptr = marsio_buff_append(mbuf, len); \ EXPECT_TRUE(ptr != nullptr); \ memcpy(ptr, data, len); \ } #define build_mbuf_for_ctrl_pkt(mbuf, data, len, id, offset) \ { \ struct metadata meta; \ set_metadata(meta, id, offset, 1, 0); \ marsio_buff_malloc_global(NULL, &mbuf, 1, 0, 0); \ EXPECT_TRUE(mbuff_set_metadata(mbuf, &meta) == 0); \ char *ptr = marsio_buff_append(mbuf, len); \ EXPECT_TRUE(ptr != nullptr); \ memcpy(ptr, data, len); \ } struct gtest_frame { struct sce_ctx *sce_ctx; char *json_file; char *desc; }; inline struct gtest_frame *gtest_frame_new(const char *json_file, const char *desc) { char cmdline[1024] = {0}; const char *profile = "./conf/sce.conf"; struct sce_ctx *sce_ctx = NULL; struct thread_ctx *thread_ctx = NULL; struct gtest_frame *instance = (struct gtest_frame *)calloc(1, sizeof(struct gtest_frame)); system("rm -rf `ls log/* | egrep -v '(*_ok.fs2)'`"); memset(&cmdline, 0, sizeof(cmdline)); snprintf(cmdline, sizeof(cmdline), "sed -i \"s/json_cfg_file=.*/json_cfg_file=resource\\/%s/\" ./conf/sce.conf", json_file); system(cmdline); EXPECT_TRUE(LOG_INIT("./conf/zlog.conf") == 0); health_check_session_init(profile); sce_ctx = sce_ctx_create(profile); EXPECT_TRUE(sce_ctx != nullptr); thread_ctx = &sce_ctx->work_threads[0]; thread_ctx->tid = 0; thread_ctx->thread_index = 0; thread_ctx->session_table = session_table_create(); thread_ctx->sf_metrics = sf_metrics_create(profile); thread_ctx->ref_io = sce_ctx->io; thread_ctx->ref_global_metrics = sce_ctx->metrics; thread_ctx->ref_enforcer = sce_ctx->enforcer; thread_ctx->ref_sce_ctx = sce_ctx; thread_ctx->session_table_need_reset = 0; EXPECT_TRUE(packet_io_init(sce_ctx->io, thread_ctx) == 0); instance->sce_ctx = sce_ctx; instance->json_file = strdup(json_file); instance->desc = strdup(desc); return instance; } inline void gtest_frame_free(struct gtest_frame *instance) { if (instance) { struct sce_ctx *sce_ctx = instance->sce_ctx; struct thread_ctx *thread_ctx = &sce_ctx->work_threads[0]; session_table_destory(thread_ctx->session_table); sf_metrics_destory(thread_ctx->sf_metrics); sce_ctx_destory(sce_ctx); LOG_CLOSE(); if (instance->json_file) { free(instance->json_file); instance->json_file = NULL; } if (instance->desc) { free(instance->desc); instance->desc = NULL; } free(instance); instance = NULL; } } inline void gtest_frame_run(struct gtest_frame *instance, marsio_buff_t *tx_mbuf, marsio_buff_t *expect_rx_mbuf, int is_poll_nf) { marsio_buff_t *rx_mbuf; struct sce_ctx *sce_ctx = instance->sce_ctx; struct thread_ctx *thread_ctx = &sce_ctx->work_threads[0]; struct mr_instance *mr_instance = packet_io_get_mr_instance(sce_ctx->io); marsio_set_recv_mbuff(mr_instance, tx_mbuf); if (is_poll_nf) { EXPECT_TRUE(packet_io_polling_nf(sce_ctx->io, thread_ctx) == 1); } else { EXPECT_TRUE(packet_io_polling_endpoint_l3(sce_ctx->io, thread_ctx) == 1); } rx_mbuf = marsio_get_send_mbuff(mr_instance); EXPECT_TRUE(marsio_mbuff_cmp(rx_mbuf, expect_rx_mbuf) == 0); } inline void gtest_frame_log(struct gtest_frame *instance) { struct stat temp_stat; char diffile[1024] = {0}; char cmdline[1024] = {0}; struct sce_ctx *sce_ctx = instance->sce_ctx; struct thread_ctx *thread_ctx = &sce_ctx->work_threads[0]; for (int i = 0; i < 10; i++) { global_metrics_update(sce_ctx->metrics, &thread_ctx->thread_metrics, thread_ctx->thread_index); global_metrics_dump(sce_ctx->metrics); usleep(1); } memset(&cmdline, 0, sizeof(cmdline)); snprintf(cmdline, sizeof(cmdline), "cp log/sce.fs2 log/test_%s.fs2", instance->desc); system(cmdline); memset(&cmdline, 0, sizeof(cmdline)); snprintf(cmdline, sizeof(cmdline), "diff -I '===' log/test_%s.fs2 log/test_%s_ok.fs2 > log/test_%s.diff", instance->desc, instance->desc, instance->desc); int ret = system(cmdline); printf("exec %s, return: %d\n", cmdline, ret); memset(&diffile, 0, sizeof(diffile)); snprintf(diffile, sizeof(diffile), "log/test_%s.diff", instance->desc); stat(diffile, &temp_stat); EXPECT_TRUE(temp_stat.st_size == 0); memset(&cmdline, 0, sizeof(cmdline)); snprintf(cmdline, sizeof(cmdline), "cp log/sce.log* log/test_%s.log", instance->desc); system(cmdline); } inline int mbuff_cmp_payload(marsio_buff_t *buff, marsio_buff_t *vxlan_pkt) { struct vxlan_hdr *vxlan_hdr = NULL; int buff_len = marsio_buff_datalen(buff); char *buff_data = marsio_buff_mtod(buff); int vxlan_pkt_len = marsio_buff_datalen(vxlan_pkt); char *vxlan_pkt_data = marsio_buff_mtod(vxlan_pkt); if (buff_len + 50 != vxlan_pkt_len) { goto error_out; } if (vxlan_frame_decode(&vxlan_hdr, vxlan_pkt_data, vxlan_pkt_len) != 0) { goto error_out; } if (memcmp(buff_data, vxlan_pkt_data + 50, buff_len) != 0) { goto error_out; } return 0; error_out: return 1; } #ifdef __cplusplus } #endif #endif