- bump version to 0.130.1
[opensuse:osc.git] / tests / test_update.py
1 import osc.core
2 import osc.oscerr
3 import os
4 import sys
5 from common import GET, OscTestCase
6 FIXTURES_DIR = os.path.join(os.getcwd(), 'update_fixtures')
7
8 def suite():
9     import unittest
10     return unittest.makeSuite(TestUpdate)
11
12 class TestUpdate(OscTestCase):
13     def _get_fixtures_dir(self):
14         return FIXTURES_DIR
15
16     @GET('http://localhost/source/osctest/simple?rev=latest', file='testUpdateNoChanges_files')
17     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
18     def testUpdateNoChanges(self):
19         """update without any changes (the wc is the most recent version)"""
20         self._change_to_pkg('simple')
21         osc.core.Package('.').update()
22         self.assertEqual(sys.stdout.getvalue(), 'At revision 1.\n')
23
24     @GET('http://localhost/source/osctest/simple?rev=2', file='testUpdateNewFile_files')
25     @GET('http://localhost/source/osctest/simple/upstream_added?rev=2', file='testUpdateNewFile_upstream_added')
26     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
27     def testUpdateNewFile(self):
28         """a new file was added to the remote package"""
29         self._change_to_pkg('simple')
30         osc.core.Package('.').update(rev=2)
31         exp = 'A    upstream_added\nAt revision 2.\n'
32         self.assertEqual(sys.stdout.getvalue(), exp)
33         self._check_digests('testUpdateNewFile_files')
34
35     @GET('http://localhost/source/osctest/simple?rev=2', file='testUpdateNewFileLocalExists_files')
36     def testUpdateNewFileLocalExists(self):
37         """
38         a new file was added to the remote package but the same (unversioned)
39         file exists locally
40         """
41         self._change_to_pkg('simple')
42         self.assertRaises(osc.oscerr.PackageFileConflict, osc.core.Package('.').update, rev=2)
43
44     @GET('http://localhost/source/osctest/simple?rev=2', file='testUpdateDeletedFile_files')
45     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
46     def testUpdateDeletedFile(self):
47         """a file was deleted from the remote package"""
48         self._change_to_pkg('simple')
49         osc.core.Package('.').update(rev=2)
50         exp = 'D    foo\nAt revision 2.\n'
51         self.assertEqual(sys.stdout.getvalue(), exp)
52         self._check_digests('testUpdateDeletedFile_files')
53         self.assertFalse(os.path.exists('foo'))
54         self.assertFalse(os.path.exists(os.path.join('.osc', 'foo')))
55
56     @GET('http://localhost/source/osctest/simple?rev=2', file='testUpdateUpstreamModifiedFile_files')
57     @GET('http://localhost/source/osctest/simple/foo?rev=2', file='testUpdateUpstreamModifiedFile_foo')
58     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
59     def testUpdateUpstreamModifiedFile(self):
60         """a file was modified in the remote package (local file isn't modified)"""
61         
62         self._change_to_pkg('simple')
63         osc.core.Package('.').update(rev=2)
64         exp = 'U    foo\nAt revision 2.\n'
65         self.assertEqual(sys.stdout.getvalue(), exp)
66         self._check_digests('testUpdateUpstreamModifiedFile_files')
67
68     @GET('http://localhost/source/osctest/conflict?rev=2', file='testUpdateConflict_files')
69     @GET('http://localhost/source/osctest/conflict/merge?rev=2', file='testUpdateConflict_merge')
70     @GET('http://localhost/source/osctest/conflict/_meta', file='meta.xml')
71     def testUpdateConflict(self):
72         """
73         a file was modified in the remote package (local file is also modified 
74         and a merge isn't possible)
75         """
76         self._change_to_pkg('conflict')
77         osc.core.Package('.').update(rev=2)
78         exp = 'C    merge\nAt revision 2.\n'
79         self._check_digests('testUpdateConflict_files')
80         self.assertEqual(sys.stdout.getvalue(), exp)
81         self._check_conflictlist('merge\n')
82
83     @GET('http://localhost/source/osctest/already_in_conflict?rev=2', file='testUpdateAlreadyInConflict_files')
84     @GET('http://localhost/source/osctest/already_in_conflict/merge?rev=2', file='testUpdateAlreadyInConflict_merge')
85     @GET('http://localhost/source/osctest/already_in_conflict/_meta', file='meta.xml')
86     def testUpdateAlreadyInConflict(self):
87         """
88         a file was modified in the remote package (the local file is already in conflict)
89         """
90         self._change_to_pkg('already_in_conflict')
91         osc.core.Package('.').update(rev=2)
92         exp = 'skipping \'merge\' (this is due to conflicts)\nAt revision 2.\n'
93         self.assertEqual(sys.stdout.getvalue(), exp)
94         self._check_conflictlist('merge\n')
95         self._check_digests('testUpdateAlreadyInConflict_files')
96
97     @GET('http://localhost/source/osctest/deleted?rev=2', file='testUpdateLocalDeletions_files')
98     @GET('http://localhost/source/osctest/deleted/foo?rev=2', file='testUpdateLocalDeletions_foo')
99     @GET('http://localhost/source/osctest/deleted/merge?rev=2', file='testUpdateLocalDeletions_merge')
100     @GET('http://localhost/source/osctest/deleted/_meta', file='meta.xml')
101     def testUpdateLocalDeletions(self):
102         """
103         the files 'foo' and 'merge' were modified in the remote package
104         and marked for deletion in the local wc. Additionally the file
105         'merge' was modified in the wc before deletion so the local file
106         still exists (and a merge with the remote file is not possible)
107         """
108         self._change_to_pkg('deleted')
109         osc.core.Package('.').update(rev=2)
110         exp = 'U    foo\nC    merge\nAt revision 2.\n'
111         self.assertEqual(sys.stdout.getvalue(), exp)
112         self._check_deletelist('foo\n')
113         self._check_conflictlist('merge\n')
114         self.assertEqual(open('foo', 'r').read(), open(os.path.join('.osc', 'foo'), 'r').read())
115         self._check_digests('testUpdateLocalDeletions_files')
116
117     @GET('http://localhost/source/osctest/restore?rev=latest', file='testUpdateRestore_files')
118     @GET('http://localhost/source/osctest/restore/foo?rev=1', file='testUpdateRestore_foo')
119     @GET('http://localhost/source/osctest/restore/_meta', file='meta.xml')
120     def testUpdateRestore(self):
121         """local file 'foo' was deleted with a non osc command and will be restored"""
122         self._change_to_pkg('restore')
123         osc.core.Package('.').update()
124         exp = 'Restored \'foo\'\nAt revision 1.\n'
125         self.assertEqual(sys.stdout.getvalue(), exp)
126         self._check_digests('testUpdateRestore_files')
127
128     @GET('http://localhost/source/osctest/limitsize?rev=latest', file='testUpdateLimitSizeNoChange_filesremote')
129     @GET('http://localhost/source/osctest/limitsize/_meta', file='meta.xml')
130     def testUpdateLimitSizeNoChange(self):
131         """
132         a new file was added to the remote package but isn't checked out because
133         of the size constraint
134         """
135         self._change_to_pkg('limitsize')
136         osc.core.Package('.').update(size_limit=50)
137         exp = 'D    bigfile\nAt revision 2.\n'
138         self.assertEqual(sys.stdout.getvalue(), exp)
139         self.assertFalse(os.path.exists(os.path.join('.osc', 'bigfile')))
140         self.assertFalse(os.path.exists('bigfile'))
141         self._check_digests('testUpdateLimitSizeNoChange_files', 'bigfile')
142
143     @GET('http://localhost/source/osctest/limitsize_local?rev=latest', file='testUpdateLocalLimitSizeNoChange_filesremote')
144     @GET('http://localhost/source/osctest/limitsize_local/_meta', file='meta.xml')
145     def testUpdateLocalLimitSizeNoChange(self):
146         """
147         a new file was added to the remote package but isn't checked out because
148         of the local size constraint
149         """
150         self._change_to_pkg('limitsize_local')
151         p = osc.core.Package('.')
152         p.update()
153         exp = 'D    bigfile\nD    merge\nAt revision 2.\n'
154         self.assertEqual(sys.stdout.getvalue(), exp)
155         self.assertFalse(os.path.exists(os.path.join('.osc', 'bigfile')))
156         self.assertFalse(os.path.exists(os.path.join('.osc', 'merge')))
157         self.assertFalse(os.path.exists('bigfile'))
158         self._check_digests('testUpdateLocalLimitSizeNoChange_files', 'bigfile', 'merge')
159         self._check_status(p, 'bigfile', 'S')
160         self._check_status(p, 'merge', 'S')
161
162     @GET('http://localhost/source/osctest/limitsize?rev=latest', file='testUpdateLimitSizeAddDelete_filesremote')
163     @GET('http://localhost/source/osctest/limitsize/exists?rev=2', file='testUpdateLimitSizeAddDelete_exists')
164     @GET('http://localhost/source/osctest/limitsize/_meta', file='meta.xml')
165     def testUpdateLimitSizeAddDelete(self):
166         """
167         a new file (exists) was added to the remote package with
168         size < size_limit and one file (nochange) was deleted from the
169         remote package (local file 'nochange' is modified). Additionally
170         files which didn't change are removed the local wc due to the
171         size constraint.
172         """
173         self._change_to_pkg('limitsize')
174         osc.core.Package('.').update(size_limit=10)
175         exp = 'A    exists\nD    bigfile\nD    foo\nD    merge\nD    nochange\nAt revision 2.\n'
176         self.assertEqual(sys.stdout.getvalue(), exp)
177         self.assertFalse(os.path.exists(os.path.join('.osc', 'bigfile')))
178         self.assertFalse(os.path.exists('bigfile'))
179         self.assertFalse(os.path.exists(os.path.join('.osc', 'foo')))
180         self.assertFalse(os.path.exists('foo'))
181         self.assertFalse(os.path.exists(os.path.join('.osc', 'merge')))
182         self.assertFalse(os.path.exists('merge'))
183         # exists because local version is modified
184         self.assertTrue(os.path.exists('nochange'))
185
186         self._check_digests('testUpdateLimitSizeAddDelete_files', 'bigfile', 'foo', 'merge', 'nochange')
187
188     @GET('http://localhost/source/osctest/services?rev=latest', file='testUpdateServiceFilesAddDelete_filesremote')
189     @GET('http://localhost/source/osctest/services/bigfile?rev=2', file='testUpdateServiceFilesAddDelete_bigfile')
190     @GET('http://localhost/source/osctest/services/_service%3Abar?rev=2', file='testUpdateServiceFilesAddDelete__service:bar')
191     @GET('http://localhost/source/osctest/services/_service%3Afoo?rev=2', file='testUpdateServiceFilesAddDelete__service:foo')
192     @GET('http://localhost/source/osctest/services/_meta', file='meta.xml')
193     def testUpdateAddDeleteServiceFiles(self):
194         """update package with _service:* files"""
195         self._change_to_pkg('services')
196         osc.core.Package('.').update(service_files=True)
197         exp = 'A    bigfile\nD    _service:exists\nA    _service:bar\nA    _service:foo\nAt revision 2.\n'
198         self.assertEqual(sys.stdout.getvalue(), exp)
199         self.assertFalse(os.path.exists(os.path.join('.osc', '_service:bar')))
200         self.assertTrue(os.path.exists('_service:bar'))
201         self.assertEqual(open('_service:bar').read(), 'another service\n')
202         self.assertFalse(os.path.exists(os.path.join('.osc', '_service:foo')))
203         self.assertTrue(os.path.exists('_service:foo'))
204         self.assertEqual(open('_service:foo').read(), 'small\n')
205         self.assertTrue(os.path.exists('_service:exists'))
206         self._check_digests('testUpdateServiceFilesAddDelete_files', '_service:foo', '_service:bar')
207
208     @GET('http://localhost/source/osctest/services?rev=latest', file='testUpdateServiceFilesAddDelete_filesremote')
209     @GET('http://localhost/source/osctest/services/bigfile?rev=2', file='testUpdateServiceFilesAddDelete_bigfile')
210     @GET('http://localhost/source/osctest/services/_meta', file='meta.xml')
211     def testUpdateDisableAddDeleteServiceFiles(self):
212         """update package with _service:* files (with service_files=False)"""
213         self._change_to_pkg('services')
214         osc.core.Package('.').update()
215         exp = 'A    bigfile\nD    _service:exists\nAt revision 2.\n'
216         self.assertEqual(sys.stdout.getvalue(), exp)
217         self.assertFalse(os.path.exists(os.path.join('.osc', '_service:bar')))
218         self.assertFalse(os.path.exists('_service:bar'))
219         self.assertFalse(os.path.exists(os.path.join('.osc', '_service:foo')))
220         self.assertFalse(os.path.exists('_service:foo'))
221         self.assertTrue(os.path.exists('_service:exists'))
222         self._check_digests('testUpdateServiceFilesAddDelete_files', '_service:foo', '_service:bar')
223
224     @GET('http://localhost/source/osctest/metamode?meta=1&rev=latest', file='testUpdateMetaMode_filesremote')
225     @GET('http://localhost/source/osctest/metamode/_meta?rev=1', file='testUpdateMetaMode__meta')
226     def testUpdateMetaMode(self):
227         """update package with metamode enabled"""
228         self._change_to_pkg('metamode')
229         p = osc.core.Package('.')
230         p.update()
231         exp = 'A    _meta\nD    foo\nD    merge\nD    nochange\nAt revision 1.\n'
232         self.assertEqual(sys.stdout.getvalue(), exp)
233         self.assertFalse(os.path.exists('foo'))
234         self.assertFalse(os.path.exists('merge'))
235         self.assertFalse(os.path.exists('nochange'))
236         self._check_digests('testUpdateMetaMode_filesremote')
237         self._check_status(p, '_meta', ' ')
238
239     @GET('http://localhost/source/osctest/new?rev=latest', file='testUpdateNew_filesremote')
240     @GET('http://localhost/source/osctest/new/_meta', file='meta.xml')
241     def testUpdateNew(self):
242         """update a new (empty) package. The package has no revision."""
243         self._change_to_pkg('new')
244         p = osc.core.Package('.')
245         p.update()
246         exp = 'At revision None.\n'
247         self.assertEqual(sys.stdout.getvalue(), exp)
248         self._check_digests('testUpdateNew_filesremote')
249
250     # tests to recover from an aborted/broken update
251
252     @GET('http://localhost/source/osctest/simple/foo?rev=2', file='testUpdateResume_foo')
253     @GET('http://localhost/source/osctest/simple/merge?rev=2', file='testUpdateResume_merge')
254     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
255     @GET('http://localhost/source/osctest/simple?rev=2', file='testUpdateResume_files')
256     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
257     def testUpdateResume(self):
258         """resume an aborted update"""
259         self._change_to_pkg('resume')
260         osc.core.Package('.').update(rev=2)
261         exp = 'resuming broken update...\nU    foo\nU    merge\nAt revision 2.\nAt revision 2.\n'
262         self.assertEqual(sys.stdout.getvalue(), exp)
263         self.assertFalse(os.path.exists(os.path.join('.osc', '_in_update')))
264         self._check_digests('testUpdateResume_files')
265
266     @GET('http://localhost/source/osctest/simple/foo?rev=1', file='testUpdateResumeDeletedFile_foo')
267     @GET('http://localhost/source/osctest/simple/merge?rev=1', file='testUpdateResumeDeletedFile_merge')
268     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
269     @GET('http://localhost/source/osctest/simple?rev=1', file='testUpdateResumeDeletedFile_files')
270     @GET('http://localhost/source/osctest/simple/_meta', file='meta.xml')
271     def testUpdateResumeDeletedFile(self):
272         """
273         resume an aborted update (the file 'added' was already deleted in the first update
274         run). It's marked as deleted again (this is due to an expected issue with the update
275         code)
276         """
277         self._change_to_pkg('resume_deleted')
278         osc.core.Package('.').update(rev=1)
279         exp = 'resuming broken update...\nD    added\nU    foo\nU    merge\nAt revision 1.\nAt revision 1.\n'
280         self.assertEqual(sys.stdout.getvalue(), exp)
281         self.assertFalse(os.path.exists(os.path.join('.osc', '_in_update')))
282         self.assertFalse(os.path.exists('added'))
283         self.assertFalse(os.path.exists(os.path.join('.osc', 'added')))
284         self._check_digests('testUpdateResumeDeletedFile_files')
285
286 if __name__ == '__main__':
287     import unittest
288     unittest.main()