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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
import unittest, os, signal, sys, random, time
execfile("commontest.py")
rbexec("restore.py")
"""Test consistency by killing rdiff-backup as it is backing up"""
Log.setverbosity(3)
class Local:
"""Hold some local RPaths"""
def get_local_rp(ext):
return RPath(Globals.local_connection, "testfiles/" + ext)
inc1rp = get_local_rp('increment1')
inc2rp = get_local_rp('increment2')
inc3rp = get_local_rp('increment3')
inc4rp = get_local_rp('increment4')
rpout = get_local_rp('output')
rpout_inc = get_local_rp('output_inc')
rpout1 = get_local_rp('restoretarget1')
rpout2 = get_local_rp('restoretarget2')
rpout3 = get_local_rp('restoretarget3')
rpout4 = get_local_rp('restoretarget4')
back1 = get_local_rp('backup1')
back2 = get_local_rp('backup2')
back3 = get_local_rp('backup3')
back4 = get_local_rp('backup4')
class Kill(unittest.TestCase):
def delete_tmpdirs(self):
"""Remove any temp directories created by previous tests"""
assert not os.system(MiscDir + '/myrm testfiles/output* '
'testfiles/restoretarget* testfiles/vft_out '
'timbar.pyc testfiles/vft2_out')
def is_aborted_backup(self):
"""True if there are signs of aborted backup in output/"""
try: dirlist = os.listdir("testfiles/output/rdiff-backup-data")
except OSError:
print "No data dir found, give process more time"
raise
dirlist = filter(lambda f: f.startswith("last-file-incremented"),
dirlist)
return len(dirlist) != 0
def exec_rb(self, time, wait, *args):
"""Run rdiff-backup return pid"""
arglist = ['python', '../src/rdiff-backup', '-v7']
if time:
arglist.append("--current-time")
arglist.append(str(time))
arglist.extend(args)
print "Running ", arglist
if wait: return os.spawnvp(os.P_WAIT, 'python', arglist)
else: return os.spawnvp(os.P_NOWAIT, 'python', arglist)
def exec_and_kill(self, mintime, maxtime, backup_time, *args):
"""Run rdiff-backup, then kill and run again
Kill after a time between mintime and maxtime. First process
should not terminate before maxtime.
"""
pid = self.exec_rb(backup_time, None, *args)
time.sleep(random.uniform(mintime, maxtime))
assert os.waitpid(pid, os.WNOHANG)[0] == 0, \
"Process already quit - try lowering max time"
os.kill(pid, self.killsignal)
while 1:
pid, exitstatus = os.waitpid(pid, os.WNOHANG)
if pid:
assert exitstatus != 0
break
time.sleep(0.2)
assert self.is_aborted_backup(), \
"Process already finished or didn't get a chance to start"
os.system("ls -l %s/rdiff-backup-data" % args[1])
return self.exec_rb(backup_time + 5, 1, '--resume', *args)
def verify_back_dirs(self):
"""Make sure testfiles/output/back? dirs exist"""
if (Local.back1.lstat() and Local.back2.lstat() and
Local.back3.lstat() and Local.back4.lstat()): return
os.system(MiscDir + "/myrm testfiles/backup[1-4]")
self.exec_rb(10000, 1, 'testfiles/increment1', 'testfiles/backup1')
Local.back1.setdata()
self.exec_rb(10000, 1, 'testfiles/increment1', 'testfiles/backup2')
self.exec_rb(20000, 1, 'testfiles/increment2', 'testfiles/backup2')
Local.back2.setdata()
self.exec_rb(10000, 1, 'testfiles/increment1', 'testfiles/backup3')
self.exec_rb(20000, 1, 'testfiles/increment2', 'testfiles/backup3')
self.exec_rb(30000, 1, 'testfiles/increment3', 'testfiles/backup3')
Local.back3.setdata()
self.exec_rb(10000, 1, 'testfiles/increment1', 'testfiles/backup4')
self.exec_rb(20000, 1, 'testfiles/increment2', 'testfiles/backup4')
self.exec_rb(30000, 1, 'testfiles/increment3', 'testfiles/backup4')
self.exec_rb(40000, 1, 'testfiles/increment4', 'testfiles/backup4')
Local.back4.setdata()
def runtest(self):
self.delete_tmpdirs()
self.verify_back_dirs()
# Backing up increment1 - unfortunately, not big enough to test?
#self.exec_and_kill(0.6, 0.6, 10000,
# 'testfiles/increment1', 'testfiles/output')
#assert CompareRecursive(Local.back1, Local.rpout, 1, None, None)
self.exec_rb(10000, 1, 'testfiles/increment1', 'testfiles/output')
time.sleep(1)
# Backing up increment2
self.exec_and_kill(0.7, 1.0, 20000,
'testfiles/increment2', 'testfiles/output')
assert CompareRecursive(Local.back2, Local.rpout, 1, None, None)
time.sleep(1)
# Backing up increment3
self.exec_and_kill(0.7, 2.0, 30000,
'testfiles/increment3', 'testfiles/output')
assert CompareRecursive(Local.back3, Local.rpout, 1, None, None)
time.sleep(1)
# Backing up increment4
self.exec_and_kill(1.0, 5.0, 40000,
'testfiles/increment4', 'testfiles/output')
assert CompareRecursive(Local.back4, Local.rpout, 1, None, None)
def testTERM(self):
"""Test sending local processes a TERM signal"""
self.killsignal = signal.SIGTERM
for i in range(5):
self.runtest()
def testKILL(self):
"""Send local backup process a KILL signal"""
self.killsignal = signal.SIGKILL
self.runtest()
if __name__ == "__main__": unittest.main()
|