commit: use the documented commit method by default now
[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         self.out, self.err = runosc('meta user poeml')
82         self.assertEqual(self.err, '')
83         self.assertEqual(self.out, expect)
84
85
86     #####################################################################
87
88     def testLs(self):
89         self.out, self.err = runosc('ls')
90         self.assertEqual(self.err, '')
91         self.assert_('Apache' in self.out)
92         self.assert_(PRJ in self.out)
93
94
95     def testLsPrj(self):
96         self.out, self.err = runosc('ls Apache')
97         self.assertEqual(self.err, '')
98         self.assert_('apache2' in self.out)
99
100
101     def testLsPac(self):
102         self.out, self.err = runosc('ls Apache apache2')
103         self.assertEqual(self.err, '')
104         self.assert_('favicon.ico' in self.out)
105
106     #####################################################################
107
108     def testMetaPrj(self):
109         self.out, self.err = runosc('meta prj Apache')
110         self.assertEqual(self.err, '')
111         self.assert_('<project name="Apache">' in self.out)
112
113
114     def testMetaPac(self):
115         self.out, self.err = runosc('meta pkg Apache apache2')
116         self.assertEqual(self.err, '')
117         self.assert_('<package project="Apache" name="apache2">' in self.out)
118
119
120     #####################################################################
121
122     def testPlatforms(self):
123         self.out, self.err = runosc('platforms')
124         self.assertEqual(self.err, '')
125         self.assert_('Factory/standard' in self.out)
126         self.assert_('SUSE:SL-10.1/standard' in self.out)
127
128
129     def testPlatformsPac(self):
130         self.out, self.err = runosc('platforms Apache')
131         self.assertEqual(self.err, '')
132         self.assert_('openSUSE_Factory' in self.out)
133
134
135     #####################################################################
136
137     def testCommitMsg(self):
138         """also tests the info and log commands"""
139
140         checkout_and_clean(self)
141
142         # ci -F
143
144         touch('foo')
145         runosc('add foo')
146         open('msgfile', 'w').write('message from file')
147
148         self.out, self.err = runosc('ci -F msgfile')
149         self.assertEqual(self.err, '')
150
151         self.out, self.err = runosc('info')
152         self.assertEqual(self.err, '')
153         self.assert_('Path: .\n' in self.out)
154         self.assert_('Repository UUID' in self.out)
155         self.assert_('Revision' in self.out)
156
157         lastrev = self.out[self.out.find('Revision') + 10 :].strip()
158
159         self.out, self.err = runosc('log -r %s' % lastrev)
160         self.assertEqual(self.err, '')
161         cl = self.out.splitlines()
162         self.assertEqual(len(cl), 5)
163         self.assert_(cl[1].startswith('r%s | poeml | ' % lastrev))
164         self.assertEqual(cl[2], '')
165         self.assertEqual(cl[3], 'message from file')
166
167         # ci -m
168
169         touch('bar')
170         runosc('add bar')
171         self.out, self.err = runosc('ci -m "message from commandline"')
172         self.assertEqual(self.err, '')
173
174         self.out, self.err = runosc('info')
175         self.assertEqual(self.err, '')
176         lastrev = self.out[self.out.find('Revision') + 10 :].strip()
177
178         self.out, self.err = runosc('log -r %s' % lastrev)
179         self.assertEqual(self.err, '')
180         cl = self.out.splitlines()
181         self.assertEqual(len(cl), 5)
182         self.assert_(cl[1].startswith('r%s | poeml | ' % lastrev))
183         self.assertEqual(cl[2], '')
184         self.assertEqual(cl[3], 'message from commandline')
185
186
187
188
189     #####################################################################
190
191     def testMerge(self):
192
193         wc1 = os.path.join(BASEDIR, TESTPACDIR)
194         wc2 = os.path.join(BASEDIR, 'otherwc')
195
196         checkout_and_clean(self)
197
198         # from wc1, create and check in a file
199         open('foo', 'w').write(dedent("""\
200             ein
201             blaues
202             Haus
203             """))
204         runosc('add foo')
205         runosc('ci')
206
207
208         # create second working copy, and do a local modification
209         mkdir(wc2)
210         chdir(wc2)
211         runosc('init %s %s' % (PRJ, PAC))
212         runosc('up')
213         open('foo', 'w').write(dedent("""\
214             kein
215             blaues
216             Haus
217             """))
218
219         self.out, self.err = runosc('st')
220         self.assertEqual(self.err, '')
221         self.assertEqual(self.out, 'M    foo\n')
222
223         # from wc1, commit a change 
224         chdir(wc1)
225         open('foo', 'a').write("""geht aus""")
226         runosc('ci')
227
228         # in wc2, update, and the change should be merged in
229         chdir(wc2)
230         self.out, self.err = runosc('up')
231         self.assertEqual(self.err, '')
232         self.assertEqual(remove_revid(self.out), 'G    foo\nAt revision XX.\n')
233
234         self.out, self.err = runosc('st')
235         self.assertEqual(self.err, '')
236         self.assertEqual(self.out, 'M    foo\n')
237
238         # successful merge is one thing, but checking the local modification 
239         # makes sure that the store copy has been updated to the upstream revision
240         self.out, self.err = runosc('diff')
241         self.assertEqual(self.err, '')
242         expected = dedent("""\
243             Index: foo
244             ===================================================================
245             --- foo     (revision XX) 
246             +++ foo     (working copy) 
247             @@ -1,4 +1,4 @@
248             -ein
249             +kein
250              blaues
251              Haus
252              geht aus
253             \\ No newline at end of file
254             """)
255         self.assertEqual(remove_revid(self.out), expected)
256
257
258
259     #####################################################################
260
261     def testUpdateLocalMod(self):
262
263         wc1 = os.path.join(BASEDIR, TESTPACDIR)
264         wc2 = os.path.join(BASEDIR, 'otherwc')
265
266         checkout_and_clean(self)
267
268         # in wc1, create and check in two files
269         touch('f1')
270         touch('f2')
271         runosc('add f1 f2')
272         runosc('ci')
273
274
275         # create second working copy, and do a local modification
276         mkdir(wc2)
277         chdir(wc2)
278         runosc('init %s %s' % (PRJ, PAC))
279         runosc('up')
280         open('f2', 'w').write('foo')
281
282         # from wc1, delete the files
283         chdir(wc1)
284         runosc('rm f1 f2')
285         runosc('ci')
286
287         # in wc2, update
288         # f1 should be deleted
289         # f2 should be kept
290         chdir(wc2)
291         self.out, self.err = runosc('up')
292         self.assertEqual(self.err, '')
293         self.assertEqual(remove_revid(self.out), 'D    f1\nD    f2\nAt revision XX.\n')
294
295         self.out, self.err = runosc('st')
296         self.assertEqual(self.err, '')
297         self.assertEqual(self.out, '?    f2\n')
298
299
300     #####################################################################
301
302     def testCoPrj(self):
303         self.out, self.err = runosc('co %s' % PRJ)
304         self.assertEqual(self.err, '')
305         self.assert_('A    %s/%s' %(PRJ, PAC) in self.out)
306
307
308     def testCoPac(self):
309         # check out package dir
310         self.out, self.err = runosc('co %s %s' % (PRJ, PAC))
311         self.assertEqual(self.err, '')
312         self.assert_('A    %s/%s' %(PRJ, PAC) in self.out)
313
314     def testCoPacAndDoStuff(self):
315         checkout_and_clean(self)
316
317         # check in a file
318         # give an error if it doesn't exist
319         self.out, self.err = runosc('add foo1')
320         self.assertEqual(self.err, 'file \'foo1\' does not exist\n')
321         self.assertEqual(self.out, '')
322
323         touch('foo1')
324         self.out, self.err = runosc('add foo1')
325         self.assertEqual(self.err, '')
326         self.assertEqual(self.out, 'A    foo1\n')
327
328         self.out, self.err = runosc('ci -m msg')
329         self.assertEqual(self.err, '')
330         self.assertEqual(remove_revid(self.out), """Sending        foo1
331 Transmitting file data .
332 Committed revision XX.
333 """)
334
335
336         # delete a file
337         self.out, self.err = runosc('rm foo1')
338         self.assertEqual(self.err, '')
339         self.assertEqual(self.out, 'D    foo1\n')
340
341         self.out, self.err = runosc('ci -m msg')
342         self.assertEqual(self.err, '')
343         self.assertEqual(remove_revid(self.out), """Deleting       foo1
344 Transmitting file data 
345 Committed revision XX.
346 """)
347
348
349         # test 'status'
350         touch('onlyinwc')
351         self.out, self.err = runosc('st')
352         self.assertEqual(self.err, '')
353         self.assertEqual(self.out, '?    onlyinwc\n')
354
355         touch('foo2')
356         self.out, self.err = runosc('add foo2')
357         self.out, self.err = runosc('st')
358         self.assertEqual(self.err, '')
359         self.assertEqual(self.out, '?    onlyinwc\nA    foo2\n')
360
361         # status with an absolute directory as argument
362         self.out, self.err = runosc('st %s' % os.getcwd())
363         self.assertEqual(self.err, '')
364         self.assertEqual(self.out, '?    %s/onlyinwc\nA    %s/foo2\n' % (os.getcwd(), os.getcwd()))
365
366         # status with an absolute directory as argument
367         self.out, self.err = runosc('st %s' % os.getcwd())
368         self.assertEqual(self.err, '')
369         self.assertEqual(self.out, '?    %s/onlyinwc\nA    %s/foo2\n' % (os.getcwd(), os.getcwd()))
370
371         # status with a single file as argument
372         reldir = os.path.basename(os.getcwd())
373         self.out, self.err = runosc('st foo2')
374         self.assertEqual(self.err, '')
375         self.assertEqual(self.out, 'A    foo2\n')
376
377         # check in a single argument
378         self.out, self.err = runosc('ci -m msg foo2')
379         self.assertEqual(self.err, '')
380         self.assertEqual(remove_revid(self.out), """Sending        foo2
381 Transmitting file data .
382 Committed revision XX.
383 """)
384
385         # clean up
386         self.out, self.err = runosc('st')
387         self.assertEqual(self.err, '')
388         self.assertEqual(self.out, '?    onlyinwc\n')
389         os.unlink('onlyinwc')
390
391
392         # test 'addremove'
393         touch('bar1')
394         os.unlink('foo2')
395         self.out, self.err = runosc('addremove')
396         self.assertEqual(self.err, '')
397         self.assertEqual(self.out, 'D    foo2\nA    bar1\n')
398         self.out, self.err = runosc('ci')
399         self.assertEqual(self.err, '')
400         self.assertEqual(remove_revid(self.out), """Sending        bar1
401 Deleting       foo2
402 Transmitting file data .
403 Committed revision XX.
404 """)
405
406
407
408     #####################################################################
409
410     # test commandline options
411
412     def testCmdOptVersion(self):
413         self.out, self.err = runosc('--version')
414         self.assertEqual(self.err, '')
415         from osc.core import get_osc_version
416         self.assertEqual(self.out, '%s\n' % get_osc_version())
417
418     def testCmdOptHelp(self):
419         self.out, self.err = runosc('--help')
420         self.assertEqual(self.err, '')
421         self.assert_('OpenSUSE build service' in self.out)
422         self.assert_('additional information' in self.out)
423
424     def testCmdOptHelpCmd(self):
425         self.out, self.err = runosc('help')
426         self.assertEqual(self.err, '')
427         self.assert_('OpenSUSE build service' in self.out)
428         self.assert_('additional information' in self.out)
429
430     # a global option
431     def testCmdOptHelpOpt(self):
432         self.out, self.err = runosc('help')
433         self.assertEqual(self.err, '')
434         self.assert_('-H, --http-debug' in self.out)
435
436     # a subcommand option
437     def testCmdOptHelpBuild(self):
438         self.out, self.err = runosc('help build')
439         self.assertEqual(self.err, '')
440         self.assert_('build: Build a package' in self.out)
441         self.assert_('--clean' in self.out)
442
443     def testCmdOptDebugLs(self):
444         self.out, self.err = runosc('-H ls')
445         self.assertEqual(self.err, '')
446         self.assert_("send: 'GET /source" in self.out)
447
448     def testCmdOptApiOption(self):
449         self.out, self.err = runosc('-A https://api.opensuse.org -H ls')
450         self.assertEqual(self.err, '')
451         self.assert_("reply: 'HTTP/1.1 200 OK" in self.out)
452
453
454
455
456
457
458 #####################################################################
459
460
461 def runosc(argstring):
462     #time.sleep(1) # don't stress the server
463
464     # we test the osc in this directory, not a system one
465     return runcmd(os.path.join(startdir, 'osc-wrapper.py'), argstring)
466
467
468 def runcmd(cmd, argstring):
469     child_stdin, child_stdout, child_stderr = os.popen3(cmd + ' ' + argstring)
470     return child_stdout.read(), child_stderr.read()
471
472
473 def touch(filename):
474     open(filename, 'w').close();
475
476
477 if __name__ == '__main__':
478
479     #unittest.main()
480     suite = unittest.makeSuite(TestOsc)
481     unittest.TextTestRunner(verbosity=2).run(suite)