File: source_builder_test.py

package info (click to toggle)
git-ubuntu 1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,688 kB
  • sloc: python: 13,378; sh: 480; makefile: 2
file content (248 lines) | stat: -rw-r--r-- 8,102 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
import os
import subprocess
import tempfile

import pygit2
from pygit2.enums import ObjectType
import pytest

import gitubuntu.source_builder as target

import gitubuntu.importer as importer
import gitubuntu.git_repository as git_repository
from gitubuntu.test_fixtures import repo


def dsc_path_to_tree(repo, dsc_path, patches_applied=False):
    """Convert a dsc filesystem path to a pygit2.Tree object.

    :param GitUbuntuRepository repo: repository wrapper object
    :param str dsc_path: path to dsc file
    :param bool patches_applied: whether all quilt patches should be
        applied during extraction
    :rtype: pygit2.Tree
    """
    tree_hash = importer.dsc_to_tree_hash(
        repo.raw_repo,
        dsc_path,
        patches_applied,
    )
    return repo.raw_repo.get(tree_hash)


def get_spec_changelog_version(repo, **kwargs):
    """Find the version of a source created with given SourceSpec arguments

    Create a SourceSpec with the given arguments, construct a Source from that
    spec using the source builder, and then extract and return the changelog
    version string from the debian/changelog file created within that source.

    :param GitUbuntuRepository: repository to create it in
    :param **kwargs: arguments to pass to the SourceSpec constructor
    :rtype: str
    :returns: the changelog version string found in debian/changelog
    """
    spec = target.SourceSpec(**kwargs)
    with target.Source(spec) as dsc_path:
        tree_hash = importer.dsc_to_tree_hash(repo.raw_repo, dsc_path)
        changelog = repo.get_changelog_from_treeish(tree_hash)
        return changelog.version


def test_source_is_created():
    with target.Source() as f:
        assert os.path.exists(f)


def test_source_create_with_version(repo):
    version = get_spec_changelog_version(repo, version='3', native=True)
    assert version == '3'


def test_source_create_with_versions(repo):
    source_spec = target.SourceSpec(changelog_versions=['3', '4'], native=True)
    with target.Source(source_spec) as f:
        tree_hash = importer.dsc_to_tree_hash(repo.raw_repo, f)
        changelog = repo.get_changelog_from_treeish(tree_hash)
        assert changelog.all_versions == ['3', '4']
    assert source_spec.version == '3'


@pytest.mark.parametrize('file_contents', [
    {'debian/random': 'Some contents'},
    {
        'debian/random': 'Some contents',
        'debian/subdir/random': 'Some other contents',
    },
])
def test_source_create_with_file_contents(repo, file_contents):
    with target.Source(
        target.SourceSpec(file_contents=file_contents)
    ) as f:
        with tempfile.TemporaryDirectory() as tmpdir:
            subprocess.check_call(
                ['dpkg-source', '-x', f, os.path.join(tmpdir, 'x')],
            )
            for _file in file_contents:
                assert os.path.exists(os.path.join(tmpdir, 'x', _file))
                with open(
                    os.path.join(tmpdir, 'x', _file)
                ) as random_file:
                    assert random_file.read() == file_contents[_file]


@pytest.mark.parametrize('_file', [
    'debian/changelog',
    'debian/control',
    'debian/rules',
])
def test_source_create_fails_with_reserved_file_contents(repo, _file):
    with pytest.raises(ValueError):
        with target.Source(
            target.SourceSpec(file_contents={_file: 'Some contents'})
        ) as f:
            pass


def test_source_create_fails_with_absolute_path(repo):
    with pytest.raises(ValueError):
        with target.Source(
            target.SourceSpec(file_contents={'/root/path': 'Some contents'})
        ) as f:
            pass


