Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit db78770

Browse files
authored
test: Fix flaky TestServer/Logging/{Multiple,Stackdriver} (#5727)
* test: Fix flaky TestServer/Logging/Multiple * test: Fix flaky TestServer/Logging/Stackdriver * test: Add testutil.TempFile and testutil.CreateTemp, cleanup tests relying on temp file
1 parent 6ebadab commit db78770

File tree

2 files changed

+107
-63
lines changed

2 files changed

+107
-63
lines changed

cli/server_test.go

Lines changed: 60 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"github.com/coder/coder/coderd/database/postgres"
3636
"github.com/coder/coder/coderd/telemetry"
3737
"github.com/coder/coder/codersdk"
38-
"github.com/coder/coder/cryptorand"
3938
"github.com/coder/coder/pty/ptytest"
4039
"github.com/coder/coder/testutil"
4140
)
@@ -1132,12 +1131,7 @@ func TestServer(t *testing.T) {
11321131
ctx, cancelFunc := context.WithCancel(context.Background())
11331132
defer cancelFunc()
11341133

1135-
random, err := cryptorand.String(5)
1136-
require.NoError(t, err)
1137-
fiName := fmt.Sprint(os.TempDir(), "/coder-logging-test-", random)
1138-
defer func() {
1139-
_ = os.Remove(fiName)
1140-
}()
1134+
fiName := testutil.TempFile(t, "", "coder-logging-test-*")
11411135

11421136
root, _ := clitest.New(t,
11431137
"server",
@@ -1165,27 +1159,23 @@ func TestServer(t *testing.T) {
11651159
ctx, cancelFunc := context.WithCancel(context.Background())
11661160
defer cancelFunc()
11671161

1168-
fi, err := os.CreateTemp("", "coder-logging-test-*")
1169-
require.NoError(t, err)
1170-
defer func() {
1171-
_ = os.Remove(fi.Name())
1172-
}()
1162+
fi := testutil.TempFile(t, "", "coder-logging-test-*")
11731163

11741164
root, _ := clitest.New(t,
11751165
"server",
11761166
"--verbose",
11771167
"--in-memory",
11781168
"--http-address", ":0",
11791169
"--access-url", "http://example.com",
1180-
"--log-human", fi.Name(),
1170+
"--log-human", fi,
11811171
)
11821172
serverErr := make(chan error, 1)
11831173
go func() {
11841174
serverErr <- root.ExecuteContext(ctx)
11851175
}()
11861176

11871177
assert.Eventually(t, func() bool {
1188-
stat, err := os.Stat(fi.Name())
1178+
stat, err := os.Stat(fi)
11891179
return err == nil && stat.Size() > 0
11901180
}, testutil.WaitShort, testutil.IntervalFast)
11911181
cancelFunc()
@@ -1197,27 +1187,23 @@ func TestServer(t *testing.T) {
11971187
ctx, cancelFunc := context.WithCancel(context.Background())
11981188
defer cancelFunc()
11991189

1200-
fi, err := os.CreateTemp("", "coder-logging-test-*")
1201-
require.NoError(t, err)
1202-
defer func() {
1203-
_ = os.Remove(fi.Name())
1204-
}()
1190+
fi := testutil.TempFile(t, "", "coder-logging-test-*")
12051191

12061192
root, _ := clitest.New(t,
12071193
"server",
12081194
"--verbose",
12091195
"--in-memory",
12101196
"--http-address", ":0",
12111197
"--access-url", "http://example.com",
1212-
"--log-json", fi.Name(),
1198+
"--log-json", fi,
12131199
)
12141200
serverErr := make(chan error, 1)
12151201
go func() {
12161202
serverErr <- root.ExecuteContext(ctx)
12171203
}()
12181204

12191205
assert.Eventually(t, func() bool {
1220-
stat, err := os.Stat(fi.Name())
1206+
stat, err := os.Stat(fi)
12211207
return err == nil && stat.Size() > 0
12221208
}, testutil.WaitShort, testutil.IntervalFast)
12231209
cancelFunc()
@@ -1229,86 +1215,97 @@ func TestServer(t *testing.T) {
12291215
ctx, cancelFunc := context.WithCancel(context.Background())
12301216
defer cancelFunc()
12311217

1232-
fi, err := os.CreateTemp("", "coder-logging-test-*")
1233-
require.NoError(t, err)
1234-
defer func() {
1235-
_ = os.Remove(fi.Name())
1236-
}()
1218+
fi := testutil.TempFile(t, "", "coder-logging-test-*")
12371219

12381220
root, _ := clitest.New(t,
12391221
"server",
12401222
"--verbose",
12411223
"--in-memory",
12421224
"--http-address", ":0",
12431225
"--access-url", "http://example.com",
1244-
"--log-stackdriver", fi.Name(),
1226+
"--log-stackdriver", fi,
12451227
)
1228+
// Attach pty so we get debug output from the command if this test
1229+
// fails.
1230+
pty := ptytest.New(t)
1231+
root.SetOut(pty.Output())
1232+
root.SetErr(pty.Output())
1233+
12461234
serverErr := make(chan error, 1)
12471235
go func() {
12481236
serverErr <- root.ExecuteContext(ctx)
12491237
}()
1238+
defer func() {
1239+
cancelFunc()
1240+
<-serverErr
1241+
}()
12501242

1251-
assert.Eventually(t, func() bool {
1252-
stat, err := os.Stat(fi.Name())
1243+
require.Eventually(t, func() bool {
1244+
line := pty.ReadLine()
1245+
return strings.HasPrefix(line, "Started HTTP listener at ")
1246+
}, testutil.WaitLong*2, testutil.IntervalMedium, "wait for server to listen on http")
1247+
1248+
require.Eventually(t, func() bool {
1249+
stat, err := os.Stat(fi)
12531250
return err == nil && stat.Size() > 0
12541251
}, testutil.WaitLong, testutil.IntervalMedium)
1255-
cancelFunc()
1256-
<-serverErr
12571252
})
12581253

12591254
t.Run("Multiple", func(t *testing.T) {
12601255
t.Parallel()
12611256
ctx, cancelFunc := context.WithCancel(context.Background())
12621257
defer cancelFunc()
12631258

1264-
fi1, err := os.CreateTemp("", "coder-logging-test-*")
1265-
require.NoError(t, err)
1266-
defer func() {
1267-
_ = os.Remove(fi1.Name())
1268-
}()
1269-
1270-
fi2, err := os.CreateTemp("", "coder-logging-test-*")
1271-
require.NoError(t, err)
1272-
defer func() {
1273-
_ = os.Remove(fi2.Name())
1274-
}()
1275-
1276-
fi3, err := os.CreateTemp("", "coder-logging-test-*")
1277-
require.NoError(t, err)
1278-
defer func() {
1279-
_ = os.Remove(fi3.Name())
1280-
}()
1259+
fi1 := testutil.TempFile(t, "", "coder-logging-test-*")
1260+
fi2 := testutil.TempFile(t, "", "coder-logging-test-*")
1261+
fi3 := testutil.TempFile(t, "", "coder-logging-test-*")
12811262

1263+
// NOTE(mafredri): This test might end up downloading Terraform
1264+
// which can take a long time and end up failing the test.
1265+
// This is why we wait extra long below for server to listen on
1266+
// HTTP.
12821267
root, _ := clitest.New(t,
12831268
"server",
12841269
"--verbose",
12851270
"--in-memory",
12861271
"--http-address", ":0",
12871272
"--access-url", "http://example.com",
1288-
"--log-human", fi1.Name(),
1289-
"--log-json", fi2.Name(),
1290-
"--log-stackdriver", fi3.Name(),
1273+
"--log-human", fi1,
1274+
"--log-json", fi2,
1275+
"--log-stackdriver", fi3,
12911276
)
1277+
// Attach pty so we get debug output from the command if this test
1278+
// fails.
1279+
pty := ptytest.New(t)
1280+
root.SetOut(pty.Output())
1281+
root.SetErr(pty.Output())
1282+
12921283
serverErr := make(chan error, 1)
12931284
go func() {
12941285
serverErr <- root.ExecuteContext(ctx)
12951286
}()
1287+
defer func() {
1288+
cancelFunc()
1289+
<-serverErr
1290+
}()
12961291

1297-
assert.Eventually(t, func() bool {
1298-
stat, err := os.Stat(fi1.Name())
1292+
require.Eventually(t, func() bool {
1293+
line := pty.ReadLine()
1294+
return strings.HasPrefix(line, "Started HTTP listener at ")
1295+
}, testutil.WaitLong*2, testutil.IntervalMedium, "wait for server to listen on http")
1296+
1297+
require.Eventually(t, func() bool {
1298+
stat, err := os.Stat(fi1)
12991299
return err == nil && stat.Size() > 0
1300-
}, testutil.WaitLong, testutil.IntervalMedium)
1301-
assert.Eventually(t, func() bool {
1302-
stat, err := os.Stat(fi2.Name())
1300+
}, testutil.WaitShort, testutil.IntervalMedium, "log human size > 0")
1301+
require.Eventually(t, func() bool {
1302+
stat, err := os.Stat(fi2)
13031303
return err == nil && stat.Size() > 0
1304-
}, testutil.WaitLong, testutil.IntervalMedium)
1305-
assert.Eventually(t, func() bool {
1306-
stat, err := os.Stat(fi3.Name())
1304+
}, testutil.WaitShort, testutil.IntervalMedium, "log json size > 0")
1305+
require.Eventually(t, func() bool {
1306+
stat, err := os.Stat(fi3)
13071307
return err == nil && stat.Size() > 0
1308-
}, testutil.WaitLong, testutil.IntervalMedium)
1309-
1310-
cancelFunc()
1311-
<-serverErr
1308+
}, testutil.WaitShort, testutil.IntervalMedium, "log stackdriver size > 0")
13121309
})
13131310
})
13141311
}

testutil/temp.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package testutil
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
// TempFile returns the name of a temporary file that does not exist.
11+
func TempFile(t *testing.T, dir, pattern string) string {
12+
t.Helper()
13+
14+
if dir == "" {
15+
dir = t.TempDir()
16+
}
17+
f, err := os.CreateTemp(dir, pattern)
18+
require.NoError(t, err, "create temp file")
19+
name := f.Name()
20+
err = f.Close()
21+
require.NoError(t, err, "close temp file")
22+
err = os.Remove(name)
23+
require.NoError(t, err, "remove temp file")
24+
25+
return name
26+
}
27+
28+
// CreateTemp is a convenience function for creating a temporary file, like
29+
// os.CreateTemp, but it also registers a cleanup function to close and remove
30+
// the file.
31+
func CreateTemp(t *testing.T, dir, pattern string) *os.File {
32+
t.Helper()
33+
34+
if dir == "" {
35+
dir = t.TempDir()
36+
}
37+
f, err := os.CreateTemp(dir, pattern)
38+
require.NoError(t, err, "create temp file")
39+
t.Cleanup(func() {
40+
_ = f.Close()
41+
err = os.Remove(f.Name())
42+
if err != nil {
43+
t.Logf("CreateTemp: Cleanup: remove failed for %q: %v", f.Name(), err)
44+
}
45+
})
46+
return f
47+
}

0 commit comments

Comments
 (0)