rework testsuite, and add a testcase for successful merging
[opensuse:osc.git] / tests.py
1 #!/usr/bin/python
2
3 import os
4 import sys
5 import time
6 import re
7 import unittest
8 import shutil
9 from textwrap import dedent
10
11 from osc import commandline
12
13 chdir = os.chdir
14 mkdir = os.mkdir
15
16 # here, all tests will happen... 
17 BASEDIR = os.path.join(os.getcwd(), 't')
18
19 PRJ = 'home:poeml'
20 PAC = 'test'
21 TESTPACDIR = os.path.join(PRJ, PAC)
22
23
24 def remove_revid(s):
25     return re.sub('revision \d*', 'revision XX', s)
26
27
28 def checkout_and_clean(self):
29     """check out the package and delete all files
30     leave behind the empty package dir"""
31     runosc('co %s %s' % (PRJ, PAC))
32     chdir(TESTPACDIR)
33
34     files, err = runosc('ls %s %s' %(PRJ, PAC))
35     files = files.strip().split('\n')
36     if files != ['']:
37         for file in files:
38             runosc('rm %s' % file)
39         runosc('ci')
40
41
42 class TestOsc(unittest.TestCase):
43     
44     def setUp(self):
45
46         if not os.path.isabs(BASEDIR):
47             sys.exit('BASEDIR must be absolute')
48
49         shutil.rmtree(BASEDIR, ignore_errors=True)
50         mkdir(BASEDIR)
51         chdir(BASEDIR)
52
53
54
55     #####################################################################
56
57     def testUsermeta(self):
58         expect = """<person>
59   <login>poeml</login>
60   <email>poeml@suse.de</email>
61   <realname>Dr. Peter Poeml</realname>
62   <source_backend>
63     <host></host>
64     <port></port>
65   </source_backend>
66   <rpm_backend>
67     <host></host>
68     <port></port>
69   </rpm_backend>
70   <watchlist>
71     <project name="server:mail"/>
72     <project name="frox"/>
73     <project name="home:cthiel1"/>
74     <project name="server:php"/>
75     <project name="Apache"/>
76     <project name="server:httpd-trunk"/>
77     <project name="server:isc-dhcp"/>
78     <project name="Subversion"/>
79     <project name="Tidy"/>
80     <project name="validators"/>
81     <project name="zsh"/>
82     <project name="home:poeml"/>
83     <project name="Apache:Modules"/>
84   </watchlist>
85 </person>
86
87 """
88
89         self.out, self.err = runosc('usermeta poeml')
90         self.assertEqual(self.err, '')
91         self.assertEqual(self.out, expect)
92
93
94     #####################################################################
95
96     def testLs(self):
97         self.out, self.err = runosc('ls')
98         self.assertEqual(self.err, '')
99         self.assert_('Apache' in self.out)
100         self.assert_(PRJ in self.out)
101
102
103     def testLsPrj(self):
104         self.out, self.err = runosc('ls Apache')
105         self.assertEqual(self.err, '')
106         self.assert_('apache2' in self.out)
107
108
109     def testLsPac(self):
110         self.out, self.err = runosc('ls Apache apache2')
111         self.assertEqual(self.err, '')
112         self.assert_('favicon.ico' in self.out)
113
114     #####################################################################
115
116     def testMetaPrj(self):
117         self.out, self.err = runosc('meta Apache')
118         self.assertEqual(self.err, '')
119         self.assert_('<project name="Apache">' in self.out)
120
121
122     def testMetaPac(self):
123         self.out, self.err = runosc('meta Apache apache2')
124         self.assertEqual(self.err, '')
125         self.assert_('<package name="apache2" project="Apache">' in self.out)
126
127
128     #####################################################################
129
130     def testPlatforms(self):
131         self.out, self.err = runosc('platforms')
132         self.assertEqual(self.err, '')
133         self.assert_('Factory/standard' in self.out)
134         self.assert_('SUSE:SL-10.1/standard' in self.out)
135
136
137     def testPlatformsPac(self):
138         self.out, self.err = runosc('platforms Apache')
139         self.assertEqual(self.err, '')
140         self.assert_('openSUSE_Factory' in self.out)
141
142
143     #####################################################################
144
145     def testMerge(self):
146
147         wc1 = os.path.join(BASEDIR, TESTPACDIR)
148         wc2 = os.path.join(BASEDIR, 'otherwc')
149
150         checkout_and_clean(self)
151
152         # from wc1, create and check in a file
153         open('foo', 'w').write(dedent("""\
154             ein
155             blaues
156             Haus
157             """))
158         runosc('add foo')
159         runosc('ci')
160
161
162         # create second working copy, and do a local modification
163         mkdir(wc2)
164         chdir(wc2)
165         runosc('init %s %s' % (PRJ, PAC))
166         runosc('up')
167         open('foo', 'w').write(dedent("""\
168             kein
169             blaues
170             Haus
171             """))
172
173         self.out, self.err = runosc('st')
174         self.assertEqual(self.err, '')
175         self.assertEqual(self.out, 'M    foo\n')
176
177         # from wc1, commit a change 
178         chdir(wc1)
179         open('foo', 'a').write("""geht aus""")
180         runosc('ci')
181
182         # in wc2, update, and the change should be merged in
183         chdir(wc2)
184         self.out, self.err = runosc('up')
185         self.assertEqual(self.err, '')
186         self.assertEqual(remove_revid(self.out), 'G    foo\nAt revision XX.\n')
187
188         self.out, self.err = runosc('st')
189         self.assertEqual(self.err, '')
190         self.assertEqual(self.out, 'M    foo\n')
191
192         # successful merge is one thing, but checking the local modification 
193         # makes sure that the store copy has been updated to the upstream revision
194         self.out, self.err = runosc('diff')
195         self.assertEqual(self.err, '')
196         expected = dedent("""\
197             Index: foo
198             ===================================================================
199             --- foo     (revision XX) 
200             +++ foo     (working copy) 
201             @@ -1,4 +1,4 @@
202             -ein
203             +kein
204              blaues
205              Haus
206              geht aus
207             """)
208         self.assertEqual(remove_revid(self.out), expected)
209
210
211
212     #####################################################################
213
214     def testCoPrj(self):
215         self.out, self.err = runosc('co %s' % PRJ)
216         self.assertEqual(self.err, '')
217         self.assert_('A    %s/%s' %(PRJ, PAC) in self.out)
218
219
220     def testCoPac(self):
221         # check out package dir
222         self.out, self.err = runosc('co %s %s' % (PRJ, PAC))
223         self.assertEqual(self.err, '')
224         self.assert_('A    %s/%s' %(PRJ, PAC) in self.out)
225
226     def testCoPacAndDoStuff(self):
227         checkout_and_clean(self)
228
229         # check in a file
230         # give an error if it doesn't exist
231         self.out, self.err = runosc('add foo1')
232         self.assertEqual(self.err, '')
233         self.assertEqual(self.out, 'file \'foo1\' does not exist\n')
234
235         touch('foo1')
236         self.out, self.err = runosc('add foo1')
237         self.assertEqual(self.err, '')
238         self.assertEqual(self.out, 'A    foo1\n')
239
240         self.out, self.err = runosc('ci')
241         self.assertEqual(self.err, '')
242         self.assertEqual(self.out, """Sending        foo1
243 Transmitting file data .
244 """)
245
246
247         # delete a file
248         self.out, self.err = runosc('rm foo1')
249         self.assertEqual(self.err, '')
250         self.assertEqual(self.out, 'D    foo1\n')
251
252         self.out, self.err = runosc('ci')
253         self.assertEqual(self.err, '')
254         self.assertEqual(self.out, """Deleting       foo1
255 Transmitting file data 
256 """)
257
258
259         # test 'status'
260         touch('onlyinwc')
261         self.out, self.err = runosc('st')
262         self.assertEqual(self.err, '')
263         self.assertEqual(self.out, '?    onlyinwc\n')
264
265         touch('foo2')
266         self.out, self.err = runosc('add foo2')
267         self.out, self.err = runosc('st')
268         self.assertEqual(self.err, '')
269         self.assertEqual(self.out, '?    onlyinwc\nA    foo2\n')
270
271         # status with an absolute directory as argument
272         self.out, self.err = runosc('st %s' % os.getcwd())
273         self.assertEqual(self.err, '')
274         self.assertEqual(self.out, '?    %s/onlyinwc\nA    %s/foo2\n' % (os.getcwd(), os.getcwd()))
275
276         # status with an absolute directory as argument
277         self.out, self.err = runosc('st %s' % os.getcwd())
278         self.assertEqual(self.err, '')
279         self.assertEqual(self.out, '?    %s/onlyinwc\nA    %s/foo2\n' % (os.getcwd(), os.getcwd()))
280
281         # status with a single file as argument
282         reldir = os.path.basename(os.getcwd())
283         self.out, self.err = runosc('st foo2')
284         self.assertEqual(self.err, '')
285         self.assertEqual(self.out, 'A    foo2\n')
286
287         # check in a single argument
288         self.out, self.err = runosc('ci foo2')
289         self.assertEqual(self.err, '')
290         self.assertEqual(self.out, """Sending        foo2
291 Transmitting file data .
292 """)
293
294         # clean up
295         self.out, self.err = runosc('st')
296         self.assertEqual(self.err, '')
297         self.assertEqual(self.out, '?    onlyinwc\n')
298         os.unlink('onlyinwc')
299
300
301         # test 'addremove'
302         touch('bar1')
303         os.unlink('foo2')
304         self.out, self.err = runosc('addremove')
305         self.assertEqual(self.err, '')
306         self.assertEqual(self.out, 'D    foo2\nA    bar1\n')
307         self.out, self.err = runosc('ci')
308         self.assertEqual(self.err, '')
309         self.assertEqual(self.out, """Sending        bar1
310 Deleting       foo2
311 Transmitting file data .
312 """)
313
314
315
316
317
318
319
320
321 #####################################################################
322
323
324 def runosc(argstring):
325     #time.sleep(1) # don't stress the server
326
327     # we test the osc in this directory, not a system one
328     return runcmd(os.path.join(startdir, 'osc-wrapper.py'), argstring)
329
330
331 def runcmd(cmd, argstring):
332     child_stdin, child_stdout, child_stderr = os.popen3(cmd + ' ' + argstring)
333     return child_stdout.read(), child_stderr.read()
334
335
336 def touch(filename):
337     open(filename, 'w').close();
338
339
340 if __name__ == '__main__':
341
342     #unittest.main()
343     startdir = os.getcwd()
344     suite = unittest.makeSuite(TestOsc)
345     unittest.TextTestRunner(verbosity=2).run(suite)