# # Copyright OpenEmbedded Contributors # # SPDX-License-Identifier: MIT # import os import shutil import unittest from oeqa.core.utils.path import remove_safe from oeqa.sdk.case import OESDKTestCase from oeqa.utils.subprocesstweak import errors_have_output from oe.go import map_arch errors_have_output() class GoCompileTest(OESDKTestCase): td_vars = ['MACHINE', 'TARGET_ARCH'] @classmethod def setUpClass(self): # Copy test.go file to SDK directory (same as GCC test uses files_dir) shutil.copyfile(os.path.join(self.tc.files_dir, 'test.go'), os.path.join(self.tc.sdk_dir, 'test.go')) def setUp(self): target_arch = self.td.get("TARGET_ARCH") # Check for go-cross-canadian package (uses target architecture) if not self.tc.hasHostPackage("go-cross-canadian-%s" % target_arch): raise unittest.SkipTest("GoCompileTest class: SDK doesn't contain a Go cross-canadian toolchain") # Additional runtime check for go command availability try: self._run('which go') except Exception as e: raise unittest.SkipTest("GoCompileTest class: go command not available: %s" % str(e)) def test_go_build(self): """Test Go build command (native compilation)""" self._run('cd %s; go build -o test test.go' % self.tc.sdk_dir) def test_go_module(self): """Test Go module creation and building""" # Create a simple Go module self._run('cd %s; go mod init hello-go' % self.tc.sdk_dir) self._run('cd %s; go build -o hello-go' % self.tc.sdk_dir) @classmethod def tearDownClass(self): files = [os.path.join(self.tc.sdk_dir, f) \ for f in ['test.go', 'test', 'hello-go', 'go.mod', 'go.sum']] for f in files: remove_safe(f) class GoHostCompileTest(OESDKTestCase): td_vars = ['MACHINE', 'SDK_SYS', 'TARGET_ARCH'] @classmethod def setUpClass(self): # Copy test.go file to SDK directory (same as GCC test uses files_dir) shutil.copyfile(os.path.join(self.tc.files_dir, 'test.go'), os.path.join(self.tc.sdk_dir, 'test.go')) def setUp(self): target_arch = self.td.get("TARGET_ARCH") # Check for go-cross-canadian package (uses target architecture) if not self.tc.hasHostPackage("go-cross-canadian-%s" % target_arch): raise unittest.SkipTest("GoHostCompileTest class: SDK doesn't contain a Go cross-canadian toolchain") # Additional runtime check for go command availability try: self._run('which go') except Exception as e: raise unittest.SkipTest("GoHostCompileTest class: go command not available: %s" % str(e)) def _get_go_arch(self): """Get Go architecture from SDK_SYS""" sdksys = self.td.get("SDK_SYS") arch = sdksys.split('-')[0] # Use mapping for other architectures return map_arch(arch) def test_go_cross_compile(self): """Test Go cross-compilation for target""" goarch = self._get_go_arch() self._run('cd %s; GOOS=linux GOARCH=%s go build -o test-%s test.go' % (self.tc.sdk_dir, goarch, goarch)) def test_go_module_cross_compile(self): """Test Go module cross-compilation""" goarch = self._get_go_arch() self._run('cd %s; go mod init hello-go' % self.tc.sdk_dir) self._run('cd %s; GOOS=linux GOARCH=%s go build -o hello-go-%s' % (self.tc.sdk_dir, goarch, goarch)) @classmethod def tearDownClass(self): # Clean up files with dynamic architecture names files = [os.path.join(self.tc.sdk_dir, f) \ for f in ['test.go', 'go.mod', 'go.sum']] # Add common architecture-specific files that might be created common_archs = ['arm64', 'arm', 'amd64', '386', 'mips', 'mipsle', 'ppc64', 'ppc64le', 'riscv64'] for arch in common_archs: files.extend([os.path.join(self.tc.sdk_dir, f) \ for f in ['test-%s' % arch, 'hello-go-%s' % arch]]) for f in files: remove_safe(f)