diff --git a/Taskfile.yaml b/Taskfile.yaml index 5b402c15..d8ad5c93 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -222,16 +222,16 @@ tasks: cmds: # Using go-testreport v0.3.2 - "go install github.com/becheran/go-testreport@90efc1ce13c872f23d6bc8a069527c26288b8f9c" - - "go test -race -cover -json -tags='!integration' ./internal/... ./pkg/... ./cmd/... | go-testreport -output unit-test-report.md -vars 'Title:Unit Test Report'" - + - "go test -p 1 -race -cover -json -tags='!integration' ./internal/... ./pkg/... ./cmd/... | go-testreport -output unit-test-report.md -vars 'Title:Unit Test Report'" + test:unit:verbose: desc: "Run unit tests with verbose console output" deps: - "generate" - "mocks" cmds: - - "go test -v -race -cover -tags='!integration' ./internal/... ./pkg/... ./cmd/..." - + - "go test -p 1 -v -race -cover -tags='!integration' ./internal/... ./pkg/... ./cmd/..." + test:integration:verbose: desc: "Run integration tests with verbose console output. Use TEST_NAME to run a specific test, e.g., task test:integration:verbose TEST_NAME='^Test_StepKubeadm_Fresh_Integration$'" cmds: @@ -282,9 +282,11 @@ tasks: cmds: # Using go-testreport v0.3.2 - "go install github.com/becheran/go-testreport@90efc1ce13c872f23d6bc8a069527c26288b8f9c" + - "go test -p 1 -v -tags='integration_block_node_full_install' ./internal/... ./pkg/... ./cmd/... -timeout 10m" + - "go test -p 1 -v -tags='integration_require_block_node_installed' ./internal/... ./pkg/... ./cmd/... -timeout 10m" - "go test -p 1 -race -cover -json -tags='integration' ./internal/... ./pkg/... ./cmd/... -timeout 60m > integration-test.json" - "go-testreport -input integration-test.json -output integration-test-report.md -vars 'Title:Integration Test Report'" - + run: deps: - "run:weaver" diff --git a/cmd/weaver/commands/block/node/install_upgrade_it_test.go b/cmd/weaver/commands/block/node/install_upgrade_it_test.go index d15823e0..7a11a910 100644 --- a/cmd/weaver/commands/block/node/install_upgrade_it_test.go +++ b/cmd/weaver/commands/block/node/install_upgrade_it_test.go @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 -//go:build integration +//go:build integration_block_node_full_install package node @@ -18,7 +18,7 @@ import ( // TestHelmLifecycle_InstallAndUpgradeWithValueReuse tests a complete installation flow with flag overrides // and multiple upgrade scenarios with different value reuse behaviors func TestHelmLifecycle_InstallAndUpgradeWithValueReuse(t *testing.T) { - serial(t) // Enforce sequential execution due to shared flag variables + testutil.Serial(t) // Enforce sequential execution due to shared flag variables testutil.Reset(t) diff --git a/cmd/weaver/commands/block/node/node_test.go b/cmd/weaver/commands/block/node/node_test.go index f703be15..57980702 100644 --- a/cmd/weaver/commands/block/node/node_test.go +++ b/cmd/weaver/commands/block/node/node_test.go @@ -7,7 +7,6 @@ import ( "os" "os/exec" "path/filepath" - "sync" "testing" "github.com/hashgraph/solo-weaver/cmd/weaver/commands/common" @@ -18,19 +17,6 @@ import ( "github.com/stretchr/testify/require" ) -// serialMu enforces sequential execution of tests that manipulate shared package-level flag variables. -// Tests acquire this lock at the start and release it via t.Cleanup, ensuring mutual exclusion. -var serialMu sync.Mutex - -// serial ensures a test runs sequentially, never in parallel with other tests using this function. -// It acquires a mutex that is released when the test completes (via t.Cleanup). -// This protects shared package-level flag variables from concurrent access. -func serial(t *testing.T) { - t.Helper() - serialMu.Lock() - t.Cleanup(serialMu.Unlock) -} - // resetFlags resets all flag variables to empty strings func resetFlags(cmd *cobra.Command) { flagProfile = "local" @@ -95,7 +81,7 @@ func getPVCStorageSize(t *testing.T, pvcName, namespace string) string { // TestNegative_InvalidValuesFilePath tests that invalid values file paths are rejected func TestNegative_InvalidValuesFilePath(t *testing.T) { - serial(t) + testutil.Serial(t) testCases := []struct { name string @@ -175,7 +161,7 @@ blockNode: // TestNegative_InvalidStoragePaths tests that invalid storage paths are rejected // when they are actually validated in GetStoragePaths() during the workflow execution func TestNegative_InvalidStoragePaths(t *testing.T) { - serial(t) + testutil.Serial(t) testCases := []struct { name string @@ -256,7 +242,7 @@ blockNode: // TestNegative_DirectoryAsValuesFile tests that directories are rejected as values files func TestNegative_DirectoryAsValuesFile(t *testing.T) { - serial(t) + testutil.Serial(t) testutil.Reset(t) @@ -294,7 +280,7 @@ blockNode: // TestNegative_InvalidChartVersion tests various invalid chart version formats func TestNegative_InvalidChartVersion(t *testing.T) { - serial(t) + testutil.Serial(t) cmd := testutil.PrepareSubCmdForTest(GetCmd()) resetFlags(cmd) @@ -425,7 +411,7 @@ blockNode: // TestNegative_InvalidYAMLInConfigFile tests that invalid YAML in config file is handled func TestNegative_InvalidYAMLInConfigFile(t *testing.T) { - serial(t) + testutil.Serial(t) testutil.Reset(t) diff --git a/internal/bll/block_node_test.go b/internal/bll/block_node_test.go deleted file mode 100644 index 8d56ec9f..00000000 --- a/internal/bll/block_node_test.go +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package bll diff --git a/internal/config/config.go b/internal/config/config.go index ad8024e2..5c40e06a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -258,6 +258,10 @@ func Initialize(path string) error { WithProperty(errorx.PropertyPayload(), path) } + // Migrate old config field names to new names for backward compatibility + // Old format: release, chart -> New format: releaseName, chartRepo + migrateOldConfigKeys() + if err := viper.Unmarshal(&globalConfig); err != nil { return errorx.IllegalFormat.Wrap(err, "failed to parse configuration"). WithProperty(errorx.PropertyPayload(), path) diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 91a2d978..653f5bda 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -55,3 +55,122 @@ blockNode: t.Fatalf("env override failed: expected %q, got %q", expected, got) } } + +func TestInitialize_BackwardCompatibility_OldFieldNames(t *testing.T) { + // Test that old config field names (release, chart) are migrated to new names (releaseName, chartRepo) + yamlCfg := ` +blockNode: + namespace: "test-ns" + release: "old-release-name" + chart: "oci://ghcr.io/old/chart" + version: "1.0.0" + storage: + basePath: "/mnt/storage" +` + tmpFile, err := os.CreateTemp("", "weaver-config-*.yaml") + if err != nil { + t.Fatalf("create temp file: %v", err) + } + defer os.Remove(tmpFile.Name()) + + if _, err := tmpFile.WriteString(yamlCfg); err != nil { + tmpFile.Close() + t.Fatalf("write temp config: %v", err) + } + tmpFile.Close() + + if err := Initialize(tmpFile.Name()); err != nil { + t.Fatalf("Initialize failed: %v", err) + } + + cfg := Get() + + // Verify old field names are migrated to new struct fields + if cfg.BlockNode.ReleaseName != "old-release-name" { + t.Errorf("ReleaseName migration failed: expected %q, got %q", "old-release-name", cfg.BlockNode.ReleaseName) + } + if cfg.BlockNode.ChartRepo != "oci://ghcr.io/old/chart" { + t.Errorf("ChartRepo migration failed: expected %q, got %q", "oci://ghcr.io/old/chart", cfg.BlockNode.ChartRepo) + } +} + +func TestInitialize_NewFieldNames(t *testing.T) { + // Test that new config field names work directly + yamlCfg := ` +blockNode: + namespace: "test-ns" + releaseName: "new-release-name" + chartRepo: "oci://ghcr.io/new/chart" + chartVersion: "2.0.0" + version: "1.0.0" + storage: + basePath: "/mnt/storage" +` + tmpFile, err := os.CreateTemp("", "weaver-config-*.yaml") + if err != nil { + t.Fatalf("create temp file: %v", err) + } + defer os.Remove(tmpFile.Name()) + + if _, err := tmpFile.WriteString(yamlCfg); err != nil { + tmpFile.Close() + t.Fatalf("write temp config: %v", err) + } + tmpFile.Close() + + if err := Initialize(tmpFile.Name()); err != nil { + t.Fatalf("Initialize failed: %v", err) + } + + cfg := Get() + + if cfg.BlockNode.ReleaseName != "new-release-name" { + t.Errorf("ReleaseName: expected %q, got %q", "new-release-name", cfg.BlockNode.ReleaseName) + } + if cfg.BlockNode.ChartRepo != "oci://ghcr.io/new/chart" { + t.Errorf("ChartRepo: expected %q, got %q", "oci://ghcr.io/new/chart", cfg.BlockNode.ChartRepo) + } + if cfg.BlockNode.ChartVersion != "2.0.0" { + t.Errorf("ChartVersion: expected %q, got %q", "2.0.0", cfg.BlockNode.ChartVersion) + } +} + +func TestInitialize_NewFieldNamesTakePrecedence(t *testing.T) { + // Test that new field names take precedence over old ones when both are specified + yamlCfg := ` +blockNode: + namespace: "test-ns" + release: "old-release" + releaseName: "new-release" + chart: "oci://old/chart" + chartRepo: "oci://new/chart" + version: "1.0.0" + storage: + basePath: "/mnt/storage" +` + tmpFile, err := os.CreateTemp("", "weaver-config-*.yaml") + if err != nil { + t.Fatalf("create temp file: %v", err) + } + defer os.Remove(tmpFile.Name()) + + if _, err := tmpFile.WriteString(yamlCfg); err != nil { + tmpFile.Close() + t.Fatalf("write temp config: %v", err) + } + tmpFile.Close() + + if err := Initialize(tmpFile.Name()); err != nil { + t.Fatalf("Initialize failed: %v", err) + } + + cfg := Get() + + // New field names should take precedence + if cfg.BlockNode.ReleaseName != "new-release" { + t.Errorf("ReleaseName precedence failed: expected %q, got %q", "new-release", cfg.BlockNode.ReleaseName) + } + if cfg.BlockNode.ChartRepo != "oci://new/chart" { + t.Errorf("ChartRepo precedence failed: expected %q, got %q", "oci://new/chart", cfg.BlockNode.ChartRepo) + } +} diff --git a/internal/config/migration.go b/internal/config/migration.go new file mode 100644 index 00000000..5659bbfd --- /dev/null +++ b/internal/config/migration.go @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package config migration.go contains backward compatibility logic for deprecated config fields. +// This file can be safely deleted once users have migrated to the new config format. +// +// Deprecated fields (remove support after v1.0.0 or similar milestone): +// - blockNode.release -> blockNode.releaseName +// - blockNode.chart -> blockNode.chartRepo + +package config + +import ( + "github.com/automa-saga/logx" + "github.com/spf13/viper" +) + +// deprecatedKeyMappings defines the mapping from old (deprecated) keys to new keys. +// Add new migrations here as needed. +var deprecatedKeyMappings = []struct { + oldKey string + newKey string +}{ + {"blockNode.release", "blockNode.releaseName"}, + {"blockNode.chart", "blockNode.chartRepo"}, +} + +// migrateOldConfigKeys migrates deprecated config field names to their new names. +// This provides backward compatibility for users with old config files. +// It also logs deprecation warnings to encourage users to update their config files. +func migrateOldConfigKeys() { + for _, mapping := range deprecatedKeyMappings { + migrateKey(mapping.oldKey, mapping.newKey) + } +} + +// migrateKey migrates a single deprecated key to its new name. +// It only migrates if the new key is not already set and the old key exists. +// Logs a deprecation warning when migration occurs. +func migrateKey(oldKey, newKey string) { + if !viper.IsSet(newKey) && viper.IsSet(oldKey) { + value := viper.Get(oldKey) + viper.Set(newKey, value) + + logx.As().Warn(). + Str("oldKey", oldKey). + Str("newKey", newKey). + Msg("DEPRECATION WARNING: Config field is deprecated and will be removed in a future release. Please update your config file.") + } +} diff --git a/internal/reality/reality_it_test.go b/internal/reality/reality_it_test.go index d2033cd1..215ca751 100644 --- a/internal/reality/reality_it_test.go +++ b/internal/reality/reality_it_test.go @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 -//go:build integration +//go:build integration_require_block_node_installed package reality diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go index 65fcb1c0..d679b8c5 100644 --- a/internal/runtime/runtime.go +++ b/internal/runtime/runtime.go @@ -57,7 +57,7 @@ func NewRuntimeBase[T any]( // It respects refreshInterval if lastSync is provided. func (rb *Base[T]) RefreshState(ctx context.Context, force bool) error { if rb.fetch == nil { - return errorx.IllegalState.New(rb.fetchName + " fetcher is not initialized") + return errorx.IllegalState.New("%s fetcher is not initialized", rb.fetchName) } now := htime.Now() diff --git a/internal/testutil/helper.go b/internal/testutil/helper.go index 33fcf6ce..0e9915b8 100644 --- a/internal/testutil/helper.go +++ b/internal/testutil/helper.go @@ -7,6 +7,7 @@ import ( "os/exec" "path/filepath" "strings" + "sync" "testing" "github.com/hashgraph/solo-weaver/internal/core" @@ -14,6 +15,19 @@ import ( "github.com/stretchr/testify/require" ) +// serialMu enforces sequential execution of tests that manipulate shared system state. +// Tests acquire this lock at the start and release it via t.Cleanup, ensuring mutual exclusion. +var serialMu sync.Mutex + +// Serial ensures a test runs sequentially, never in parallel with other tests using this function. +// It acquires a mutex that is released when the test completes (via t.Cleanup). +// This protects shared system state (e.g., /opt/solo/weaver, /usr/local/bin) from concurrent access. +func Serial(t *testing.T) { + t.Helper() + serialMu.Lock() + t.Cleanup(serialMu.Unlock) +} + // PrepareSubCmdForTest creates a root command with the given subcommand added. // Use this from tests in other packages to avoid duplicating the helper. func PrepareSubCmdForTest(sub *cobra.Command) *cobra.Command { diff --git a/internal/workflows/notify/handler_test.go b/internal/workflows/notify/handler_test.go index 518a4685..9e40bb9e 100644 --- a/internal/workflows/notify/handler_test.go +++ b/internal/workflows/notify/handler_test.go @@ -36,6 +36,11 @@ func (m *mockStep) State() automa.StateBag { return m.state } +func (m *mockStep) WithState(s automa.StateBag) automa.Step { + m.state = s + return m +} + func (m *mockStep) Id() string { return m.id } func TestNotificationHandler_Callbacks(t *testing.T) { diff --git a/internal/workflows/steps/step_setup_directories_test.go b/internal/workflows/steps/step_setup_directories_test.go index fad0d2ca..11fa192f 100644 --- a/internal/workflows/steps/step_setup_directories_test.go +++ b/internal/workflows/steps/step_setup_directories_test.go @@ -17,7 +17,7 @@ func TestSetupHomeDirectoryStructure_Integration(t *testing.T) { tmpHome := t.TempDir() pp := core.NewWeaverPaths(tmpHome) - step, err := SetupHomeDirectoryStructure(pp).Build() + step, err := SetupHomeDirectoryStructure(*pp).Build() require.NoError(t, err) report := step.Execute(context.Background()) diff --git a/pkg/helm/helpers.go b/pkg/helm/helpers.go index fa3e7f54..15086447 100644 --- a/pkg/helm/helpers.go +++ b/pkg/helm/helpers.go @@ -4,9 +4,11 @@ package helm import ( "os" + "path/filepath" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v3/pkg/kube" "helm.sh/helm/v3/pkg/registry" ) @@ -15,6 +17,32 @@ import ( // helmDriver is the Helm storage driver, default is "secrets" var helmDriver string = os.Getenv("HELM_DRIVER") +func init() { + // Fix for fieldManager length issue - Kubernetes API rejects field managers > 128 bytes. + // When running via `go test` or IntelliJ, os.Args[0] can be a very long temp path like + // "/private/var/folders/.../go_build_github_com_hashgraph_solo_weaver_..." which exceeds 128 bytes. + // We truncate to ensure it stays under the limit while preserving as much useful info as possible. + kube.ManagedFieldsManager = truncateFieldManager(os.Args[0], 128) +} + +// truncateFieldManager ensures the field manager name doesn't exceed maxLen bytes. +// It uses the base name of the path and truncates if necessary. +func truncateFieldManager(path string, maxLen int) string { + if path == "" { + return "helm" + } + + // Use base name to get a shorter, more meaningful name + name := filepath.Base(path) + + // If still too long, truncate from the beginning to keep the end (usually more meaningful) + if len(name) > maxLen { + name = name[len(name)-maxLen:] + } + + return name +} + func initActionConfig(settings *cli.EnvSettings, debug action.DebugLog) (*action.Configuration, error) { return initActionConfigList(settings, debug, false) } diff --git a/pkg/helm/helpers_test.go b/pkg/helm/helpers_test.go new file mode 100644 index 00000000..5ff24f5c --- /dev/null +++ b/pkg/helm/helpers_test.go @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: Apache-2.0 + +package helm + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTruncateFieldManager(t *testing.T) { + tests := []struct { + name string + path string + maxLen int + expected string + }{ + { + name: "empty path returns helm", + path: "", + maxLen: 128, + expected: "helm", + }, + { + name: "short path unchanged", + path: "/usr/local/bin/weaver", + maxLen: 128, + expected: "weaver", + }, + { + name: "long IntelliJ test path base name extracted", + path: "/private/var/folders/30/yl_b12wx77q66hvnshhf66c40000gp/T/GoLand/___go_build_github_com_hashgraph_solo_weaver_cmd_weaver_commands_block_node", + maxLen: 128, + expected: "___go_build_github_com_hashgraph_solo_weaver_cmd_weaver_commands_block_node", + }, + { + name: "base name exactly at limit", + path: "/some/path/" + strings.Repeat("a", 128), + maxLen: 128, + expected: strings.Repeat("a", 128), + }, + { + name: "base name over limit truncated from start", + path: "/some/path/" + strings.Repeat("a", 10) + strings.Repeat("b", 130), + maxLen: 128, + expected: strings.Repeat("b", 128), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := truncateFieldManager(tt.path, tt.maxLen) + if len(result) > tt.maxLen { + t.Errorf("truncateFieldManager() returned %d bytes, want <= %d", len(result), tt.maxLen) + } + require.Equal(t, tt.expected, result) + + }) + } +} + +func TestTruncateFieldManager_RealWorldPaths(t *testing.T) { + // Test with real-world IntelliJ/GoLand test execution paths + longPaths := []string{ + "/private/var/folders/30/yl_b12wx77q66hvnshhf66c40000gp/T/GoLand/___go_build_github_com_hashgraph_solo_weaver_cmd_weaver_commands_block_node", + "/var/folders/30/yl_b12wx77q66hvnshhf66c40000gp/T/go-build1234567890/b001/exe/node.test", + "/tmp/go-build1234567890/b001/exe/___TestHelmLifecycle_InstallAndUpgradeWithValueReuse_in_github_com_hashgraph_solo_weaver_cmd_weaver_commands_block_node", + } + + for _, path := range longPaths { + result := truncateFieldManager(path, 128) + if len(result) > 128 { + t.Errorf("truncateFieldManager(%q) = %q (len=%d), want len <= 128", path, result, len(result)) + } + if result == "" { + t.Errorf("truncateFieldManager(%q) returned empty string", path) + } + } +} diff --git a/pkg/software/base_installer_test.go b/pkg/software/base_installer_test.go index 458ac5fd..7051ed08 100644 --- a/pkg/software/base_installer_test.go +++ b/pkg/software/base_installer_test.go @@ -194,6 +194,7 @@ func calculateSHA256(data []byte) string { // Test scenarios using table-driven tests func Test_BaseInstaller_Scenarios(t *testing.T) { + testutil.Serial(t) // Enforce sequential execution due to shared system state requireLinux(t) requireRoot(t) @@ -589,6 +590,7 @@ func newTestInstaller(t *testing.T) *baseInstaller { // Test successful download func Test_BaseInstaller_Download_Success(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -609,6 +611,7 @@ func Test_BaseInstaller_Download_Success(t *testing.T) { // Test when download fails due to invalid configuration func Test_BaseInstaller_Download_Fails(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -631,6 +634,7 @@ func Test_BaseInstaller_Download_Fails(t *testing.T) { // Test when checksum fails (this test might need adjustment based on actual config) func Test_BaseInstaller_Download_ChecksumFails(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -668,6 +672,7 @@ func Test_BaseInstaller_Download_ChecksumFails(t *testing.T) { // Test idempotency with existing valid file func Test_BaseInstaller_Download_Idempotency_ExistingFile(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -692,6 +697,7 @@ func Test_BaseInstaller_Download_Idempotency_ExistingFile(t *testing.T) { } func Test_BaseInstaller_Download_Idempotency_ExistingFile_WrongChecksum(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -723,6 +729,7 @@ func Test_BaseInstaller_Download_Idempotency_ExistingFile_WrongChecksum(t *testi } func Test_BaseInstaller_Extract_Success(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -750,6 +757,7 @@ func Test_BaseInstaller_Extract_Success(t *testing.T) { } func Test_BaseInstaller_Extract_Error(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -824,6 +832,7 @@ func Test_BaseInstaller_replaceAllInFile(t *testing.T) { } func Test_BaseInstaller_Uninstall_Success(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -897,6 +906,7 @@ func Test_BaseInstaller_Uninstall_Success(t *testing.T) { } func Test_BaseInstaller_Uninstall_PermissionError(t *testing.T) { + testutil.Serial(t) testutil.RequireChattrSupport(t) testutil.ResetTestEnvironment(t) @@ -961,6 +971,7 @@ func Test_BaseInstaller_Uninstall_PermissionError(t *testing.T) { } func Test_BaseInstaller_Uninstall_NoDownloadFolder(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -1026,6 +1037,7 @@ func Test_BaseInstaller_Uninstall_NoDownloadFolder(t *testing.T) { } func Test_BaseInstaller_Uninstall_VersionNotFound(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -1068,6 +1080,7 @@ func Test_BaseInstaller_Uninstall_VersionNotFound(t *testing.T) { } func Test_BaseInstaller_Uninstall_MultipleBinaries(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -1166,6 +1179,7 @@ func Test_BaseInstaller_Uninstall_MultipleBinaries(t *testing.T) { } func Test_BaseInstaller_Uninstall_SymlinkPointsToOurBinary(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -1241,6 +1255,7 @@ func Test_BaseInstaller_Uninstall_SymlinkPointsToOurBinary(t *testing.T) { // Tests for RemoveConfiguration method func Test_BaseInstaller_RestoreConfiguration_Success(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -1312,6 +1327,7 @@ func Test_BaseInstaller_RestoreConfiguration_Success(t *testing.T) { } func Test_BaseInstaller_RestoreConfiguration_SymlinkPointsToOtherBinary(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -1392,6 +1408,7 @@ func Test_BaseInstaller_RestoreConfiguration_SymlinkPointsToOtherBinary(t *testi } func Test_BaseInstaller_RestoreConfiguration_MultipleBinaries(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // @@ -1483,6 +1500,7 @@ func Test_BaseInstaller_RestoreConfiguration_MultipleBinaries(t *testing.T) { } func Test_BaseInstaller_RestoreConfiguration_SymlinkError(t *testing.T) { + testutil.Serial(t) testutil.RequireChattrSupport(t) testutil.ResetTestEnvironment(t) @@ -1552,6 +1570,7 @@ func Test_BaseInstaller_RestoreConfiguration_SymlinkError(t *testing.T) { } func Test_BaseInstaller_RestoreConfiguration_VersionNotFound(t *testing.T) { + testutil.Serial(t) testutil.ResetTestEnvironment(t) // diff --git a/results.txt b/results.txt new file mode 100644 index 00000000..e69de29b