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