From fbb64f2a826f3fcf9584ed65d59e5bd8eb0c26e8 Mon Sep 17 00:00:00 2001 From: Itxaka Date: Tue, 17 Sep 2024 17:51:11 +0200 Subject: [PATCH] Run tests in parallel and output github formats on workflow (#543) * Run tests in parallel and output github formats on workflow Signed-off-by: Itxaka * Fix broken parallel tests We were using a fixed file for the tests which several tests could be accessing at the same time. This fixes it by setting a temp random file at the test start Signed-off-by: Itxaka * Fix the tests logging to stdout Signed-off-by: Itxaka * Drop the verbose Signed-off-by: Itxaka * Fix agent test Signed-off-by: Itxaka * Let the event consumer create the logfile or whatever Signed-off-by: Itxaka * Drop Focus Signed-off-by: Itxaka --------- Signed-off-by: Itxaka --- .github/workflows/unit-tests.yml | 11 +++++------ Earthfile | 2 +- internal/agent/agent.go | 20 ++++---------------- internal/agent/agent_test.go | 2 +- pkg/action/install_test.go | 7 +++++-- pkg/config/spec_test.go | 27 +++++++++++++++------------ pkg/elemental/elemental_test.go | 17 ++++++++++------- 7 files changed, 41 insertions(+), 45 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 9d35217..55d2c7a 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -13,21 +13,20 @@ jobs: unit-tests: strategy: matrix: - go-version: [ "1.23-bookworm" ] + go-version: [ "1.23" ] runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install earthly - uses: Luet-lab/luet-install-action@v1 + - name: Setup Go environment + uses: actions/setup-go@v5.0.2 with: - repository: quay.io/kairos/packages - packages: utils/earthly + go-version: '${{ matrix.go-version }}' - name: Run tests run: | - earthly -P +test --GO_VERSION=${{ matrix.go-version }} + go run github.com/onsi/ginkgo/v2/ginkgo run -p --github-output --covermode=atomic --coverprofile=coverage.out --race -r ./... - name: Codecov uses: codecov/codecov-action@v4 env: diff --git a/Earthfile b/Earthfile index 3a5c290..a9eb2d0 100644 --- a/Earthfile +++ b/Earthfile @@ -23,7 +23,7 @@ test: ARG TEST_PATHS=./... ARG LABEL_FILTER= ENV CGO_ENABLED=1 - RUN go run github.com/onsi/ginkgo/v2/ginkgo run --label-filter "$LABEL_FILTER" --covermode=atomic --coverprofile=coverage.out -v --race -r $TEST_PATHS + RUN go run github.com/onsi/ginkgo/v2/ginkgo run -p --label-filter "$LABEL_FILTER" --covermode=atomic --coverprofile=coverage.out --race -r $TEST_PATHS SAVE ARTIFACT coverage.out AS LOCAL coverage.out version: diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 323e031..18160ce 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -2,17 +2,15 @@ package agent import ( "fmt" - v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1" - "os" - "path/filepath" - hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks" "github.com/kairos-io/kairos-agent/v2/internal/bus" config "github.com/kairos-io/kairos-agent/v2/pkg/config" + v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1" events "github.com/kairos-io/kairos-sdk/bus" "github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/machine" "github.com/kairos-io/kairos-sdk/utils" + "os" ) // Run starts the agent provider emitting the bootstrap event. @@ -38,18 +36,8 @@ func Run(opts ...Option) error { return nil } - os.MkdirAll("/var/log/kairos", 0600) //nolint:errcheck - - fileName := filepath.Join("/var/log/kairos", "agent-provider.log") - - // Create if not exist - if _, err := os.Stat(fileName); err != nil { - err = os.WriteFile(fileName, []byte{}, os.ModePerm) - if err != nil { - return err - } - } - + fileName := "/var/log/kairos/agent-provider.log" + if !machine.SentinelExist("firstboot") { spec := v1.EmptySpec{} if err := hook.Run(*c, &spec, hook.FirstBoot...); err != nil { diff --git a/internal/agent/agent_test.go b/internal/agent/agent_test.go index f74b822..9451f04 100644 --- a/internal/agent/agent_test.go +++ b/internal/agent/agent_test.go @@ -28,7 +28,7 @@ var _ = Describe("Bootstrap provider", func() { defer os.RemoveAll(f) wd, _ := os.Getwd() - os.WriteFile(filepath.Join(wd, "agent-provider-test"), []byte(testProvider), 0655) + os.WriteFile(filepath.Join(wd, "agent-provider-test"), []byte(testProvider), 0777) defer os.RemoveAll(filepath.Join(wd, "agent-provider-test")) diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 70d7318..9c98c5f 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -94,13 +94,15 @@ var _ = Describe("Install action tests", func() { }) Describe("Install Action", Label("install"), func() { - var device, cmdFail string + var device, cmdFail, tmpdir string var err error var spec *v1.InstallSpec var installer *action.InstallAction BeforeEach(func() { - device = "/tmp/test.img" + tmpdir, err = os.MkdirTemp("", "install-*") + Expect(err).Should(BeNil()) + device = filepath.Join(tmpdir, "test.img") Expect(os.RemoveAll(device)).Should(Succeed()) // at least 2Gb in size as state is set to 1G _, err = diskfs.Create(device, 2*1024*1024*1024, diskfs.Raw, 512) @@ -201,6 +203,7 @@ var _ = Describe("Install action tests", func() { } Expect(os.RemoveAll(device)).ToNot(HaveOccurred()) ghwTest.Clean() + Expect(os.RemoveAll(tmpdir)).ToNot(HaveOccurred()) }) It("Successfully installs", func() { diff --git a/pkg/config/spec_test.go b/pkg/config/spec_test.go index b5df206..2ba568b 100644 --- a/pkg/config/spec_test.go +++ b/pkg/config/spec_test.go @@ -49,14 +49,19 @@ var _ = Describe("Types", Label("types", "config"), func() { var logger sdkTypes.KairosLogger var ci *v1mock.FakeCloudInitRunner var c *config.Config + var memLog bytes.Buffer + BeforeEach(func() { + memLog = bytes.Buffer{} + logger = sdkTypes.NewBufferLogger(&memLog) + logger.SetLevel("debug") + fs, cleanup, err = vfst.NewTestFS(nil) Expect(err).ToNot(HaveOccurred()) mounter = v1mock.NewErrorMounter() runner = v1mock.NewFakeRunner() client = &v1mock.FakeHTTPClient{} sysc = &v1mock.FakeSyscall{} - logger = sdkTypes.NewNullLogger() ci = &v1mock.FakeCloudInitRunner{} c = config.NewConfig( config.WithFs(fs), @@ -535,10 +540,11 @@ cloud-init-paths: ghwTest.Clean() }) It("Reads properly the cloud config for install", func() { - cfg, err := config.Scan(collector.Directories([]string{dir}...), + cfg, err := config.ScanNoLogs(collector.Directories([]string{dir}...), collector.NoLogs, ) cfg.Fs = fs + cfg.Logger = logger Expect(err).ToNot(HaveOccurred()) // Once we got the cfg override the fs to our test fs @@ -559,13 +565,14 @@ cloud-init-paths: }) It("Reads properly the cloud config for reset", func() { bootedFrom = constants.SystemLabel - cfg, err := config.Scan(collector.Directories([]string{dir}...), collector.NoLogs) + cfg, err := config.ScanNoLogs(collector.Directories([]string{dir}...), collector.NoLogs) Expect(err).ToNot(HaveOccurred()) // Override the config with our test params cfg.Runner = runner cfg.Fs = fs cfg.Mounter = mounter cfg.CloudInitRunner = ci + cfg.Logger = logger spec, err := config.ReadSpecFromCloudConfig(cfg, "reset") Expect(err).ToNot(HaveOccurred()) resetSpec := spec.(*v1.ResetSpec) @@ -574,37 +581,33 @@ cloud-init-paths: Expect(resetSpec.Passive.Label).To(Equal("MY_LABEL")) }) It("Reads properly the cloud config for upgrade", func() { - cfg, err := config.Scan(collector.Directories([]string{dir}...), collector.NoLogs) + cfg, err := config.ScanNoLogs(collector.Directories([]string{dir}...), collector.NoLogs) Expect(err).ToNot(HaveOccurred()) // Override the config with our test params cfg.Runner = runner cfg.Fs = fs cfg.Mounter = mounter cfg.CloudInitRunner = ci + cfg.Logger = logger spec, err := config.ReadSpecFromCloudConfig(cfg, "upgrade") Expect(err).ToNot(HaveOccurred()) upgradeSpec := spec.(*v1.UpgradeSpec) Expect(upgradeSpec.RecoveryUpgrade()).To(BeTrue()) }) It("Fails when a wrong action is read", func() { - cfg, err := config.Scan(collector.Directories([]string{dir}...), collector.NoLogs) + cfg, err := config.ScanNoLogs(collector.Directories([]string{dir}...), collector.NoLogs) + cfg.Logger = logger Expect(err).ToNot(HaveOccurred()) _, err = config.ReadSpecFromCloudConfig(cfg, "nope") Expect(err).To(HaveOccurred()) }) - It("Sets info level if its not on the cloud-config", func() { - // Now again but with no config - cfg, err := config.Scan(collector.Directories([]string{""}...), collector.NoLogs) - Expect(err).ToNot(HaveOccurred()) - Expect(cfg.Logger.GetLevel()).To(Equal(zerolog.InfoLevel)) - }) It("Sets debug level if its on the cloud-config", func() { ccdata := []byte(`#cloud-config debug: true `) err = os.WriteFile(filepath.Join(dir, "cc.yaml"), ccdata, os.ModePerm) Expect(err).ToNot(HaveOccurred()) - cfg, err := config.Scan(collector.Directories([]string{dir}...), collector.NoLogs) + cfg, err := config.ScanNoLogs(collector.Directories([]string{dir}...), collector.NoLogs) Expect(err).ToNot(HaveOccurred()) Expect(cfg.Logger.GetLevel()).To(Equal(zerolog.DebugLevel)) diff --git a/pkg/elemental/elemental_test.go b/pkg/elemental/elemental_test.go index 8e6226d..78fb572 100644 --- a/pkg/elemental/elemental_test.go +++ b/pkg/elemental/elemental_test.go @@ -355,23 +355,26 @@ var _ = Describe("Elemental", Label("elemental"), func() { var install *v1.InstallSpec var err error var el *elemental.Elemental + var tmpDir string BeforeEach(func() { cInit = &v1mock.FakeCloudInitRunner{ExecStages: []string{}, Error: false} config.CloudInitRunner = cInit - Expect(os.RemoveAll("/tmp/test.img")).ToNot(HaveOccurred()) + tmpDir, err = os.MkdirTemp("", "elements-*") + Expect(err).To(BeNil()) + Expect(os.RemoveAll(filepath.Join(tmpDir, "/test.img"))).ToNot(HaveOccurred()) // at least 2Gb in size as state is set to 1G - _, err = diskfs.Create("/tmp/test.img", 2*1024*1024*1024, diskfs.Raw, 512) + _, err = diskfs.Create(filepath.Join(tmpDir, "/test.img"), 2*1024*1024*1024, diskfs.Raw, 512) Expect(err).ToNot(HaveOccurred()) - config.Install.Device = "/tmp/test.img" + config.Install.Device = filepath.Join(tmpDir, "/test.img") install, err = agentConfig.NewInstallSpec(config) Expect(err).ToNot(HaveOccurred()) - install.Target = "/tmp/test.img" + install.Target = filepath.Join(tmpDir, "/test.img") el = elemental.NewElemental(config) }) AfterEach(func() { - Expect(os.RemoveAll("/tmp/test.img")).ToNot(HaveOccurred()) + Expect(os.RemoveAll(tmpDir)).ToNot(HaveOccurred()) }) It("Successfully creates partitions and formats them, EFI boot", func() { @@ -379,7 +382,7 @@ var _ = Describe("Elemental", Label("elemental"), func() { install.Firmware = v1.EFI Expect(install.Partitions.SetFirmwarePartitions(v1.EFI, v1.GPT)).To(BeNil()) Expect(el.PartitionAndFormatDevice(install)).To(BeNil()) - disk, err := diskfs.Open("/tmp/test.img", diskfs.WithOpenMode(diskfs.ReadOnly)) + disk, err := diskfs.Open(filepath.Join(tmpDir, "/test.img"), diskfs.WithOpenMode(diskfs.ReadOnly)) defer disk.Close() Expect(err).ToNot(HaveOccurred()) // check that its type GPT @@ -412,7 +415,7 @@ var _ = Describe("Elemental", Label("elemental"), func() { install.Firmware = v1.BIOS Expect(install.Partitions.SetFirmwarePartitions(v1.BIOS, v1.GPT)).To(BeNil()) Expect(el.PartitionAndFormatDevice(install)).To(BeNil()) - disk, err := diskfs.Open("/tmp/test.img", diskfs.WithOpenMode(diskfs.ReadOnly)) + disk, err := diskfs.Open(filepath.Join(tmpDir, "/test.img"), diskfs.WithOpenMode(diskfs.ReadOnly)) defer disk.Close() Expect(err).ToNot(HaveOccurred()) // check that its type GPT