예제 #1
0
    def test_build_go_mod(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""
            go_buildtags = ""

        self.run_output_mock.return_value = "go version go1.13 linux/amd64"

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.builddir)
        open(os.path.join(plugin.builddir, "go.mod"), "w").close()

        plugin.build()

        self.run_output_mock.assert_called_once_with(["go", "version"],
                                                     cwd=mock.ANY,
                                                     env=mock.ANY)
        self.run_mock.assert_called_once_with(
            ["go", "build", "-o", plugin._install_bin_dir, "./..."],
            cwd=plugin.builddir,
            env=mock.ANY,
        )
예제 #2
0
    def test_build_go_packages(self):
        class Options:
            source = ""
            go_channel = "latest/stable"
            go_packages = ["github.com/gotools/vet"]
            go_importpath = ""
            go_buildtags = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)

        plugin.pull()

        os.makedirs(plugin.builddir)

        self.run_mock.reset_mock()
        plugin.build()

        self.run_mock.assert_called_once_with(
            ["go", "build", plugin.options.go_packages[0]],
            cwd=os.path.join(plugin.installdir, "bin"),
            env=mock.ANY,
        )

        self.assert_go_paths(plugin)
예제 #3
0
    def test_build_packages(self):
        self.options.go_channel = ""

        plugin = go.GoPlugin("test-part", self.options, self.project)

        self.assertThat(plugin.build_packages, Contains("golang-go"))
        self.assertThat(plugin.build_snaps, Not(Contains("go/latest/stable")))
예제 #4
0
    def test_clean_build(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""
            go_buildtags = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)

        plugin.pull()

        os.makedirs(plugin._gopath_pkg)
        os.makedirs(plugin.builddir)

        plugin.build()

        self.assert_go_paths(plugin)

        plugin.clean_build()

        self.assertTrue(os.path.exists(plugin._gopath))
        self.assertTrue(os.path.exists(plugin._gopath_src))
        self.assertFalse(os.path.exists(plugin._gopath_bin))
        self.assertFalse(os.path.exists(plugin._gopath_pkg))
예제 #5
0
    def test_build_with_local_sources_and_go_importpath(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = "github.com/snapcore/launcher"
            go_buildtags = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)
        open(os.path.join(plugin.sourcedir, "main.go"), "w").close()

        plugin.pull()

        os.makedirs(plugin.builddir)
        self.run_output_mock.return_value = "github.com/snapcore/launcher main"

        plugin.build()

        self.run_output_mock.assert_called_once_with(
            [
                "go",
                "list",
                "-f",
                "{{.ImportPath}} {{.Name}}",
                "./github.com/snapcore/launcher/...",
            ],
            cwd=plugin._gopath_src,
            env=mock.ANY,
        )

        self.run_mock.assert_has_calls([
            mock.call(
                [
                    "go", "get", "-t", "-d",
                    "./github.com/snapcore/launcher/..."
                ],
                cwd=plugin._gopath_src,
                env=mock.ANY,
            ),
            mock.call(
                ["go", "build", "github.com/snapcore/launcher"],
                cwd=os.path.join(plugin.installdir, "bin"),
                env=mock.ANY,
            ),
        ])

        self.assertTrue(
            os.path.exists(
                os.path.join(plugin._gopath_src,
                             plugin.options.go_importpath)))

        self.assert_go_paths(plugin)
예제 #6
0
    def test_pull_with_local_sources_or_go_packages(self):
        class Options:
            source = None
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)
        plugin.pull()

        self.run_mock.assert_has_calls([])

        self.assert_go_paths(plugin)
예제 #7
0
    def test_build_go_mod_classic_dynamic_relink(self, mock_elffile):
        class Options:
            source = ""
            go_channel = "latest/stable"
            go_packages = ["github.com/gotools/vet"]
            go_importpath = ""
            go_buildtags = ""

        self.run_output_mock.return_value = "go version go13 linux/amd64"

        mock_elffile.return_value = MockElfFile(path="foo")
        self.project._snap_meta.confinement = "classic"
        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.builddir)
        open(os.path.join(plugin.builddir, "go.mod"), "w").close()

        plugin.build()

        self.run_output_mock.assert_called_once_with(["go", "version"],
                                                     cwd=mock.ANY,
                                                     env=mock.ANY)
        self.assertThat(self.run_mock.call_count, Equals(2))
        self.run_mock.assert_has_calls([
            mock.call(
                ["go", "build", "-o", plugin._install_bin_dir, "./..."],
                cwd=plugin.builddir,
                env=mock.ANY,
            ),
            mock.call(
                [
                    "go",
                    "build",
                    "-ldflags",
                    "-linkmode=external",
                    "-o",
                    plugin._install_bin_dir,
                    "./...",
                ],
                cwd=plugin.builddir,
                env=mock.ANY,
            ),
        ])
