Skip to content

Commit b495991

Browse files
committed
Refactor provisionerd tests to disconnect from coderd
1 parent c440af4 commit b495991

25 files changed

+866
-342
lines changed

coderd/coderd.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func New(options *Options) http.Handler {
2525
Database: options.Database,
2626
Pubsub: options.Pubsub,
2727
}
28-
provisionerd := &provisionerd{
28+
provisioners := &provisioners{
2929
Database: options.Database,
3030
Pubsub: options.Pubsub,
3131
}
@@ -46,7 +46,8 @@ func New(options *Options) http.Handler {
4646
})
4747
r.Post("/login", users.loginWithPassword)
4848
r.Post("/logout", users.logout)
49-
r.Get("/provisionerd", provisionerd.listen)
49+
r.Get("/provisionerd", provisioners.listen)
50+
5051
// Used for setup.
5152
r.Post("/user", users.createInitialUser)
5253
r.Route("/users", func(r chi.Router) {
@@ -109,6 +110,10 @@ func New(options *Options) http.Handler {
109110
})
110111
})
111112
})
113+
114+
r.Route("/provisioners", func(r chi.Router) {
115+
r.Get("/daemons", provisioners.listDaemons)
116+
})
112117
})
113118
r.NotFound(site.Handler().ServeHTTP)
114119
return r

coderd/coderdtest/coderdtest.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,27 @@ package coderdtest
33
import (
44
"context"
55
"database/sql"
6+
"io"
67
"net/http/httptest"
78
"net/url"
89
"os"
910
"testing"
11+
"time"
1012

1113
"github.com/stretchr/testify/require"
1214

15+
"cdr.dev/slog"
1316
"cdr.dev/slog/sloggers/slogtest"
1417
"github.com/coder/coder/coderd"
1518
"github.com/coder/coder/codersdk"
1619
"github.com/coder/coder/cryptorand"
1720
"github.com/coder/coder/database"
1821
"github.com/coder/coder/database/databasefake"
1922
"github.com/coder/coder/database/postgres"
23+
"github.com/coder/coder/provisioner/terraform"
24+
"github.com/coder/coder/provisionerd"
25+
"github.com/coder/coder/provisionersdk"
26+
"github.com/coder/coder/provisionersdk/proto"
2027
)
2128

2229
// Server represents a test instance of coderd.
@@ -57,6 +64,37 @@ func (s *Server) RandomInitialUser(t *testing.T) coderd.CreateInitialUserRequest
5764
return req
5865
}
5966

