]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Monday
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 16 Jul 2024 01:55:19 +0000 (19:55 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 16 Jul 2024 01:55:19 +0000 (19:55 -0600)
src/cache/cachent.c
src/cache/cachent.h
src/cache/local_cache.c
test/cache/local_cache_test.c

index 485ee8e73f3f96b76a7392af24d05b0553159c3d..190414e9a158e52a44f7df5b763cce4d3bcec9c1 100644 (file)
@@ -132,10 +132,8 @@ provide(struct cache_node *parent, char const *url,
        child = pzalloc(sizeof(struct cache_node));
        child->url = pstrndup(url, name - url + namelen);
        child->name = child->url + (name - url);
-       if ((parent->flags & RSYNC_INHERIT) == RSYNC_INHERIT) {
-               PR_DEBUG_MSG("parent %s has inherit; setting on %s.", parent->name, child->name);
+       if ((parent->flags & RSYNC_INHERIT) == RSYNC_INHERIT)
                child->flags = RSYNC_INHERIT;
-       }
        child->parent = parent;
        HASH_ADD_KEYPTR(hh, parent->children, child->name, namelen, child);
        return child;
index 1d124caa77f496170113e927c5769709786f179b..94beb66e34ad092068b9a9fb5177827faf84c9c0 100644 (file)
@@ -41,6 +41,7 @@
 /*
  * Flags for children of downloaded rsync nodes that should be cleaned later.
  * (FRESH prevents redownload.)
+ * XXX useful?
  */
 #define RSYNC_INHERIT          (CNF_RSYNC | CNF_FRESH)
 
index b6a4d338e79b96313063833b623fca42ed4b5e2c..ccc8e7fe6d9bfa3d7d6f6d95fe3813dc73c1422a 100644 (file)
@@ -589,13 +589,10 @@ try_uri(char const *uri, int (*download)(struct cache_node *),
                return pr_val_err("Malformed URL: %s", uri);
 
        if (download != NULL) {
-               PR_DEBUG;
                if (rpp->flags & CNF_FRESH) {
-                       PR_DEBUG_MSG("%s is fresh.", rpp->url);
                        if (rpp->dlerr)
                                return rpp->dlerr;
                } else {
-                       PR_DEBUG;
                        rpp->flags |= CNF_FRESH;
                        error = rpp->dlerr = download(rpp);
                        if (error)
@@ -674,18 +671,26 @@ commit_rpp_delta(struct cache_node *node, char const *path)
 {
        int error;
 
-       PR_DEBUG_MSG("Commiting %s", node->url);
+       pr_op_debug("Commiting %s", node->url);
 
-       if (node->tmpdir == NULL)
-               return true; /* Not updated */
+       if (node == cache.rsync || node == cache.https) {
+               pr_op_debug("Root; nothing to commit.");
+               return true;
+       }
+
+       if (node->tmpdir == NULL) {
+               pr_op_debug("Not changed; nothing to commit.");
+               return true;
+       }
 
        if (node->flags & CNF_VALID) {
+               pr_op_debug("Validation successful; committing.");
                error = file_merge_into(node->tmpdir, path);
                if (error)
                        printf("rename errno: %d\n", error); // XXX
        } else {
+               pr_op_debug("Validation unsuccessful; rollbacking.");
                /* XXX same; just do remove(). */
-               /* XXX and rename "tmpdir" into "tmp". */
                file_rm_f(node->tmpdir);
        }
 
@@ -754,6 +759,8 @@ rmf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
 {
        if (remove(fpath))
                pr_op_warn("Can't remove %s: %s", fpath, strerror(errno));
+       else
+               pr_op_debug("Removed %s.", fpath);
        return 0;
 }
 
@@ -850,19 +857,19 @@ nftw_remove_abandoned(const char *path, const struct stat *st,
        lookup = path + strlen(config_get_local_repository());
        while (lookup[0] == '/')
                lookup++;
-       PR_DEBUG_MSG("Removing if abandoned: %s", lookup);
+       pr_op_debug("Removing if abandoned: %s", lookup);
 
        pm = cachent_find(nftw_root, lookup, &msm);
        if (pm == cache.rsync || pm == cache.https) {
-               PR_DEBUG_MSG("%s", "Root; skipping.");
+               pr_op_debug("Root; skipping.");
                return 0;
        }
        if (!msm) {
-               PR_DEBUG_MSG("%s", "Not matched by the tree.");
+               pr_op_debug("Not matched by the tree; unknown.");
                goto unknown;
        }
        if (!pm && !(msm->flags & CNF_RSYNC)) {
-               PR_DEBUG_MSG("%s", "Unknown.");
+               pr_op_debug("RRDP and no perfect match; unknown.");
                goto unknown; /* The traversal is depth-first */
        }
 
@@ -872,13 +879,13 @@ nftw_remove_abandoned(const char *path, const struct stat *st,
                 * This will happen most of the time.
                 */
                if (rmdir(path) == 0) {
-                       PR_DEBUG_MSG("%s", "Directory deleted; purging node.");
+                       pr_op_debug("Directory empty; purging node.");
                        cachent_delete(pm);
                } else if (errno == ENOENT) {
-                       PR_DEBUG_MSG("%s", "Directory does not exist; purging node.");
+                       pr_op_debug("Directory does not exist; purging node.");
                        cachent_delete(pm);
                } else {
-                       PR_DEBUG_MSG("%s", "Directory exists and has contents; skipping.");
+                       pr_op_debug("Directory exists and has contents; preserving.");
                }
 
        } else if (S_ISREG(st->st_mode)) {
@@ -886,25 +893,23 @@ nftw_remove_abandoned(const char *path, const struct stat *st,
                        clock_gettime(CLOCK_REALTIME, &now); // XXX
                        PR_DEBUG_MSG("%ld > %ld", now.tv_sec - st->st_atim.tv_sec, cfg_cache_threshold());
                        if (now.tv_sec - st->st_atim.tv_sec > cfg_cache_threshold()) {
-                               PR_DEBUG_MSG("%s", "Too old.");
+                               pr_op_debug("Too old; abandoned.");
                                goto abandoned;
                        }
-                       PR_DEBUG_MSG("%s", "Young; preserving.");
+                       pr_op_debug("Still young; preserving.");
                }
 
        } else {
-               PR_DEBUG_MSG("%s", "Unknown type.");
+               pr_op_debug("Unknown type; abandoned.");
                goto abandoned;
        }
 
        return 0;
 
 abandoned:
-       PR_DEBUG;
        if (pm)
                cachent_delete(pm);
 unknown:
-       PR_DEBUG;
        if (remove(path))
                PR_DEBUG_MSG("remove(): %s", strerror(errno)); // XXX
        return 0;
@@ -923,18 +928,43 @@ remove_abandoned(void)
        rootpath = join_paths(config_get_local_repository(), "rsync");
 
        nftw_root = cache.rsync;
-       PR_DEBUG_MSG("nftw(%s)", rootpath);
        nftw(rootpath, nftw_remove_abandoned, 32, FTW_DEPTH | FTW_PHYS); // XXX
 
        strcpy(rootpath + strlen(rootpath) - 5, "https");
 
        nftw_root = cache.https;
-       PR_DEBUG_MSG("nftw(%s)", rootpath);
        nftw(rootpath, nftw_remove_abandoned, 32, FTW_DEPTH | FTW_PHYS); // XXX
 
        free(rootpath);
 }
 
+static void
+remove_leftover_nodes(void)
+{
+       struct cache_node *domain, *tmp1;
+       struct cache_node *module, *tmp2;
+       struct cache_node *child, *tmp3;
+
+       HASH_ITER(hh, cache.rsync->children, domain, tmp1)
+               HASH_ITER(hh, domain->children, module, tmp2)
+                       HASH_ITER(hh, module->children, child, tmp3) {
+                               pr_op_debug("Removing leftover: %s", child->url);
+                               cachent_delete(child);
+                       }
+}
+
+static bool
+remove_orphaned(struct cache_node *node, char const *path)
+{
+       if (file_exists(path) == ENOENT) {
+               pr_op_debug("Missing file; deleting node: %s", path);
+               cachent_delete(node);
+               return false;
+       }
+
+       return true;
+}
+
 /*
  * Deletes unknown and old untraversed cached files, writes metadata into XML.
  */
@@ -951,6 +981,11 @@ cleanup_cache(void)
        pr_op_debug("Cleaning up old abandoned and unknown cache files.");
        remove_abandoned();
 
+       pr_op_debug("Cleaning up leftover nodes.");
+       remove_leftover_nodes();
+       cachent_traverse(cache.rsync, remove_orphaned);
+       cachent_traverse(cache.https, remove_orphaned);
+
        /* XXX delete nodes for which no file exists? */
 }
 
index 7ad51e816c50a938b189bb9f01682faa8b1b93c9..303fe5dca8087a80ff42d5bd2402627d2792c907 100644 (file)
@@ -108,13 +108,45 @@ run_dl_rsync(char const *caRepository, int expected_error,
 
        rsync_counter = 0;
        https_counter = 0;
+       printf("---- Downloading... ----\n");
        ck_assert_int_eq(expected_error, cache_download_alt(&sias, okay, NULL));
+       printf("---- Downloaded. ----\n");
        ck_assert_uint_eq(expected_calls, rsync_counter);
        ck_assert_uint_eq(0, https_counter);
 
        sias_cleanup(&sias);
 }
 
+static int
+print_file(const char *fpath, const struct stat *sb, int typeflag,
+    struct FTW *ftwbuf)
+{
+       printf("- %s\n", fpath);
+       return 0;
+}
+
+static void
+print_tree(void)
+{
+       printf("Tree nodes:\n");
+       cache_print();
+       printf("\n");
+
+       printf("Files in cache:\n");
+       ck_assert_int_eq(0, nftw("tmp/", print_file, 32, FTW_PHYS));
+       printf("\n");
+}
+
+static void
+run_cleanup(void)
+{
+       print_tree();
+
+       pr_op_debug("---- Cleaning up... ----");
+       cleanup_cache();
+       pr_op_debug("---- Cleant. ----");
+}
+
 static bool
 ck_path(struct cache_node *node, char const *_)
 {
@@ -123,7 +155,6 @@ ck_path(struct cache_node *node, char const *_)
        if (!node->tmpdir)
                return true;
 
-       PR_DEBUG_MSG("Checking file exists in cache: %s (%s)", node->tmpdir, node->url);
        error = file_exists(node->tmpdir);
        if (error)
                ck_abort_msg("Missing file in cache: %s (%s)", node->tmpdir, strerror(error));
@@ -173,6 +204,10 @@ ck_assert_cachent_eq(struct cache_node *expected, struct cache_node *actual)
        ck_assert_str_eq(expected->url, actual->url);
        ck_assert_str_eq(expected->name, actual->name);
        ck_assert_int_eq(expected->flags, actual->flags);
+       if (expected->tmpdir)
+               ck_assert_str_eq(expected->tmpdir, actual->tmpdir);
+       else
+               ck_assert_ptr_eq(NULL, actual->tmpdir);
 
        HASH_ITER(hh, expected->children, echild, tmp) {
                HASH_FIND(hh, actual->children, echild->name,
@@ -190,31 +225,17 @@ ck_assert_cachent_eq(struct cache_node *expected, struct cache_node *actual)
        }
 }
 
-static int
-print_file(const char *fpath, const struct stat *sb, int typeflag,
-    struct FTW *ftwbuf)
-{
-       printf("- %s\n", fpath);
-       return 0;
-}
-
 static void
 ck_cache(struct cache_node *rsync, struct cache_node *https)
 {
-       printf("------------------------------\n");
+       printf("---- Validating tree... ----\n");
 
        printf("Expected nodes:\n");
        cachent_print(rsync);
        cachent_print(https);
        printf("\n");
 
-       printf("Actual nodes:\n");
-       cache_print();
-       printf("\n");
-
-       printf("Files in cache:\n");
-       ck_assert_int_eq(0, nftw("tmp/", print_file, 32, FTW_PHYS));
-       printf("\n");
+       print_tree();
 
        /* Compare expected and cache */
        // XXX fix
@@ -229,6 +250,8 @@ ck_cache(struct cache_node *rsync, struct cache_node *https)
 
        cachent_delete(rsync);
        cachent_delete(https);
+
+       printf("---- Validated. ----\n");
 }
 
 static void
@@ -297,106 +320,106 @@ 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;
+static const int BRANCH = RSYNC_INHERIT;
+static const int FAILED = CNF_FRESH;
 
-//START_TEST(test_cache_download_rsync)
-//{
-//     setup_test(false);
-//
-//     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));
-//
-//     /* 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));
-//
-//     /*
-//      * 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));
-//
-//     /*
-//      * 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", 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));
-//
-//     /* 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));
-//
-//     cleanup_test();
-//}
-//END_TEST
-//
-//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));
-//
-//     /* 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_download_rsync)
+{
+       setup_test(false);
+
+       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));
+
+       /* 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));
+
+       /*
+        * 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));
+
+       /*
+        * 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", 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));
+
+       /* 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));
+
+       cleanup_test();
+}
+END_TEST
+
+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));
+
+       /* 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)
 {
@@ -406,11 +429,11 @@ START_TEST(test_cache_cleanup_rsync)
         * First iteration: Tree is created. No prunes, because nothing's
         * outdated.
         */
-       PR_DEBUG;
+       printf("==== First iteration: Tree is created ====\n");
        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();
+       run_cleanup();
        ck_cache_rsync(
                unode("rsync",
                        unode("rsync/a.b.c",
@@ -418,11 +441,11 @@ START_TEST(test_cache_cleanup_rsync)
                                ufnode("rsync/a.b.c/e", FULL, NULL), NULL), NULL));
 
        /* One iteration with no changes, for paranoia */
-       PR_DEBUG;
+       printf("==== No changes, for paranoia ====\n");
        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();
+       run_cleanup();
        ck_cache_rsync(
                unode("rsync",
                        unode("rsync/a.b.c",
@@ -430,12 +453,12 @@ START_TEST(test_cache_cleanup_rsync)
                                ufnode("rsync/a.b.c/e", FULL, NULL), NULL), NULL));
 
        /* Add one sibling */
-       PR_DEBUG;
+       printf("==== Add one sibling ====\n");
        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();
+       run_cleanup();
        ck_cache_rsync(
                unode("rsync",
                        unode("rsync/a.b.c",
@@ -444,9 +467,9 @@ START_TEST(test_cache_cleanup_rsync)
                                ufnode("rsync/a.b.c/f", FULL, NULL), NULL), NULL));
 
        /* Nodes don't get updated, but they're still too young. */
-       PR_DEBUG;
+       printf("==== Still too young ====\n");
        new_iteration(false);
-       cleanup_cache();
+       run_cleanup();
        ck_cache_rsync(
                unode("rsync",
                        unode("rsync/a.b.c",
@@ -455,57 +478,74 @@ START_TEST(test_cache_cleanup_rsync)
                                ufnode("rsync/a.b.c/f", STALE, NULL), NULL), NULL));
 
        /* Remove some branches */
+       printf("==== Remove some branches ====\n");
        new_iteration(true);
        run_dl_rsync("rsync://a.b.c/d", 0, 1);
-       cleanup_cache();
+       run_cleanup();
        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 */
+       printf("==== Remove old branch + add sibling ====\n");
        new_iteration(true);
        run_dl_rsync("rsync://a.b.c/e", 0, 1);
-       cleanup_cache();
+       run_cleanup();
        ck_cache_rsync(
                unode("rsync",
                        unode("rsync/a.b.c",
                                ufnode("rsync/a.b.c/e", FULL, NULL), NULL), NULL));
 
        /* Try child */
+       printf("==== Try child ====\n");
        new_iteration(true);
        run_dl_rsync("rsync://a.b.c/e/f/g", 0, 1);
-       cleanup_cache();
+       run_cleanup();
        ck_cache_rsync(
                unode("rsync",
                        unode("rsync/a.b.c",
                                ufnode("rsync/a.b.c/e", FULL, NULL), NULL), NULL));
 
-//     /* Parent again */
-//     new_iteration(true);
-//     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/e", FULL, NULL), NULL), NULL));
-//
-//     /* Empty the tree */
-//     new_iteration(true);
-//     cleanup_cache();
-//     ck_cache(NULL);
-//
-//     /* Node exists, but file doesn't */
-//     new_iteration(true);
-//     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"));
-//     cleanup_cache();
-//     ck_cache(NODE("rsync://a.b.c/e/", 0, 1, true), NULL);
+       /* Parent again */
+       printf("==== Parent again ====\n");
+       new_iteration(true);
+       run_dl_rsync("rsync://a.b.c/e", 0, 1);
+       run_cleanup();
+       ck_cache_rsync(
+               unode("rsync",
+                       unode("rsync/a.b.c",
+                               ufnode("rsync/a.b.c/e", FULL, NULL), NULL), NULL));
+
+       /* Empty the tree */
+       printf("==== Empty the tree ====\n");
+       new_iteration(true);
+       run_cleanup();
+       ck_cache_rsync(unode("rsync", NULL));
+
+
+       /* Node exists, but file doesn't */
+       printf("==== Node exists, but file doesn't ====\n");
+       new_iteration(true);
+       run_dl_rsync("rsync://a.b.c/e", 0, 1);
+       run_dl_rsync("rsync://a.b.c/f", 0, 1);
+       ck_cache_rsync(
+               unode("rsync",
+                       unode("rsync/a.b.c",
+                               uftnode("rsync/a.b.c/e", FULL, "tmp/tmp/B", NULL),
+                               uftnode("rsync/a.b.c/f", FULL, "tmp/tmp/C", NULL), NULL), NULL));
+       run_cleanup();
+       ck_cache_rsync(
+               unode("rsync",
+                       unode("rsync/a.b.c",
+                               ufnode("rsync/a.b.c/e", FULL, NULL),
+                               ufnode("rsync/a.b.c/f", FULL, NULL), NULL), NULL));
+       ck_assert_int_eq(0, file_rm_rf("tmp/rsync/a.b.c/f"));
+       run_cleanup();
+       ck_cache_rsync(
+               unode("rsync",
+                       unode("rsync/a.b.c",
+                               ufnode("rsync/a.b.c/e", FULL, NULL), NULL), NULL));
 
        cleanup_test();
 }
@@ -526,7 +566,7 @@ END_TEST
 //             NULL);
 //
 //     /* Node gets deleted because cached file doesn't exist */
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(NODE("rsync://a.b.c/d/", 0, 1, true), NULL);
 //
 //     /*
@@ -541,7 +581,7 @@ END_TEST
 //
 //     /* Error is old; gets deleted */
 //     new_iteration(true);
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(NULL);
 //
 //     cleanup_test();
@@ -610,7 +650,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);
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(
 //             NODE("https://a.b.c/d", 0, 1, 1),
 //             NODE("https://a.b.c/e", 0, 1, 1),
@@ -619,19 +659,19 @@ END_TEST
 //     /* Remove one branch */
 //     new_iteration(true);
 //     run_cache_download("https://a.b.c/d", 0, 0, 1);
-//     cleanup_cache();
+//     do_cleanup();
 //     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);
-//     cleanup_cache();
+//     do_cleanup();
 //     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);
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(
 //             NODE("https://a.b.c/e/f/g", 0, 1, 1), NULL);
 //
@@ -641,18 +681,18 @@ END_TEST
 //      */
 //     new_iteration(true);
 //     run_cache_download("https://a.b.c/e/f", 0, 0, 1);
-//     cleanup_cache();
+//     do_cleanup();
 //     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);
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(NODE("https://a.b.c/e", 0, 1, 1), NULL);
 //
 //     /* Empty the tree */
 //     new_iteration(true);
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(NULL);
 //
 //     /* Node exists, but file doesn't */
@@ -664,7 +704,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"));
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(NODE("https://a.b.c/e", 0, 1, 1), NULL);
 //
 //     cleanup_test();
@@ -686,7 +726,7 @@ END_TEST
 //         NULL);
 //
 //     /* Deleted because file ENOENT. */
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(
 //         NODE("https://a.b.c/d", 0, 1, 1),
 //         NULL);
@@ -699,12 +739,12 @@ END_TEST
 //
 //     /* Not deleted, because not old */
 //     new_iteration(false);
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(NODE("https://a.b.c/d", -EINVAL, 1, 1), NULL);
 //
 //     /* Become old */
 //     new_iteration(true);
-//     cleanup_cache();
+//     do_cleanup();
 //     ck_cache(NULL);
 //
 //     cleanup_test();
@@ -930,8 +970,8 @@ 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_error);
+       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_error);