예제 #8
0
    def test_build_classic_dynamic_relink(self, mock_elffile):
        class Options:
            source = ""
            go_channel = "latest/stable"
            go_packages = ["github.com/gotools/vet"]
            go_importpath = ""
            go_buildtags = ""

        mock_elffile.return_value = MockElfFile(path="foo")
        self.project._snap_meta.confinement = "classic"
        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)

        plugin.pull()

        os.makedirs(plugin.builddir)

        self.run_mock.reset_mock()
        plugin.build()

        self.assertThat(self.run_mock.call_count, Equals(2))
        self.run_mock.assert_has_calls([
            mock.call(
                ["go", "build", plugin.options.go_packages[0]],
                cwd=os.path.join(plugin.installdir, "bin"),
                env=mock.ANY,
            ),
            mock.call(
                [
                    "go",
                    "build",
                    "-ldflags",
                    "-linkmode=external",
                    plugin.options.go_packages[0],
                ],
                cwd=os.path.join(plugin.installdir, "bin"),
                env=mock.ANY,
            ),
        ])

        self.assert_go_paths(plugin)
예제 #9
0
    def test_clean_pull(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""
            go_buildtags = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)
        open(os.path.join(plugin.sourcedir, "main.go"), "w").close()

        plugin.pull()

        self.assertTrue(os.path.exists(plugin._gopath))

        plugin.clean_pull()

        self.assertFalse(os.path.exists(plugin._gopath))
예제 #10
0
    def test_go_mod_requires_newer_go_version(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""
            go_buildtags = ""

        self.run_output_mock.return_value = "go version go1.6.4 linux/amd64"

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)
        open(os.path.join(plugin.sourcedir, "go.mod"), "w").close()

        self.assertRaises(go.GoModRequiredVersionError, plugin.pull)

        self.run_output_mock.assert_called_once_with(["go", "version"],
                                                     cwd=mock.ANY,
                                                     env=mock.ANY)
        self.run_mock.assert_not_called()
예제 #11
0
    def test_build_go_mod_with_older_go_version(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""
            go_buildtags = ""

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        self.run_output_mock.return_value = "go version go1.11 linux/amd64"

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.builddir)
        with open(os.path.join(plugin.builddir, "go.mod"), "w") as go_mod_file:
            print("module github.com/foo/bar/module", file=go_mod_file)
            print("go 1.11", file=go_mod_file)

        plugin.build()

        self.run_output_mock.assert_called_once_with(["go", "version"],
                                                     cwd=mock.ANY,
                                                     env=mock.ANY)
        self.run_mock.assert_called_once_with(
            ["go", "build", "-o", f"{plugin._install_bin_dir}/module"],
            cwd=plugin.builddir,
            env=mock.ANY,
        )

        self.assertThat(
            fake_logger.output.strip(),
            Equals(
                "Ensure build environment configuration is correct for this version of Go. "
                "Read more about it at "
                "https://github.com/golang/go/wiki/Modules#how-to-install-and-activate-module-support"
            ),
        )
예제 #12
0
    def test_build_environment(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""
            go_buildtags = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)
        open(os.path.join(plugin.sourcedir, "main.go"), "w").close()
        os.makedirs(os.path.join(plugin.installdir, "lib"))
        os.makedirs(os.path.join(plugin.installdir, "usr", "lib"))
        os.makedirs(os.path.join(plugin.project.stage_dir, "lib"))
        os.makedirs(os.path.join(plugin.project.stage_dir, "usr", "lib"))
        plugin.pull()

        self.assertThat(self.run_mock.call_count, Equals(1))
        for call_args in self.run_mock.call_args_list:
            env = call_args[1]["env"]
            self.assertTrue("GOPATH" in env,
                            "Expected environment to include GOPATH")
            self.assertThat(env["GOPATH"], Equals(plugin._gopath))

            self.assertTrue("CGO_LDFLAGS" in env,
                            "Expected environment to include CGO_LDFLAGS")
            expected_flags = [
                "-L{}/lib".format(plugin.installdir),
                "-L{}/usr/lib".format(plugin.installdir),
                "-L{}/lib".format(plugin.project.stage_dir),
                "-L{}/usr/lib".format(plugin.project.stage_dir),
            ]
            for flag in expected_flags:
                self.assertTrue(
                    flag in env["CGO_LDFLAGS"],
                    "Expected $CGO_LDFLAGS to include {!r}, but it was "
                    '"{}"'.format(flag, env["CGO_LDFLAGS"]),
                )
