From: Tomas Mlcoch Date: Sun, 26 May 2013 12:22:20 +0000 (+0200) Subject: xml_parser: More tests for xml_parser_filelists. X-Git-Tag: upstream/0.2.1~165 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=06e62cc18a58a6224270fe98e53263e42e8a840a;p=services%2Fcreaterepo_c.git xml_parser: More tests for xml_parser_filelists. --- diff --git a/src/xml_parser.c b/src/xml_parser.c index 9cdccf1..67255c3 100644 --- a/src/xml_parser.c +++ b/src/xml_parser.c @@ -5,23 +5,29 @@ #include "misc.h" cr_ParserData * -cr_xml_parser_data() +cr_xml_parser_data(unsigned int numstates) { cr_ParserData *pd = g_new0(cr_ParserData, 1); pd->ret = CRE_OK; pd->content = g_malloc(CONTENT_REALLOC_STEP); pd->acontent = CONTENT_REALLOC_STEP; pd->msgs = g_string_new(0); + pd->swtab = g_malloc0(sizeof(cr_StatesSwitch *) * numstates); + pd->sbtab = g_malloc(sizeof(unsigned int) * numstates); return pd; } -void +char * cr_xml_parser_data_free(cr_ParserData *pd) { + char *msgs; g_free(pd->content); - g_string_free(pd->msgs, TRUE); + msgs = g_string_free(pd->msgs, FALSE); + g_free(pd->swtab); + g_free(pd->sbtab); g_free(pd); + return msgs; } void XMLCALL @@ -37,7 +43,6 @@ cr_char_handler(void *pdata, const XML_Char *s, int len) if (!pd->docontent) return; /* Do not store the content */ - /* XXX: TODO: Maybe rewrite this reallocation step */ l = pd->lcontent + len + 1; if (l > pd->acontent) { pd->acontent = l + CONTENT_REALLOC_STEP; diff --git a/src/xml_parser.h b/src/xml_parser.h index 1ecec4e..5863afd 100644 --- a/src/xml_parser.h +++ b/src/xml_parser.h @@ -62,6 +62,8 @@ typedef int (*cr_XmlParserNewPkgCb)(cr_Package **pkg, void *cbdata, GError **err); +/** Default callback for the new package. + */ int cr_newpkgcb(cr_Package **pkg, const char *pkgId, const char *name, @@ -69,14 +71,28 @@ int cr_newpkgcb(cr_Package **pkg, void *cbdata, GError **err); +/** Parse filelists.xml. File could be compressed. + * @param path Path to filelists.xml (plain or compressed) + * @param newpkgcb Callback for new package (Called when new package + * xml chunk is found and package object to store + * the data is needed). If NULL cr_newpkgcb is used. + * @param newpkgcb_data User data for the newpkgcb. + * @param pkgcb Package callback. (Called when complete package + * xml chunk is parsed.). Could be NULL if newpkgcb is + * not NULL. + * @param pkgcb_data User data for the pkgcb. + * @param messages Pointer to char* where messages (warnings) + * from parsing will be stored. + * @param err GError ** + * @return cr_Error code. + */ int cr_xml_parse_filelists(const char *path, cr_XmlParserNewPkgCb newpkgcb, void *newpkgcb_data, cr_XmlParserPkgCb pkgcb, void *pkgcb_data, + char **messages, GError **err); - - /** @} */ #ifdef __cplusplus diff --git a/src/xml_parser_filelists.c b/src/xml_parser_filelists.c index 5d3d382..fc4d6cd 100644 --- a/src/xml_parser_filelists.c +++ b/src/xml_parser_filelists.c @@ -73,7 +73,6 @@ cr_start_handler(void *pdata, const char *element, const char **attr) if (!pd->swtab[pd->state]) return; // Current element should not have any sub elements - /* TODO TEST THIS */ if (!pd->pkg && pd->state != STATE_FILELISTS && pd->state != STATE_START) return; // Do not parse current package tag and its content @@ -97,18 +96,21 @@ cr_start_handler(void *pdata, const char *element, const char **attr) break; case STATE_PACKAGE: { - /* TODO: Parse all attrs in single loop instead of use cr_find_attr */ const char *pkgId = cr_find_attr("pkgid", attr); const char *name = cr_find_attr("name", attr); const char *arch = cr_find_attr("arch", attr); + if (!pkgId) { + // Package without a pkgid attr is error pd->ret = CRE_BADXMLFILELISTS; - g_set_error(pd->err, CR_XML_PARSER_FIL_ERROR, CRE_BADXMLFILELISTS, + g_set_error(&pd->err, CR_XML_PARSER_FIL_ERROR, CRE_BADXMLFILELISTS, "Package pkgid attributte is missing!"); break; } + // Get package object to store current package or NULL if + // current XML package element shoud be skipped/ignored. if (pd->newpkgcb(&pd->pkg, pkgId, name, @@ -118,20 +120,40 @@ cr_start_handler(void *pdata, const char *element, const char **attr) { pd->ret = CRE_CBINTERRUPTED; if (tmp_err) - g_propagate_prefixed_error(pd->err, + g_propagate_prefixed_error(&pd->err, tmp_err, "Parsing interrupted:"); else - g_set_error(pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED, + g_set_error(&pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED, "Parsing interrupted"); } - /* TODO: Insert name and pkg id to the package */ + if (pd->pkg) { + if (!pd->pkg->pkgId) + pd->pkg->pkgId = g_string_chunk_insert(pd->pkg->chunk, pkgId); + if (!pd->pkg->name && name) + pd->pkg->name = g_string_chunk_insert(pd->pkg->chunk, name); + if (!pd->pkg->arch && arch) + pd->pkg->arch = g_string_chunk_insert(pd->pkg->chunk, arch); + } break; } case STATE_VERSION: - /* TODO: Parse version */ + if (!pd->pkg) + break; + + // Version string insert only if them don't already exists + + if (!pd->pkg->epoch) + pd->pkg->epoch = cr_safe_string_chunk_insert(pd->pkg->chunk, + cr_find_attr("epoch", attr)); + if (!pd->pkg->version) + pd->pkg->version = cr_safe_string_chunk_insert(pd->pkg->chunk, + cr_find_attr("ver", attr)); + if (!pd->pkg->release) + pd->pkg->release = cr_safe_string_chunk_insert(pd->pkg->chunk, + cr_find_attr("rel", attr)); break; case STATE_FILE: { @@ -188,16 +210,21 @@ cr_end_handler(void *pdata, const char *element) if (!pd->pkg) return; - if (pd->pkgcb(pd->pkg, pd->pkgcb_data, &tmp_err)) { + if (pd->pkgcb && pd->pkgcb(pd->pkg, pd->pkgcb_data, &tmp_err)) { pd->ret = CRE_CBINTERRUPTED; if (tmp_err) - g_propagate_prefixed_error(pd->err, + g_propagate_prefixed_error(&pd->err, tmp_err, "Parsing interrupted:"); else - g_set_error(pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED, + g_set_error(&pd->err, CR_XML_PARSER_FIL_ERROR, CRE_CBINTERRUPTED, "Parsing interrupted"); + } else { + // If callback return CRE_OK but it simultaneously set + // the tmp_err then it's a programming error. + assert(tmp_err == NULL); } + pd->pkg = NULL; break; @@ -231,15 +258,18 @@ cr_xml_parse_filelists(const char *path, void *newpkgcb_data, cr_XmlParserPkgCb pkgcb, void *pkgcb_data, + char **messages, GError **err) { int ret = CRE_OK; CR_FILE *f; cr_ParserData *pd; XML_Parser parser; + char *msgs; assert(path); - assert(pkgcb); + assert(newpkgcb || pkgcb); + assert(!messages || *messages == NULL); assert(!err || *err == NULL); if (!newpkgcb) @@ -255,15 +285,13 @@ cr_xml_parse_filelists(const char *path, XML_SetElementHandler(parser, cr_start_handler, cr_end_handler); XML_SetCharacterDataHandler(parser, cr_char_handler); - pd = cr_xml_parser_data(); + pd = cr_xml_parser_data(NUMSTATES); pd->parser = &parser; pd->state = STATE_START; pd->newpkgcb_data = newpkgcb_data; pd->newpkgcb = newpkgcb; pd->pkgcb_data = pkgcb_data; pd->pkgcb = pkgcb; - pd->swtab = g_malloc0(sizeof(cr_StatesSwitch *) * NUMSTATES); - pd->sbtab = g_malloc(sizeof(cr_FilState) * NUMSTATES); for (cr_StatesSwitch *sw = stateswitches; sw->from != NUMSTATES; sw++) { if (!pd->swtab[sw->from]) pd->swtab[sw->from] = sw; @@ -303,17 +331,26 @@ cr_xml_parse_filelists(const char *path, break; } - if (len == 0) - break; - if (pd->ret != CRE_OK) { ret = pd->ret; break; } + + if (len == 0) + break; } - cr_xml_parser_data_free(pd); + if (pd->err) + g_propagate_error(err, pd->err); + + msgs = cr_xml_parser_data_free(pd); XML_ParserFree(parser); + cr_close(f); + + if (messages) + *messages = msgs; + else + g_free(msgs); return ret; } diff --git a/src/xml_parser_internal.h b/src/xml_parser_internal.h index 39fa360..fc66e96 100644 --- a/src/xml_parser_internal.h +++ b/src/xml_parser_internal.h @@ -80,7 +80,7 @@ typedef struct _cr_ParserData { The package which is currently loaded. */ GString *msgs; /*!< Messages from xml parser (warnings about unknown elements etc.) */ - GError **err; /*!< + GError *err; /*!< Error message */ /* Filelists related stuff */ @@ -90,7 +90,7 @@ typedef struct _cr_ParserData { cr_ParserData *cr_xml_parser_data(); -void cr_xml_parser_data_free(cr_ParserData *pd); +char *cr_xml_parser_data_free(cr_ParserData *pd); static inline const char * cr_find_attr(const char *name, const char **attr) diff --git a/tests/fixtures.h b/tests/fixtures.h index 172eacf..c048114 100644 --- a/tests/fixtures.h +++ b/tests/fixtures.h @@ -48,6 +48,7 @@ // Modified repo files (MFR) +#define TEST_MRF_BAD_TYPE_FIL TEST_MODIFIED_REPO_FILES_PATH"bad_file_type-filelists.xml" #define TEST_MRF_NO_PKGID_FIL TEST_MODIFIED_REPO_FILES_PATH"no_pkgid-filelists.xml" #define TEST_MRF_NO_PKGID_OTH TEST_MODIFIED_REPO_FILES_PATH"no_pkgid-other.xml" #define TEST_MRF_UE_PRI_00 TEST_MODIFIED_REPO_FILES_PATH"unknown_element_00-primary.xml" diff --git a/tests/test_xml_parser_filelists.c b/tests/test_xml_parser_filelists.c index 73d315f..fb1d286 100644 --- a/tests/test_xml_parser_filelists.c +++ b/tests/test_xml_parser_filelists.c @@ -26,67 +26,241 @@ #include "createrepo/misc.h" #include "createrepo/xml_parser.h" +// Callbacks + static int pkgcb(cr_Package *pkg, void *cbdata, GError **err) { + g_assert(pkg); g_assert(!err || *err == NULL); if (cbdata) *((int *)cbdata) += 1; + cr_package_free(pkg); return CRE_OK; } -static void test_cr_xml_parse_filelists_00(void) +static int +pkgcb_interrupt(cr_Package *pkg, void *cbdata, GError **err) +{ + g_assert(pkg); + g_assert(!err || *err == NULL); + if (cbdata) *((int *)cbdata) += 1; + cr_package_free(pkg); + return 1; +} + +static int +newpkgcb_skip_fake_bash(cr_Package **pkg, + const char *pkgId, + const char *name, + const char *arch, + void *cbdata, + GError **err) +{ + CR_UNUSED(pkgId); + CR_UNUSED(arch); + CR_UNUSED(cbdata); + + g_assert(pkg != NULL); + g_assert(*pkg == NULL); + g_assert(pkgId != NULL); + g_assert(!err || *err == NULL); + + if (!g_strcmp0(name, "fake_bash")) + return CRE_OK; + + *pkg = cr_package_new(); + return CRE_OK; +} + +static int +newpkgcb_interrupt(cr_Package **pkg, + const char *pkgId, + const char *name, + const char *arch, + void *cbdata, + GError **err) +{ + CR_UNUSED(pkgId); + CR_UNUSED(arch); + CR_UNUSED(cbdata); + + g_assert(pkg != NULL); + g_assert(*pkg == NULL); + g_assert(pkgId != NULL); + g_assert(!err || *err == NULL); + + return 1; +} + +// Tests + +static void +test_cr_xml_parse_filelists_00(void) +{ + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_REPO_00_FILELISTS, NULL, NULL, + pkgcb, NULL, NULL, &tmp_err); + g_assert(tmp_err == NULL); + g_assert_cmpint(ret, ==, CRE_OK); +} + +static void +test_cr_xml_parse_filelists_01(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_REPO_01_FILELISTS, NULL, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err == NULL); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 1); +} + +static void +test_cr_xml_parse_filelists_02(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS, NULL, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err == NULL); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 2); +} + +static void +test_cr_xml_parse_filelists_unknown_element_00(void) { - int ret; + int parsed = 0; GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_00, NULL, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err == NULL); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 2); +} - ret = cr_xml_parse_filelists(TEST_REPO_00_FILELISTS, - NULL, - NULL, - pkgcb, - NULL, - &tmp_err); +static void +test_cr_xml_parse_filelists_unknown_element_01(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_01, NULL, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err == NULL); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 1); +} +static void +test_cr_xml_parse_filelists_unknown_element_02(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_02, NULL, NULL, + pkgcb, &parsed, NULL, &tmp_err); g_assert(tmp_err == NULL); g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 2); } -static void test_cr_xml_parse_filelists_01(void) +static void +test_cr_xml_parse_filelists_no_pkgid(void) { - int ret; int parsed = 0; GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_NO_PKGID_FIL, NULL, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err != NULL); + g_error_free(tmp_err); + g_assert_cmpint(ret, ==, CRE_BADXMLFILELISTS); +} - ret = cr_xml_parse_filelists(TEST_REPO_01_FILELISTS, - NULL, - NULL, - pkgcb, - &parsed, - &tmp_err); +static void +test_cr_xml_parse_filelists_skip_fake_bash_00(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_00, + newpkgcb_skip_fake_bash, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err == NULL); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 1); +} +static void +test_cr_xml_parse_filelists_skip_fake_bash_01(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_UE_FIL_01, + newpkgcb_skip_fake_bash, NULL, + pkgcb, &parsed, NULL, &tmp_err); g_assert(tmp_err == NULL); g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 0); +} + +static void +test_cr_xml_parse_filelists_pkgcb_interrupt(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS, NULL, NULL, + pkgcb_interrupt, &parsed, NULL, &tmp_err); + g_assert(tmp_err != NULL); + g_error_free(tmp_err); + g_assert_cmpint(ret, ==, CRE_CBINTERRUPTED); g_assert_cmpint(parsed, ==, 1); } -static void test_cr_xml_parse_filelists_02(void) +static void +test_cr_xml_parse_filelists_newpkgcb_interrupt(void) { - int ret; int parsed = 0; GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS, + newpkgcb_interrupt, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err != NULL); + g_error_free(tmp_err); + g_assert_cmpint(ret, ==, CRE_CBINTERRUPTED); + g_assert_cmpint(parsed, ==, 0); +} - ret = cr_xml_parse_filelists(TEST_REPO_02_FILELISTS, - NULL, - NULL, - pkgcb, - &parsed, - &tmp_err); +static void +test_cr_xml_parse_filelists_bad_file_type_00(void) +{ + int parsed = 0; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_BAD_TYPE_FIL, + NULL, NULL, + pkgcb, &parsed, NULL, &tmp_err); + g_assert(tmp_err == NULL); + g_assert_cmpint(ret, ==, CRE_OK); + g_assert_cmpint(parsed, ==, 2); +} +static void +test_cr_xml_parse_filelists_bad_file_type_01(void) +{ + int parsed = 0; + char *msgs = NULL; + GError *tmp_err = NULL; + int ret = cr_xml_parse_filelists(TEST_MRF_BAD_TYPE_FIL, + NULL, NULL, + pkgcb, &parsed, &msgs, &tmp_err); + g_assert(msgs != NULL); + g_assert_cmpstr(msgs, ==, "Unknown file type \"foo\";"); + g_free(msgs); g_assert(tmp_err == NULL); g_assert_cmpint(ret, ==, CRE_OK); g_assert_cmpint(parsed, ==, 2); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { g_test_init(&argc, &argv, NULL); @@ -96,5 +270,26 @@ int main(int argc, char *argv[]) test_cr_xml_parse_filelists_01); g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_02", test_cr_xml_parse_filelists_02); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_unknown_element_00", + test_cr_xml_parse_filelists_unknown_element_00); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_unknown_element_01", + test_cr_xml_parse_filelists_unknown_element_01); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_unknown_element_02", + test_cr_xml_parse_filelists_unknown_element_02); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_no_pgkid", + test_cr_xml_parse_filelists_no_pkgid); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_skip_fake_bash_00", + test_cr_xml_parse_filelists_skip_fake_bash_00); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_skip_fake_bash_01", + test_cr_xml_parse_filelists_skip_fake_bash_01); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_pkgcb_interrupt", + test_cr_xml_parse_filelists_pkgcb_interrupt); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_newpkgcb_interrupt", + test_cr_xml_parse_filelists_newpkgcb_interrupt); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_bad_file_type_00", + test_cr_xml_parse_filelists_bad_file_type_00); + g_test_add_func("/xml_parser_filelists/test_cr_xml_parse_filelists_bad_file_type_01", + test_cr_xml_parse_filelists_bad_file_type_01); + return g_test_run(); } diff --git a/tests/testdata/modified_repo_files/bad_file_type-filelists.xml b/tests/testdata/modified_repo_files/bad_file_type-filelists.xml new file mode 100644 index 0000000..e3158fb --- /dev/null +++ b/tests/testdata/modified_repo_files/bad_file_type-filelists.xml @@ -0,0 +1,13 @@ + + + + + /usr/bin/fake_bash + + + + /usr/bin/super_kernel + /usr/share/man/super_kernel.8.gz + /usr/file_with_bad_type + + \ No newline at end of file