1package cli
2
3import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "net/http"
8 "net/http/httptest"
9 "testing"
10
11 "github.com/stretchr/testify/assert"
12 "github.com/stretchr/testify/require"
13
14 "github.com/bnema/gordon/internal/adapters/dto"
15 "github.com/bnema/gordon/internal/adapters/in/cli/mocks"
16 "github.com/bnema/gordon/internal/adapters/in/cli/remote"
17 "github.com/bnema/gordon/internal/domain"
18)
19
20func TestTrafficCommandExists(t *testing.T) {
21 cmd := NewRootCmd()
22 traffic, _, err := cmd.Find([]string{"daemon", "traffic"})
23 require.NoError(t, err)
24 require.NotNil(t, traffic)
25 assert.Equal(t, "traffic", traffic.Name())
26}
27
28func TestTrafficStatusRejectsArgs(t *testing.T) {
29 cmd := newTrafficCmd()
30 require.Error(t, cmd.Args(cmd, []string{"extra"}))
31}
32
33func TestTrafficStatusHumanOutput(t *testing.T) {
34 status := &dto.TrafficStatusResponse{
35 LastReloadStatus: "ok",
36 EntryPoints: []dto.TrafficEntryPointStatus{{
37 Name: "postgres", Address: "127.0.0.1:5432", Protocol: domain.EntryPointProtocolTCP,
38 Active: true, ActiveTCPConnections: 1, TotalAccepted: 2, BytesIn: 10, BytesOut: 20,
39 SmartTCP: dto.SmartTCPCounters{HTTPAccepted: 1, PROXYRefused: 1},
40 }},
41 Routers: []dto.TrafficRouterStatus{{
42 Name: "pg-router", EntryPoint: "postgres", Protocol: domain.RouterProtocolTCP,
43 Service: "network_service:postgres:db", Active: true,
44 }},
45 Services: []dto.TrafficServiceStatus{{
46 Name: "network_service:postgres:db", Active: true,
47 Backends: []dto.TrafficBackendStatus{{Name: "postgres:db", Host: "127.0.0.1", Port: 5432, Protocol: domain.NetworkProtocolTCP, Active: true}},
48 }},
49 Counters: dto.TrafficCounters{ActiveTCPConnections: 1, TotalAccepted: 2, BytesIn: 10, BytesOut: 20, SmartTCP: dto.SmartTCPCounters{HTTPAccepted: 1, PROXYRefused: 1}},
50 }
51 var buf bytes.Buffer
52 require.NoError(t, renderTrafficStatus(&buf, status, false))
53 output := buf.String()
54 assert.Contains(t, output, "Traffic Status")
55 assert.Contains(t, output, "postgres")
56 assert.Contains(t, output, "127.0.0.1:5432")
57 assert.Contains(t, output, "pg-router")
58 assert.Contains(t, output, "network_service:postgres:db")
59 assert.Contains(t, output, "tcp://127.0.0.1:5432")
60 assert.Contains(t, output, "accepted=2")
61 assert.Contains(t, output, "smart_tcp")
62 assert.Contains(t, output, "http_accepted=1")
63 assert.Contains(t, output, "proxy_refused=1")
64}
65
66func TestTrafficStatusJSONOutput(t *testing.T) {
67 status := &dto.TrafficStatusResponse{LastReloadStatus: "ok", Counters: dto.TrafficCounters{ActiveUDPSessions: 3, SmartTCP: dto.SmartTCPCounters{SniffTimeout: 1}}}
68 var buf bytes.Buffer
69 require.NoError(t, renderTrafficStatus(&buf, status, true))
70 var got dto.TrafficStatusResponse
71 require.NoError(t, json.Unmarshal(buf.Bytes(), &got))
72 assert.Equal(t, "ok", got.LastReloadStatus)
73 assert.Equal(t, int64(3), got.Counters.ActiveUDPSessions)
74 assert.Equal(t, int64(1), got.Counters.SmartTCP.SniffTimeout)
75}
76
77func TestRunTrafficStatusUsesControlPlane(t *testing.T) {
78 status := &dto.TrafficStatusResponse{LastReloadStatus: "ok"}
79 cp := mocks.NewMockControlPlane(t)
80 cp.EXPECT().GetTrafficStatus(context.Background()).Return(status, nil).Once()
81
82 var buf bytes.Buffer
83 require.NoError(t, runTrafficStatus(context.Background(), cp, &buf, true))
84
85 assert.Contains(t, buf.String(), `"last_reload_status": "ok"`)
86}
87
88func TestRemoteTrafficStatusControlPlaneStillRenders(t *testing.T) {
89 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
90 require.Equal(t, "/admin/traffic/status", r.URL.Path)
91 require.Equal(t, http.MethodGet, r.Method)
92 _, err := w.Write([]byte(`{"last_reload_status":"ok","counters":{"active_udp_sessions":3}}`))
93 require.NoError(t, err)
94 }))
95 defer srv.Close()
96
97 cp := remote.NewClient(srv.URL)
98 var buf bytes.Buffer
99 require.NoError(t, runTrafficStatus(context.Background(), cp, &buf, false))
100
101 output := buf.String()
102 assert.Contains(t, output, "Traffic Status")
103 assert.Contains(t, output, "Reload")
104 assert.Contains(t, output, "ok")
105 assert.Contains(t, output, "udp=3")
106}