From: Alberto Leiva Popper Date: Thu, 11 Jul 2024 22:22:14 +0000 (-0600) Subject: Thursday X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=7db38e74efe6f773f25615a6c1e17466da07dc5e;p=thirdparty%2FFORT-validator.git Thursday --- diff --git a/src/cache/cachent.h b/src/cache/cachent.h index 5f9107b7..7443b793 100644 --- a/src/cache/cachent.h +++ b/src/cache/cachent.h @@ -8,6 +8,7 @@ /* XXX rename "touched" and "validated" into "preserve"? */ +// XXX trees now separated; consider removing this flag #define CNF_RSYNC (1 << 0) /* * Do we have a (full) copy in the cache? @@ -45,11 +46,13 @@ // XXX rename to cache_entity or cachent struct cache_node { - char const *name; /* Points to the last component of @url */ + char const *name; /* Points to the last component of @url XXX redundant */ char *url; int flags; - /* Last successful download time, or zero */ - time_t mtim; + + int dlerr; /* Result code of recent download attempt */ + time_t mtim; /* Last successful download time, or zero */ + /* * If flags & CNF_FRESH, path to the temporal directory where we * downloaded the latest refresh. @@ -60,17 +63,13 @@ struct cache_node { */ char *tmpdir; - struct cache_node *rpp; // XXX delete? - - /* Only if flags & CNF_NOTIFICATION. */ + /* Only if flags & CNF_NOTIFICATION */ // struct cachefile_notification notif; - /* Tree parent. Only defined during cleanup. */ - struct cache_node *parent; - /* Tree children. */ - struct cache_node *children; + struct cache_node *parent; /* Tree parent */ + struct cache_node *children; /* Tree children */ - UT_hash_handle hh; /* Hash table hook */ + UT_hash_handle hh; /* Hash table hook */ }; struct cache_node *cachent_create_root(char const *); diff --git a/src/cache/local_cache.c b/src/cache/local_cache.c index 52cba691..2b0d6447 100644 --- a/src/cache/local_cache.c +++ b/src/cache/local_cache.c @@ -3,6 +3,7 @@ * * - We only need to keep nodes for the rsync root. * - The tree traverse only needs to touch files. + * - RRDP needs caging. */ #include "cache/local_cache.h" @@ -241,16 +242,16 @@ cache_tmpfile(char **filename) return 0; } -static char * -get_tal_json_filename(void) -{ - struct path_builder pb; - return pb_init_cache(&pb, TAL_METAFILE) ? NULL : pb.string; -} - -static struct cache_node * -json2node(json_t *json) -{ +//static char * +//get_tal_json_filename(void) +//{ +// struct path_builder pb; +// return pb_init_cache(&pb, TAL_METAFILE) ? NULL : pb.string; +//} +// +//static struct cache_node * +//json2node(json_t *json) +//{ // struct cache_node *node; // char const *type_str; // enum map_type type; @@ -330,8 +331,8 @@ json2node(json_t *json) // map_refput(node->map); // rrdp_notif_free(node->notif); // free(node); - return NULL; -} +// return NULL; +//} static void load_tal_json(void) @@ -388,9 +389,9 @@ cache_prepare(void) load_tal_json(); } -static json_t * -node2json(struct cache_node *node) -{ +//static json_t * +//node2json(struct cache_node *node) +//{ // json_t *json; // char const *type; // json_t *notification; @@ -434,19 +435,19 @@ node2json(struct cache_node *node) // //cancel: // json_decref(json); - return NULL; -} - -static json_t * -build_tal_json(struct rpki_cache *cache) -{ +// return NULL; +//} +// +//static json_t * +//build_tal_json(struct rpki_cache *cache) +//{ // struct cache_node *node, *tmp; // json_t *root, *child; // // root = json_array_new(); // if (root == NULL) - return NULL; - +// return NULL; +// // HASH_ITER(hh, cache->ht, node, tmp) { // child = node2json(node); // if (child != NULL && json_array_append_new(root, child)) { @@ -457,7 +458,7 @@ build_tal_json(struct rpki_cache *cache) // } // // return root; -} +//} static void write_tal_json(void) @@ -529,28 +530,28 @@ get_rsync_module(struct cache_node *node) return node; } -static struct cache_node * -get_rsync_rpp(char const *caRepository, struct cache_node *rpkiManifest) +static int +dl_rrdp(struct cache_node *rpp) { - struct cache_node *node; - char *normal; + int error; - normal = url_normalize(caRepository); - if (normal == NULL) - return NULL; + if (!config_get_http_enabled()) { + pr_val_debug("HTTP is disabled."); + return 1; + } - for (node = rpkiManifest; node != NULL; node = node->parent) - if (strcmp(node->url, normal) == 0) { - free(normal); - return node; - } + // XXX needs to add all files to node. + // Probably also update node itself. + // XXX maybe pr_crit() on !mft->parent? + error = rrdp_update(rpp); + if (error) + pr_val_debug("RRDP RPP: Failed refresh."); - free(normal); - return NULL; + return error; } static int -dl_rsync(char const *caRepository, struct cache_node *mft) +dl_rsync(struct cache_node *rpp) { struct cache_node *module, *node; char *path; @@ -561,14 +562,9 @@ dl_rsync(char const *caRepository, struct cache_node *mft) return 1; } - module = get_rsync_module(mft); - if (module == NULL) { + module = get_rsync_module(rpp); + if (module == NULL) return -EINVAL; // XXX - } - mft->rpp = get_rsync_rpp(caRepository, mft); - if (!mft->rpp) - return pr_val_err("Manifest '%s' does not seem to be inside its publication point '%s'.", - mft->url, caRepository); error = cache_tmpfile(&path); if (error) @@ -585,19 +581,15 @@ dl_rsync(char const *caRepository, struct cache_node *mft) module->mtim = time(NULL); // XXX catch -1 module->tmpdir = path; - for (node = mft; node != module; node = node->parent) { + for (node = rpp; node != module; node = node->parent) { node->flags |= RSYNC_INHERIT; node->mtim = module->mtim; - if (mft) { - node->rpp = mft->rpp; - if (node == mft->rpp) - mft = NULL; - } } return 0; } +/* static int dl_http(struct cache_node *node) { @@ -608,73 +600,51 @@ dl_http(struct cache_node *node) return http_download_cache_node(node); } +*/ +/* @uri is either a caRepository or a rpkiNotify */ static int -dl_rrdp(char const *notif_url, struct cache_node *mft) -{ - if (!config_get_http_enabled()) { - pr_val_debug("HTTP is disabled."); - return 1; - } - - // XXX needs to add all files to node. Probably also update node itself. - // XXX maybe pr_crit() on !mft->parent? - return rrdp_update(cachent_provide(cache.https, notif_url), mft->parent); - -// node->flags |= CNF_FRESH; -// node->mtim = time(NULL); // XXX catch -1 -// node->tmpdir = path; -} - -static int -download(char const *uri, enum map_type type, struct cache_node *mft) +try_uri(char const *uri, int (*download)(struct cache_node *), + maps_dl_cb validate, void *arg) { - switch (type) { - case MAP_RSYNC: - return dl_rsync(uri, mft); - case MAP_HTTP: - return dl_http(mft); - case MAP_NOTIF: - return dl_rrdp(uri, mft); - } + struct cache_node *rpp; + int error; - pr_crit("Unreachable."); - return -EINVAL; /* Warning shutupper */ -} + if (!uri) + return 1; /* Protocol unavailable; ignore */ -/* - * XXX review result sign - * - * uri is a rpkiNotify or a caRepository. - */ -static int -try_uri(struct cache_node *mft, char const *uri, enum map_type type, - bool online, maps_dl_cb cb, void *arg) -{ - int error; + pr_val_debug("Trying %s (%s)...", uri, download ? "online" : "offline"); - pr_val_debug("Trying %s...", uri); + rpp = cachent_provide(cache.rsync, uri); + if (!rpp) + return pr_val_err("Malformed URL: %s", uri); - if (online) { - error = download(uri, type, mft); - if (error) { - pr_val_debug("RPP refresh failed."); - return error; + if (download != NULL) { + if (rpp->flags & CNF_FRESH) { + if (rpp->dlerr) + return rpp->dlerr; + } else { + rpp->flags |= CNF_FRESH; + error = rpp->dlerr = download(rpp); + if (error) + return error; } } - error = cb(mft->rpp, arg); + error = validate(rpp, arg); if (error) { pr_val_debug("RPP validation failed."); return error; } /* XXX commit the files (later, during cleanup) */ - pr_val_debug("RPP downloaded and validated successfully."); + pr_val_debug("RPP validated successfully."); return 0; } /** + * XXX outdated comment + * * Assumes the URIs represent different ways to access the same content. * * Sequentially (in the order dictated by their priorities) attempts to update @@ -688,31 +658,32 @@ try_uri(struct cache_node *mft, char const *uri, enum map_type type, int cache_download_alt(struct sia_uris *uris, maps_dl_cb cb, void *arg) { - struct cache_node *mft; - int online; - int error = 0; + int error; - /* XXX mutex */ - /* XXX if parent is downloaded, child is downloaded. */ - mft = cachent_provide(cache.rsync, uris->rpkiManifest); + // XXX Make sure somewhere validates rpkiManifest matches caRepository. - if (mft->flags & CNF_FRESH) - return cb(mft->rpp, arg); // XXX can rpp be NULL? + /* XXX mutex */ +// /* XXX if parent is downloaded, child is downloaded. */ +// mft = cachent_provide(cache.rsync, uris->rpkiManifest); +// +// if (mft->flags & CNF_FRESH) +// return cb(mft->rpp, arg); // XXX can rpp be NULL? - for (online = 1; online >= 0; online--) { - if (uris->rpkiNotify) { - error = try_uri(mft, uris->rpkiNotify, MAP_NOTIF, - online, cb, arg); - if (error <= 0) - return error; - } - error = try_uri(mft, uris->caRepository, MAP_RSYNC, - online, cb, arg); - if (error <= 0) - return error; - } + /* Online attempts */ + // XXX review result signs + // XXX normalize rpkiNotify & caRepository? + error = try_uri(uris->rpkiNotify, dl_rrdp, cb, arg); + if (error <= 0) + return error; + error = try_uri(uris->caRepository, dl_rsync, cb, arg); + if (error <= 0) + return error; - return error; + /* Offline attempts */ + error = try_uri(uris->rpkiNotify, NULL, cb, arg); + if (error <= 0) + return error; + return try_uri(uris->caRepository, NULL, cb, arg); } void @@ -729,6 +700,8 @@ cache_print(void) static bool commit_rpp_delta(struct cache_node *node, char const *path) { + PR_DEBUG_MSG("Commiting %s", node->url); + if (node->tmpdir == NULL) return true; /* Not updated */ @@ -775,30 +748,30 @@ commit_rpp_delta(struct cache_node *node, char const *path) // // delete_node(cache, node); //} -// -//static time_t -//get_days_ago(int days) -//{ -// time_t tt_now, last_week; -// struct tm tm; -// int error; -// -// tt_now = time(NULL); -// if (tt_now == (time_t) -1) -// pr_crit("time(NULL) returned (time_t) -1."); -// if (localtime_r(&tt_now, &tm) == NULL) { -// error = errno; -// pr_crit("localtime_r(tt, &tm) returned error: %s", -// strerror(error)); -// } -// tm.tm_mday -= days; -// last_week = mktime(&tm); -// if (last_week == (time_t) -1) -// pr_crit("mktime(tm) returned (time_t) -1."); -// -// return last_week; -//} -// + +static time_t +get_days_ago(int days) +{ + time_t tt_now, last_week; + struct tm tm; + int error; + + tt_now = time(NULL); + if (tt_now == (time_t) -1) + pr_crit("time(NULL) returned (time_t) -1."); + if (localtime_r(&tt_now, &tm) == NULL) { + error = errno; + pr_crit("localtime_r(tt, &tm) returned error: %s", + strerror(error)); + } + tm.tm_mday -= days; + last_week = mktime(&tm); + if (last_week == (time_t) -1) + pr_crit("mktime(tm) returned (time_t) -1."); + + return last_week; +} + //static void //cleanup_tmp(struct rpki_cache *cache, struct cache_node *node) //{ @@ -898,6 +871,8 @@ nftw_remove_abandoned(const char *path, const struct stat *st, struct cache_node *msm; /* Most Specific Match */ struct timespec now; + PR_DEBUG_MSG("Removing potentially abandoned %s", path); + /* XXX node->parent has to be set */ pm = find_msm(nftw_root, pstrdup(path), &msm); if (!pm && !(msm->flags & CNF_RSYNC)) diff --git a/src/common.c b/src/common.c index daaaa7af..4db2093b 100644 --- a/src/common.c +++ b/src/common.c @@ -238,6 +238,91 @@ valid_file_or_dir(char const *location, bool check_file) return result; } +/* + * > 0: exists + * = 0: !exists + * < 0: error + */ +static int +dir_exists(char const *path) +{ + struct stat meta; + int error; + + if (stat(path, &meta) != 0) { + error = errno; + if (error == ENOENT) + return 0; + pr_op_err_st("stat() failed: %s", strerror(error)); + return -error; + } + + if (!S_ISDIR(meta.st_mode)) { + return pr_op_err_st("Path '%s' exists and is not a directory.", + path); + } + + return 1; +} + +static int +ensure_dir(char const *path) +{ + int error; + + if (mkdir(path, 0777) != 0) { + error = errno; + if (error != EEXIST) { + pr_op_err_st("Error while making directory '%s': %s", + path, strerror(error)); + return error; + } + } + + return 0; +} + +/* mkdir -p $_path */ +/* XXX Maybe also short-circuit by parent? */ +int +mkdir_p(char const *_path, bool include_basename) +{ + char *path, *last_slash; + int i, result = 0; + + path = pstrdup(_path); /* Remove const */ + + if (!include_basename) { + last_slash = strrchr(path, '/'); + if (last_slash == NULL) + goto end; + *last_slash = '\0'; + } + + result = dir_exists(path); /* short circuit */ + if (result > 0) { + result = 0; + goto end; + } else if (result < 0) { + goto end; + } + + for (i = 1; path[i] != '\0'; i++) { + if (path[i] == '/') { + path[i] = '\0'; + result = ensure_dir(path); + path[i] = '/'; + if (result != 0) + goto end; /* error msg already printed */ + } + } + result = ensure_dir(path); + +end: + free(path); + return result; +} + /* * Delete @path. * If path's parent is now empty, delete parent as well. diff --git a/src/common.h b/src/common.h index 6a3989e9..34333dcf 100644 --- a/src/common.h +++ b/src/common.h @@ -50,6 +50,8 @@ int foreach_file(char const *, char const *, bool, foreach_file_cb, void *); // XXX bool valid_file_or_dir(char const *, bool); + +int mkdir_p(char const *, bool); int delete_dir_recursive_bottom_up(char const *); int get_current_time(time_t *); diff --git a/src/file.c b/src/file.c index 81a50572..0f83e457 100644 --- a/src/file.c +++ b/src/file.c @@ -169,88 +169,3 @@ file_rm_rf(char const *path) /* TODO (performance) optimize that 32 */ return nftw(path, rm, 32, FTW_DEPTH | FTW_PHYS); } - -/* - * > 0: exists - * = 0: !exists - * < 0: error - */ -static int -dir_exists(char const *path) -{ - struct stat meta; - int error; - - if (stat(path, &meta) != 0) { - error = errno; - if (error == ENOENT) - return 0; - pr_op_err_st("stat() failed: %s", strerror(error)); - return -error; - } - - if (!S_ISDIR(meta.st_mode)) { - return pr_op_err_st("Path '%s' exists and is not a directory.", - path); - } - - return 1; -} - -static int -ensure_dir(char const *path) -{ - int error; - - if (mkdir(path, 0777) != 0) { - error = errno; - if (error != EEXIST) { - pr_op_err_st("Error while making directory '%s': %s", - path, strerror(error)); - return error; - } - } - - return 0; -} - -/* mkdir -p $_path */ -/* XXX Maybe also short-circuit by parent? */ -int -mkdir_p(char const *_path, bool include_basename) -{ - char *path, *last_slash; - int i, result = 0; - - path = pstrdup(_path); /* Remove const */ - - if (!include_basename) { - last_slash = strrchr(path, '/'); - if (last_slash == NULL) - goto end; - *last_slash = '\0'; - } - - result = dir_exists(path); /* short circuit */ - if (result > 0) { - result = 0; - goto end; - } else if (result < 0) { - goto end; - } - - for (i = 1; path[i] != '\0'; i++) { - if (path[i] == '/') { - path[i] = '\0'; - result = ensure_dir(path); - path[i] = '/'; - if (result != 0) - goto end; /* error msg already printed */ - } - } - result = ensure_dir(path); - -end: - free(path); - return result; -} diff --git a/src/file.h b/src/file.h index 0d1fd8c7..1de125ae 100644 --- a/src/file.h +++ b/src/file.h @@ -36,8 +36,6 @@ int file_merge_into(char const *, char const *); int file_rm_f(char const *); int file_rm_rf(char const *); -int mkdir_p(char const *, bool); - /* * Remember that this API is awkward: * diff --git a/src/rrdp.c b/src/rrdp.c index d616d76d..6bee4e32 100644 --- a/src/rrdp.c +++ b/src/rrdp.c @@ -1093,7 +1093,7 @@ update_notif(struct cachefile_notification *old, struct update_notification *new * snapshot, and explodes them into @rpp's tmp directory. */ int -rrdp_update(struct cache_node *notif, struct cache_node *rpp) +rrdp_update(struct cache_node *notif) { char *path = NULL; struct cachefile_notification *old; diff --git a/src/rrdp.h b/src/rrdp.h index 89950010..3800c9f9 100644 --- a/src/rrdp.h +++ b/src/rrdp.h @@ -6,7 +6,7 @@ struct cachefile_notification; struct cache_node; -int rrdp_update(struct cache_node *, struct cache_node *); +int rrdp_update(struct cache_node *); json_t *rrdp_notif2json(struct cachefile_notification *); int rrdp_json2notif(json_t *, struct cachefile_notification **); diff --git a/test/Makefile.am b/test/Makefile.am index a0ff28aa..a2805cbb 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -23,7 +23,7 @@ AM_CFLAGS += -I../src -DUNIT_TESTING ${CHECK_CFLAGS} ${XML2_CFLAGS} ${JANSSON_CF MY_LDADD = ${CHECK_LIBS} ${JANSSON_LIBS} check_PROGRAMS = url.test -#check_PROGRAMS += cachent.test +check_PROGRAMS += cachent.test check_PROGRAMS += cache.test TESTS = ${check_PROGRAMS} diff --git a/test/cache/cachent_test.c b/test/cache/cachent_test.c index 17df8b42..8bbe6388 100644 --- a/test/cache/cachent_test.c +++ b/test/cache/cachent_test.c @@ -2,7 +2,7 @@ #include "alloc.c" #include "cache/cachent.c" -#include "cache/common.c" +#include "cache/util.c" #include "data_structure/path_builder.c" #include "mock.c" #include "types/url.c" @@ -20,14 +20,14 @@ START_TEST(test_delete) { struct cache_node *root, *a, *b; - a = node("a", 0, NULL); + a = unode("a", NULL); dn = 0; cachent_delete(a); ck_assert_uint_eq(1, dn); ck_assert_str_eq("a", deleted[0]); - a = node("a", 0, NULL); - root = node("root", 0, a, NULL); + a = unode("a", NULL); + root = unode("root", a, NULL); dn = 0; cachent_delete(a); ck_assert_ptr_eq(NULL, root->children); @@ -39,23 +39,23 @@ START_TEST(test_delete) ck_assert_uint_eq(1, dn); ck_assert_str_eq("root", deleted[0]); - b = node("b", 0, - node("c", 0, NULL), - node("d", 0, NULL), - node("e", 0, NULL), - node("f", 0, NULL), NULL); - a = node("a", 0, + b = unode("b", + unode("c", NULL), + unode("d", NULL), + unode("e", NULL), + unode("f", NULL), NULL); + a = unode("a", b, - node("g", 0, - node("h", 0, - node("i", 0, NULL), NULL), - node("j", 0, - node("k", 0, NULL), NULL), - node("l", 0, - node("m", 0, NULL), NULL), - node("n", 0, - node("o", 0, NULL), NULL), NULL), NULL); - root = node("root", 0, a, NULL); + unode("g", + unode("h", + unode("i", NULL), NULL), + unode("j", + unode("k", NULL), NULL), + unode("l", + unode("m", NULL), NULL), + unode("n", + unode("o", NULL), NULL), NULL), NULL); + root = unode("root", a, NULL); dn = 0; cachent_delete(b); @@ -124,36 +124,36 @@ START_TEST(test_traverse) root = NULL; ck_traverse(root, NULL); - root = node("a", 0, NULL); + root = unode("a", NULL); ck_traverse(root, "tmp/a", NULL); - root = node("a", 0, - node("b", 0, NULL), NULL); + root = unode("a", + unode("b", NULL), NULL); ck_traverse(root, "tmp/a", "tmp/a/b", NULL); - root = node("a", 0, - node("b", 0, - node("c", 0, NULL), NULL), NULL); + root = unode("a", + unode("b", + unode("c", NULL), NULL), NULL); ck_traverse(root, "tmp/a", "tmp/a/b", "tmp/a/b/c", NULL); - root = node("a", 0, - node("b", 0, - node("c", 0, NULL), - node("d", 0, NULL), NULL), NULL); + root = unode("a", + unode("b", + unode("c", NULL), + unode("d", NULL), NULL), NULL); ck_traverse(root, "tmp/a", "tmp/a/b", "tmp/a/b/c", "tmp/a/b/d", NULL); - root = node("a", 0, - node("b", 0, - node("c", 0, NULL), - node("d", 0, NULL), NULL), - node("e", 0, NULL), NULL); + root = unode("a", + unode("b", + unode("c", NULL), + unode("d", NULL), NULL), + unode("e", NULL), NULL); ck_traverse(root, "tmp/a", "tmp/a/b", @@ -161,11 +161,11 @@ START_TEST(test_traverse) "tmp/a/b/d", "tmp/a/e", NULL); - root = node("a", 0, - node("b", 0, NULL), - node("c", 0, - node("d", 0, NULL), - node("e", 0, NULL), NULL), NULL); + root = unode("a", + unode("b", NULL), + unode("c", + unode("d", NULL), + unode("e", NULL), NULL), NULL); ck_traverse(root, "tmp/a", "tmp/a/b", @@ -173,13 +173,13 @@ START_TEST(test_traverse) "tmp/a/c/d", "tmp/a/c/e", NULL); - root = node("a", 0, - node("b", 0, - node("c", 0, NULL), - node("d", 0, NULL), NULL), - node("e", 0, - node("f", 0, NULL), - node("g", 0, NULL), NULL), NULL); + root = unode("a", + unode("b", + unode("c", NULL), + unode("d", NULL), NULL), + unode("e", + unode("f", NULL), + unode("g", NULL), NULL), NULL); ck_traverse(root, "tmp/a", "tmp/a/b", @@ -189,21 +189,21 @@ START_TEST(test_traverse) "tmp/a/e/f", "tmp/a/e/g", NULL); - root = node("a", 0, - node("b", 0, - node("c", 0, NULL), - node("d", 0, NULL), - node("e", 0, NULL), - node("f", 0, NULL), NULL), - node("g", 0, - node("h", 0, - node("i", 0, NULL), NULL), - node("j", 0, - node("k", 0, NULL), NULL), - node("l", 0, - node("m", 0, NULL), NULL), - node("n", 0, - node("o", 0, NULL), NULL), NULL), NULL); + root = unode("a", + unode("b", + unode("c", NULL), + unode("d", NULL), + unode("e", NULL), + unode("f", NULL), NULL), + unode("g", + unode("h", + unode("i", NULL), NULL), + unode("j", + unode("k", NULL), NULL), + unode("l", + unode("m", NULL), NULL), + unode("n", + unode("o", NULL), NULL), NULL), NULL); ck_traverse(root, "tmp/a", "tmp/a/b", diff --git a/test/cache/common.c b/test/cache/common.c deleted file mode 100644 index ebb67dc6..00000000 --- a/test/cache/common.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "cache/common.h" - -#include -#include -#include "data_structure/uthash.h" - -struct cache_node * -node(char const *url, int flags, char const *tmpdir, ...) -{ - struct cache_node *result; - struct cache_node *child; - char const *slash; - va_list args; - - result = pzalloc(sizeof(struct cache_node)); - result->url = pstrdup(url); - slash = strrchr(url, '/'); - result->name = slash ? (slash + 1) : result->url; - result->flags = flags; - result->tmpdir = tmpdir ? pstrdup(tmpdir) : NULL; - - va_start(args, tmpdir); - while ((child = va_arg(args, struct cache_node *)) != NULL) { - HASH_ADD_KEYPTR(hh, result->children, child->name, - strlen(child->name), child); - child->parent = result; - } - va_end(args); - - return result; -} diff --git a/test/cache/common.h b/test/cache/common.h deleted file mode 100644 index d8b2ec3c..00000000 --- a/test/cache/common.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef TEST_CACHE_COMMON_H_ -#define TEST_CACHE_COMMON_H_ - -#include "cache/cachent.h" - -struct cache_node *node(char const *, int , char const *, ...); - -#endif /* TEST_CACHE_COMMON_H_ */ diff --git a/test/cache/local_cache_test.c b/test/cache/local_cache_test.c index 5b99e27a..03571a3b 100644 --- a/test/cache/local_cache_test.c +++ b/test/cache/local_cache_test.c @@ -8,18 +8,20 @@ #include #include "alloc.c" +#include "common.c" //#include "json_util.c" #include "mock.c" #include "cache/cachent.c" -#include "cache/common.c" #include "cache/local_cache.c" +#include "cache/util.c" #include "data_structure/path_builder.c" #include "types/str.c" #include "types/url.c" /* Mocks */ -static bool dl_error; /* Download should return error? */ +static unsigned int rsync_counter; /* Times the rsync function was called */ +static unsigned int https_counter; /* Times the https function was called */ struct downloaded_path { char *path; @@ -27,18 +29,24 @@ struct downloaded_path { SLIST_ENTRY(downloaded_path) hook; }; + +static bool dl_mock_type; /* false = list. true = list + actual files */ +static int dl_error; + /* Paths downloaded during the test */ static SLIST_HEAD(downloaded_paths, downloaded_path) downloaded; -static unsigned int rsync_counter; /* Times the rsync function was called */ -static unsigned int https_counter; /* Times the https function was called */ - int -file_exists(char const *file) +file_exists(char const *path) { - struct downloaded_path *path; - SLIST_FOREACH(path, &downloaded, hook) - if (strcmp(file, path->path) == 0) + struct stat meta; + struct downloaded_path *dp; + + if (dl_mock_type) + return (stat(path, &meta) == 0) ? 0 : errno; + + SLIST_FOREACH(dp, &downloaded, hook) + if (strcmp(path, dp->path) == 0) return 0; return ENOENT; } @@ -47,13 +55,17 @@ int file_rm_rf(char const *file) { struct downloaded_path *path; + SLIST_FOREACH(path, &downloaded, hook) if (strcmp(file, path->path) == 0) { SLIST_REMOVE(&downloaded, path, downloaded_path, hook); free(path->path); free(path); + if (dl_mock_type) + ck_assert_int_eq(0, remove(file)); return 0; } + return ENOENT; } @@ -78,7 +90,7 @@ pretend_download(char const *local) struct downloaded_path *dl; if (dl_error) - return -EINVAL; + return dl_error; if (file_exists(local) == 0) return 0; @@ -86,6 +98,10 @@ pretend_download(char const *local) dl->path = pstrdup(local); dl->visited = false; SLIST_INSERT_HEAD(&downloaded, dl, hook); + + if (dl_mock_type) + ck_assert_int_eq(0, mkdir_p(local, true)); + return 0; } @@ -107,17 +123,19 @@ http_download(char const *url, char const *path, curl_off_t ims, bool *changed) return error; } -MOCK_ABORT_INT(rrdp_update, struct cache_node *notif, struct cache_node *rpp) +MOCK_ABORT_INT(rrdp_update, struct cache_node *notif) __MOCK_ABORT(rrdp_notif2json, json_t *, NULL, struct cachefile_notification *notif) MOCK_VOID(rrdp_notif_free, struct cachefile_notification *notif) MOCK_ABORT_INT(rrdp_json2notif, json_t *json, struct cachefile_notification **result) +MOCK(cfg_cache_threshold, time_t, get_days_ago(7), void) /* Helpers */ static void -setup_test(void) +setup_test(bool dl_type) { - dl_error = false; + dl_error = 0; + dl_mock_type = dl_type; SLIST_INIT(&downloaded); ck_assert_int_eq(0, system("rm -rf tmp/")); @@ -133,14 +151,14 @@ okay(struct cache_node *node, void *arg) } static void -run_dl_rsync(char const *caRepository, char const *rpkiManifest, - int expected_error, unsigned int expected_calls) +run_dl_rsync(char const *caRepository, int expected_error, + unsigned int expected_calls) { static struct sia_uris sias; sias.caRepository = pstrdup(caRepository); sias.rpkiNotify = NULL; - sias.rpkiManifest = pstrdup(rpkiManifest); + sias.rpkiManifest = NULL; rsync_counter = 0; https_counter = 0; @@ -167,6 +185,9 @@ find_downloaded_path(struct cache_node *node) if (!node->tmpdir) return NULL; + if (dl_mock_type && !file_exists(node->tmpdir)) + return NULL; + SLIST_FOREACH(path, &downloaded, hook) { if (strcmp(node->tmpdir, path->path) == 0) { if (path->visited) @@ -184,6 +205,8 @@ check_path(struct cache_node *node, char const *_) { struct downloaded_path *path; + PR_DEBUG_MSG("Checking %s", node->url); + path = find_downloaded_path(node); if (node->tmpdir) { if (path == NULL) @@ -244,6 +267,8 @@ ck_assert_cachent_eq(struct cache_node *expected, struct cache_node *actual) { struct cache_node *echild, *achild, *tmp; + PR_DEBUG_MSG("Comparing %s", expected->url); + ck_assert_str_eq(expected->url, actual->url); ck_assert_str_eq(expected->name, actual->name); ck_assert_int_eq(expected->flags, actual->flags); @@ -299,17 +324,29 @@ ck_cache(struct cache_node *rsync, struct cache_node *https) cachent_delete(https); } -//static void -//new_iteration(bool outdate) -//{ -// struct cache_node *node, *tmp; -// time_t epoch; -// -// epoch = outdate ? get_days_ago(30) : get_days_ago(1); -// HASH_ITER(hh, cache->ht, node, tmp) -// node->attempt.ts = epoch; -//} -// +static void +ck_cache_rsync(struct cache_node *rsync) +{ + ck_cache(rsync, unode("https:", NULL)); +} + +static time_t epoch; + +static bool +unfreshen(struct cache_node *node, char const *path) +{ + node->flags &= ~CNF_FRESH; + node->mtim = epoch; + return true; +} + +static void +new_iteration(bool outdate) +{ + epoch = outdate ? get_days_ago(30) : get_days_ago(1); + cachent_traverse(cache.rsync, unfreshen); +} + //static void //cache_reset(struct rpki_cache *cache) //{ @@ -323,7 +360,7 @@ cleanup_test(void) { struct downloaded_path *path; - dl_error = false; + dl_error = 0; cache_commit(); while (!SLIST_EMPTY(&downloaded)) { @@ -336,235 +373,228 @@ cleanup_test(void) /* Tests */ -START_TEST(test_cache_download_rsync) -{ - static const int SUCCESS = CNF_RSYNC | CNF_CACHED | CNF_FRESH | CNF_VALID; - - setup_test(); - - run_dl_rsync("rsync://a.b.c/d", "rsync://a.b.c/d/mft", 0, 1); - ck_cache( - node("rsync:", 0, NULL, - node("rsync://a.b.c", 0, NULL, - node("rsync://a.b.c/d", SUCCESS, "tmp/tmp/0", - node("rsync://a.b.c/d/mft", RSYNC_INHERIT, NULL, NULL), - NULL), - NULL), - NULL), - node("https:", 0, NULL, NULL)); - - /* Redownload same file, nothing should happen */ - run_dl_rsync("rsync://a.b.c/d", "rsync://a.b.c/d/mft", 0, 0); - ck_cache( - node("rsync:", 0, NULL, - node("rsync://a.b.c", 0, NULL, - node("rsync://a.b.c/d", SUCCESS, "tmp/tmp/0", - node("rsync://a.b.c/d/mft", RSYNC_INHERIT, NULL, NULL), - NULL), - NULL), - NULL), - node("https:", 0, NULL, NULL)); - - /* - * rsyncs are recursive, which means if we've been recently asked to - * download d, we needn't bother redownloading d/e. - */ - run_dl_rsync("rsync://a.b.c/d/e", "rsync://a.b.c/d/e/mft", 0, 0); - ck_cache( - node("rsync:", 0, NULL, - node("rsync://a.b.c", 0, NULL, - node("rsync://a.b.c/d", SUCCESS, "tmp/tmp/0", - node("rsync://a.b.c/d/e", RSYNC_INHERIT, NULL, - node("rsync://a.b.c/d/e/mft", RSYNC_INHERIT, NULL, NULL), - NULL), - node("rsync://a.b.c/d/mft", RSYNC_INHERIT, NULL, NULL), - NULL), - NULL), - NULL), - node("https:", 0, NULL, NULL)); - - /* - * rsyncs get truncated, because it results in much faster - * synchronization in practice. - * This is not defined in any RFCs; it's an effective standard, - * and there would be consequences for violating it. - */ - run_dl_rsync("rsync://x.y.z/m/n/o", "rsync://x.y.z/m/n/o/mft", 0, 1); - ck_cache( - node("rsync:", 0, NULL, - node("rsync://a.b.c", 0, NULL, - node("rsync://a.b.c/d", SUCCESS, "tmp/tmp/0", - node("rsync://a.b.c/d/e", RSYNC_INHERIT, NULL, - node("rsync://a.b.c/d/e/mft", RSYNC_INHERIT, NULL, NULL), - NULL), - node("rsync://a.b.c/d/mft", RSYNC_INHERIT, NULL, NULL), - NULL), - NULL), - node("rsync://x.y.z", 0, NULL, - node("rsync://x.y.z/m", SUCCESS, "tmp/tmp/1", - node("rsync://x.y.z/m/n", RSYNC_INHERIT, NULL, - node("rsync://x.y.z/m/n/o", RSYNC_INHERIT, NULL, - node("rsync://x.y.z/m/n/o/mft", RSYNC_INHERIT, NULL, NULL), - NULL), - NULL), - NULL), - NULL), - NULL), - node("https:", 0, NULL, NULL)); - -// /* Sibling */ -// run_dl_rsync("rsync://a.b.c/e/f", "rsync://a.b.c/e/f/mft", 0, 1); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", 0, 1, true), -// NODE("rsync://x.y.z/m/", 0, 1, true), -// NULL); - - cleanup_test(); -} -END_TEST - -//START_TEST(test_cache_download_rsync_error) +static const int DOWNLOADED = CNF_RSYNC | CNF_CACHED | CNF_FRESH; +static const int VALIDATED = RSYNC_INHERIT | CNF_VALID; +static const int FULL = DOWNLOADED | VALIDATED; +static const int STALE = CNF_RSYNC | CNF_CACHED | CNF_VALID; +/* Intermediary between a downloaded and a validated node */ +//static const int BRANCH = RSYNC_INHERIT; +//static const int FAILED = CNF_FRESH; +// +//START_TEST(test_cache_download_rsync) //{ -// setup_test(); +// setup_test(false); // -// dl_error = false; -// run_cache_download("rsync://a.b.c/d", 0, 1, 0); -// dl_error = true; -// run_cache_download("rsync://a.b.c/e", -EINVAL, 1, 0); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", -EINVAL, 0, false), -// NULL); +// run_dl_rsync("rsync://a.b.c/d", 0, 1); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", NULL), NULL), NULL)); // -// /* Regardless of error, not reattempted because same iteration */ -// dl_error = true; -// run_cache_download("rsync://a.b.c/e", -EINVAL, 0, 0); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", -EINVAL, 0, false), -// NULL); +// /* Redownload same file, nothing should happen */ +// run_dl_rsync("rsync://a.b.c/d", 0, 0); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", NULL), NULL), NULL)); // -// dl_error = false; -// run_cache_download("rsync://a.b.c/e", -EINVAL, 0, 0); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", -EINVAL, 0, false), -// NULL); -// -// cleanup_test(); -//} -//END_TEST -// -//START_TEST(test_cache_cleanup_rsync) -//{ -// setup_test(); +// /* +// * rsyncs are recursive, which means if we've been recently asked to +// * download d, we needn't bother redownloading d/e. +// */ +// run_dl_rsync("rsync://a.b.c/d/e", 0, 0); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", +// ufnode("rsync://a.b.c/d/e", VALIDATED, NULL), NULL), NULL), NULL)); // // /* -// * First iteration: Tree is created. No prunes, because nothing's -// * outdated. +// * rsyncs get truncated, because it results in much faster +// * synchronization in practice. +// * This is not defined in any RFCs; it's an effective standard, +// * and there would be consequences for violating it. // */ -// new_iteration(true); -// run_cache_download("rsync://a.b.c/d", 0, 1, 0); -// run_cache_download("rsync://a.b.c/e", 0, 1, 0); -// cache_cleanup(cache); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", 0, 1, true), -// NULL); +// run_dl_rsync("rsync://x.y.z/m/n/o", 0, 1); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", +// ufnode("rsync://a.b.c/d/e", VALIDATED, NULL), NULL), NULL), +// unode("rsync://x.y.z", +// uftnode("rsync://x.y.z/m", DOWNLOADED, "tmp/tmp/1", +// ufnode("rsync://x.y.z/m/n", BRANCH, +// ufnode("rsync://x.y.z/m/n/o", VALIDATED, NULL), NULL), NULL), NULL), NULL)); // -// /* One iteration with no changes, for paranoia */ -// new_iteration(true); -// run_cache_download("rsync://a.b.c/d", 0, 1, 0); -// run_cache_download("rsync://a.b.c/e", 0, 1, 0); -// cache_cleanup(cache); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", 0, 1, true), -// NULL); +// /* Sibling */ +// run_dl_rsync("rsync://a.b.c/e/f", 0, 1); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", +// ufnode("rsync://a.b.c/d/e", VALIDATED, NULL), NULL), +// uftnode("rsync://a.b.c/e", DOWNLOADED, "tmp/tmp/2", +// ufnode("rsync://a.b.c/e/f", VALIDATED, NULL), NULL), NULL), +// unode("rsync://x.y.z", +// uftnode("rsync://x.y.z/m", DOWNLOADED, "tmp/tmp/1", +// ufnode("rsync://x.y.z/m/n", BRANCH, +// ufnode("rsync://x.y.z/m/n/o", VALIDATED, NULL), NULL), NULL), NULL), NULL)); // -// /* Add one sibling */ -// new_iteration(true); -// run_cache_download("rsync://a.b.c/d", 0, 1, 0); -// run_cache_download("rsync://a.b.c/e", 0, 1, 0); -// run_cache_download("rsync://a.b.c/f", 0, 1, 0); -// cache_cleanup(cache); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", 0, 1, true), -// NODE("rsync://a.b.c/f/", 0, 1, true), -// NULL); +// cleanup_test(); +//} +//END_TEST // -// /* Nodes don't get updated, but they're still too young. */ -// new_iteration(false); -// cache_cleanup(cache); -// ck_cache( -// NODE("rsync://a.b.c/d/", 0, 1, true), -// NODE("rsync://a.b.c/e/", 0, 1, true), -// NODE("rsync://a.b.c/f/", 0, 1, true), -// NULL); +//START_TEST(test_cache_download_rsync_error) +//{ +// setup_test(false); +// +// dl_error = 0; +// run_dl_rsync("rsync://a.b.c/d", 0, 1); +// dl_error = -EINVAL; +// run_dl_rsync("rsync://a.b.c/e", -EINVAL, 1); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", NULL), +// ufnode("rsync://a.b.c/e", FAILED, NULL), NULL), NULL)); // -// /* Remove some branches */ -// new_iteration(true); -// run_cache_download("rsync://a.b.c/d", 0, 1, 0); -// cache_cleanup(cache); -// ck_cache(NODE("rsync://a.b.c/d/", 0, 1, true), NULL); +// /* Regardless of error, not reattempted because same iteration */ +// dl_error = EINVAL; +// run_dl_rsync("rsync://a.b.c/e", -EINVAL, 0); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", NULL), +// ufnode("rsync://a.b.c/e", FAILED, NULL), NULL), NULL)); +// +// dl_error = 0; +// run_dl_rsync("rsync://a.b.c/e", -EINVAL, 0); +// ck_cache_rsync( +// unode("rsync:", +// unode("rsync://a.b.c", +// uftnode("rsync://a.b.c/d", FULL, "tmp/tmp/0", NULL), +// ufnode("rsync://a.b.c/e", FAILED, NULL), NULL), NULL)); // +// cleanup_test(); +//} +//END_TEST + +START_TEST(test_cache_cleanup_rsync) +{ + setup_test(true); + + /* + * First iteration: Tree is created. No prunes, because nothing's + * outdated. + */ + new_iteration(true); + run_dl_rsync("rsync://a.b.c/d", 0, 1); + run_dl_rsync("rsync://a.b.c/e", 0, 1); + cleanup_cache(); + ck_cache_rsync( + unode("rsync:", + unode("rsync://a.b.c", + ufnode("rsync://a.b.c/d", FULL, NULL), + ufnode("rsync://a.b.c/e", FULL, NULL), NULL), NULL)); + + /* One iteration with no changes, for paranoia */ + new_iteration(true); + run_dl_rsync("rsync://a.b.c/d", 0, 1); + run_dl_rsync("rsync://a.b.c/e", 0, 1); + cleanup_cache(); + ck_cache_rsync( + unode("rsync:", + unode("rsync://a.b.c", + ufnode("rsync://a.b.c/d", FULL, NULL), + ufnode("rsync://a.b.c/e", FULL, NULL), NULL), NULL)); + + /* Add one sibling */ + new_iteration(true); + run_dl_rsync("rsync://a.b.c/d", 0, 1); + run_dl_rsync("rsync://a.b.c/e", 0, 1); + run_dl_rsync("rsync://a.b.c/f", 0, 1); + cleanup_cache(); + ck_cache_rsync( + unode("rsync:", + unode("rsync://a.b.c", + ufnode("rsync://a.b.c/d", FULL, NULL), + ufnode("rsync://a.b.c/e", FULL, NULL), + ufnode("rsync://a.b.c/f", FULL, NULL), NULL), NULL)); + + /* Nodes don't get updated, but they're still too young. */ + new_iteration(false); + cleanup_cache(); + ck_cache_rsync( + unode("rsync:", + unode("rsync://a.b.c", + ufnode("rsync://a.b.c/d", STALE, NULL), + ufnode("rsync://a.b.c/e", STALE, NULL), + ufnode("rsync://a.b.c/f", STALE, NULL), NULL), NULL)); + + /* Remove some branches */ + new_iteration(true); + run_dl_rsync("rsync://a.b.c/d", 0, 1); + cleanup_cache(); + ck_cache_rsync( + unode("rsync:", + unode("rsync://a.b.c", + ufnode("rsync://a.b.c/d", FULL, NULL), NULL), NULL)); + // /* Remove old branch and add sibling at the same time */ // new_iteration(true); -// run_cache_download("rsync://a.b.c/e", 0, 1, 0); -// cache_cleanup(cache); +// run_dl_rsync("rsync://a.b.c/e", 0, 1); +// cleanup_cache(); // ck_cache(NODE("rsync://a.b.c/e/", 0, 1, true), NULL); // // /* Try child */ // new_iteration(true); -// run_cache_download("rsync://a.b.c/e/f/g", 0, 1, 0); -// cache_cleanup(cache); +// run_dl_rsync("rsync://a.b.c/e/f/g", 0, 1); +// cleanup_cache(); // ck_cache(NODE("rsync://a.b.c/e/", 0, 1, true), NULL); // // /* Parent again */ // new_iteration(true); -// run_cache_download("rsync://a.b.c/e", 0, 1, 0); -// cache_cleanup(cache); +// run_dl_rsync("rsync://a.b.c/e", 0, 1); +// cleanup_cache(); // ck_cache(NODE("rsync://a.b.c/e/", 0, 1, true), NULL); // // /* Empty the tree */ // new_iteration(true); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NULL); // // /* Node exists, but file doesn't */ // new_iteration(true); -// run_cache_download("rsync://a.b.c/e", 0, 1, 0); -// run_cache_download("rsync://a.b.c/f", 0, 1, 0); +// run_dl_rsync("rsync://a.b.c/e", 0, 1); +// run_dl_rsync("rsync://a.b.c/f", 0, 1); // ck_cache( // NODE("rsync://a.b.c/e/", 0, 1, true), // NODE("rsync://a.b.c/f/", 0, 1, true), // NULL); // ck_assert_int_eq(0, file_rm_rf("tmp/rsync/a.b.c/f")); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("rsync://a.b.c/e/", 0, 1, true), NULL); -// -// cleanup_test(); -//} -//END_TEST -// + + cleanup_test(); +} +END_TEST + //START_TEST(test_cache_cleanup_rsync_error) //{ // setup_test(); // // /* Set up */ // dl_error = false; -// run_cache_download("rsync://a.b.c/d", 0, 1, 0); +// run_dl_rsync("rsync://a.b.c/d", 0, 1); // dl_error = true; -// run_cache_download("rsync://a.b.c/e", -EINVAL, 1, 0); +// run_dl_rsync("rsync://a.b.c/e", -EINVAL, 1); // ck_cache( // NODE("rsync://a.b.c/d/", 0, 1, true), // NODE("rsync://a.b.c/e/", -EINVAL, 0, false), // NULL); // // /* Node gets deleted because cached file doesn't exist */ -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("rsync://a.b.c/d/", 0, 1, true), NULL); // // /* @@ -574,12 +604,12 @@ END_TEST // */ // new_iteration(false); // dl_error = true; -// run_cache_download("rsync://a.b.c/d", -EINVAL, 1, 0); +// run_dl_rsync("rsync://a.b.c/d", -EINVAL, 1); // ck_cache(NODE("rsync://a.b.c/d/", -EINVAL, 1, true), NULL); // // /* Error is old; gets deleted */ // new_iteration(true); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NULL); // // cleanup_test(); @@ -648,7 +678,7 @@ END_TEST // new_iteration(true); // run_cache_download("https://a.b.c/d", 0, 0, 1); // run_cache_download("https://a.b.c/e", 0, 0, 1); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache( // NODE("https://a.b.c/d", 0, 1, 1), // NODE("https://a.b.c/e", 0, 1, 1), @@ -657,19 +687,19 @@ END_TEST // /* Remove one branch */ // new_iteration(true); // run_cache_download("https://a.b.c/d", 0, 0, 1); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("https://a.b.c/d", 0, 1, 1), NULL); // // /* Change the one branch */ // new_iteration(true); // run_cache_download("https://a.b.c/e", 0, 0, 1); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("https://a.b.c/e", 0, 1, 1), NULL); // // /* Add a child to the same branch, do not update the old one */ // new_iteration(true); // run_cache_download("https://a.b.c/e/f/g", 0, 0, 1); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache( // NODE("https://a.b.c/e/f/g", 0, 1, 1), NULL); // @@ -679,18 +709,18 @@ END_TEST // */ // new_iteration(true); // run_cache_download("https://a.b.c/e/f", 0, 0, 1); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("https://a.b.c/e/f", 0, 1, 1), NULL); // // /* Do it again. */ // new_iteration(true); // run_cache_download("https://a.b.c/e", 0, 0, 1); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("https://a.b.c/e", 0, 1, 1), NULL); // // /* Empty the tree */ // new_iteration(true); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NULL); // // /* Node exists, but file doesn't */ @@ -702,7 +732,7 @@ END_TEST // NODE("https://a.b.c/f/g/h", 0, 1, 1), // NULL); // ck_assert_int_eq(0, file_rm_rf("tmp/https/a.b.c/f/g/h")); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("https://a.b.c/e", 0, 1, 1), NULL); // // cleanup_test(); @@ -724,7 +754,7 @@ END_TEST // NULL); // // /* Deleted because file ENOENT. */ -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache( // NODE("https://a.b.c/d", 0, 1, 1), // NULL); @@ -737,20 +767,20 @@ END_TEST // // /* Not deleted, because not old */ // new_iteration(false); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NODE("https://a.b.c/d", -EINVAL, 1, 1), NULL); // // /* Become old */ // new_iteration(true); -// cache_cleanup(cache); +// cleanup_cache(); // ck_cache(NULL); // // cleanup_test(); //} //END_TEST - -START_TEST(test_dots) -{ +// +//START_TEST(test_dots) +//{ // setup_test(); // // run_cache_download("https://a.b.c/d", 0, 0, 1); @@ -769,9 +799,9 @@ START_TEST(test_dots) // NULL); // // cleanup_test(); -} -END_TEST - +//} +//END_TEST +// //START_TEST(test_tal_json) //{ // json_t *json; @@ -968,9 +998,9 @@ static Suite *thread_pool_suite(void) TCase *rsync, *https, *dot, *meta, *recover; rsync = tcase_create("rsync"); - tcase_add_test(rsync, test_cache_download_rsync); +// tcase_add_test(rsync, test_cache_download_rsync); // tcase_add_test(rsync, test_cache_download_rsync_error); -// tcase_add_test(rsync, test_cache_cleanup_rsync); + tcase_add_test(rsync, test_cache_cleanup_rsync); // tcase_add_test(rsync, test_cache_cleanup_rsync_error); https = tcase_create("https"); @@ -980,7 +1010,7 @@ static Suite *thread_pool_suite(void) // tcase_add_test(https, test_cache_cleanup_https_error); dot = tcase_create("dot"); - tcase_add_test(dot, test_dots); +// tcase_add_test(dot, test_dots); meta = tcase_create(TAL_METAFILE); // tcase_add_test(meta, test_tal_json); diff --git a/test/cache/util.c b/test/cache/util.c new file mode 100644 index 00000000..682383a8 --- /dev/null +++ b/test/cache/util.c @@ -0,0 +1,66 @@ +#include "cache/util.h" + +#include +#include "data_structure/uthash.h" + +struct cache_node * +vnode(char const *url, int flags, char const *tmpdir, va_list children) +{ + struct cache_node *result; + struct cache_node *child; + char const *slash; + + result = pzalloc(sizeof(struct cache_node)); + result->url = pstrdup(url); + slash = strrchr(url, '/'); + result->name = slash ? (slash + 1) : result->url; + result->flags = flags; + result->tmpdir = tmpdir ? pstrdup(tmpdir) : NULL; + + while ((child = va_arg(children, struct cache_node *)) != NULL) { + HASH_ADD_KEYPTR(hh, result->children, child->name, + strlen(child->name), child); + child->parent = result; + } + + return result; +} + +struct cache_node * +uftnode(char const *url, int flags, char const *tmpdir, ...) +{ + struct cache_node *result; + va_list children; + + va_start(children, tmpdir); + result = vnode(url, flags, tmpdir, children); + va_end(children); + + return result; +} + +struct cache_node * +ufnode(char const *url, int flags, ...) +{ + struct cache_node *result; + va_list children; + + va_start(children, flags); + result = vnode(url, flags, NULL, children); + va_end(children); + + return result; +} + +struct cache_node * +unode(char const *url, ...) +{ + struct cache_node *result; + va_list children; + + va_start(children, url); + result = vnode(url, 0, NULL, children); + va_end(children); + + return result; +} diff --git a/test/cache/util.h b/test/cache/util.h new file mode 100644 index 00000000..4ff43efa --- /dev/null +++ b/test/cache/util.h @@ -0,0 +1,12 @@ +#ifndef TEST_CACHE_UTIL_H_ +#define TEST_CACHE_UTIL_H_ + +#include +#include "cache/cachent.h" + +struct cache_node *vnode(char const *, int, char const *, va_list); +struct cache_node *uftnode(char const *, int , char const *, ...); +struct cache_node *ufnode(char const *, int , ...); +struct cache_node *unode(char const *, ...); + +#endif /* TEST_CACHE_UTIL_H_ */ diff --git a/test/mock.c b/test/mock.c index 5717f797..b0bb560d 100644 --- a/test/mock.c +++ b/test/mock.c @@ -113,7 +113,6 @@ v6addr2str2(struct in6_addr const *addr) MOCK_NULL(config_get_slurm, char const *, void) MOCK(config_get_tal, char const *, "tal/", void) MOCK(config_get_local_repository, char const *, "tmp", void) -MOCK(cfg_cache_threshold, time_t, 0, void) MOCK(config_get_mode, enum mode, STANDALONE, void) MOCK_TRUE(config_get_rsync_enabled, void) MOCK_UINT(config_get_rsync_priority, 50, void)