Skip to content

Commit 7fc87bf

Browse files
authored
Merge branch 'main' into matifali/devcontainer
2 parents 8c02e7e + b4751c7 commit 7fc87bf

File tree

2 files changed

+36
-37
lines changed

2 files changed

+36
-37
lines changed

agent/agent_test.go

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"go.uber.org/goleak"
3636
"golang.org/x/crypto/ssh"
3737
"golang.org/x/exp/maps"
38+
"golang.org/x/exp/slices"
3839
"golang.org/x/xerrors"
3940
"tailscale.com/net/speedtest"
4041
"tailscale.com/tailcfg"
@@ -1099,7 +1100,7 @@ func TestAgent_Lifecycle(t *testing.T) {
10991100
t.Parallel()
11001101

11011102
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
1102-
StartupScript: "sleep 5",
1103+
StartupScript: "sleep 3",
11031104
StartupScriptTimeout: time.Nanosecond,
11041105
}, 0)
11051106

@@ -1111,10 +1112,10 @@ func TestAgent_Lifecycle(t *testing.T) {
11111112
var got []codersdk.WorkspaceAgentLifecycle
11121113
assert.Eventually(t, func() bool {
11131114
got = client.getLifecycleStates()
1114-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1115+
return slices.Contains(got, want[len(want)-1])
11151116
}, testutil.WaitShort, testutil.IntervalMedium)
11161117

1117-
require.Equal(t, want, got)
1118+
require.Equal(t, want, got[:len(want)])
11181119
})
11191120