67+
func (s *Server) AddProvisionerd(t *testing.T) io.Closer {
68+
tfClient, tfServer := provisionersdk.TransportPipe()
69+
ctx, cancelFunc := context.WithCancel(context.Background())
70+
t.Cleanup(func() {
71+
_ = tfClient.Close()
72+
_ = tfServer.Close()
73+
cancelFunc()
74+
})
75+
go func() {
76+
err := terraform.Serve(ctx, &terraform.ServeOptions{
77+
ServeOptions: &provisionersdk.ServeOptions{
78+
Listener: tfServer,
79+
},
80+
})
81+
require.NoError(t, err)
82+
}()
83+
84+
closer := provisionerd.New(s.Client.ProvisionerDaemonClient, &provisionerd.Options{
85+
Logger: slogtest.Make(t, nil).Named("provisionerd").Leveled(slog.LevelInfo),
86+
PollInterval: 50 * time.Millisecond,
87+
Provisioners: provisionerd.Provisioners{
88+
string(database.ProvisionerTypeTerraform): proto.NewDRPCProvisionerClient(provisionersdk.Conn(tfClient)),
89+
},
90+
WorkDirectory: t.TempDir(),
91+
})
92+
t.Cleanup(func() {
93+
_ = closer.Close()
94+
})
95+
return closer
96+
}
97+
6098
// New constructs a new coderd test instance. This returned Server
6199
// should contain no side-effects.
62100
func New(t *testing.T) Server {

coderd/coderdtest/coderdtest_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ func TestNew(t *testing.T) {
1616
t.Parallel()
1717
server := coderdtest.New(t)
1818
_ = server.RandomInitialUser(t)
19+
_ = server.AddProvisionerd(t)
1920
}

coderd/provisionerd_test.go

Lines changed: 0 additions & 21 deletions
This file was deleted.

coderd/provisionerd.go renamed to coderd/provisioners.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"storj.io/drpc/drpcmux"
1515
"storj.io/drpc/drpcserver"
1616

17+
"github.com/go-chi/render"
1718
"github.com/google/uuid"
1819
"github.com/hashicorp/yamux"
1920
"github.com/moby/moby/pkg/namesgenerator"
@@ -27,12 +28,30 @@ import (
2728
"nhooyr.io/websocket"
2829
)
2930

30-
type provisionerd struct {
31+
type ProvisionerDaemon database.ProvisionerDaemon
32+
33+
type provisioners struct {
3134
Database database.Store
3235
Pubsub database.Pubsub
3336
}
3437

35-
func (p *provisionerd) listen(rw http.ResponseWriter, r *http.Request) {
38+
func (p *provisioners) listDaemons(rw http.ResponseWriter, r *http.Request) {
39+
daemons, err := p.Database.GetProvisionerDaemons(r.Context())
40+
if errors.Is(err, sql.ErrNoRows) {
41+
err = nil
42+
}
43+
if err != nil {
44+
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
45+
Message: fmt.Sprintf("get provisioner daemons: %s", err),
46+
})
47+
return
48+
}
49+
50+
render.Status(r, http.StatusOK)
51+
render.JSON(rw, r, daemons)
52+
}
53+
54+
func (p *provisioners) listen(rw http.ResponseWriter, r *http.Request) {
3655
conn, err := websocket.Accept(rw, r, nil)
3756
if err != nil {
3857
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{

coderd/provisioners_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package coderd_test
2+
3+
import (
4+
"archive/tar"
5+
"bytes"
6+
"context"
7+
"fmt"
8+
"testing"
9+
"time"
10+
11+
"github.com/stretchr/testify/require"
12+
13+
"github.com/coder/coder/coderd"
14+
"github.com/coder/coder/coderd/coderdtest"
15+
"github.com/coder/coder/database"
16+
)
17+
18+
func TestProvisionerd(t *testing.T) {
19+
t.Parallel()
20+
t.Run("ListDaemons", func(t *testing.T) {
21+
t.Parallel()
22+
server := coderdtest.New(t)
23+
_ = server.AddProvisionerd(t)
24+
require.Eventually(t, func() bool {
25+
daemons, err := server.Client.ProvisionerDaemons(context.Background())
26+
require.NoError(t, err)
27+
return len(daemons) > 0
28+
}, time.Second, 10*time.Millisecond)
29+
})
30+
31+
t.Run("RunJob", func(t *testing.T) {
32+
t.Parallel()
33+
server := coderdtest.New(t)
34+
user := server.RandomInitialUser(t)
35+
_ = server.AddProvisionerd(t)
36+
37+
project, err := server.Client.CreateProject(context.Background(), user.Organization, coderd.CreateProjectRequest{
38+
Name: "my-project",
39+
Provisioner: database.ProvisionerTypeTerraform,
40+
})
41+
require.NoError(t, err)
42+
43+
var buffer bytes.Buffer
44+
writer := tar.NewWriter(&buffer)
45+
content := `variable "frog" {}
46+
resource "null_resource" "dev" {}`
47+
err = writer.WriteHeader(&tar.Header{
48+
Name: "main.tf",
49+
Size: int64(len(content)),
50+
})
51+
require.NoError(t, err)
52+
_, err = writer.Write([]byte(content))
53+
require.NoError(t, err)
54+
55+
projectHistory, err := server.Client.CreateProjectHistory(context.Background(), user.Organization, project.Name, coderd.CreateProjectVersionRequest{
56+
StorageMethod: database.ProjectStorageMethodInlineArchive,
57+
StorageSource: buffer.Bytes(),
58+
})
59+
require.NoError(t, err)
60+
61+
workspace, err := server.Client.CreateWorkspace(context.Background(), "", coderd.CreateWorkspaceRequest{
62+
ProjectID: project.ID,
63+
Name: "wowie",
64+
})
65+
require.NoError(t, err)
66+
67+
workspaceHistory, err := server.Client.CreateWorkspaceHistory(context.Background(), "", workspace.Name, coderd.CreateWorkspaceHistoryRequest{
68+
ProjectHistoryID: projectHistory.ID,
69+
Transition: database.WorkspaceTransitionCreate,
70+
})
71+
require.NoError(t, err)
72+
73+
logs, err := server.Client.FollowWorkspaceHistoryLogs(context.Background(), "me", workspace.Name, workspaceHistory.Name)
74+
require.NoError(t, err)
75+
76+
for {
77+
log := <-logs
78+
fmt.Printf("Got %s %s\n", log.CreatedAt, log.Output)
79+
}
80+
})
81+
}

codersdk/provisionerd.go

Lines changed: 0 additions & 71 deletions
This file was deleted.

codersdk/provisioners.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package codersdk
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"net/http"
7+
8+
"golang.org/x/xerrors"
9+
"nhooyr.io/websocket"
10+
11+
"github.com/hashicorp/yamux"
12+
13+
"github.com/coder/coder/coderd"
14+
"github.com/coder/coder/provisionerd/proto"
15+
"github.com/coder/coder/provisionersdk"
16+
)
17+
18+
func (c *Client) ProvisionerDaemons(ctx context.Context) ([]coderd.ProvisionerDaemon, error) {
19+
res, err := c.request(ctx, http.MethodGet, "/api/v2/provisioners/daemons", nil)
20+
if err != nil {
21+
return nil, err
22+
}
23+
defer res.Body.Close()
24+
if res.StatusCode != http.StatusOK {
25+
return nil, readBodyAsError(res)
26+
}
27+
var daemons []coderd.ProvisionerDaemon
28+
return daemons, json.NewDecoder(res.Body).Decode(&daemons)
29+
}
30+
31+
// ProvisionerDaemonClient returns the gRPC service for a provisioner daemon implementation.
32+
func (c *Client) ProvisionerDaemonClient(ctx context.Context) (proto.DRPCProvisionerDaemonClient, error) {
33+
serverURL, err := c.url.Parse("/api/v2/provisionerd")
34+
if err != nil {
35+
return nil, xerrors.Errorf("parse url: %w", err)
36+
}
37+
conn, res, err := websocket.Dial(ctx, serverURL.String(), &websocket.DialOptions{
38+
HTTPClient: c.httpClient,
39+
})
40+
if err != nil {
41+
if res == nil {
42+
return nil, err
43+
}
44+
return nil, readBodyAsError(res)
45+
}
46+
session, err := yamux.Client(websocket.NetConn(context.Background(), conn, websocket.MessageBinary), nil)
47+
if err != nil {
48+
return nil, xerrors.Errorf("multiplex client: %w", err)
49+
}
50+
return proto.NewDRPCProvisionerDaemonClient(provisionersdk.Conn(session)), nil
51+
}

codersdk/provisioners_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package codersdk_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/coder/coder/coderd/coderdtest"
10+
)
11+
12+
func TestProvisioners(t *testing.T) {
13+
t.Parallel()
14+
t.Run("ListDaemons", func(t *testing.T) {
15+
t.Parallel()
16+
server := coderdtest.New(t)
17+
_, err := server.Client.ProvisionerDaemons(context.Background())
18+
require.NoError(t, err)
19+
})
20+
}

0 commit comments

Comments
 (0)