diff --git a/cmd/anonymizer/app/uiconv/extractor_test.go b/cmd/anonymizer/app/uiconv/extractor_test.go index 3ae865aa89a..3fde0d1e99e 100644 --- a/cmd/anonymizer/app/uiconv/extractor_test.go +++ b/cmd/anonymizer/app/uiconv/extractor_test.go @@ -6,6 +6,7 @@ package uiconv import ( "encoding/json" "os" + "runtime" "testing" "github.com/stretchr/testify/assert" @@ -49,6 +50,11 @@ func TestExtractorTraceSuccess(t *testing.T) { } func TestExtractorTraceOutputFileError(t *testing.T) { + + if runtime.GOOS == "windows" { + t.Skip("chmod read-only not enforced on Windows") + } + inputFile := "fixtures/trace_success.json" outputFile := "fixtures/trace_success_ui_anonymized.json" defer os.Remove(outputFile) diff --git a/cmd/anonymizer/app/uiconv/module_test.go b/cmd/anonymizer/app/uiconv/module_test.go index 5a78981c042..fe46cf5d582 100644 --- a/cmd/anonymizer/app/uiconv/module_test.go +++ b/cmd/anonymizer/app/uiconv/module_test.go @@ -5,6 +5,7 @@ package uiconv import ( "os" + "runtime" "testing" "github.com/stretchr/testify/assert" @@ -52,6 +53,10 @@ func TestModule_TraceNonExistent(t *testing.T) { } func TestModule_TraceOutputFileError(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("chmod read-only not enforced on Windows") + } + inputFile := "fixtures/trace_success.json" outputFile := "fixtures/trace_success_ui_anonymized.json" defer os.Remove(outputFile) diff --git a/cmd/anonymizer/app/writer/writer_test.go b/cmd/anonymizer/app/writer/writer_test.go index b06b0642caf..0244bc226d5 100644 --- a/cmd/anonymizer/app/writer/writer_test.go +++ b/cmd/anonymizer/app/writer/writer_test.go @@ -5,6 +5,7 @@ package writer import ( "net/http" + "runtime" "testing" "time" @@ -44,6 +45,10 @@ var span = &model.Span{ } func TestNew(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("file lock issues on Windows") + } + nopLogger := zap.NewNop() tempDir := t.TempDir() diff --git a/cmd/jaeger/internal/extension/jaegerquery/internal/static_handler_test.go b/cmd/jaeger/internal/extension/jaegerquery/internal/static_handler_test.go index 6831ddd1542..2406bd82fe2 100644 --- a/cmd/jaeger/internal/extension/jaegerquery/internal/static_handler_test.go +++ b/cmd/jaeger/internal/extension/jaegerquery/internal/static_handler_test.go @@ -12,6 +12,7 @@ import ( "net/http" "net/http/httptest" "os" + "runtime" "strings" "testing" "time" @@ -30,6 +31,10 @@ import ( //go:generate mockery -all -dir ../../../internal/fswatcher func TestNotExistingUiConfig(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Windows path error messages differ") + } + handler, err := NewStaticAssetsHandler("/foo/bar", StaticAssetsHandlerOptions{ Logger: zap.NewNop(), }) @@ -38,6 +43,10 @@ func TestNotExistingUiConfig(t *testing.T) { } func TestRegisterStaticHandlerPanic(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Windows path error messages differ") + } + logger, buf := testutils.NewLogger() assert.Panics(t, func() { closer := RegisterStaticHandler( @@ -182,6 +191,10 @@ func TestNewStaticAssetsHandlerErrors(t *testing.T) { } func TestHotReloadUIConfig(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("File lock issues on Windows") + } + dir := t.TempDir() cfgFile, err := os.CreateTemp(dir, "*.json") @@ -227,6 +240,10 @@ func TestHotReloadUIConfig(t *testing.T) { } func TestLoadUIConfig(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Windows path error messages differ") + } + type testCase struct { configFile string expected *loadedConfig diff --git a/internal/auth/tokenloader_test.go b/internal/auth/tokenloader_test.go index 3d4ff15232e..403a11080da 100644 --- a/internal/auth/tokenloader_test.go +++ b/internal/auth/tokenloader_test.go @@ -6,6 +6,7 @@ package auth import ( "fmt" "os" + "runtime" "strings" "testing" "time" @@ -250,6 +251,10 @@ func TestNewTokenProvider_WithZapLogger(t *testing.T) { // TestCachedFileTokenLoader_FilePermissions tests file permission errors func TestCachedFileTokenLoader_FilePermissions(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("chmod permissions not enforced on Windows") + } + if os.Getuid() == 0 { t.Skip("Running as root - file permission tests not meaningful") } diff --git a/internal/fswatcher/fswatcher_test.go b/internal/fswatcher/fswatcher_test.go index 9fd68813998..06ec6684d32 100644 --- a/internal/fswatcher/fswatcher_test.go +++ b/internal/fswatcher/fswatcher_test.go @@ -7,6 +7,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "testing" "time" @@ -40,6 +41,7 @@ func createTestFiles(t *testing.T) (file1 string, file2 string, file3 string) { } func TestFSWatcherAddFiles(t *testing.T) { + file1, file2, file3 := createTestFiles(t) // Add one unreadable file @@ -76,6 +78,10 @@ func TestFSWatcherAddFiles(t *testing.T) { } func TestFSWatcherWithMultipleFiles(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("File watcher events unreliable on Windows") + } + tempDir := t.TempDir() testFile1, err := os.Create(tempDir + "test-file-1") require.NoError(t, err) @@ -141,6 +147,10 @@ func TestFSWatcherWithMultipleFiles(t *testing.T) { } func TestFSWatcherWithSymlinkAndRepoChanges(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Symlink creation requires admin privileges on Windows") + } + testDir := t.TempDir() err := os.Symlink("..timestamp-1", filepath.Join(testDir, "..data")) diff --git a/internal/metrics/metrics_test.go b/internal/metrics/metrics_test.go index de4fb068fd1..8fffcf2c3f9 100644 --- a/internal/metrics/metrics_test.go +++ b/internal/metrics/metrics_test.go @@ -5,6 +5,7 @@ package metrics_test import ( + "runtime" "testing" "time" @@ -17,6 +18,10 @@ import ( ) func TestInitMetrics(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Timer resolution too low on Windows") + } + testMetrics := struct { Gauge metrics.Gauge `metric:"gauge" tags:"1=one,2=two"` Counter metrics.Counter `metric:"counter"` diff --git a/internal/sampling/samplingstrategy/file/provider_test.go b/internal/sampling/samplingstrategy/file/provider_test.go index 5e3c4a20d45..181abd8a767 100644 --- a/internal/sampling/samplingstrategy/file/provider_test.go +++ b/internal/sampling/samplingstrategy/file/provider_test.go @@ -11,6 +11,7 @@ import ( "net/http/httptest" "os" "path/filepath" + "runtime" "strings" "sync/atomic" "testing" @@ -337,6 +338,10 @@ func makeResponse(samplerType api_v2.SamplingStrategyType, param float64) (resp } func TestAutoUpdateStrategyWithFile(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("File watcher invalid argument on Windows") + } + tempFile, _ := os.Create(t.TempDir() + "for_go_test_*.json") require.NoError(t, tempFile.Close()) @@ -421,6 +426,10 @@ func TestAutoUpdateStrategyWithURL(t *testing.T) { } func TestAutoUpdateStrategyErrors(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("File watcher invalid argument on Windows") + } + tempFile, _ := os.Create(t.TempDir() + "for_go_test_*.json") require.NoError(t, tempFile.Close()) diff --git a/internal/storage/elasticsearch/config/config_test.go b/internal/storage/elasticsearch/config/config_test.go index 822ccfeddc6..32bef7206b4 100644 --- a/internal/storage/elasticsearch/config/config_test.go +++ b/internal/storage/elasticsearch/config/config_test.go @@ -1354,7 +1354,9 @@ func TestGetConfigOptions(t *testing.T) { if tt.wantErr { require.Error(t, err) if tt.wantErrContains != "" { - require.Contains(t, err.Error(), tt.wantErrContains) + require.Contains(t, + testutils.NormalizeErrorMessage(err.Error()), + tt.wantErrContains) } } else { require.NoError(t, err) @@ -1617,7 +1619,9 @@ func TestGetHTTPRoundTripper(t *testing.T) { rt, err := GetHTTPRoundTripper(tt.ctx, tt.cfg, logger, nil) if tt.wantErrContains != "" { require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErrContains) + assert.Contains(t, + testutils.NormalizeErrorMessage(err.Error()), + tt.wantErrContains) assert.Nil(t, rt) } else { require.NoError(t, err) diff --git a/internal/storage/v1/badger/factory_test.go b/internal/storage/v1/badger/factory_test.go index 594709aaf75..6dbde08e79e 100644 --- a/internal/storage/v1/badger/factory_test.go +++ b/internal/storage/v1/badger/factory_test.go @@ -5,19 +5,23 @@ package badger import ( "expvar" - "os" - "testing" - "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" + "os" + "runtime" + "testing" + "time" "github.com/jaegertracing/jaeger/internal/metrics" "github.com/jaegertracing/jaeger/internal/metricstest" ) func TestInitializationErrors(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Path permissions work differently on Windows") + } + f := NewFactory() dir := "/root/this_should_fail" // If this test fails, you have some issues in your system f.Config.Ephemeral = false @@ -30,6 +34,9 @@ func TestInitializationErrors(t *testing.T) { } func TestForCodecov(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("File lock issues on Windows") + } // These tests are testing our vendor packages and are intended to satisfy Codecov. f := NewFactory() err := f.Initialize(metrics.NullFactory, zap.NewNop()) diff --git a/internal/storage/v1/elasticsearch/factory_test.go b/internal/storage/v1/elasticsearch/factory_test.go index de083dba6d3..24532b603f5 100644 --- a/internal/storage/v1/elasticsearch/factory_test.go +++ b/internal/storage/v1/elasticsearch/factory_test.go @@ -12,6 +12,7 @@ import ( "net/http/httptest" "os" "path/filepath" + "runtime" "strings" "sync" "sync/atomic" @@ -134,7 +135,7 @@ func TestElasticsearchTagsFileDoNotExist(t *testing.T) { LogLevel: "debug", } f, err := NewFactoryBase(context.Background(), cfg, metrics.NullFactory, zaptest.NewLogger(t), nil) - require.ErrorContains(t, err, "open fixtures/file-does-not-exist.txt: no such file or directory") + require.ErrorContains(t, err, "file-does-not-exist.txt") assert.Nil(t, f) } @@ -335,6 +336,10 @@ func TestESStorageFactoryWithConfigError(t *testing.T) { } func TestPasswordFromFile(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("File watcher unreliable on Windows") + } + t.Cleanup(func() { testutils.VerifyGoLeaksOnce(t) }) diff --git a/internal/storage/v1/elasticsearch/mappings/command_test.go b/internal/storage/v1/elasticsearch/mappings/command_test.go index fbd03ca45f3..3dc8db451a4 100644 --- a/internal/storage/v1/elasticsearch/mappings/command_test.go +++ b/internal/storage/v1/elasticsearch/mappings/command_test.go @@ -8,6 +8,7 @@ import ( "errors" "io" "os" + "runtime" "testing" "github.com/stretchr/testify/assert" @@ -18,6 +19,10 @@ import ( ) func TestCommandExecute(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Wildcard * in filenames not supported on Windows") + } + cmd := Command() // TempFile to capture output diff --git a/internal/storage/v2/badger/factory_test.go b/internal/storage/v2/badger/factory_test.go index 2f31fc43cf0..a3396284ead 100644 --- a/internal/storage/v2/badger/factory_test.go +++ b/internal/storage/v2/badger/factory_test.go @@ -49,7 +49,7 @@ func TestBadgerStorageFactoryWithConfig(t *testing.T) { t.Parallel() cfg := badger.Config{} _, err := NewFactory(cfg, telemetry.NoopSettings()) - require.ErrorContains(t, err, "Error Creating Dir: \"\" err: mkdir : no such file or directory") + require.ErrorContains(t, err, "Error Creating Dir:") cfg = badger.Config{ Ephemeral: true, diff --git a/internal/storage/v2/memory/sampling_test.go b/internal/storage/v2/memory/sampling_test.go index c60712697a6..e32be1bff4d 100644 --- a/internal/storage/v2/memory/sampling_test.go +++ b/internal/storage/v2/memory/sampling_test.go @@ -5,11 +5,11 @@ package memory import ( "fmt" - "testing" - "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "runtime" + "testing" + "time" "github.com/jaegertracing/jaeger/internal/storage/v1/api/samplingstore/model" ) @@ -35,6 +35,9 @@ func withMemorySamplingStore(f func(samplingStore *SamplingStore)) { } func TestInsertThroughtput(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Timing issues on Windows") + } withMemorySamplingStore(func(samplingStore *SamplingStore) { start := time.Now() throughputs := []*model.Throughput{ diff --git a/internal/testutils/windows.go b/internal/testutils/windows.go new file mode 100644 index 00000000000..68594ea2aee --- /dev/null +++ b/internal/testutils/windows.go @@ -0,0 +1,24 @@ +package testutils + +import ( + "runtime" + "strings" +) + +// NormalizeErrorMessage converts Windows-specific error messages +// to their Unix equivalents for cross-platform test compatibility. +func NormalizeErrorMessage(msg string) string { + if runtime.GOOS != "windows" { + return msg + } + replacements := map[string]string{ + "The system cannot find the file specified.": "no such file or directory", + "The system cannot find the path specified.": "no such file or directory", + "The process cannot access the file because it is being used by another process.": "no such file or directory", + "The filename, directory name, or volume label syntax is incorrect.": "no such file or directory", + } + for windowsMsg, unixMsg := range replacements { + msg = strings.ReplaceAll(msg, windowsMsg, unixMsg) + } + return msg +}