1package commands
2
3import (
4	"testing"
5
6	"github.com/digitalocean/doctl"
7	"github.com/digitalocean/doctl/do"
8	"github.com/digitalocean/godo"
9
10	"github.com/stretchr/testify/assert"
11)
12
13var (
14	testLoadBalancer = do.LoadBalancer{
15		LoadBalancer: &godo.LoadBalancer{
16			Algorithm: "round_robin",
17			Region: &godo.Region{
18				Slug: "nyc1",
19			},
20			SizeSlug:       "lb-small",
21			StickySessions: &godo.StickySessions{},
22			HealthCheck:    &godo.HealthCheck{},
23		}}
24
25	testLoadBalancerList = do.LoadBalancers{
26		testLoadBalancer,
27	}
28)
29
30func TestLoadBalancerCommand(t *testing.T) {
31	cmd := LoadBalancer()
32	assert.NotNil(t, cmd)
33	assertCommandNames(t, cmd, "get", "list", "create", "update", "delete", "add-droplets", "remove-droplets", "add-forwarding-rules", "remove-forwarding-rules")
34}
35
36func TestLoadBalancerGet(t *testing.T) {
37	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
38		lbID := "cde2c0d6-41e3-479e-ba60-ad971227232c"
39		tm.loadBalancers.EXPECT().Get(lbID).Return(&testLoadBalancer, nil)
40
41		config.Args = append(config.Args, lbID)
42
43		err := RunLoadBalancerGet(config)
44		assert.NoError(t, err)
45	})
46}
47
48func TestLoadBalancerGetNoID(t *testing.T) {
49	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
50		err := RunLoadBalancerGet(config)
51		assert.Error(t, err)
52	})
53}
54
55func TestLoadBalancerList(t *testing.T) {
56	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
57		tm.loadBalancers.EXPECT().List().Return(testLoadBalancerList, nil)
58
59		err := RunLoadBalancerList(config)
60		assert.NoError(t, err)
61	})
62}
63
64func TestLoadBalancerCreateWithInvalidDropletIDsArgs(t *testing.T) {
65	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
66		config.Doit.Set(config.NS, doctl.ArgDropletIDs, []string{"bogus"})
67
68		err := RunLoadBalancerCreate(config)
69		assert.Error(t, err)
70	})
71}
72
73func TestLoadBalancerCreateWithMalformedForwardingRulesArgs(t *testing.T) {
74	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
75		config.Doit.Set(config.NS, doctl.ArgForwardingRules, "something,something")
76
77		err := RunLoadBalancerCreate(config)
78		assert.Error(t, err)
79	})
80}
81
82func TestLoadBalancerCreate(t *testing.T) {
83	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
84		vpcUUID := "00000000-0000-4000-8000-000000000000"
85		r := godo.LoadBalancerRequest{
86			Name:       "lb-name",
87			Region:     "nyc1",
88			SizeSlug:   "lb-small",
89			DropletIDs: []int{1, 2},
90			StickySessions: &godo.StickySessions{
91				Type: "none",
92			},
93			HealthCheck: &godo.HealthCheck{
94				Protocol:               "http",
95				Port:                   80,
96				CheckIntervalSeconds:   4,
97				ResponseTimeoutSeconds: 23,
98				HealthyThreshold:       5,
99				UnhealthyThreshold:     10,
100			},
101			ForwardingRules: []godo.ForwardingRule{
102				{
103					EntryProtocol:  "tcp",
104					EntryPort:      3306,
105					TargetProtocol: "tcp",
106					TargetPort:     3306,
107					TlsPassthrough: true,
108				},
109			},
110			VPCUUID: vpcUUID,
111		}
112		disableLetsEncryptDNSRecords := true
113		r.DisableLetsEncryptDNSRecords = &disableLetsEncryptDNSRecords
114		tm.loadBalancers.EXPECT().Create(&r).Return(&testLoadBalancer, nil)
115
116		config.Doit.Set(config.NS, doctl.ArgRegionSlug, "nyc1")
117		config.Doit.Set(config.NS, doctl.ArgSizeSlug, "lb-small")
118		config.Doit.Set(config.NS, doctl.ArgLoadBalancerName, "lb-name")
119		config.Doit.Set(config.NS, doctl.ArgVPCUUID, vpcUUID)
120		config.Doit.Set(config.NS, doctl.ArgDropletIDs, []string{"1", "2"})
121		config.Doit.Set(config.NS, doctl.ArgStickySessions, "type:none")
122		config.Doit.Set(config.NS, doctl.ArgHealthCheck, "protocol:http,port:80,check_interval_seconds:4,response_timeout_seconds:23,healthy_threshold:5,unhealthy_threshold:10")
123		config.Doit.Set(config.NS, doctl.ArgForwardingRules, "entry_protocol:tcp,entry_port:3306,target_protocol:tcp,target_port:3306,tls_passthrough:true")
124		config.Doit.Set(config.NS, doctl.ArgDisableLetsEncryptDNSRecords, true)
125
126		err := RunLoadBalancerCreate(config)
127		assert.NoError(t, err)
128	})
129}
130
131func TestLoadBalancerUpdate(t *testing.T) {
132	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
133		lbID := "cde2c0d6-41e3-479e-ba60-ad971227232c"
134		r := godo.LoadBalancerRequest{
135			Name:       "lb-name",
136			Region:     "nyc1",
137			DropletIDs: []int{1, 2},
138			SizeUnit:   4,
139			StickySessions: &godo.StickySessions{
140				Type:             "cookies",
141				CookieName:       "DO-LB",
142				CookieTtlSeconds: 5,
143			},
144			HealthCheck: &godo.HealthCheck{
145				Protocol:               "http",
146				Port:                   80,
147				CheckIntervalSeconds:   4,
148				ResponseTimeoutSeconds: 23,
149				HealthyThreshold:       5,
150				UnhealthyThreshold:     10,
151			},
152			ForwardingRules: []godo.ForwardingRule{
153				{
154					EntryProtocol:  "http",
155					EntryPort:      80,
156					TargetProtocol: "http",
157					TargetPort:     80,
158				},
159			},
160		}
161		disableLetsEncryptDNSRecords := true
162		r.DisableLetsEncryptDNSRecords = &disableLetsEncryptDNSRecords
163		tm.loadBalancers.EXPECT().Update(lbID, &r).Return(&testLoadBalancer, nil)
164
165		config.Args = append(config.Args, lbID)
166		config.Doit.Set(config.NS, doctl.ArgRegionSlug, "nyc1")
167		config.Doit.Set(config.NS, doctl.ArgSizeSlug, "")
168		config.Doit.Set(config.NS, doctl.ArgSizeUnit, 4)
169		config.Doit.Set(config.NS, doctl.ArgLoadBalancerName, "lb-name")
170		config.Doit.Set(config.NS, doctl.ArgDropletIDs, []string{"1", "2"})
171		config.Doit.Set(config.NS, doctl.ArgStickySessions, "type:cookies,cookie_name:DO-LB,cookie_ttl_seconds:5")
172		config.Doit.Set(config.NS, doctl.ArgHealthCheck, "protocol:http,port:80,check_interval_seconds:4,response_timeout_seconds:23,healthy_threshold:5,unhealthy_threshold:10")
173		config.Doit.Set(config.NS, doctl.ArgForwardingRules, "entry_protocol:http,entry_port:80,target_protocol:http,target_port:80")
174		config.Doit.Set(config.NS, doctl.ArgDisableLetsEncryptDNSRecords, true)
175
176		err := RunLoadBalancerUpdate(config)
177		assert.NoError(t, err)
178	})
179}
180
181func TestLoadBalancerUpdateNoID(t *testing.T) {
182	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
183		err := RunLoadBalancerUpdate(config)
184		assert.Error(t, err)
185	})
186}
187
188func TestLoadBalancerDelete(t *testing.T) {
189	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
190		lbID := "cde2c0d6-41e3-479e-ba60-ad971227232c"
191		tm.loadBalancers.EXPECT().Delete(lbID).Return(nil)
192
193		config.Args = append(config.Args, lbID)
194		config.Doit.Set(config.NS, doctl.ArgForce, true)
195
196		err := RunLoadBalancerDelete(config)
197		assert.NoError(t, err)
198	})
199}
200
201func TestLoadBalancerDeleteNoID(t *testing.T) {
202	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
203		err := RunLoadBalancerDelete(config)
204		assert.Error(t, err)
205	})
206}
207
208func TestLoadBalancerAddDroplets(t *testing.T) {
209	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
210		lbID := "cde2c0d6-41e3-479e-ba60-ad971227232c"
211		tm.loadBalancers.EXPECT().AddDroplets(lbID, 1, 23).Return(nil)
212
213		config.Args = append(config.Args, lbID)
214		config.Doit.Set(config.NS, doctl.ArgDropletIDs, []string{"1", "23"})
215
216		err := RunLoadBalancerAddDroplets(config)
217		assert.NoError(t, err)
218	})
219}
220
221func TestLoadBalancerAddDropletsNoID(t *testing.T) {
222	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
223		err := RunLoadBalancerAddDroplets(config)
224		assert.Error(t, err)
225	})
226}
227
228func TestLoadBalancerRemoveDroplets(t *testing.T) {
229	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
230		lbID := "cde2c0d6-41e3-479e-ba60-ad971227232c"
231		tm.loadBalancers.EXPECT().RemoveDroplets(lbID, 321).Return(nil)
232
233		config.Args = append(config.Args, lbID)
234		config.Doit.Set(config.NS, doctl.ArgDropletIDs, []string{"321"})
235
236		err := RunLoadBalancerRemoveDroplets(config)
237		assert.NoError(t, err)
238	})
239}
240
241func TestLoadBalancerRemoveDropletsNoID(t *testing.T) {
242	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
243		err := RunLoadBalancerRemoveDroplets(config)
244		assert.Error(t, err)
245	})
246}
247
248func TestLoadBalancerAddForwardingRules(t *testing.T) {
249	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
250		lbID := "cde2c0d6-41e3-479e-ba60-ad971227232c"
251		forwardingRule := godo.ForwardingRule{
252			EntryProtocol:  "http",
253			EntryPort:      80,
254			TargetProtocol: "http",
255			TargetPort:     80,
256		}
257		tm.loadBalancers.EXPECT().AddForwardingRules(lbID, forwardingRule).Return(nil)
258
259		config.Args = append(config.Args, lbID)
260		config.Doit.Set(config.NS, doctl.ArgForwardingRules, "entry_protocol:http,entry_port:80,target_protocol:http,target_port:80")
261
262		err := RunLoadBalancerAddForwardingRules(config)
263		assert.NoError(t, err)
264	})
265}
266
267func TestLoadBalancerAddForwardingRulesNoID(t *testing.T) {
268	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
269		err := RunLoadBalancerAddForwardingRules(config)
270		assert.Error(t, err)
271	})
272}
273
274func TestLoadBalancerRemoveForwardingRules(t *testing.T) {
275	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
276		lbID := "cde2c0d6-41e3-479e-ba60-ad971227232c"
277		forwardingRules := []godo.ForwardingRule{
278			{
279				EntryProtocol:  "http",
280				EntryPort:      80,
281				TargetProtocol: "http",
282				TargetPort:     80,
283			},
284			{
285				EntryProtocol:  "tcp",
286				EntryPort:      3306,
287				TargetProtocol: "tcp",
288				TargetPort:     3306,
289				TlsPassthrough: true,
290			},
291		}
292		tm.loadBalancers.EXPECT().RemoveForwardingRules(lbID, forwardingRules[0], forwardingRules[1]).Return(nil)
293
294		config.Args = append(config.Args, lbID)
295		config.Doit.Set(config.NS, doctl.ArgForwardingRules, "entry_protocol:http,entry_port:80,target_protocol:http,target_port:80 entry_protocol:tcp,entry_port:3306,target_protocol:tcp,target_port:3306,tls_passthrough:true")
296
297		err := RunLoadBalancerRemoveForwardingRules(config)
298		assert.NoError(t, err)
299	})
300}
301
302func TestLoadBalancerRemoveForwardingRulesNoID(t *testing.T) {
303	withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
304		err := RunLoadBalancerRemoveForwardingRules(config)
305		assert.Error(t, err)
306	})
307}
308