Skip to content

Commit f1705ca

Browse files
Fix flaky tests (#2178)
Signed-off-by: NastyaAR <[email protected]> Co-authored-by: Eleftheria Stein-Kousathana <[email protected]>
1 parent 9f46bff commit f1705ca

File tree

1 file changed

+40
-25
lines changed

1 file changed

+40
-25
lines changed

pkg/client/config_test.go

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
package client
44

55
import (
6-
"bytes"
76
"context"
8-
"io"
97
"os"
108
"path/filepath"
119
"strings"
1210
"testing"
1311

12+
"github.com/spf13/viper"
1413
"github.com/stretchr/testify/assert"
1514
"github.com/stretchr/testify/require"
15+
"go.uber.org/zap"
16+
"go.uber.org/zap/zaptest/observer"
1617

1718
"github.com/stacklok/toolhive/pkg/config"
1819
"github.com/stacklok/toolhive/pkg/logger"
@@ -186,27 +187,14 @@ func CreateTestConfigProvider(t *testing.T, cfg *config.Config) (config.Provider
186187
}
187188
}
188189

189-
func TestFindClientConfigs(t *testing.T) {
190-
t.Parallel()
191-
logger.Initialize()
192-
190+
//nolint:paralleltest // This test modifies global logger
191+
func TestFindClientConfigs(t *testing.T) { // Can't run in parallel because it uses global logger
193192
// Setup a temporary home directory for testing
194193
tempHome := t.TempDir()
195194

196195
t.Run("InvalidConfigFileFormat", func(t *testing.T) {
197-
t.Parallel() // Now we can use parallel since we don't modify global state
198-
// Set up environment for unstructured logs and capture stderr before initializing logger
199-
originalUnstructuredLogs := os.Getenv("UNSTRUCTURED_LOGS")
200-
os.Setenv("UNSTRUCTURED_LOGS", "true")
201-
defer os.Setenv("UNSTRUCTURED_LOGS", originalUnstructuredLogs)
202-
203-
// Capture log output to verify error logging
204-
originalStderr := os.Stderr
205-
r, w, _ := os.Pipe()
206-
os.Stderr = w
207-
208-
// Re-initialize logger to use the captured stderr
209-
logger.Initialize()
196+
// Initialize in-memory test logger
197+
observerLogs := initializeTest(t)
210198

211199
// Create an invalid JSON file
212200
invalidPath := filepath.Join(tempHome, ".cursor", "invalid.json")
@@ -266,13 +254,13 @@ func TestFindClientConfigs(t *testing.T) {
266254
// We expect 1 config (VSCode) since cursor with invalid JSON should be skipped
267255
assert.Len(t, configs, 1, "Should find configs for valid clients only, skipping invalid ones")
268256

269-
// Restore stderr and capture log output
270-
w.Close()
271-
os.Stderr = originalStderr
257+
// Read all log entries
258+
var sb strings.Builder
259+
for _, entry := range observerLogs.All() {
260+
sb.WriteString(entry.Message)
261+
}
272262

273-
var capturedOutput bytes.Buffer
274-
io.Copy(&capturedOutput, r)
275-
logOutput := capturedOutput.String()
263+
logOutput := sb.String()
276264

277265
// Verify that the error was logged
278266
assert.Contains(t, logOutput, "Unable to process client config for cursor", "Should log warning about cursor client config")
@@ -281,6 +269,33 @@ func TestFindClientConfigs(t *testing.T) {
281269
})
282270
}
283271

272+
func initializeTest(t *testing.T) *observer.ObservedLogs {
273+
t.Helper()
274+
275+
// Set log level based on current debug flag
276+
var level zap.AtomicLevel
277+
if viper.GetBool("debug") {
278+
level = zap.NewAtomicLevelAt(zap.DebugLevel)
279+
} else {
280+
level = zap.NewAtomicLevelAt(zap.InfoLevel)
281+
}
282+
283+
core, observedLogs := observer.New(level)
284+
testLogger := zap.New(core)
285+
286+
// Save original logger for restoring
287+
originalLogger := zap.L()
288+
289+
zap.ReplaceGlobals(testLogger)
290+
291+
// Restore original logger
292+
t.Cleanup(func() {
293+
zap.ReplaceGlobals(originalLogger)
294+
})
295+
296+
return observedLogs
297+
}
298+
284299
func TestSuccessfulClientConfigOperations(t *testing.T) {
285300
t.Parallel()
286301
logger.Initialize()

0 commit comments

Comments
 (0)