1 # vim: set fileencoding=utf-8 :
3 # (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 """Test the classes under L{gbp.rpm}"""
23 from nose.tools import assert_raises, eq_, ok_ # pylint: disable=E0611
25 from gbp.errors import GbpError
26 from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec,
27 guess_spec_repo, spec_from_repo)
28 from gbp.git.repository import GitRepository
30 # Disable "Method could be a function"
31 # pylint: disable=R0201
34 DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data',
36 SRPM_DIR = os.path.join(DATA_DIR, 'srpms')
37 SPEC_DIR = os.path.join(DATA_DIR, 'specs')
40 class SpecFileTester(SpecFile):
41 """Helper class for testing"""
43 def protected(self, name):
44 """Get a protected member"""
45 return super(SpecFileTester, self).__getattribute__(name)
48 class RpmTestBase(object):
55 self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.')
58 """Test case teardown"""
59 shutil.rmtree(self.tmpdir)
61 class TestSrcRpmFile(RpmTestBase):
62 """Test L{gbp.rpm.SrcRpmFile}"""
65 """Test parsing of a source rpm"""
66 srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm'))
67 eq_(srpm.version, {'release': '1', 'upstreamversion': '1.0'})
68 eq_(srpm.name, 'gbp-test')
69 eq_(srpm.upstreamversion, '1.0')
70 eq_(srpm.packager, None)
72 def test_srpm_2(self):
73 """Test parsing of another source rpm"""
74 srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test2-3.0-0.src.rpm'))
75 eq_(srpm.version, {'release': '0', 'upstreamversion': '3.0',
77 eq_(srpm.packager, 'Markus Lehtonen <markus.lehtonen@linux.intel.com>')
79 def test_unpack_srpm(self):
80 """Test unpacking of a source rpm"""
81 srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm'))
82 srpm.unpack(self.tmpdir)
83 for fn in ['gbp-test-1.0.tar.bz2', 'foo.txt', 'bar.tar.gz', 'my.patch',
84 'my2.patch', 'my3.patch']:
85 ok_(os.path.exists(os.path.join(self.tmpdir, fn)),
88 class TestSpecFile(RpmTestBase):
89 """Test L{gbp.rpm.SpecFile}"""
92 """Test parsing of a valid spec file"""
93 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec')
94 spec = SpecFileTester(spec_filepath)
96 # Test basic properties
97 eq_(spec.specfile, os.path.basename(spec_filepath))
98 eq_(spec.specdir, os.path.dirname(spec_filepath))
99 eq_(spec.specpath, spec_filepath)
101 eq_(spec.name, 'gbp-test')
102 eq_(spec.packager, None)
104 eq_(spec.upstreamversion, '1.0')
105 eq_(spec.release, '1')
106 eq_(spec.epoch, None)
107 eq_(spec.version, {'release': '1', 'upstreamversion': '1.0'})
110 eq_(orig['filename'], 'gbp-test-1.0.tar.bz2')
111 eq_(orig['uri'], 'gbp-test-1.0.tar.bz2')
112 eq_(orig['filename_base'], 'gbp-test-1.0')
113 eq_(orig['archive_fmt'], 'tar')
114 eq_(orig['compression'], 'bzip2')
115 eq_(orig['prefix'], 'gbp-test/')
117 def test_spec_2(self):
118 """Test parsing of another valid spec file"""
119 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec')
120 spec = SpecFile(spec_filepath)
122 # Test basic properties
123 eq_(spec.name, 'gbp-test2')
124 eq_(spec.packager, 'Markus Lehtonen <markus.lehtonen@linux.intel.com>')
127 eq_(spec.version, {'release': '0', 'upstreamversion': '3.0',
131 eq_(orig['filename'], 'gbp-test2-3.0.tar.gz')
132 eq_(orig['uri'], 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz')
133 eq_(orig['archive_fmt'], 'tar')
134 eq_(orig['compression'], 'gzip')
135 eq_(orig['prefix'], '')
137 def test_spec_3(self):
138 """Test parsing of yet another valid spec file"""
139 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec')
140 spec = SpecFile(spec_filepath)
142 # Test basic properties
143 eq_(spec.name, 'gbp-test-native')
145 eq_(orig['filename'], 'gbp-test-native-1.0.zip')
146 eq_(orig['archive_fmt'], 'zip')
147 eq_(orig['compression'], None)
148 eq_(orig['prefix'], 'gbp-test-native-1.0/')
150 def test_spec_4(self):
151 """Test parsing of spec without orig tarball"""
152 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native2.spec')
153 spec = SpecFile(spec_filepath)
155 # Test basic properties
156 eq_(spec.name, 'gbp-test-native2')
157 eq_(spec.orig_src, None)
159 def test_parse_raw(self):
160 """Test parsing of a valid spec file"""
161 with assert_raises(NoSpecError):
163 with assert_raises(NoSpecError):
164 SpecFile('filename', 'filedata')
166 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec')
167 with open(spec_filepath, 'r') as spec_fd:
168 spec_data = spec_fd.read()
169 spec = SpecFile(filedata=spec_data)
171 # Test basic properties
172 eq_(spec.specfile, None)
173 eq_(spec.specdir, None)
174 eq_(spec.name, 'gbp-test')
176 def test_update_spec(self):
177 """Test spec autoupdate functionality"""
178 # Create temporary spec file
179 tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec')
180 shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test.spec'), tmp_spec)
182 reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference.spec')
183 spec = SpecFile(tmp_spec)
184 spec.update_patches(['new.patch'], {})
185 spec.write_spec_file()
186 eq_(filecmp.cmp(tmp_spec, reference_spec), True)
188 # Test adding the VCS tag and adding changelog
189 reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference2.spec')
190 spec.set_tag('VCS', None, 'myvcstag')
191 spec.set_changelog("* Wed Feb 05 2014 Name <email> 1\n- New entry\n")
192 spec.write_spec_file()
193 eq_(filecmp.cmp(tmp_spec, reference_spec), True)
195 def test_update_spec2(self):
196 """Another test for spec autoupdate functionality"""
197 tmp_spec = os.path.join(self.tmpdir, 'gbp-test2.spec')
198 shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test2.spec'), tmp_spec)
200 reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec')
201 spec = SpecFile(tmp_spec)
202 spec.update_patches(['1.patch', '2.patch'],
203 {'1.patch': {'if': 'true'},
204 '2.patch': {'ifarch': '%ix86'}})
205 spec.set_tag('VCS', None, 'myvcstag')
206 spec.write_spec_file()
207 eq_(filecmp.cmp(tmp_spec, reference_spec), True)
209 # Test updating patches again, removing the VCS tag and re-writing
211 reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec')
212 spec.update_patches(['new.patch'], {'new.patch': {'if': '1'}})
213 spec.set_tag('VCS', None, '')
214 spec.set_changelog("* Wed Feb 05 2014 Name <email> 2\n- New entry\n\n")
215 spec.write_spec_file()
216 eq_(filecmp.cmp(tmp_spec, reference_spec), True)
218 def test_modifying(self):
219 """Test updating/deleting of tags and macros"""
220 tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec')
221 shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test-updates.spec'), tmp_spec)
222 reference_spec = os.path.join(SPEC_DIR,
223 'gbp-test-updates-reference.spec')
224 spec = SpecFileTester(tmp_spec)
227 prev = spec.protected('_delete_tag')('Vendor', None)
228 spec.protected('_set_tag')('License', None, 'new license', prev)
229 spec.protected('_delete_tag')('source', 0)
230 eq_(spec.sources(), {})
231 spec.protected('_delete_tag')('patch', 0)
232 spec.protected('_delete_tag')('patch', -1)
233 eq_(spec.protected('_patches')(), {})
234 prev = spec.protected('_delete_tag')('invalidtag', None)
236 with assert_raises(GbpError):
237 # Check that setting empty value fails
238 spec.protected('_set_tag')('Version', None, '', prev)
239 with assert_raises(GbpError):
240 # Check that setting invalid tag with public method fails
241 spec.set_tag('invalidtag', None, 'value')
244 prev = spec.protected('_delete_special_macro')('patch', -1)
245 spec.protected('_delete_special_macro')('patch', 123)
246 spec.protected('_set_special_macro')('patch', 0, 'my new args', prev)
247 with assert_raises(GbpError):
248 spec.protected('_delete_special_macro')('invalidmacro', 0)
249 with assert_raises(GbpError):
250 spec.protected('_set_special_macro')('invalidmacro', 0, 'args',
253 # Check resulting spec file
254 spec.write_spec_file()
255 eq_(filecmp.cmp(tmp_spec, reference_spec), True)
257 def test_modifying_err(self):
258 """Test error conditions of modification methods"""
259 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec')
260 spec = SpecFileTester(spec_filepath)
262 # Unknown/invalid section name
263 with assert_raises(GbpError):
264 spec.protected('_set_section')('patch', 'new content\n')
266 # Multiple sections with the same name
267 with assert_raises(GbpError):
268 spec.protected('_set_section')('files', '%{_sysconfdir}/foo\n')
270 def test_changelog(self):
271 """Test changelog methods"""
272 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec')
273 spec = SpecFile(spec_filepath)
276 eq_(spec.get_changelog(),
277 "* Tue Feb 04 2014 Name <email> 1\n- My change\n\n\n")
279 # Set changelog and check again
280 new_text = "* Wed Feb 05 2014 Name <email> 2\n- New entry\n\n\n"
281 spec.set_changelog(new_text)
282 eq_(spec.get_changelog(), new_text)
284 def test_quirks(self):
285 """Test spec that is broken/has anomalities"""
286 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec')
287 spec = SpecFile(spec_filepath)
289 # Check that we quess orig source and prefix correctly
290 eq_(spec.orig_src['prefix'], 'foobar/')
293 """Test parsing of all the different tags of spec file"""
294 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-tags.spec')
295 spec = SpecFileTester(spec_filepath)
298 for name, val in spec.protected('_tags').iteritems():
300 if name in ('version', 'release', 'epoch'):
302 elif name in ('autoreq', 'autoprov', 'autoreqprov'):
304 elif name not in spec.protected('_listtags'):
305 rval = 'my_%s' % name
307 eq_(val['value'], rval, ("'%s:' is '%s', expecting '%s'" %
308 (name, val['value'], rval)))
309 eq_(spec.ignorepatches, [])
310 # Check patch numbers and patch filenames
312 for patch in spec.protected('_tags')['patch']['lines']:
313 patches[patch['num']] = patch['linevalue']
315 eq_(patches, {0: 'my_patch0', -1: 'my_patch'})
317 def test_patch_series(self):
318 """Test the getting the patches as a patchseries"""
319 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec')
320 spec = SpecFileTester(spec_filepath)
322 eq_(len(spec.patchseries()), 0)
323 spec.update_patches(['1.patch', '2.patch', '3.patch'], {})
324 eq_(len(spec.patchseries()), 3)
325 spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"})
326 spec.update_patches(['4.patch'], {})
327 eq_(len(spec.patchseries()), 1)
328 eq_(len(spec.patchseries(ignored=True)), 2)
329 spec.protected('_delete_special_macro')('patch', 0)
330 eq_(len(spec.patchseries(ignored=True)), 1)
331 series = spec.patchseries(unapplied=True, ignored=True)
333 eq_(os.path.basename(series[-1].path), '1.patch')
335 def test_patch_series_quirks(self):
336 """Patches are applied in order different from the patch numbering"""
337 spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec')
338 spec = SpecFileTester(spec_filepath)
340 # Check series is returned in the order the patches are applied
341 files = [os.path.basename(patch.path) for patch in spec.patchseries()]
342 eq_(files, ['05.patch', '01.patch'])
343 # Also ignored patches are returned in the correct order
344 files = [os.path.basename(patch.path) for patch in
345 spec.patchseries(ignored=True)]
346 eq_(files, ['05.patch', '02.patch', '01.patch'])
347 # Unapplied patches are added to the end of the series
348 files = [os.path.basename(patch.path) for patch in
349 spec.patchseries(unapplied=True)]
350 eq_(files, ['05.patch', '01.patch', '03.patch'])
351 # Return all patches (for which tag is found)
352 files = [os.path.basename(patch.path) for patch in
353 spec.patchseries(unapplied=True, ignored=True)]
354 eq_(files, ['05.patch', '02.patch', '01.patch', '03.patch', '04.patch'])
357 class TestUtilityFunctions(RpmTestBase):
358 """Test utility functions of L{gbp.rpm}"""
360 def test_guess_spec(self):
361 """Test guess_spec() function"""
363 with assert_raises(NoSpecError):
364 guess_spec(DATA_DIR, recursive=False)
365 # Multiple spec files
366 with assert_raises(NoSpecError):
367 guess_spec(DATA_DIR, recursive=True)
368 with assert_raises(NoSpecError):
369 guess_spec(SPEC_DIR, recursive=False)
371 spec = guess_spec(SPEC_DIR, recursive=False,
372 preferred_name = 'gbp-test2.spec')
373 eq_(spec.specfile, 'gbp-test2.spec')
374 eq_(spec.specdir, SPEC_DIR)
376 def test_guess_spec_repo(self):
377 """Test guess_spec_repo() and spec_from_repo() functions"""
378 # Create dummy repository with some commits
379 repo = GitRepository.create(self.tmpdir)
380 with open(os.path.join(repo.path, 'foo.txt'), 'w') as fobj:
382 repo.add_files('foo.txt')
383 repo.commit_all('Add dummy file')
384 os.mkdir(os.path.join(repo.path, 'packaging'))
385 shutil.copy(os.path.join(SPEC_DIR, 'gbp-test.spec'),
386 os.path.join(repo.path, 'packaging'))
387 repo.add_files('packaging/gbp-test.spec')
388 repo.commit_all('Add spec file')
391 with assert_raises(NoSpecError):
392 guess_spec_repo(repo, 'HEAD~1', recursive=True)
393 with assert_raises(NoSpecError):
394 guess_spec_repo(repo, 'HEAD', recursive=False)
396 spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False)
397 spec = guess_spec_repo(repo, 'HEAD', recursive=True)
398 eq_(spec.specfile, 'gbp-test.spec')
399 eq_(spec.specdir, 'packaging')
400 eq_(spec.specpath, 'packaging/gbp-test.spec')
402 # Test spec_from_repo()
403 with assert_raises(NoSpecError):
404 spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec')
405 spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec')
406 eq_(spec.specfile, 'gbp-test.spec')
408 # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: