test-dsync-mailbox-tree-sync.c revision 191153d1a5b0eb0c129139570e3aa5212f28d2ac
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainenstatic struct mail_namespace inbox_namespace = {
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen .prefix_len = sizeof(TEST_NAMESPACE_NAME)-1 + 1
5a470af15391d6fc73bebb41512a671b3d847644Timo Sirainenchar mail_namespace_get_sep(struct mail_namespace *ns ATTR_UNUSED)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenvoid mailbox_name_get_sha128(const char *name, guid_128_t guid_128_r)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen memcpy(guid_128_r, sha, I_MIN(GUID_128_SIZE, sizeof(sha)));
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainennode_create(struct dsync_mailbox_tree *tree, unsigned int counter,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen const char *name, unsigned int last_renamed_or_created)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen memcpy(node->mailbox_guid, &counter, sizeof(counter));
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen node->last_renamed_or_created = last_renamed_or_created;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenrandom_node_create(struct dsync_mailbox_tree *tree, unsigned int counter,
191153d1a5b0eb0c129139570e3aa5212f28d2acJosef 'Jeff' Sipek return node_create(tree, counter, name, i_rand_limit(10));
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void nodes_create(struct dsync_mailbox_tree *tree, unsigned int *counter,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen const char *const *names)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void nodes_delete(struct dsync_mailbox_tree *tree, unsigned int *counter,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen const char *const *names)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen node = node_create(tree, *counter, *names, 0);
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainencreate_random_nodes(struct dsync_mailbox_tree *tree, const char *parent_name,
191153d1a5b0eb0c129139570e3aa5212f28d2acJosef 'Jeff' Sipek unsigned int parent_len, i, nodes_count = i_rand_minmax(1, 3);
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen for (i = 0; i < nodes_count; i++) {
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen random_node_create(tree, *counter, str_c(str));
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen create_random_nodes(tree, str_c(str), depth+1, counter);
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic struct dsync_mailbox_tree *create_random_tree(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen unsigned int counter = 0;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_tree_nodes_fixup(struct dsync_mailbox_node **pos,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen for (node = *pos; node != NULL; node = node->next) {
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen /* the real code will pick one of the GUIDs.
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen we don't really care which one gets picked, so we'll
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen just change them to the same new one */
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen if (node->existence == DSYNC_MAILBOX_NODE_DELETED)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen node->existence = DSYNC_MAILBOX_NODE_NONEXISTENT;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_tree_nodes_fixup(&node->first_child, newguid_counter);
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen if (node->existence != DSYNC_MAILBOX_NODE_EXISTS &&
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen /* nonexistent node, drop it */
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_tree_fixup(struct dsync_mailbox_tree *tree)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_tree_nodes_fixup(&tree->root.first_child, &newguid_counter);
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void nodes_dump(const struct dsync_mailbox_node *node, unsigned int depth)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen unsigned int i;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen printf("%-*s guid:%.5s uidv:%u %d%d %ld\n", 40-depth, node->name,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen guid_128_to_string(node->mailbox_guid), node->uid_validity,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void trees_dump(struct dsync_mailbox_tree *tree1,
28542ffed61d0b860e0d1f9c837e0eb622df6b51Timo Sirainenstatic void test_trees_nofree(struct dsync_mailbox_tree *tree1,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen struct dsync_mailbox_tree *orig_tree1, *orig_tree2;
e3df4d9063a06e0cd228a1713677ec105b0a4aa2Timo Sirainen struct dsync_mailbox_node *dup_node1, *dup_node2;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen const struct dsync_mailbox_tree_sync_change *change;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen /* test tree1 -> tree2 */
e3df4d9063a06e0cd228a1713677ec105b0a4aa2Timo Sirainen dsync_mailbox_tree_build_guid_hash(tree1, &dup_node1, &dup_node2);
e3df4d9063a06e0cd228a1713677ec105b0a4aa2Timo Sirainen dsync_mailbox_tree_build_guid_hash(tree2, &dup_node1, &dup_node2);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen ctx = dsync_mailbox_trees_sync_init(tree1, tree2,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen while ((change = dsync_mailbox_trees_sync_next(ctx)) != NULL) {
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen if (!dsync_mailbox_trees_equal(tree1, tree2)) {
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen /* test tree2 -> tree1 */
e3df4d9063a06e0cd228a1713677ec105b0a4aa2Timo Sirainen dsync_mailbox_tree_build_guid_hash(orig_tree1, &dup_node1, &dup_node2);
e3df4d9063a06e0cd228a1713677ec105b0a4aa2Timo Sirainen dsync_mailbox_tree_build_guid_hash(orig_tree2, &dup_node1, &dup_node2);
e83126866761632b437e532dfdc30be01d14039dTimo Sirainen ctx = dsync_mailbox_trees_sync_init(orig_tree2, orig_tree1,
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen while ((change = dsync_mailbox_trees_sync_next(ctx)) != NULL) {
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen if (!dsync_mailbox_trees_equal(orig_tree1, orig_tree2)) {
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen /* make sure both directions produced equal trees */
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen if (!dsync_mailbox_trees_equal(tree1, orig_tree1)) {
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainentest_tree_nodes_add_namespace(struct dsync_mailbox_node *node,
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen test_tree_nodes_add_namespace(node->first_child, ns);
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainentest_tree_add_namespace(struct dsync_mailbox_tree *tree,
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen node = dsync_mailbox_tree_get(tree, TEST_NAMESPACE_NAME);
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen for (n = node->first_child; n != NULL; n = n->next)
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen test_tree_nodes_add_namespace(&tree->root, ns);
28542ffed61d0b860e0d1f9c837e0eb622df6b51Timo Sirainenstatic void test_trees(struct dsync_mailbox_tree *tree1,
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen struct dsync_mailbox_tree *tree1_dup, *tree2_dup;
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen /* test without namespace prefix */
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen /* test with namespace prefix */
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen test_tree_add_namespace(tree1_dup, &inbox_namespace);
7676a044f800a539bb0cbbc59fb9d1ad3f30ba7fTimo Sirainen test_tree_add_namespace(tree2_dup, &inbox_namespace);
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_creates(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen static const char *common_nodes[] = { "foo", "foo/bar", NULL };
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen static const char *create1_nodes[] = { "bar", "foo/baz", NULL };
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen static const char *create2_nodes[] = { "foo/xyz", "foo/bar/3", NULL };
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen unsigned int counter = 0;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync creates");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_deletes(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen static const char *common_nodes[] = { "1", "2", "3", "2/s1", "2/s2", "x/y", NULL };
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen static const char *delete1_nodes[] = { "1", "2", NULL };
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen static const char *delete2_nodes[] = { "2/s1", "x/y", NULL };
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen unsigned int counter = 0;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync deletes");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames1(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen static const char *common_nodes[] = { "1", "2", "3", "2/s1", "2/s2", "x/y", "3/s3", NULL };
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen unsigned int counter = 0;
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 1");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen dsync_mailbox_tree_node_attach(node, &tree1->root);
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames2(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 2");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames3(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 3");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames4(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 4");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames5(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 5");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames6(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 6");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames7(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 7");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames8(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 8");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames9(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 9");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames10(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 10");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames11(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 11");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames12(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 12");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames13(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 13");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames14(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 14");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames15(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 15");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames16(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 16");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames17(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 17");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames18(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 18");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames19(void)
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainen test_begin("dsync mailbox tree sync renames 19");
28542ffed61d0b860e0d1f9c837e0eb622df6b51Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames20(void)
28542ffed61d0b860e0d1f9c837e0eb622df6b51Timo Sirainen test_begin("dsync mailbox tree sync renames 20");
28542ffed61d0b860e0d1f9c837e0eb622df6b51Timo Sirainen /* rename 0 -> 1/0 */
d229d26d263a57a77eec8fe7cba24fbfd9509966Timo Sirainen test_assert(tree1->root.first_child != NULL &&
d12ea923bd1d532c6f7fee44304dde8d0f321dd0Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames21(void)
d12ea923bd1d532c6f7fee44304dde8d0f321dd0Timo Sirainen /* FIXME: we can't currently test this without crashing */
d12ea923bd1d532c6f7fee44304dde8d0f321dd0Timo Sirainen test_begin("dsync mailbox tree sync renames 21");
d12ea923bd1d532c6f7fee44304dde8d0f321dd0Timo Sirainen /* swap INBOX and foo - the INBOX name is important since it's
d12ea923bd1d532c6f7fee44304dde8d0f321dd0Timo Sirainen treated specially */
088bfb6b26ee72122f2ed8a632c741b19d8821d7Timo Sirainenstatic void test_dsync_mailbox_tree_sync_renames22(void)
088bfb6b26ee72122f2ed8a632c741b19d8821d7Timo Sirainen test_begin("dsync mailbox tree sync renames 22");
39ee82dad4d4fa61e3ed074d191afc6a9b82e249Timo Sirainenstatic void test_dsync_mailbox_tree_sync_random(void)
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen static void (*const test_functions[])(void) = {