~andrewjbeach/juju-ci-tools/get-juju-dict

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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
import argparse
import mock
import subprocess

import git_gate
import tests


class TestParseArgs(tests.TestCase):

    def test_project_and_url(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project",
             "--project-url", "https://git.testing/project"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.project_url, "https://git.testing/project")
        self.assertEqual(args.keep, False)

    def test_keep(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project",
             "--project-url", "https://git.testing/project", "--keep"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.keep, True)

    def test_project_and_ref(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project", "--go-get-all",
             "--project-ref", "v1"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.project_ref, "v1")

    def test_merging_other(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project", "--go-get-all",
             "--merge-url", "https://git.testing/proposed"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.merge_url, "https://git.testing/proposed")
        self.assertEqual(args.merge_ref, "HEAD")

    def test_merging_other_ref(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project", "--go-get-all",
             "--merge-url", "https://git.testing/proposed",
             "--merge-ref", "feature"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.merge_url, "https://git.testing/proposed")
        self.assertEqual(args.merge_ref, "feature")

    def test_project_with_deps(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project",
             "--project-url", "https://git.testing/project",
             "--dependencies", "git.testing/a", "git.testing/b"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.project_url, "https://git.testing/project")
        self.assertEqual(args.dependencies, ["git.testing/a", "git.testing/b"])
        self.assertEqual(args.go_get_all, False)
        self.assertEqual(args.tsv_path, None)

    def test_project_with_go_deps(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project", "--go-get-all"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.dependencies, None)
        self.assertEqual(args.go_get_all, True)
        self.assertEqual(args.tsv_path, None)

    def test_project_with_tsv_path(self):
        args = git_gate.parse_args(
            ["--project", "git.testing/project",
             "--project-url", "https://git.testing/project",
             "--tsv-path", "/a/file.tsv"])
        self.assertEqual(args.project, "git.testing/project")
        self.assertEqual(args.project_url, "https://git.testing/project")
        self.assertEqual(args.dependencies, None)
        self.assertEqual(args.go_get_all, False)
        self.assertEqual(args.tsv_path, "/a/file.tsv")

    def test_error_on_project_url_missing(self):
        with tests.parse_error(self) as stderr:
            git_gate.parse_args(["--project", "git.testing/project"])
        self.assertIn(
            "Must supply either --project-url or --go-get-all",
            stderr.getvalue())

    def test_error_go_get_feature_branch(self):
        with tests.parse_error(self) as stderr:
            git_gate.parse_args(
                ["--project", "git.testing/project",
                 "--project-url", "https://git.testing/project",
                 "--go-get-all", "--feature-branch"])
        self.assertIn(
            "Cannot use --feature-branch and --go-get-all together",
            stderr.getvalue())


class TestSubcommandError(tests.TestCase):

    def test_subcommand_error(self):
        proc_error = subprocess.CalledProcessError(1, ["git"])
        err = git_gate.SubcommandError("git", "clone", proc_error)
        self.assertEqual(str(err), "Subprocess git clone failed with code 1")


class TestGoTest(tests.TestCase):
    """
    Tests for go_test function.

    Class has setup that patches out each operation with relevent side effects,
    running a command, printing output, or changing directory. Those are
    recorded in order in the actions list, so each test can supply a set of
    arguments then just match the actions.
    """

    maxDiff = None

    def setUp(self):
        super(TestGoTest, self).setUp()
        # Patch out and record actions run as part of go_test()
        self.actions = []
        self.patch_action("git_gate.print_now", lambda s: ("print", s))
        self.patch_action("git_gate.SubcommandRunner.__call__",
                          lambda self, *args: (self.command,) + args)
        self.patch_action("os.chdir", lambda d: ("chdir", d))

        # Verify go commands run with GOPATH overridden
        real_runner = git_gate.SubcommandRunner

        def _check(command, environ=None):
            if command in ("go", "godeps"):
                self.assertIsInstance(environ, dict)
                self.assertEquals(environ.get("GOPATH"), "/tmp/fake")
            return real_runner(command, environ)

        patcher = mock.patch("git_gate.SubcommandRunner", side_effect=_check)
        patcher.start()
        self.addCleanup(patcher.stop)

    def patch_action(self, target, func):
        """Patch target recording each call in actions as wrapped by func."""
        def _record(*args, **kwargs):
            self.actions.append(func(*args, **kwargs))
        patcher = mock.patch(target, _record)
        patcher.start()
        self.addCleanup(patcher.stop)

    args = frozenset("project project_url project_ref feature_branch merge_url"
                     " merge_ref go_get_all dependencies tsv_path".split())

    @classmethod
    def make_args(cls, project, **kwargs):
        """Gives args like parse_args with all values defaulted to None."""
        if not cls.args.issuperset(kwargs):
            raise ValueError("Invalid arguments given: {!r}".format(kwargs))
        kwargs["project"] = project
        return argparse.Namespace(**dict((k, kwargs.get(k)) for k in cls.args))

    def test_get_test(self):
        args = self.make_args("git.testing/project", go_get_all=True)
        git_gate.go_test(args, "/tmp/fake")
        self.assertEqual(self.actions, [
            ('print', 'Getting git.testing/project and dependencies using go'),
            ('go', 'get', '-v', '-d', '-t', 'git.testing/project/...'),
            ('chdir', '/tmp/fake/src/git.testing/project'),
            ('go', 'build', 'git.testing/project/...'),
            ('go', 'test', 'git.testing/project/...')
        ])

    def test_get_merge_test(self):
        args = self.make_args("git.testing/project", go_get_all=True,
                              merge_url="https://git.testing/proposed",
                              merge_ref="HEAD")
        git_gate.go_test(args, "/tmp/fake")
        self.assertEqual(self.actions, [
            ('print', 'Getting git.testing/project and dependencies using go'),
            ('go', 'get', '-v', '-d', '-t', 'git.testing/project/...'),
            ('chdir', '/tmp/fake/src/git.testing/project'),
            ('print', 'Merging https://git.testing/proposed ref HEAD'),
            ('git', 'fetch', 'https://git.testing/proposed', 'HEAD'),
            ('git', 'merge', '--no-ff', '-m', 'Merged HEAD', 'FETCH_HEAD'),
            ('print', 'Updating git.testing/project dependencies using go'),
            ('go', 'get', '-v', '-d', '-t', 'git.testing/project/...'),
            ('go', 'build', 'git.testing/project/...'),
            ('go', 'test', 'git.testing/project/...')
        ])

    def test_get_merge_other_test(self):
        args = self.make_args("git.testing/project", go_get_all=True,
                              project_url="https://git.testing/project",
                              project_ref="v1",
                              merge_url="https://git.testing/proposed",
                              merge_ref="feature")
        git_gate.go_test(args, "/tmp/fake")
        self.assertEqual(self.actions, [
            ('print', 'Cloning git.testing/project from'
             ' https://git.testing/project'),
            ('git', 'clone', 'https://git.testing/project',
             '/tmp/fake/src/git.testing/project'),
            ('chdir', '/tmp/fake/src/git.testing/project'),
            ('print', 'Switching repository to v1'),
            ('git', 'checkout', 'v1'),
            ('print', 'Merging https://git.testing/proposed ref feature'),
            ('git', 'fetch', 'https://git.testing/proposed', 'feature'),
            ('git', 'merge', '--no-ff', '-m', 'Merged feature', 'FETCH_HEAD'),
            ('print', 'Updating git.testing/project dependencies using go'),
            ('go', 'get', '-v', '-d', '-t', 'git.testing/project/...'),
            ('go', 'build', 'git.testing/project/...'),
            ('go', 'test', 'git.testing/project/...')
        ])

    def test_deps_test(self):
        args = self.make_args("git.testing/project",
                              project_url="https://git.testing/project",
                              dependencies=["git.testing/a", "git.testing/b"])
        git_gate.go_test(args, "/tmp/fake")
        self.assertEqual(self.actions, [
            ('print', 'Cloning git.testing/project from'
             ' https://git.testing/project'),
            ('git', 'clone', 'https://git.testing/project',
             '/tmp/fake/src/git.testing/project'),
            ('chdir', '/tmp/fake/src/git.testing/project'),
            ('print', 'Getting git.testing/a and dependencies using go'),
            ('go', 'get', '-v', '-d', 'git.testing/a'),
            ('print', 'Getting git.testing/b and dependencies using go'),
            ('go', 'get', '-v', '-d', 'git.testing/b'),
            ('go', 'build', 'git.testing/project/...'),
            ('go', 'test', 'git.testing/project/...')
        ])

    def test_tsv_test(self):
        args = self.make_args("git.testing/project",
                              project_url="https://git.testing/project",
                              tsv_path="dependencies.tsv")
        git_gate.go_test(args, "/tmp/fake")
        self.assertEqual(self.actions, [
            ('print', 'Getting and installing godeps'),
            ('go', 'get', '-v', '-d', 'github.com/rogpeppe/godeps/...'),
            ('go', 'install', 'github.com/rogpeppe/godeps/...'),
            ('print', 'Cloning git.testing/project from'
             ' https://git.testing/project'),
            ('git', 'clone', 'https://git.testing/project',
             '/tmp/fake/src/git.testing/project'),
            ('chdir', '/tmp/fake/src/git.testing/project'),
            ('print', 'Getting dependencies using godeps from'
             ' /tmp/fake/src/git.testing/project/dependencies.tsv'),
            ('/tmp/fake/bin/godeps', '-u',
             '/tmp/fake/src/git.testing/project/dependencies.tsv'),
            ('go', 'build', 'git.testing/project/...'),
            ('go', 'test', 'git.testing/project/...')
        ])

    def test_feature_branch(self):
        args = self.make_args("vgo.testing/project.v2.feature",
                              project_url="https://git.testing/project",
                              project_ref="v2.feature",
                              feature_branch=True, dependencies=[])
        git_gate.go_test(args, "/tmp/fake")
        self.assertEqual(self.actions, [
            ('print', 'Cloning vgo.testing/project.v2 from'
             ' https://git.testing/project'),
            ('git', 'clone', 'https://git.testing/project',
             '/tmp/fake/src/vgo.testing/project.v2'),
            ('chdir', '/tmp/fake/src/vgo.testing/project.v2'),
            ('print', 'Switching repository to v2.feature'),
            ('git', 'checkout', 'v2.feature'),
            ('go', 'build', 'vgo.testing/project.v2/...'),
            ('go', 'test', 'vgo.testing/project.v2/...')
        ])

    def test_no_magic_dots(self):
        args = self.make_args("vgo.testing/project.dot.love",
                              project_url="https://git.testing/project",
                              project_ref="dot.love", dependencies=[])
        git_gate.go_test(args, "/tmp/fake")
        self.assertEqual(self.actions, [
            ('print', 'Cloning vgo.testing/project.dot.love from'
             ' https://git.testing/project'),
            ('git', 'clone', 'https://git.testing/project',
             '/tmp/fake/src/vgo.testing/project.dot.love'),
            ('chdir', '/tmp/fake/src/vgo.testing/project.dot.love'),
            ('print', 'Switching repository to dot.love'),
            ('git', 'checkout', 'dot.love'),
            ('go', 'build', 'vgo.testing/project.dot.love/...'),
            ('go', 'test', 'vgo.testing/project.dot.love/...')
        ])


class TestFromFeatureDir(tests.TestCase):
    """Tests for from_feature_dir function."""

    def test_boring(self):
        directory = git_gate.from_feature_dir("github.com/juju/juju")
        self.assertEqual(directory, "github.com/juju/juju")

    def test_gopkg(self):
        directory = git_gate.from_feature_dir("gopkg.in/juju/charm.v6")
        self.assertEqual(directory, "gopkg.in/juju/charm.v6")

    def test_gopkg_feature(self):
        directory = git_gate.from_feature_dir("gopkg.in/juju/charm.v6.minver")
        self.assertEqual(directory, "gopkg.in/juju/charm.v6")