#include #include #include "stellar/stellar.h" #include "stellar/module_manager.h" #include "stellar/session.h" #include "stellar/utils.h" #include "stellar/rtp.h" #include #include "cjson/cJSON.h" #define RTP_TEST_MODULE_NAME "RTP_TEST_MODULE" #define RTP_TEST_RESULT_EXPECT_ENV "RTP_TEST_RESULT_EXPECT" #define RTP_TEST_STELLAR_CONFIG_FILE "RTP_TEST_STELLAR_CONFIG" struct rtp_test_result { cJSON *test_json; cJSON *expect_json; int count; }; struct rtp_test_module_ctx { struct rtp_test_result *result; // depends a single session pcap int rtp_count; }; static void rtp_test_result_add(struct rtp_test_result *result, cJSON *json) { cJSON_AddItemToArray(result->test_json, json); } static void rtp_test_result_compare(struct rtp_test_result *result) { EXPECT_TRUE(result->expect_json != NULL && result->test_json != NULL); int i; int test_result_count, expect_result_count; char *test_str, *expect_str; cJSON *tmp_test, *tmp_expect; /* expect_str = cJSON_Print(result->expect_json); test_str = cJSON_Print(result->test_json); printf("LOAD Raw:\n%s\n", expect_str); printf("TEST Raw:\n%s\n", test_str); */ test_result_count = cJSON_GetArraySize(result->test_json); expect_result_count = cJSON_GetArraySize(result->expect_json); EXPECT_EQ(test_result_count, expect_result_count); for (i = 0; i < MIN(test_result_count, expect_result_count); i++) { tmp_test = cJSON_GetArrayItem(result->test_json, i); tmp_expect = cJSON_GetArrayItem(result->expect_json, i); expect_str = cJSON_Print(tmp_expect); test_str = cJSON_Print(tmp_test); EXPECT_STREQ(expect_str, test_str); free(expect_str); free(test_str); break; } } static void rtp_test_result_exit(struct rtp_test_result *result) { if (result->expect_json) { cJSON_Delete(result->expect_json); } if (result->test_json) { cJSON_Delete(result->test_json); } } static struct rtp_test_result * rtp_test_result_init(void) { long filesize; char *buffer; FILE *file; struct rtp_test_result *result; result = (struct rtp_test_result *)calloc(1, sizeof(struct rtp_test_result)); file = fopen(getenv(RTP_TEST_RESULT_EXPECT_ENV), "rb"); if (file) { fseek(file, 0, SEEK_END); filesize = ftell(file); rewind(file); buffer = (char *)calloc(filesize + 1, 1); fread(buffer, 1, filesize, file); result->expect_json = cJSON_Parse(buffer); free(buffer); fclose(file); } result->test_json = cJSON_CreateArray(); return result; } static const char* rtp_test_rtp_payload_to_string(unsigned char payload_type) { switch (payload_type) { case PT_PCMU: return "PCMU"; case PT_1016: return "1016"; case PT_G721: return "G721"; case PT_GSM: return "GSM"; case PT_G723: return "G723"; case PT_DVI4_8000: return "DVI4_8000"; case PT_DVI4_16000: return "DVI4_16000"; case PT_LPC: return "LPC"; case PT_PCMA: return "PCMA"; case PT_G722: return "G722"; case PT_L16_STEREO: return "L16_STEREO"; case PT_L16_MONO: return "L16_MONO"; case PT_QCELP: return "QCELP"; case PT_CN: return "CN"; case PT_MPA: return "MPA"; case PT_G728: return "G728"; case PT_DVI4_11025: return "DVI4_11025"; case PT_DVI4_22050: return "DVI4_22050"; case PT_G729: return "G729"; case PT_CN_OLD: return "CN_OLD"; case PT_CELB: return "CELB"; case PT_JPEG: return "JPEG"; case PT_NV: return "NV"; case PT_H261: return "H261"; case PT_MPV: return "MPV"; case PT_MP2T: return "MP2T"; case PT_H263: return "H263"; case PT_UNDF_96: return "UNDF_96"; case PT_UNDF_97: return "UNDF_97"; case PT_UNDF_98: return "UNDF_98"; case PT_UNDF_99: return "UNDF_99"; case PT_UNDF_100: return "UNDF_100"; case PT_UNDF_101: return "UNDF_101"; case PT_UNDF_102: return "UNDF_102"; case PT_UNDF_103: return "UNDF_103"; case PT_UNDF_104: return "UNDF_104"; case PT_UNDF_105: return "UNDF_105"; case PT_UNDF_106: return "UNDF_106"; case PT_UNDF_107: return "UNDF_107"; case PT_UNDF_108: return "UNDF_108"; case PT_UNDF_109: return "UNDF_109"; case PT_UNDF_110: return "UNDF_110"; case PT_UNDF_111: return "UNDF_111"; case PT_UNDF_112: return "UNDF_112"; case PT_UNDF_113: return "UNDF_113"; case PT_UNDF_114: return "UNDF_114"; case PT_UNDF_115: return "UNDF_115"; case PT_UNDF_116: return "UNDF_116"; case PT_UNDF_117: return "UNDF_117"; case PT_UNDF_118: return "UNDF_118"; case PT_UNDF_119: return "UNDF_119"; case PT_UNDF_120: return "UNDF_120"; case PT_UNDF_121: return "UNDF_121"; case PT_UNDF_122: return "UNDF_122"; case PT_UNDF_123: return "UNDF_123"; case PT_UNDF_124: return "UNDF_124"; case PT_UNDF_125: return "UNDF_125"; case PT_UNDF_126: return "UNDF_126"; case PT_UNDF_127: return "UNDF_127"; default: return "UNKNOWN"; } return NULL; } static void rtp_test_rtp_callback(struct session *sess, const struct rtp_header *hdr, const char *payload, size_t payload_len, void *arg) { (void)(sess); (void)(payload); struct rtp_test_module_ctx *mod_ctx = (struct rtp_test_module_ctx *)arg; cJSON *json = cJSON_CreateObject(); cJSON_AddNumberToObject(json, "CSRC_LEN", hdr->csrc_len); cJSON_AddNumberToObject(json, "EXTENSION", hdr->extension); cJSON_AddNumberToObject(json, "PADDING", hdr->padding); cJSON_AddNumberToObject(json, "VERSION", hdr->version); cJSON_AddStringToObject(json, "PAYLOAD_TYPE", rtp_test_rtp_payload_to_string(hdr->payload_type)); cJSON_AddNumberToObject(json, "MARKER", hdr->marker); cJSON_AddNumberToObject(json, "SEQ", ntohs(hdr->seq)); cJSON_AddNumberToObject(json, "TIMESTAMP", ntohl(hdr->timestamp)); cJSON_AddNumberToObject(json, "SSRC", ntohl(hdr->ssrc)); cJSON_AddNumberToObject(json, "PAYLOAD_LEN", payload_len); cJSON_AddNumberToObject(json, "PAYLOAD_SEQ", mod_ctx->rtp_count++); rtp_test_result_add(mod_ctx->result, json); return; } extern "C" void rtp_test_exit(struct stellar_module_manager *mod_mgr, struct stellar_module *mod) { struct rtp_test_module_ctx *mod_ctx; if (mod_mgr && mod) { mod_ctx = (struct rtp_test_module_ctx *)stellar_module_get_ctx(mod); if (mod_ctx) { rtp_test_result_compare(mod_ctx->result); rtp_test_result_exit(mod_ctx->result); free(mod_ctx); } stellar_module_free(mod); } } extern "C" struct stellar_module *rtp_test_init(struct stellar_module_manager *mod_mgr) { int ret; struct stellar_module *mod; struct rtp_test_module_ctx *mod_ctx; struct session_manager *sess_mgr; mod_ctx = (struct rtp_test_module_ctx *)calloc(1, sizeof(struct rtp_test_module_ctx)); mod = stellar_module_new(RTP_TEST_MODULE_NAME, mod_ctx); sess_mgr = stellar_module_get_session_manager(mod_mgr); if (mod_mgr == NULL || sess_mgr == NULL) { goto exit; } mod_ctx->result = rtp_test_result_init(); if (mod_ctx->result == NULL) { goto exit; } ret = rtp_subscribe(mod_mgr, rtp_test_rtp_callback, mod_ctx); if (ret < 0) { goto exit; } return mod; exit: printf("rtp_test module init failed!\n"); rtp_test_exit(mod_mgr, mod); return NULL; } TEST(rtp, rtp_module) { struct stellar *st; setenv(RTP_TEST_RESULT_EXPECT_ENV, "./rtp_result.json", 0); st = stellar_new(getenv(RTP_TEST_STELLAR_CONFIG_FILE)); stellar_run(st); stellar_free(st); } int main(int argc, char ** argv) { setenv(RTP_TEST_STELLAR_CONFIG_FILE, "./stellar.toml", 0); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }