Skip to content

Commit 4771842

Browse files
committed
chore: more tests
Signed-off-by: Lucas Fontes <[email protected]>
1 parent ced2501 commit 4771842

File tree

9 files changed

+296
-304
lines changed

9 files changed

+296
-304
lines changed

wasmbus/control/api.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"time"
99
)
1010

11+
// Lattice Control
12+
// https://wasmcloud.com/docs/reference/nats#control-interface
1113
type APIv1 interface {
1214
ProviderAuction(ctx context.Context, req *ProviderAuctionRequest) (*ProviderAuctionResponse, error)
1315
ComponentAuction(ctx context.Context, req *ComponentAuctionRequest) (*ComponentAuctionResponse, error)
@@ -37,14 +39,18 @@ type APIv1 interface {
3739
HostPing(ctx context.Context, req *HostPingRequest) (*HostPingResponse, error)
3840
}
3941

42+
// Response is a generic response type for the control interface.
43+
// All API Responses have the same structure.
4044
type Response[T any] struct {
4145
Success bool `json:"success"`
4246
Message string `json:"message"`
4347
Response T `json:"response"`
4448
}
4549

4650
type ProviderAuctionRequest struct {
47-
Constraints map[string]string `json:"constraints,omitempty"`
51+
// Constraints are key-value pairs that are used to filter hosts.
52+
// Required even if empty (unfortunately).
53+
Constraints map[string]string `json:"constraints"`
4854
ProviderId string `json:"provider_id,omitempty"`
4955
ProviderRef string `json:"provider_ref,omitempty"`
5056
}
@@ -59,7 +65,9 @@ type ProviderAuctionResponsePayload struct {
5965
type ProviderAuctionResponse = Response[ProviderAuctionResponsePayload]
6066

6167
type ComponentAuctionRequest struct {
62-
Constraints map[string]string `json:"constraints,omitempty"`
68+
// Constraints are key-value pairs that are used to filter hosts.
69+
// Required even if empty (unfortunately).
70+
Constraints map[string]string `json:"constraints"`
6371
ComponentId string `json:"component_id,omitempty"`
6472
ComponentRef string `json:"component_ref,omitempty"`
6573
}
@@ -89,8 +97,9 @@ type ScaleComponentResponsePayload struct {
8997
type ScaleComponentResponse = Response[ScaleComponentResponsePayload]
9098

9199
type UpdateComponentRequest struct {
100+
HostId string `json:"-"`
101+
92102
ComponentId string `json:"component_id"`
93-
HostId string `json:"host_id"`
94103
NewComponentRef string `json:"new_component_ref"`
95104
Annotations map[string]string `json:"annotations,omitempty"`
96105
}
@@ -271,7 +280,10 @@ type HostInventoryResponsePayload struct {
271280

272281
type HostInventoryResponse = Response[HostInventoryResponsePayload]
273282

283+
// HostPingRequest is a special case where the request is not sent to a specific host.
284+
// This is because the request is a scatter/gather pattern where the response is composed client side.
274285
type HostPingRequest struct {
286+
// Wait is the duration to wait before returning the response.
275287
Wait time.Duration `json:"-"`
276288
}
277289

@@ -287,7 +299,7 @@ type HostPingResponsePayload struct {
287299
UptimeHuman string `json:"uptime_human"`
288300
}
289301

290-
// NOTE(lxf): Needed cause this is a scatter/gather api.
302+
// NOTE(lxf): Needed cause this is a scatter/gather api and the response is composed client side.
291303
type HostPingSingleResponse = Response[HostPingResponsePayload]
292304

293305
type HostPingResponse = Response[[]HostPingResponsePayload]

wasmbus/control/client.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ type Client struct {
1313
lattice string
1414
}
1515

16-
//var _ APIv1 = (*Client)(nil)
16+
var _ APIv1 = (*Client)(nil)
1717

18+
// NewClient creates a new control client for a given lattice
1819
func NewClient(bus wasmbus.Bus, lattice string) *Client {
1920
return &Client{
2021
Bus: bus,

wasmbus/control/client_test.go

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,114 @@ package control
33
import (
44
"context"
55
"testing"
6+
"time"
67

7-
"github.com/nats-io/nats.go"
88
"go.wasmcloud.dev/wasmbus"
9+
"go.wasmcloud.dev/wasmbus/wasmbustest"
910
)
1011

1112
func TestClient(t *testing.T) {
12-
nc, err := nats.Connect(nats.DefaultURL)
13+
nc, teardown := wasmbustest.WithWash(t)
14+
defer teardown(t)
15+
16+
bus := wasmbus.NewNatsBus(nc)
17+
c := NewClient(bus, "default")
18+
19+
t.Run("component", wrapTest(testComponent, c))
20+
t.Run("provider", wrapTest(testProvider, c))
21+
22+
}
23+
24+
func wrapTest(f func(*testing.T, *Client), c *Client) func(*testing.T) {
25+
return func(t *testing.T) {
26+
f(t, c)
27+
}
28+
}
29+
30+
func testProvider(t *testing.T, c *Client) {
31+
req := &ProviderAuctionRequest{
32+
ProviderId: "test-provider",
33+
ProviderRef: wasmbustest.ValidProvider,
34+
Constraints: make(map[string]string),
35+
}
36+
37+
resp, err := c.ProviderAuction(context.TODO(), req)
1338
if err != nil {
14-
t.Fatal(err)
39+
t.Fatalf("failed to auction: %v", err)
1540
}
1641

17-
bus := wasmbus.NewNatsBus(nc)
18-
client := NewClient(bus, "default")
19-
t.Log("Client created")
42+
if !resp.Success {
43+
t.Fatalf("auction failed: %v", resp)
44+
}
45+
46+
if resp.Response.HostId == "" {
47+
t.Fatalf("host id is empty")
48+
}
49+
50+
reqStart := &ProviderStartRequest{
51+
HostId: resp.Response.HostId,
52+
ProviderId: req.ProviderId,
53+
ProviderRef: req.ProviderRef,
54+
}
2055

21-
resp, err := client.ConfigGet(context.Background(), &ConfigGetRequest{
22-
Name: "test",
23-
})
56+
startResp, err := c.ProviderStart(context.TODO(), reqStart)
2457
if err != nil {
25-
t.Fatal(err)
58+
t.Fatalf("failed to start: %v", err)
59+
}
60+
61+
if !startResp.Success {
62+
t.Fatalf("start failed: %v", startResp)
63+
}
64+
}
65+
66+
func testComponent(t *testing.T, c *Client) {
67+
// we first need an auction to find the host id
68+
69+
auctionReq := &ComponentAuctionRequest{
70+
ComponentId: "test-component",
71+
ComponentRef: wasmbustest.ValidComponent,
72+
Constraints: make(map[string]string),
73+
}
74+
75+
auctionResp, err := c.ComponentAuction(context.TODO(), auctionReq)
76+
if err != nil {
77+
t.Fatalf("failed to auction: %v", err)
78+
}
79+
80+
scaleReq := &ScaleComponentRequest{
81+
HostId: auctionResp.Response.HostId,
82+
ComponentId: auctionReq.ComponentId,
83+
ComponentRef: auctionReq.ComponentRef,
84+
Count: 1,
85+
}
86+
87+
scaleResp, err := c.ScaleComponent(context.TODO(), scaleReq)
88+
if err != nil {
89+
t.Fatalf("failed to scale: %v", err)
90+
}
91+
92+
if !scaleResp.Success {
93+
t.Fatalf("scale failed: %v", scaleResp)
94+
}
95+
96+
// NOTE(lxf): it takes time for the component to be ready
97+
// and the only way to know is to watch for lattice events.
98+
// For now, we'll just sleep for a bit.
99+
<-time.After(1 * time.Second)
100+
101+
updateReq := &UpdateComponentRequest{
102+
HostId: auctionResp.Response.HostId,
103+
ComponentId: auctionReq.ComponentId,
104+
NewComponentRef: auctionReq.ComponentRef,
105+
Annotations: map[string]string{"test": "test"},
106+
}
107+
108+
updateResp, err := c.UpdateComponent(context.TODO(), updateReq)
109+
if err != nil {
110+
t.Fatalf("failed to update: %v", err)
111+
}
112+
113+
if !updateResp.Success {
114+
t.Fatalf("update failed: %v", updateResp)
26115
}
27-
t.Log(resp)
28116
}

wasmbus/control/server.go

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

0 commit comments

Comments
 (0)