aboutsummaryrefslogtreecommitdiffstats
path: root/tests/repair/t
blob: 10fab0de81965e0e39d9926632ddd072b90396ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# create some mailboxes and populate them
doveadm -u "local"  mailbox create "foo.bar"
doveadm -u "remote" mailbox create "foo~bar" "baz"
for ((i = 0; i < 8; i++)); do
    sample_message | deliver -u "local"  -- -m "foo.bar"
    sample_message | deliver -u "remote" -- -m "foo~bar"
done
for ((i = 0; i < 64; i++)); do
    sample_message | deliver -u "remote" -- -m "baz"
done

interimap_init
check_mailbox_list
check_mailboxes_status "foo.bar" "baz" "INBOX"

# make more changes (flag updates, new massages, deletions)
sample_message | deliver -u "remote" -- -m "INBOX"
doveadm -u "local"  expunge mailbox "baz" 1:10
doveadm -u "remote" expunge mailbox "baz" "$(seq -s"," 1 2 32),$(seq -s"," 40 2 64)"
doveadm -u "local"  expunge mailbox "foo.bar" 2,3,5:7,10
doveadm -u "remote" expunge mailbox "foo~bar" 4,5,7,10
doveadm -u "local"  flags add "\\Answered" mailbox "foo.bar" 2,3,5:7,10
doveadm -u "remote" flags add "\\Seen"     mailbox "foo~bar" 4,5,7

# spoof HIGHESTMODSEQ value in the database to make it look that we recorded the new changes already
spoof() {
    local k="$1" v m hex="$(printf "%s\\0%s" "foo" "bar" | xxd -ps)"
    shift
    while [ $# -gt 0 ]; do
        [ "$1" = "local" ] && m="foo.bar" || m="$(printf "%s" "foo.bar" | tr "." "~")"
        v="$(doveadm -u "$1"  -f flow mailbox status "${k,,[A-Z]}" "$m" | sed 's/.*=//')"
	    sqlite3 "$XDG_DATA_HOME/interimap/remote.db" <<-EOF
			UPDATE \`$1\` SET $k = $v
			 WHERE idx = (SELECT idx FROM mailboxes WHERE mailbox = x'$hex');
		EOF
        shift
    done
}

spoof HIGHESTMODSEQ "local" "remote"
sqlite3 "$XDG_DATA_HOME/interimap/remote.db" >"$TMPDIR/dump.sql" <<-EOF
	.dump
EOF
doveadm -u "local"  mailbox status "all" "foo.bar" >"$TMPDIR/foo-bar.status.local"
doveadm -u "remote" mailbox status "all" "foo~bar" >"$TMPDIR/foo-bar.status.remote"


# verify that without --repair interimap does nothing due to the spoofed HIGHESTMODSEQ values
interimap "foo.bar" || error

sqlite3 "$XDG_DATA_HOME/interimap/remote.db" >"$TMPDIR/dump2.sql" <<-EOF
	.dump
EOF
doveadm -u "local"  mailbox status all "foo.bar" >"$TMPDIR/foo-bar.status2.local"
doveadm -u "remote" mailbox status all "foo~bar" >"$TMPDIR/foo-bar.status2.remote"
diff -u --label="a/dump.sql"       --label="b/dump.sql"       "$TMPDIR/dump.sql"              "$TMPDIR/dump2.sql"
diff -u --label="a/foo_bar.local"  --label="a/foo_bar.local"  "$TMPDIR/foo-bar.status.local"  "$TMPDIR/foo-bar.status2.local"
diff -u --label="a/foo_bar.remote" --label="a/foo_bar.remote" "$TMPDIR/foo-bar.status.remote" "$TMPDIR/foo-bar.status2.remote"


# deliver more messages and spoof UIDNEXT *on one side only*
sample_message | deliver -u "local"  -- -m "foo.bar"
sample_message | deliver -u "remote" -- -m "foo~bar"
spoof UIDNEXT "local"
spoof HIGHESTMODSEQ "local" "remote"

# now repair
interimap --repair "baz" "foo.bar" || error

# 6 updates with \Answered (luid 4,8,11:13,16), 2 of which (luid 12,13) vanished from remote
# 3 updates with \Seen (ruid 6,8,10), 1 of which (uid 10) vanished from remote
# luid 16 <-> ruid 8 has both \Answered and \Seen
xcgrep 5 '^WARNING: Missed flag update in foo\.bar for '  <"$STDERR"
xcgrep 5 '^WARNING: Conflicting flag update in foo\.bar ' <"$STDERR"

# luid 2 <-> ruid 10
xcgrep 1 -E '^WARNING: Pair \(lUID,rUID\) = \([0-9]+,[0-9]+\) vanished from foo\.bar\. Repairing\.$' <"$STDERR"

# 6-1 (luid 2 <-> ruid 10 is gone from both)
xcgrep 5 -E '^local\(foo\.bar\): WARNING: UID [0-9]+ disappeared. Redownloading remote UID [0-9]+\.$' <"$STDERR"

# 6-1 (luid 2 <-> ruid 10 is gone from both)
xcgrep 3 -E '^remote\(foo~bar\): WARNING: UID [0-9]+ disappeared. Redownloading local UID [0-9]+\.$' <"$STDERR"

grep -E '^local\(baz\): Removed 24 UID\(s\) ' <"$STDERR" || error
grep -E '^remote\(baz\): Removed 5 UID\(s\) ' <"$STDERR" || error

# hardcoding UIDs here is not very robust...
grep -E '^local\(foo\.bar\): Updated flags \(\\Answered \\Seen\) for UID 16$' <"$STDERR" || error
grep -E '^local\(foo\.bar\): Updated flags \(\\Seen\) for UID 14$'            <"$STDERR" || error
grep -E '^remote\(foo~bar\): Updated flags \(\\Answered \\Seen\) for UID 8$'  <"$STDERR" || error
grep -E '^remote\(foo~bar\): Updated flags \(\\Answered\) for UID 3,12,16$'   <"$STDERR" || error

# luid 17
xcgrep 1 -E '^remote\(foo~bar\): WARNING: No match for modified local UID [0-9]+. Redownloading\.' <"$STDERR"

grep -E '^local\(foo\.bar\): Added 5 UID\(s\) ' <"$STDERR" || error
grep -E '^remote\(foo~bar\): Added 4 UID\(s\) ' <"$STDERR" || error
grep -E '^local\(foo\.bar\): Added 1 UID\(s\) ' <"$STDERR" || error # the new message

check_mailbox_list
check_mailboxes_status "baz" "foo.bar"

interimap || error
check_mailboxes_status "baz" "foo.bar" "INBOX"

# vim: set filetype=bash :