xref: /unit/test/unit/applications/lang/go.py (revision 2616:ab2896c980ab)
1import os
2import shutil
3import subprocess
4
5from unit.applications.proto import ApplicationProto
6from unit.option import option
7
8
9class ApplicationGo(ApplicationProto):
10    @staticmethod
11    def prepare_env(script, name='app', static=False):
12        try:
13            subprocess.check_output(['which', 'go'])
14        except subprocess.CalledProcessError:
15            return None
16
17        temp_dir = f'{option.temp_dir}/go/'
18
19        if not os.path.exists(temp_dir):
20            os.mkdir(temp_dir)
21
22        cache_dir = f'{option.cache_dir}/go-build'
23
24        if not os.path.exists(cache_dir):
25            os.mkdir(cache_dir)
26
27        env = os.environ.copy()
28        env['GOPATH'] = f'{option.current_dir}/build/go'
29        env['GOCACHE'] = cache_dir
30
31        shutil.copy2(f'{option.test_dir}/go/{script}/{name}.go', temp_dir)
32
33        if static:
34            args = [
35                'go',
36                'build',
37                '-tags',
38                'netgo',
39                '-ldflags',
40                '-extldflags "-static"',
41                '-o',
42                f'{temp_dir}{name}',
43                f'{temp_dir}{name}.go',
44            ]
45        else:
46            args = [
47                'go',
48                'build',
49                '-o',
50                f'{temp_dir}{name}',
51                f'{temp_dir}{name}.go',
52            ]
53
54        replace_path = f'{option.current_dir}/build/go/src/unit.nginx.org/go'
55
56        with open(f'{temp_dir}go.mod', 'w', encoding='utf-8') as f:
57            f.write(
58                f"""module test/app
59require unit.nginx.org/go v0.0.0
60replace unit.nginx.org/go => {replace_path}
61"""
62            )
63
64        if option.detailed:
65            print(f'\n$ GOPATH={env["GOPATH"]} {" ".join(args)}')
66
67        try:
68            output = subprocess.check_output(
69                args, env=env, cwd=temp_dir, stderr=subprocess.STDOUT
70            )
71
72        except KeyboardInterrupt:
73            raise
74
75        except subprocess.CalledProcessError:
76            return None
77
78        return output
79
80    def load(self, script, name='app', **kwargs):
81        static_build = False
82
83        wdir = f'{option.test_dir}/go/{script}'
84        executable = f'{option.temp_dir}/go/{name}'
85
86        if 'isolation' in kwargs and 'rootfs' in kwargs['isolation']:
87            wdir = "/go/"
88            executable = f"/go/{name}"
89            static_build = True
90
91        ApplicationGo.prepare_env(script, name, static=static_build)
92
93        conf = {
94            "listeners": {"*:8080": {"pass": f"applications/{script}"}},
95            "applications": {
96                script: {
97                    "type": "external",
98                    "processes": {"spare": 0},
99                    "working_directory": wdir,
100                    "executable": executable,
101                },
102            },
103        }
104
105        self._load_conf(conf, **kwargs)
106