diff --git a/main/test.c b/main/test.c index b117c08147e2909895da8d88a01de308713c1121..2abe6988db8a9f9618d7ffa8a93d7f86a5730cda 100644 --- a/main/test.c +++ b/main/test.c @@ -267,21 +267,80 @@ void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state test->state = state; } +/* + * These are the Java reserved words we need to munge so Jenkins + * doesn't barf on them. + */ +static char *reserved_words[] = { + "abstract", "arguments", "as", "assert", "await", + "boolean", "break", "byte", "case", "catch", "char", "class", + "const", "continue", "debugger", "def", "default", "delete", "do", + "double", "else", "enum", "eval", "export", "extends", "false", + "final", "finally", "float", "for", "function", "goto", "if", + "implements", "import", "in", "instanceof", "int", "interface", + "let", "long", "native", "new", "null", "package", "private", + "protected", "public", "return", "short", "static", "strictfp", + "string", "super", "switch", "synchronized", "this", "throw", "throws", + "trait", "transient", "true", "try", "typeof", "var", "void", + "volatile", "while", "with", "yield" }; + +static int is_reserved_word(const char *word) +{ + int i; + + for (i = 0; i < ARRAY_LEN(reserved_words); i++) { + if (strcmp(word, reserved_words[i]) == 0) { + return 1; + } + } + + return 0; +} + static void test_xml_entry(struct ast_test *test, FILE *f) { - if (!f || !test || test->state == AST_TEST_NOT_RUN) { + /* We need a copy of the category skipping past the initial '/' */ + char *test_cat = ast_strdupa(test->info.category + 1); + char *next_cat; + char *test_name = (char *)test->info.name; + struct ast_str *category = ast_str_create(strlen(test->info.category) + 32); + + if (!category || test->state == AST_TEST_NOT_RUN) { + ast_free(category); + return; } - fprintf(f, "\t<testcase time=\"%u.%u\" name=\"%s%s\"%s>\n", + while ((next_cat = ast_strsep(&test_cat, '/', AST_STRSEP_TRIM))) { + char *prefix = ""; + + if (is_reserved_word(next_cat)) { + prefix = "_"; + } + ast_str_append(&category, 0, ".%s%s", prefix, next_cat); + } + test_cat = ast_str_buffer(category); + /* Skip past the initial '.' */ + test_cat++; + + if (is_reserved_word(test->info.name)) { + size_t name_length = strlen(test->info.name) + 2; + + test_name = ast_alloca(name_length); + snprintf(test_name, name_length, "_%s", test->info.name); + } + + fprintf(f, "\t\t<testcase time=\"%u.%u\" classname=\"%s\" name=\"%s\"%s>\n", test->time / 1000, test->time % 1000, - test->info.category, test->info.name, + test_cat, test_name, test->state == AST_TEST_PASS ? "/" : ""); + ast_free(category); + if (test->state == AST_TEST_FAIL) { - fprintf(f, "\t\t<failure><![CDATA[\n%s\n\t\t]]></failure>\n", + fprintf(f, "\t\t\t<failure><![CDATA[\n%s\n\t\t]]></failure>\n", S_OR(ast_str_buffer(test->status_str), "NA")); - fprintf(f, "\t</testcase>\n"); + fprintf(f, "\t\t</testcase>\n"); } } @@ -473,13 +532,14 @@ static int test_generate_results(const char *name, const char *category, const c * http://confluence.atlassian.com/display/BAMBOO/JUnit+parsing+in+Bamboo */ fprintf(f_xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - fprintf(f_xml, "<testsuite errors=\"0\" time=\"%u.%u\" tests=\"%u\" " + fprintf(f_xml, "<testsuites>\n"); + fprintf(f_xml, "\t<testsuite errors=\"0\" time=\"%u.%u\" tests=\"%u\" " "name=\"AsteriskUnitTests\">\n", last_results.total_time / 1000, last_results.total_time % 1000, last_results.total_tests); - fprintf(f_xml, "\t<properties>\n"); - fprintf(f_xml, "\t\t<property name=\"version\" value=\"%s\"/>\n", ast_get_version()); - fprintf(f_xml, "\t</properties>\n"); + fprintf(f_xml, "\t\t<properties>\n"); + fprintf(f_xml, "\t\t\t<property name=\"version\" value=\"%s\"/>\n", ast_get_version()); + fprintf(f_xml, "\t\t</properties>\n"); } /* txt header information */ @@ -517,7 +577,8 @@ static int test_generate_results(const char *name, const char *category, const c done: if (f_xml) { - fprintf(f_xml, "</testsuite>\n"); + fprintf(f_xml, "\t</testsuite>\n"); + fprintf(f_xml, "</testsuites>\n"); fclose(f_xml); } if (f_txt) {