예제 #13
0
    def test_no_local_source_with_go_packages(self):
        class Options:
            source = None
            go_channel = "latest/stable"
            go_packages = ["github.com/gotools/vet"]
            go_importpath = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)

        plugin.pull()

        self.run_mock.assert_has_calls([
            mock.call(
                ["go", "get", "-t", "-d", plugin.options.go_packages[0]],
                env=mock.ANY,
                cwd=plugin._gopath_src,
            )
        ])

        self.assert_go_paths(plugin)
예제 #14
0
def test_cross_compile(monkeypatch, tmp_work_path, mock_run, deb_arch,
                       go_arch):
    monkeypatch.setattr(Project, "is_cross_compiling", True)

    class Options:
        source = ""
        go_packages = ["github.com/gotools/vet"]
        go_importpath = ""
        go_buildtags = ""
        go_channel = ""

    project = Project(target_deb_arch=deb_arch)
    project._snap_meta = meta.snap.Snap(name="test-snap", base="core18")

    plugin = go.GoPlugin("test-part", Options(), project)

    os.makedirs(plugin.sourcedir)

    plugin.pull()

    assert mock_run.call_count == 1

    for call_args in mock_run.call_args_list:
        env = call_args[1]["env"]
        assert "CC" in env
        assert env["CC"] == f"{project.arch_triplet}-gcc"

        assert "CXX" in env
        assert env["CXX"] == f"{project.arch_triplet}-g++"

        assert "CGO_ENABLED" in env
        assert env["CGO_ENABLED"] == "1"

        assert "GOARCH" in env
        assert env["GOARCH"] == go_arch

        if deb_arch == "armhf":
            assert "GOARM" in env
            assert env["GOARM"] == "7"
예제 #15
0
    def test_pull_go_mod_with_older_go_version(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = "foo"
            go_buildtags = ""

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        self.run_output_mock.return_value = "go version go1.11 linux/amd64"

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)
        open(os.path.join(plugin.sourcedir, "go.mod"), "w").close()

        plugin.pull()

        self.run_output_mock.assert_called_once_with(["go", "version"],
                                                     cwd=mock.ANY,
                                                     env=mock.ANY)
        self.run_mock.assert_called_once_with(["go", "mod", "download"],
                                              cwd=plugin.sourcedir,
                                              env=mock.ANY)

        # Call pull again and ensure nothing new is logged.
        plugin.pull()

        self.assertThat(
            fake_logger.output.strip(),
            Equals(
                "Ensure build environment configuration is correct for this version of Go. "
                "Read more about it at "
                "https://github.com/golang/go/wiki/Modules#how-to-install-and-activate-module-support"
            ),
        )
예제 #16
0
    def test_pull_local_sources(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_packages = []
            go_importpath = ""

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.sourcedir)
        open(os.path.join(plugin.sourcedir, "main.go"), "w").close()

        plugin.pull()

        self.run_mock.assert_has_calls([
            mock.call(
                ["go", "get", "-t", "-d", "./dir/..."],
                cwd=plugin._gopath_src,
                env=mock.ANY,
            )
        ])

        self.assert_go_paths(plugin)
예제 #17
0
    def test_build_with_buildtag(self):
        class Options:
            source = "dir"
            go_channel = "latest/stable"
            go_importpath = ""
            go_packages = []
            go_buildtags = ["testbuildtag1", "testbuildtag2"]

        plugin = go.GoPlugin("test-part", Options(), self.project)

        os.makedirs(plugin.options.source)
        os.makedirs(plugin.sourcedir)

        plugin.pull()

        os.makedirs(plugin._gopath_bin)
        os.makedirs(plugin.builddir)

        self.run_mock.reset_mock()
        self.run_output_mock.return_value = "dir/pkg/main main"

        plugin.build()

        self.run_output_mock.assert_called_once_with(
            ["go", "list", "-f", "{{.ImportPath}} {{.Name}}", "./dir/..."],
            cwd=plugin._gopath_src,
            env=mock.ANY,
        )

        self.run_mock.assert_called_once_with(
            [
                "go", "build", "-tags=testbuildtag1,testbuildtag2",
                "dir/pkg/main"
            ],
            cwd=os.path.join(plugin.installdir, "bin"),
            env=mock.ANY,
        )