8000 test: add specific test (and fix bug) · coder/coder@220f25f · GitHub
[go: up one dir, main page]

Skip to content

Commit 220f25f

Browse files
test: add specific test (and fix bug)
1 parent 8989dbb commit 220f25f

File tree

2 files changed

+109
-2
lines changed

2 files changed

+109
-2
lines changed

agent/agentcontainers/api.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,9 +703,10 @@ func (api *API) processUpdatedContainersLocked(ctx context.Context, updated code
703703
err := api.maybeInjectSubAgentIntoContainerLocked(ctx, dc)
704704
if err != nil {
705705
logger.Error(ctx, "inject subagent into container failed", slog.Error(err))
706+
dc.Error = err.Error()
707+
} else {
708+
dc.Error = ""
706709
}
707-
708-
dc.Error = err.Error()
709710
}
710711

711712
case dc.Container == nil:

agent/agentcontainers/api_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package agentcontainers_test
33
import (
44
"context"
55
"encoding/json"
6+
"errors"
67
"fmt"
78
"math/rand"
89
"net/http"
@@ -1649,6 +1650,111 @@ func TestAPI(t *testing.T) {
16491650
assert.Empty(t, fakeSAC.agents)
16501651
})
16511652

1653+
t.Run("Error", func(t *testing.T) {
1654+
t.Parallel()
1655+
1656+
var (
1657+
ctx = testutil.Context(t, testutil.WaitMedium)
1658+
logger = slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
1659+
mClock = quartz.NewMock(t)
1660+
mCCLI = acmock.NewMockContainerCLI(gomock.NewController(t))
1661+
fDCCLI = &fakeDevcontainerCLI{}
1662+
fSAC = &fakeSubAgentClient{
1663+
logger: logger.Named("fakeSubAgentClient"),
1664+
createErrC: make(chan error, 1),
1665+
}
1666+
1667+
testContainer = codersdk.WorkspaceAgentContainer{
1668+
ID: "test-container-id",
1669+
FriendlyName: "test-container",
1670+
Image: "test-image",
1671+
Running: true,
1672+
CreatedAt: time.Now(),
1673+
Labels: map[string]string{
1674+
agentcontainers.DevcontainerLocalFolderLabel: "/workspaces",
1675+
agentcontainers.DevcontainerConfigFileLabel: "/workspace/.devcontainer/devcontainer.json",
1676+
},
1677+
}
1678+
)
1679+
1680+
coderBin, err := os.Executable()
1681+
require.NoError(t, err)
1682+
1683+
// Mock the `List` function to always return the test container.
1684+
mCCLI.EXPECT().List(gomock.Any()).Return(codersdk.WorkspaceAgentListContainersResponse{
1685+
Containers: []codersdk.WorkspaceAgentContainer{testContainer},
1686+
}, nil).AnyTimes()
1687+
1688+
// We're going to force the container CLI to fail, which will allow us to test the
1689+
// error handling.
1690+
var simulatedError = errors.New("simulated error")
1691+
mCCLI.EXPECT().DetectArchitecture(gomock.Any(), testContainer.ID).Return("", simulatedError).Times(1)
1692+
1693+
mClock.Set(time.Now()).MustWait(ctx)
1694+
tickerTrap := mClock.Trap().TickerFunc("updaterLoop")
1695+
1696+
api := agentcontainers.NewAPI(logger,
1697+
agentcontainers.WithClock(mClock),
1698+
agentcontainers.WithContainerCLI(mCCLI),
1699+
agentcontainers.WithDevcontainerCLI(fDCCLI),
1700+
agentcontainers.WithSubAgentClient(fSAC),
1701+
agentcontainers.WithSubAgentURL("test-subagent-url"),
1702+
agentcontainers.WithWatcher(watcher.NewNoop()),
1703+
)
1704+
api.Start()
1705+
defer func() {
1706+
close(fSAC.createErrC)
1707+
api.Close()
1708+
}()
1709+
1710+
r := chi.NewRouter()
1711+
r.Mount("/", api.Routes())
1712+
1713+
// Given: We allow an attempt at creation to occur.
1714+
tickerTrap.MustWait(ctx).MustRelease(ctx)
1715+
tickerTrap.Close()
1716+
1717+
req := httptest.NewRequest(http.MethodGet, "/", nil)
1718+
rec := httptest.NewRecorder()
1719+
r.ServeHTTP(rec, req)
1720+
require.Equal(t, http.StatusOK, rec.Code)
1721+
1722+
var response codersdk.WorkspaceAgentListContainersResponse
1723+
err = json.NewDecoder(rec.Body).Decode(&response)
1724+
require.NoError(t, err)
1725+
1726+
// Then: We expect that there will be an error associated with the devcontainer.
1727+
require.Len(t, response.Devcontainers, 1)
1728+
require.Equal(t, "detect architecture: simulated error", response.Devcontainers[0].Error)
1729+
1730+
gomock.InOrder(
1731+
mCCLI.EXPECT().DetectArchitecture(gomock.Any(), testContainer.ID).Return(runtime.GOARCH, nil),
1732+
mCCLI.EXPECT().ExecAs(gomock.Any(), testContainer.ID, "root", "mkdir", "-p", "/.coder-agent").Return(nil, nil),
1733+
mCCLI.EXPECT().Copy(gomock.Any(), testContainer.ID, coderBin, "/.coder-agent/coder").Return(nil),
1734+
mCCLI.EXPECT().ExecAs(gomock.Any(), testContainer.ID, "root", "chmod", "0755", "/.coder-agent", "/.coder-agent/coder").Return(nil, nil),
1735+
mCCLI.EXPECT().ExecAs(gomock.Any(), testContainer.ID, "root", "/bin/sh", "-c", "chown $(id -u):$(id -g) /.coder-agent/coder").Return(nil, nil),
1736+
)
1737+
1738+
// Given: We allow creation to succeed.
1739+
testutil.RequireSend(ctx, t, fSAC.createErrC, nil)
1740+
1741+
_, aw := mClock.AdvanceNext()
1742+
aw.MustWait(ctx)
1743+
1744+
req = httptest.NewRequest(http.MethodGet, "/", nil)
1745+
rec = httptest.NewRecorder()
1746+
r.ServeHTTP(rec, req)
1747+
require.Equal(t, http.StatusOK, rec.Code)
1748+
1749+
response = codersdk.WorkspaceAgentListContainersResponse{}
1750+
err = json.NewDecoder(rec.Body).Decode(&response)
1751+
require.NoError(t, err)
1752+
1753+
// Then: We expect that the error will be gone
1754+
require.Len(t, response.Devcontainers, 1)
1755+
require.Equal(t, "", response.Devcontainers[0].Error)
1756+
})
1757+
16521758
t.Run("Create", func(t *testing.T) {
16531759
t.Parallel()
16541760

0 commit comments

Comments
 (0)
0