package couchctl import ( "context" "fmt" "net/http" "net/http/httptest" "net/url" "strings" "testing" "time" "github.com/gorilla/websocket" "github.com/stretchr/testify/assert" "k8s.io/client-go/util/workqueue" ) // write interlock client tests here func TestGetHostState(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) { _, err := rw.Write([]byte(`{"hostname": "test-host", "network": {"lan-outage-detected": false, "lan-outage-mode": true}}`)) assert.NoError(t, err) })) defer server.Close() t.Run("GetHostStateReturnsHostStateOnValidURL", func(t *testing.T) { client := NewInterlockClient(server.URL, nil) // callback func not needed for this test ctx := context.Background() hostState, err := client.GetHostState(ctx) assert.NoError(t, err) assert.NotNil(t, hostState) assert.Equal(t, "test-host", hostState.Hostname) assert.True(t, hostState.InLOM()) }) } func TestReconcileSource(t *testing.T) { ch := make(chan *Event) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { upgrader := websocket.Upgrader{} conn, err := upgrader.Upgrade(w, r, nil) if err != nil { t.Fatalf("fail to upgrade connection: %v", err) } defer conn.Close() for { e := <-ch err = conn.WriteJSON(e) if err != nil { t.Fatalf("fail to write message: %v", err) } t.Log("message sent", e) } })) defer s.Close() e := &Event{ Topic: "host", HostState: HostState{ Hostname: "test-host", Network: HostNetwork{ LanOutageDetected: true, LanOutageMode: true, }, }, } var fnCalled bool cb := func(hs HostState, _ workqueue.RateLimitingInterface) { t.Log("callback HostState", hs) assert.Equal(t, e.HostState, hs) fnCalled = true } u := url.URL{Scheme: "ws", Host: s.Listener.Addr().String()} client := NewInterlockClient(u.String(), cb) queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() err := client.Start(ctx, queue) assert.Nil(t, err) ch <- e // websocket send message assert.Eventually(t, func() bool { return fnCalled }, 10*time.Second, time.Second, "callback func should have been called") } func mockInterlockClient(ctx context.Context) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { if strings.HasSuffix(req.URL.String(), "/v1/subscribe") { upgrader := websocket.Upgrader{} conn, err := upgrader.Upgrade(res, req, nil) if err != nil { fmt.Println("error Upgrading connection", err) } defer conn.Close() <-ctx.Done() return } else if strings.HasSuffix(req.URL.String(), "/v1/host") { _, err := res.Write([]byte(`{"hostname": "test-host", "network": {"lan-outage-detected": false, "lan-outage-mode": false}}`)) if err != nil { fmt.Println("error writing response", err) } return } res.WriteHeader(http.StatusNotFound) })) }