fix up tests:TestOsc.testMerge for r1732 (diff handling files not ending with a newline)
[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 startdir = os.getcwd()
23
24
25 def remove_revid(s):
26     return re.sub('revision \d*', 'revision XX', s)
27
28
29 def checkout_and_clean(self):
30     """check out the package and delete all files
31     leave behind the empty package dir"""
32     runosc('co %s %s' % (PRJ, PAC))
33     chdir(TESTPACDIR)
34
35     files, err = runosc('ls %s %s' %(PRJ, PAC))
36     files = files.strip().split('\n')
37     if files != ['']:
38         for file in files:
39             runosc('rm %s' % file)
40         runosc('ci')
41
42
43 class TestOsc(unittest.TestCase):
44     
45     def setUp(self):
46
47         if not os.path.isabs(BASEDIR):
48             sys.exit('BASEDIR must be absolute')
49
50         shutil.rmtree(BASEDIR, ignore_errors=True)
51         mkdir(BASEDIR)
52         chdir(BASEDIR)
53
54
55
56     #####################################################################
57
58     def testUsermeta(self):
59         expect = """<person>
60   <login>poeml</login>
61   <email>poeml@suse.de</email>
62   <realname>Dr. Peter Poeml</realname>
63   <watchlist>
64     <project name="server:mail"/>
65     <project name="frox"/>
66     <project name="home:cthiel1"/>
67     <project name="server:php"/>
68     <project name="Apache"/>
69     <project name="server:httpd-trunk"/>
70     <project name="server:isc-dhcp"/>
71     <project name="Subversion"/>
72     <project name="Tidy"/>
73     <project name="validators"/>
74     <project name="zsh"/>
75     <project name="Apache:Modules"/>
76     <project name="home:poeml"/>
77   </watchlist>
78 </person>
79
80 """
81
82         self.out, self.err = runosc('usermeta poeml')
83         self.assertEqual(self.err, '')
84         self.assertEqual(self.out, expect)
85
86
87     #####################################################################
88
89     def testLs(self):
90         self.out, self.err = runosc('ls')
91         self.assertEqual(self.err, '')
92         self.assert_('Apache' in self.out)
93         self.assert_(PRJ in self.out)
94
95
96     def testLsPrj(self):
97         self.out, self.err = runosc('ls Apache')
98         self.assertEqual(self.err, '')
99         self.assert_('apache2' in self.out)
100
101
102     def testLsPac(self):
103         self.out, self.err = runosc('ls Apache apache2')
104         self.assertEqual(self.err, '')
105         self.assert_('favicon.ico' in self.out)
106
107     #####################################################################
108
109     def testMetaPrj(self):
110         self.out, self.err = runosc('meta Apache')
111         self.assertEqual(self.err, '')
112         self.assert_('<project name="Apache">' in self.out)
113
114
115     def testMetaPac(self):
116         self.out, self.err = runosc('meta Apache apache2')
117         self.assertEqual(self.err, '')
118         self.assert_('<package project="Apache" name="apache2">' in self.out)
119
120
121     #####################################################################
122
123     def testPlatforms(self):
124         self.out, self.err = runosc('platforms')
125         self.assertEqual(self.err, '')
126         self.assert_('Factory/standard' in self.out)
127         self.assert_('SUSE:SL-10.1/standard' in self.out)
128
129
130     def testPlatformsPac(self):
131         self.out, self.err = runosc('platforms Apache')
132         self.assertEqual(self.err, '')
133         self.assert_('openSUSE_Factory' in self.out)
134
135
136     #####################################################################
137
138     def testMerge(self):
139
140         wc1 = os.path.join(BASEDIR, TESTPACDIR)
141         wc2 = os.path.join(BASEDIR, 'otherwc')
142
143         checkout_and_clean(self)
144
145         # from wc1, create and check in a file
146         open('foo', 'w').write(dedent("""\
147             ein
148             blaues
149             Haus
150             """))
151         runosc('add foo')
152         runosc('ci')
153
154
155         # create second working copy, and do a local modification
156         mkdir(wc2)
157         chdir(wc2)
158         runosc('init %s %s' % (PRJ, PAC))
159         runosc('up')
160         open('foo', 'w').write(dedent("""\
161             kein
162             blaues
163             Haus
164             """))
165
166         self.out, self.err = runosc('st')
167         self.assertEqual(self.err, '')
168         self.assertEqual(self.out, 'M    foo\n')
169
170         # from wc1, commit a change 
171         chdir(wc1)
172         open('foo', 'a').write("""geht aus""")
173         runosc('ci')
174
175         # in wc2, update, and the change should be merged in
176         chdir(wc2)
177         self.out, self.err = runosc('up')
178         self.assertEqual(self.err, '')
179         self.assertEqual(remove_revid(self.out), 'G    foo\nAt revision XX.\n')
180
181         self.out, self.err = runosc('st')
182         self.assertEqual(self.err, '')
183         self.assertEqual(self.out, 'M    foo\n')
184
185         # successful merge is one thing, but checking the local modification 
186         # makes sure that the store copy has been updated to the upstream revision
187         self.out, self.err = runosc('diff')
188         self.assertEqual(self.err, '')
189         expected = dedent("""\
190             Index: foo
191             ===================================================================
192             --- foo     (revision XX) 
193             +++ foo     (working copy) 
194             @@ -1,4 +1,4 @@
195             -ein
196             +kein
197              blaues
198              Haus
199              geht aus
200             \\ No newline at end of file
201             """)
202         self.assertEqual(remove_revid(self.out), expected)
203
204
205
206     #####################################################################
207
208     def testUpdateLocalMod(self):
209
210         wc1 = os.path.join(BASEDIR, TESTPACDIR)
211         wc2 = os.path.join(BASEDIR, 'otherwc')
212
213         checkout_and_clean(self)
214
215         # in wc1, create and check in two files
216         touch('f1')
217         touch('f2')
218         runosc('add f1 f2')
219         runosc('ci')
220
221
222         # create second working copy, and do a local modification
223         mkdir(wc2)
224         chdir(wc2)
225         runosc('init %s %s' % (PRJ, PAC))
226         runosc('up')
227         open('f2', 'w').write('foo')
228
229         # from wc1, delete the files
230         chdir(wc1)
231         runosc('rm f1 f2')
232         runosc('ci')
233
234         # in wc2, update
235         # f1 should be deleted
236         # f2 should be kept
237         chdir(wc2)
238         self.out, self.err = runosc('up')
239         self.assertEqual(self.err, '')
240         self.assertEqual(remove_revid(self.out), 'D    f1\nD    f2\nAt revision XX.\n')
241
242         self.out, self.err = runosc('st')
243         self.assertEqual(self.err, '')
244         self.assertEqual(self.out, '?    f2\n')
245
246
247     #####################################################################
248
249     def testCoPrj(self):
250         self.out, self.err = runosc('co %s' % PRJ)
251         self.assertEqual(self.err, '')
252         self.assert_('A    %s/%s' %(PRJ, PAC) in self.out)
253
254
255     def testCoPac(self):
256         # check out package dir
257         self.out, self.err = runosc('co %s %s' % (PRJ, PAC))
258         self.assertEqual(self.err, '')
259         self.assert_('A    %s/%s' %(PRJ, PAC) in self.out)
260
261     def testCoPacAndDoStuff(self):
262         checkout_and_clean(self)
263
264         # check in a file
265         # give an error if it doesn't exist
266         self.out, self.err = runosc('add foo1')
267         self.assertEqual(self.err, 'file \'foo1\' does not exist\n')
268         self.assertEqual(self.out, '')
269
270         touch('foo1')
271         self.out, self.err = runosc('add foo1')
272         self.assertEqual(self.err, '')
273         self.assertEqual(self.out, 'A    foo1\n')
274
275         self.out, self.err = runosc('ci')
276         self.assertEqual(self.err, '')
277         self.assertEqual(self.out, """Sending        foo1
278 Transmitting file data .
279 """)
280
281
282         # delete a file
283         self.out, self.err = runosc('rm foo1')
284         self.assertEqual(self.err, '')
285         self.assertEqual(self.out, 'D    foo1\n')
286
287         self.out, self.err = runosc('ci')
288         self.assertEqual(self.err, '')
289         self.assertEqual(self.out, """Deleting       foo1
290 Transmitting file data 
291 """)
292
293
294         # test 'status'
295         touch('onlyinwc')
296         self.out, self.err = runosc('st')
297         self.assertEqual(self.err, '')
298         self.assertEqual(self.out, '?    onlyinwc\n')
299
300         touch('foo2')
301         self.out, self.err = runosc('add foo2')
302         self.out, self.err = runosc('st')
303         self.assertEqual(self.err, '')
304         self.assertEqual(self.out, '?    onlyinwc\nA    foo2\n')
305
306         # status with an absolute directory as argument
307         self.out, self.err = runosc('st %s' % os.getcwd())
308         self.assertEqual(self.err, '')
309         self.assertEqual(self.out, '?    %s/onlyinwc\nA    %s/foo2\n' % (os.getcwd(), os.getcwd()))
310
311         # status with an absolute directory as argument
312         self.out, self.err = runosc('st %s' % os.getcwd())
313         self.assertEqual(self.err, '')
314         self.assertEqual(self.out, '?    %s/onlyinwc\nA    %s/foo2\n' % (os.getcwd(), os.getcwd()))
315
316         # status with a single file as argument
317         reldir = os.path.basename(os.getcwd())
318         self.out, self.err = runosc('st foo2')
319         self.assertEqual(self.err, '')
320         self.assertEqual(self.out, 'A    foo2\n')
321
322         # check in a single argument
323         self.out, self.err = runosc('ci foo2')
324         self.assertEqual(self.err, '')
325         self.assertEqual(self.out, """Sending        foo2
326 Transmitting file data .
327 """)
328
329         # clean up
330         self.out, self.err = runosc('st')
331         self.assertEqual(self.err, '')
332         self.assertEqual(self.out, '?    onlyinwc\n')
333         os.unlink('onlyinwc')
334
335
336         # test 'addremove'
337         touch('bar1')
338         os.unlink('foo2')
339         self.out, self.err = runosc('addremove')
340         self.assertEqual(self.err, '')
341         self.assertEqual(self.out, 'D    foo2\nA    bar1\n')
342         self.out, self.err = runosc('ci')
343         self.assertEqual(self.err, '')
344         self.assertEqual(self.out, """Sending        bar1
345 Deleting       foo2
346 Transmitting file data .
347 """)
348
349
350
351     #####################################################################
352
353     # test commandline options
354
355     def testCmdOptVersion(self):
356         self.out, self.err = runosc('--version')
357         self.assertEqual(self.err, '')
358         from osc.core import get_osc_version
359         self.assertEqual(self.out, '%s\n' % get_osc_version())
360
361     def testCmdOptHelp(self):
362         self.out, self.err = runosc('--help')
363         self.assertEqual(self.err, '')
364         self.assert_('OpenSUSE build service' in self.out)
365         self.assert_('additional information' in self.out)
366
367     def testCmdOptHelpCmd(self):
368         self.out, self.err = runosc('help')
369         self.assertEqual(self.err, '')
370         self.assert_('OpenSUSE build service' in self.out)
371         self.assert_('additional information' in self.out)
372
373     # a global option
374     def testCmdOptHelpOpt(self):
375         self.out, self.err = runosc('help')
376         self.assertEqual(self.err, '')
377         self.assert_('-H, --http-debug' in self.out)
378
379     # a subcommand option
380     def testCmdOptHelpBuild(self):
381         self.out, self.err = runosc('help build')
382         self.assertEqual(self.err, '')
383         self.assert_('build: Build a package' in self.out)
384         self.assert_('--clean' in self.out)
385
386     def testCmdOptDebugLs(self):
387         self.out, self.err = runosc('-H ls')
388         self.assertEqual(self.err, '')
389         self.assert_("send: 'GET /source" in self.out)
390
391     def testCmdOptApiOption(self):
392         self.out, self.err = runosc('-A https://api.opensuse.org -H ls')
393         self.assertEqual(self.err, '')
394         self.assert_("reply: 'HTTP/1.1 200 OK" in self.out)
395
396
397
398
399
400
401 #####################################################################
402
403
404 def runosc(argstring):
405     #time.sleep(1) # don't stress the server
406
407     # we test the osc in this directory, not a system one
408     return runcmd(os.path.join(startdir, 'osc-wrapper.py'), argstring)
409
410
411 def runcmd(cmd, argstring):
412     child_stdin, child_stdout, child_stderr = os.popen3(cmd + ' ' + argstring)
413     return child_stdout.read(), child_stderr.read()
414
415
416 def touch(filename):
417     open(filename, 'w').close();
418
419
420 if __name__ == '__main__':
421
422     #unittest.main()
423     suite = unittest.makeSuite(TestOsc)
424     unittest.TextTestRunner(verbosity=2).run(suite)