11201121
t.Run("StartError", func(t *testing.T) {
@@ -1133,10 +1134,10 @@ func TestAgent_Lifecycle(t *testing.T) {
11331134
var got []codersdk.WorkspaceAgentLifecycle
11341135
assert.Eventually(t, func() bool {
11351136
got = client.getLifecycleStates()
1136-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1137+
return slices.Contains(got, want[len(want)-1])
11371138
}, testutil.WaitShort, testutil.IntervalMedium)
11381139

1139-
require.Equal(t, want, got)
1140+
require.Equal(t, want, got[:len(want)])
11401141
})
11411142

11421143
t.Run("Ready", func(t *testing.T) {
@@ -1165,14 +1166,12 @@ func TestAgent_Lifecycle(t *testing.T) {
11651166
t.Parallel()
11661167

11671168
_, client, _, _, closer := setupAgent(t, agentsdk.Manifest{
1168-
ShutdownScript: "sleep 5",
1169+
ShutdownScript: "sleep 3",
11691170
StartupScriptTimeout: 30 * time.Second,
11701171
}, 0)
11711172

1172-
var ready []codersdk.WorkspaceAgentLifecycle
11731173
assert.Eventually(t, func() bool {
1174-
ready = client.getLifecycleStates()
1175-
return len(ready) > 0 && ready[len(ready)-1] == codersdk.WorkspaceAgentLifecycleReady
1174+
return slices.Contains(client.getLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
11761175
}, testutil.WaitShort, testutil.IntervalMedium)
11771176

11781177
// Start close asynchronously so that we an inspect the state.
@@ -1187,30 +1186,30 @@ func TestAgent_Lifecycle(t *testing.T) {
11871186
})
11881187

11891188
want := []codersdk.WorkspaceAgentLifecycle{
1189+
codersdk.WorkspaceAgentLifecycleStarting,
1190+
codersdk.WorkspaceAgentLifecycleReady,
11901191
codersdk.WorkspaceAgentLifecycleShuttingDown,
11911192
}
11921193

11931194
var got []codersdk.WorkspaceAgentLifecycle
11941195
assert.Eventually(t, func() bool {
1195-
got = client.getLifecycleStates()[len(ready):]
1196-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1196+
got = client.getLifecycleStates()
1197+
return slices.Contains(got, want[len(want)-1])
11971198
}, testutil.WaitShort, testutil.IntervalMedium)
11981199

1199-
require.Equal(t, want, got)
1200+
require.Equal(t, want, got[:len(want)])
12001201
})
12011202

12021203
t.Run("ShutdownTimeout", func(t *testing.T) {
12031204
t.Parallel()
12041205

12051206
_, client, _, _, closer := setupAgent(t, agentsdk.Manifest{
1206-
ShutdownScript: "sleep 5",
1207+
ShutdownScript: "sleep 3",
12071208
ShutdownScriptTimeout: time.Nanosecond,
12081209
}, 0)
12091210

1210-
var ready []codersdk.WorkspaceAgentLifecycle
12111211
assert.Eventually(t, func() bool {
1212-
ready = client.getLifecycleStates()
1213-
return len(ready) > 0 && ready[len(ready)-1] == codersdk.WorkspaceAgentLifecycleReady
1212+
return slices.Contains(client.getLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
12141213
}, testutil.WaitShort, testutil.IntervalMedium)
12151214

12161215
// Start close asynchronously so that we an inspect the state.
@@ -1225,17 +1224,19 @@ func TestAgent_Lifecycle(t *testing.T) {
12251224
})
12261225

12271226
want := []codersdk.WorkspaceAgentLifecycle{
1227+
codersdk.WorkspaceAgentLifecycleStarting,
1228+
codersdk.WorkspaceAgentLifecycleReady,
12281229
codersdk.WorkspaceAgentLifecycleShuttingDown,
12291230
codersdk.WorkspaceAgentLifecycleShutdownTimeout,
12301231
}
12311232

12321233
var got []codersdk.WorkspaceAgentLifecycle
12331234
assert.Eventually(t, func() bool {
1234-
got = client.getLifecycleStates()[len(ready):]
1235-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1235+
got = client.getLifecycleStates()
1236+
return slices.Contains(got, want[len(want)-1])
12361237
}, testutil.WaitShort, testutil.IntervalMedium)
12371238

1238-
require.Equal(t, want, got)
1239+
require.Equal(t, want, got[:len(want)])
12391240
})
12401241

12411242
t.Run("ShutdownError", func(t *testing.T) {
@@ -1246,10 +1247,8 @@ func TestAgent_Lifecycle(t *testing.T) {
12461247
ShutdownScriptTimeout: 30 * time.Second,
12471248
}, 0)
12481249

1249-
var ready []codersdk.WorkspaceAgentLifecycle
12501250
assert.Eventually(t, func() bool {
1251-
ready = client.getLifecycleStates()
1252-
return len(ready) > 0 && ready[len(ready)-1] == codersdk.WorkspaceAgentLifecycleReady
1251+
return slices.Contains(client.getLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
12531252
}, testutil.WaitShort, testutil.IntervalMedium)
12541253

12551254
// Start close asynchronously so that we an inspect the state.
@@ -1264,17 +1263,19 @@ func TestAgent_Lifecycle(t *testing.T) {
12641263
})
12651264

12661265
want := []codersdk.WorkspaceAgentLifecycle{
1266+
codersdk.WorkspaceAgentLifecycleStarting,
1267+
codersdk.WorkspaceAgentLifecycleReady,
12671268
codersdk.WorkspaceAgentLifecycleShuttingDown,
12681269
codersdk.WorkspaceAgentLifecycleShutdownError,
12691270
}
12701271

12711272
var got []codersdk.WorkspaceAgentLifecycle
12721273
assert.Eventually(t, func() bool {
1273-
got = client.getLifecycleStates()[len(ready):]
1274-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1274+
got = client.getLifecycleStates()
1275+
return slices.Contains(got, want[len(want)-1])
12751276
}, testutil.WaitShort, testutil.IntervalMedium)
12761277

1277-
require.Equal(t, want, got)
1278+
require.Equal(t, want, got[:len(want)])
12781279
})
12791280

12801281
t.Run("ShutdownScriptOnce", func(t *testing.T) {

cli/agent.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,12 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
106106
// Spawn a reaper so that we don't accumulate a ton
107107
// of zombie processes.
108108
if reaper.IsInitProcess() && !noReap && isLinux {
109-
logWriter := &lumberjack.Logger{
109+
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
110110
Filename: filepath.Join(logDir, "coder-agent-init.log"),
111111
MaxSize: 5, // MB
112112
// Without this, rotated logs will never be deleted.
113113
MaxBackups: 1,
114-
}
114+
}}
115115
defer logWriter.Close()
116116

117117
sinks = append(sinks, sloghuman.Sink(logWriter))
@@ -149,14 +149,12 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
149149
// reaper.
150150
go DumpHandler(ctx)
151151

152-
ljLogger := &lumberjack.Logger{
152+
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
153153
Filename: filepath.Join(logDir, "coder-agent.log"),
154154
MaxSize: 5, // MB
155155
// Without this, rotated logs will never be deleted.
156156
MaxBackups: 1,
157-
}
158-
defer ljLogger.Close()
159-
logWriter := &closeWriter{w: ljLogger}
157+
}}
160158
defer logWriter.Close()
161159

162160
sinks = append(sinks, sloghuman.Sink(logWriter))
@@ -403,24 +401,24 @@ func ServeHandler(ctx context.Context, logger slog.Logger, handler http.Handler,
403401
}
404402
}
405403

406-
// closeWriter is a wrapper around an io.WriteCloser that prevents
407-
// writes after Close. This is necessary because lumberjack will
408-
// re-open the file on write.
409-
type closeWriter struct {
404+
// lumberjackWriteCloseFixer is a wrapper around an io.WriteCloser that
405+
// prevents writes after Close. This is necessary because lumberjack
406+
// re-opens the file on Write.
407+
type lumberjackWriteCloseFixer struct {
410408
w io.WriteCloser
411409
mu sync.Mutex // Protects following.
412410
closed bool
413411
}
414412

415-
func (c *closeWriter) Close() error {
413+
func (c *lumberjackWriteCloseFixer) Close() error {
416414
c.mu.Lock()
417415
defer c.mu.Unlock()
418416

419417
c.closed = true
420418
return c.w.Close()
421419
}
422420

423-
func (c *closeWriter) Write(p []byte) (int, error) {
421+
func (c *lumberjackWriteCloseFixer) Write(p []byte) (int, error) {
424422
c.mu.Lock()
425423
defer c.mu.Unlock()
426424

0 commit comments

Comments
 (0)