def test_source_mutate():
    """mutate kwarg results in a debian/mutate file

    If mutate is used, then a file called 'debian/mutate' should be generated
    with the same contents.
    """
    source = target.Source(target.SourceSpec(mutate='foo'))

    # It is sufficient to just verify spec_files contains what we want here as
    # the spec_files functionality is checked in a separate test already.
    assert source.files.spec_files['debian/mutate'] == 'foo'


@pytest.mark.parametrize('native,expected', [
    (True, b"3.0 (native)\n"),
    (False, b"3.0 (quilt)\n"),
])
def test_source_native_source_format(repo, native, expected):
    with target.Source(target.SourceSpec(native=native)) as dsc_path:
        blob = git_repository.follow_symlinks_to_blob(
            repo.raw_repo,
            dsc_path_to_tree(repo, dsc_path),
            'debian/source/format',
        )
        assert blob.data == expected

def test_source_quilt_no_patches(repo):
    with target.Source(target.SourceSpec()) as dsc_path:
        top = dsc_path_to_tree(repo, dsc_path)
        debian_entry = top['debian']
        assert debian_entry.type in [ObjectType.TREE, 'tree']
        debian = repo.raw_repo.get(debian_entry.id)
        with pytest.raises(KeyError):
            debian['patches']


def test_source_quilt_with_patches(repo):
    spec = target.SourceSpec(has_patches=True)
    with target.Source(spec) as dsc_path:
        top = dsc_path_to_tree(repo, dsc_path)
        expected_files = ['series', 'a', 'b']
        for basename in expected_files:
            assert git_repository.follow_symlinks_to_blob(
                repo.raw_repo,
                top,
                'debian/patches/%s' % basename,
            )
        unexpected_files = ['a', 'b']
        for filename in unexpected_files:
            with pytest.raises(KeyError):
                git_repository.follow_symlinks_to_blob(
                    repo.raw_repo,
                    top,
                    filename,
                )


def test_source_quilt_with_patches_applied(repo):
    spec = target.SourceSpec(has_patches=True)
    with target.Source(spec) as dsc_path:
        top = dsc_path_to_tree(repo, dsc_path, patches_applied=True)
        expected_files = [
            'debian/patches/series',
            'debian/patches/a',
            'debian/patches/b',
            'a',
            'b',
        ]
        for filename in expected_files:
            assert git_repository.follow_symlinks_to_blob(
                repo.raw_repo,
                top,
                filename,
            )


def test_source_version_native_default(repo):
    """The default version string for a native package should not have a
    '-' in it.
    """
    version = get_spec_changelog_version(repo, native=True)
    assert '-' not in version


def test_source_version_non_native_default(repo):
    """The default version string for a non-native package should have a
    '-' in it.
    """
    version = get_spec_changelog_version(repo, native=False)
    assert '-' in version


def test_source_version_native_specific(repo):
    """We should be able to create a native package with a
    native-looking version string.
    """
    version = get_spec_changelog_version(repo, native=True, version='1.0')
    assert version == '1.0'


def test_source_version_non_native_specific(repo):
    """We should be able to create a non-native package with a
    non-native-looking version string.
    """
    version = get_spec_changelog_version(repo, native=False, version='1.0-1')
    assert version == '1.0-1'


def test_source_non_native_version_no_hyphen_raises(repo):
    """Creating a non-native package with a native-looking version
    string should fail.
    """
    with pytest.raises(ValueError):
        get_spec_changelog_version(repo, native=False, version='1')
    with pytest.raises(ValueError):
        get_spec_changelog_version(
            repo,
            native=False,
            changelog_versions=['1-1', '2'],
        )


def test_source_native_version_hyphen_raises(repo):
    """Creating a native package with a non-native-looking version
    string should fail.
    """
    with pytest.raises(ValueError):
        get_spec_changelog_version(repo, native=True, version='1-1')
    with pytest.raises(ValueError):
        get_spec_changelog_version(
            repo,
            native=True,
            changelog_versions=['1', '1-2'],
        )