1 package couchctl
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7 "net/http/httptest"
8 "net/url"
9 "strings"
10 "testing"
11 "time"
12
13 "github.com/gorilla/websocket"
14 "github.com/stretchr/testify/assert"
15 "k8s.io/client-go/util/workqueue"
16 )
17
18
19
20 func TestGetHostState(t *testing.T) {
21 server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
22 _, err := rw.Write([]byte(`{"hostname": "test-host", "network": {"lan-outage-detected": false, "lan-outage-mode": true}}`))
23 assert.NoError(t, err)
24 }))
25 defer server.Close()
26
27 t.Run("GetHostStateReturnsHostStateOnValidURL", func(t *testing.T) {
28 client := NewInterlockClient(server.URL, nil)
29 ctx := context.Background()
30
31 hostState, err := client.GetHostState(ctx)
32
33 assert.NoError(t, err)
34 assert.NotNil(t, hostState)
35 assert.Equal(t, "test-host", hostState.Hostname)
36 assert.True(t, hostState.InLOM())
37 })
38 }
39
40 func TestReconcileSource(t *testing.T) {
41 ch := make(chan *Event)
42 s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
43 upgrader := websocket.Upgrader{}
44 conn, err := upgrader.Upgrade(w, r, nil)
45 if err != nil {
46 t.Fatalf("fail to upgrade connection: %v", err)
47 }
48 defer conn.Close()
49
50 for {
51 e := <-ch
52 err = conn.WriteJSON(e)
53 if err != nil {
54 t.Fatalf("fail to write message: %v", err)
55 }
56 t.Log("message sent", e)
57 }
58 }))
59 defer s.Close()
60
61 e := &Event{
62 Topic: "host",
63 HostState: HostState{
64 Hostname: "test-host",
65 Network: HostNetwork{
66 LanOutageDetected: true,
67 LanOutageMode: true,
68 },
69 },
70 }
71 var fnCalled bool
72 cb := func(hs HostState, _ workqueue.RateLimitingInterface) {
73 t.Log("callback HostState", hs)
74 assert.Equal(t, e.HostState, hs)
75 fnCalled = true
76 }
77 u := url.URL{Scheme: "ws", Host: s.Listener.Addr().String()}
78 client := NewInterlockClient(u.String(), cb)
79
80 queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
81 ctx, cancel := context.WithCancel(context.Background())
82 defer cancel()
83
84 err := client.Start(ctx, queue)
85 assert.Nil(t, err)
86
87 ch <- e
88
89 assert.Eventually(t, func() bool { return fnCalled },
90 10*time.Second, time.Second, "callback func should have been called")
91 }
92
93 func mockInterlockClient(ctx context.Context) *httptest.Server {
94 return httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
95 if strings.HasSuffix(req.URL.String(), "/v1/subscribe") {
96 upgrader := websocket.Upgrader{}
97 conn, err := upgrader.Upgrade(res, req, nil)
98 if err != nil {
99 fmt.Println("error Upgrading connection", err)
100 }
101 defer conn.Close()
102 <-ctx.Done()
103 return
104 } else if strings.HasSuffix(req.URL.String(), "/v1/host") {
105 _, err := res.Write([]byte(`{"hostname": "test-host", "network": {"lan-outage-detected": false, "lan-outage-mode": false}}`))
106 if err != nil {
107 fmt.Println("error writing response", err)
108 }
109 return
110 }
111 res.WriteHeader(http.StatusNotFound)
112 }))
113 }
114
View as plain text