From 2ab9ce3019abe3fba47dd34ba802985f900698ee Mon Sep 17 00:00:00 2001 From: pauhull Date: Wed, 13 Dec 2023 10:44:24 +0100 Subject: [PATCH] test: add more unit tests (#616) --- internal/cmd/firewall/add_rule_test.go | 56 +++++++++ .../cmd/firewall/apply_to_resource_test.go | 93 +++++++++++++++ internal/cmd/firewall/delete_rule_test.go | 55 +++++++++ .../cmd/firewall/remove_from_resource_test.go | 93 +++++++++++++++ internal/cmd/firewall/replace_rules_test.go | 79 +++++++++++++ internal/cmd/firewall/testdata/rules.json | 23 ++++ internal/cmd/floatingip/assign_test.go | 44 +++++++ .../cmd/floatingip/disable_protection_test.go | 43 +++++++ .../cmd/floatingip/enable_protection_test.go | 43 +++++++ internal/cmd/floatingip/set_rdns_test.go | 47 ++++++++ internal/cmd/floatingip/unassign_test.go | 41 +++++++ internal/cmd/image/disable_protection_test.go | 40 +++++++ internal/cmd/image/enable_protection_test.go | 40 +++++++ internal/cmd/loadbalancer/add_service_test.go | 50 ++++++++ internal/cmd/loadbalancer/add_target_test.go | 111 ++++++++++++++++++ .../loadbalancer/attach_to_network_test.go | 46 ++++++++ .../cmd/loadbalancer/change_algorithm_test.go | 43 +++++++ internal/cmd/loadbalancer/change_type_test.go | 48 ++++++++ .../cmd/loadbalancer/delete_service_test.go | 38 ++++++ .../loadbalancer/detach_from_network_test.go | 46 ++++++++ .../loadbalancer/disable_protection_test.go | 43 +++++++ .../disable_public_interface_test.go | 41 +++++++ .../loadbalancer/enable_protection_test.go | 43 +++++++ .../enable_public_interface_test.go | 41 +++++++ internal/cmd/loadbalancer/metrics_test.go | 103 ++++++++++++++++ .../cmd/loadbalancer/remove_target_test.go | 103 ++++++++++++++++ internal/cmd/loadbalancer/set_rdns_test.go | 51 ++++++++ .../cmd/loadbalancer/update_service_test.go | 88 ++++++++++++++ 28 files changed, 1592 insertions(+) create mode 100644 internal/cmd/firewall/add_rule_test.go create mode 100644 internal/cmd/firewall/apply_to_resource_test.go create mode 100644 internal/cmd/firewall/delete_rule_test.go create mode 100644 internal/cmd/firewall/remove_from_resource_test.go create mode 100644 internal/cmd/firewall/replace_rules_test.go create mode 100644 internal/cmd/firewall/testdata/rules.json create mode 100644 internal/cmd/floatingip/assign_test.go create mode 100644 internal/cmd/floatingip/disable_protection_test.go create mode 100644 internal/cmd/floatingip/enable_protection_test.go create mode 100644 internal/cmd/floatingip/set_rdns_test.go create mode 100644 internal/cmd/floatingip/unassign_test.go create mode 100644 internal/cmd/image/disable_protection_test.go create mode 100644 internal/cmd/image/enable_protection_test.go create mode 100644 internal/cmd/loadbalancer/add_service_test.go create mode 100644 internal/cmd/loadbalancer/add_target_test.go create mode 100644 internal/cmd/loadbalancer/attach_to_network_test.go create mode 100644 internal/cmd/loadbalancer/change_algorithm_test.go create mode 100644 internal/cmd/loadbalancer/change_type_test.go create mode 100644 internal/cmd/loadbalancer/delete_service_test.go create mode 100644 internal/cmd/loadbalancer/detach_from_network_test.go create mode 100644 internal/cmd/loadbalancer/disable_protection_test.go create mode 100644 internal/cmd/loadbalancer/disable_public_interface_test.go create mode 100644 internal/cmd/loadbalancer/enable_protection_test.go create mode 100644 internal/cmd/loadbalancer/enable_public_interface_test.go create mode 100644 internal/cmd/loadbalancer/metrics_test.go create mode 100644 internal/cmd/loadbalancer/remove_target_test.go create mode 100644 internal/cmd/loadbalancer/set_rdns_test.go create mode 100644 internal/cmd/loadbalancer/update_service_test.go diff --git a/internal/cmd/firewall/add_rule_test.go b/internal/cmd/firewall/add_rule_test.go new file mode 100644 index 00000000..c7052daf --- /dev/null +++ b/internal/cmd/firewall/add_rule_test.go @@ -0,0 +1,56 @@ +package firewall + +import ( + "context" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestAddRule(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := AddRuleCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + firewall := &hcloud.Firewall{ + ID: 123, + Name: "test", + } + + fx.Client.FirewallClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(firewall, nil, nil) + fx.Client.FirewallClient.EXPECT(). + SetRules(gomock.Any(), firewall, hcloud.FirewallSetRulesOpts{ + Rules: []hcloud.FirewallRule{{ + Direction: hcloud.FirewallRuleDirectionIn, + SourceIPs: []net.IPNet{{IP: net.IP{0, 0, 0, 0}, Mask: net.IPMask{0, 0, 0, 0}}}, + DestinationIPs: nil, + Protocol: hcloud.FirewallRuleProtocolTCP, + Port: hcloud.Ptr("80"), + Description: hcloud.Ptr("http"), + }}, + }). + Return([]*hcloud.Action{{ID: 123}, {ID: 321}}, nil, nil) + fx.ActionWaiter.EXPECT(). + WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 123}, {ID: 321}}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--direction", "in", "--protocol", "tcp", "--source-ips", "0.0.0.0/0", "--port", "80", "--description", "http", "test"}) + + expOut := "Firewall Rules for Firewall 123 updated\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/firewall/apply_to_resource_test.go b/internal/cmd/firewall/apply_to_resource_test.go new file mode 100644 index 00000000..7c805ba7 --- /dev/null +++ b/internal/cmd/firewall/apply_to_resource_test.go @@ -0,0 +1,93 @@ +package firewall + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestApplyToServer(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := ApplyToResourceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + firewall := &hcloud.Firewall{ + ID: 123, + Name: "test", + } + + fx.Client.FirewallClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(firewall, nil, nil) + fx.Client.ServerClient.EXPECT(). + Get(gomock.Any(), "my-server"). + Return(&hcloud.Server{ID: 456}, nil, nil) + fx.Client.FirewallClient.EXPECT(). + ApplyResources(gomock.Any(), firewall, []hcloud.FirewallResource{{ + Type: hcloud.FirewallResourceTypeServer, + Server: &hcloud.FirewallResourceServer{ + ID: 456, + }, + }}). + Return([]*hcloud.Action{{ID: 123}, {ID: 321}}, nil, nil) + fx.ActionWaiter.EXPECT(). + WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 123}, {ID: 321}}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--type", "server", "--server", "my-server", "test"}) + + expOut := "Firewall 123 applied\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} + +func TestApplyToLabelSelector(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := ApplyToResourceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + firewall := &hcloud.Firewall{ + ID: 123, + Name: "test", + } + + fx.Client.FirewallClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(firewall, nil, nil) + fx.Client.FirewallClient.EXPECT(). + ApplyResources(gomock.Any(), firewall, []hcloud.FirewallResource{{ + Type: hcloud.FirewallResourceTypeLabelSelector, + LabelSelector: &hcloud.FirewallResourceLabelSelector{ + Selector: "my-label", + }, + }}). + Return([]*hcloud.Action{{ID: 123}, {ID: 321}}, nil, nil) + fx.ActionWaiter.EXPECT(). + WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 123}, {ID: 321}}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--type", "label_selector", "--label-selector", "my-label", "test"}) + + expOut := "Firewall 123 applied\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/firewall/delete_rule_test.go b/internal/cmd/firewall/delete_rule_test.go new file mode 100644 index 00000000..40d646e4 --- /dev/null +++ b/internal/cmd/firewall/delete_rule_test.go @@ -0,0 +1,55 @@ +package firewall + +import ( + "context" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestDeleteRule(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := DeleteRuleCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + firewall := &hcloud.Firewall{ + ID: 123, + Name: "test", + Rules: []hcloud.FirewallRule{{ + Direction: hcloud.FirewallRuleDirectionIn, + SourceIPs: []net.IPNet{{IP: net.IP{0, 0, 0, 0}, Mask: net.IPMask{0, 0, 0, 0}}}, + DestinationIPs: []net.IPNet{}, + Protocol: hcloud.FirewallRuleProtocolTCP, + Port: hcloud.Ptr("80"), + Description: hcloud.Ptr("http"), + }}, + } + + fx.Client.FirewallClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(firewall, nil, nil) + fx.Client.FirewallClient.EXPECT(). + SetRules(gomock.Any(), firewall, hcloud.FirewallSetRulesOpts{Rules: nil}). + Return([]*hcloud.Action{{ID: 123}, {ID: 321}}, nil, nil) + fx.ActionWaiter.EXPECT(). + WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 123}, {ID: 321}}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--direction", "in", "--protocol", "tcp", "--source-ips", "0.0.0.0/0", "--port", "80", "--description", "http", "test"}) + + expOut := "Firewall Rules for Firewall 123 updated\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/firewall/remove_from_resource_test.go b/internal/cmd/firewall/remove_from_resource_test.go new file mode 100644 index 00000000..31522bb9 --- /dev/null +++ b/internal/cmd/firewall/remove_from_resource_test.go @@ -0,0 +1,93 @@ +package firewall + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestRemoveFromServer(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := RemoveFromResourceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + firewall := &hcloud.Firewall{ + ID: 123, + Name: "test", + } + + fx.Client.FirewallClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(firewall, nil, nil) + fx.Client.ServerClient.EXPECT(). + Get(gomock.Any(), "my-server"). + Return(&hcloud.Server{ID: 456}, nil, nil) + fx.Client.FirewallClient.EXPECT(). + RemoveResources(gomock.Any(), firewall, []hcloud.FirewallResource{{ + Type: hcloud.FirewallResourceTypeServer, + Server: &hcloud.FirewallResourceServer{ + ID: 456, + }, + }}). + Return([]*hcloud.Action{{ID: 123}, {ID: 321}}, nil, nil) + fx.ActionWaiter.EXPECT(). + WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 123}, {ID: 321}}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--type", "server", "--server", "my-server", "test"}) + + expOut := "Firewall 123 applied\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} + +func TestRemoveFromLabelSelector(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := RemoveFromResourceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + firewall := &hcloud.Firewall{ + ID: 123, + Name: "test", + } + + fx.Client.FirewallClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(firewall, nil, nil) + fx.Client.FirewallClient.EXPECT(). + RemoveResources(gomock.Any(), firewall, []hcloud.FirewallResource{{ + Type: hcloud.FirewallResourceTypeLabelSelector, + LabelSelector: &hcloud.FirewallResourceLabelSelector{ + Selector: "my-label", + }, + }}). + Return([]*hcloud.Action{{ID: 123}, {ID: 321}}, nil, nil) + fx.ActionWaiter.EXPECT(). + WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 123}, {ID: 321}}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--type", "label_selector", "--label-selector", "my-label", "test"}) + + expOut := "Firewall 123 applied\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/firewall/replace_rules_test.go b/internal/cmd/firewall/replace_rules_test.go new file mode 100644 index 00000000..24105519 --- /dev/null +++ b/internal/cmd/firewall/replace_rules_test.go @@ -0,0 +1,79 @@ +package firewall + +import ( + "context" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestReplaceRules(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := ReplaceRulesCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + firewall := &hcloud.Firewall{ + ID: 123, + Name: "test", + } + + fx.Client.FirewallClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(firewall, nil, nil) + fx.Client.FirewallClient.EXPECT(). + SetRules(gomock.Any(), firewall, hcloud.FirewallSetRulesOpts{ + Rules: []hcloud.FirewallRule{ + { + Direction: hcloud.FirewallRuleDirectionIn, + SourceIPs: []net.IPNet{ + {IP: net.IP{28, 239, 13, 1}, Mask: net.IPMask{255, 255, 255, 255}}, + {IP: net.IP{28, 239, 14, 0}, Mask: net.IPMask{255, 255, 255, 0}}, + { + IP: net.IP{0xff, 0x21, 0x1e, 0xac, 0x9a, 0x3b, 0xee, 0x58, 0x05, 0xca, 0x99, 0x0c, 0x8b, 0xc9, 0xc0, 0x3b}, + Mask: net.IPMask{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + }, + DestinationIPs: nil, + Protocol: hcloud.FirewallRuleProtocolTCP, + Port: hcloud.Ptr("80"), + Description: hcloud.Ptr("Allow port 80"), + }, + { + Direction: hcloud.FirewallRuleDirectionIn, + SourceIPs: []net.IPNet{ + {IP: net.IP{0, 0, 0, 0}, Mask: net.IPMask{0, 0, 0, 0}}, + { + IP: net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + Mask: net.IPMask{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + }, + DestinationIPs: nil, + Protocol: hcloud.FirewallRuleProtocolTCP, + Port: hcloud.Ptr("443"), + Description: hcloud.Ptr("Allow port 443"), + }, + }, + }). + Return([]*hcloud.Action{{ID: 123}, {ID: 321}}, nil, nil) + fx.ActionWaiter.EXPECT(). + WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 123}, {ID: 321}}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--rules-file", "testdata/rules.json", "test"}) + + expOut := "Firewall Rules for Firewall 123 updated\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/firewall/testdata/rules.json b/internal/cmd/firewall/testdata/rules.json new file mode 100644 index 00000000..7efec894 --- /dev/null +++ b/internal/cmd/firewall/testdata/rules.json @@ -0,0 +1,23 @@ +[ + { + "description": "Allow port 80", + "direction": "in", + "port": "80", + "protocol": "tcp", + "source_ips": [ + "28.239.13.1/32", + "28.239.14.0/24", + "ff21:1eac:9a3b:ee58:5ca:990c:8bc9:c03b/128" + ] + }, + { + "description": "Allow port 443", + "direction": "in", + "port": "443", + "protocol": "tcp", + "source_ips": [ + "0.0.0.0/0", + "::/0" + ] + } +] diff --git a/internal/cmd/floatingip/assign_test.go b/internal/cmd/floatingip/assign_test.go new file mode 100644 index 00000000..abfb8c9d --- /dev/null +++ b/internal/cmd/floatingip/assign_test.go @@ -0,0 +1,44 @@ +package floatingip + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestAssign(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := AssignCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.FloatingIPClient.EXPECT(). + Get(gomock.Any(), "my-ip"). + Return(&hcloud.FloatingIP{ID: 123}, nil, nil) + fx.Client.ServerClient.EXPECT(). + Get(gomock.Any(), "my-server"). + Return(&hcloud.Server{ID: 456}, nil, nil) + fx.Client.FloatingIPClient.EXPECT(). + Assign(gomock.Any(), &hcloud.FloatingIP{ID: 123}, &hcloud.Server{ID: 456}). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"my-ip", "my-server"}) + + expOut := "Floating IP 123 assigned to server 456\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/floatingip/disable_protection_test.go b/internal/cmd/floatingip/disable_protection_test.go new file mode 100644 index 00000000..bff1037b --- /dev/null +++ b/internal/cmd/floatingip/disable_protection_test.go @@ -0,0 +1,43 @@ +package floatingip + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestDisableProtection(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := DisableProtectionCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.FloatingIPClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(&hcloud.FloatingIP{ID: 123}, nil, nil) + fx.Client.FloatingIPClient.EXPECT(). + ChangeProtection(gomock.Any(), &hcloud.FloatingIP{ID: 123}, hcloud.FloatingIPChangeProtectionOpts{ + Delete: hcloud.Ptr(false), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"test", "delete"}) + + expOut := "Resource protection disabled for floating IP 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/floatingip/enable_protection_test.go b/internal/cmd/floatingip/enable_protection_test.go new file mode 100644 index 00000000..80e6effb --- /dev/null +++ b/internal/cmd/floatingip/enable_protection_test.go @@ -0,0 +1,43 @@ +package floatingip + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestEnableProtection(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := EnableProtectionCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.FloatingIPClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(&hcloud.FloatingIP{ID: 123}, nil, nil) + fx.Client.FloatingIPClient.EXPECT(). + ChangeProtection(gomock.Any(), &hcloud.FloatingIP{ID: 123}, hcloud.FloatingIPChangeProtectionOpts{ + Delete: hcloud.Ptr(true), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"test", "delete"}) + + expOut := "Resource protection enabled for floating IP 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/floatingip/set_rdns_test.go b/internal/cmd/floatingip/set_rdns_test.go new file mode 100644 index 00000000..d5b45ee7 --- /dev/null +++ b/internal/cmd/floatingip/set_rdns_test.go @@ -0,0 +1,47 @@ +package floatingip + +import ( + "context" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestSetRDNS(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := SetRDNSCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + floatingIP := &hcloud.FloatingIP{ + ID: 123, + IP: net.ParseIP("192.168.2.1"), + } + + fx.Client.FloatingIPClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(floatingIP, nil, nil) + fx.Client.RDNSClient.EXPECT(). + ChangeDNSPtr(gomock.Any(), floatingIP, floatingIP.IP, hcloud.Ptr("example.com")). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--hostname", "example.com", "test"}) + + expOut := "Reverse DNS of Floating IP test changed\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/floatingip/unassign_test.go b/internal/cmd/floatingip/unassign_test.go new file mode 100644 index 00000000..de655f8e --- /dev/null +++ b/internal/cmd/floatingip/unassign_test.go @@ -0,0 +1,41 @@ +package floatingip + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestUnassign(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := UnassignCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.FloatingIPClient.EXPECT(). + Get(gomock.Any(), "my-ip"). + Return(&hcloud.FloatingIP{ID: 123}, nil, nil) + fx.Client.FloatingIPClient.EXPECT(). + Unassign(gomock.Any(), &hcloud.FloatingIP{ID: 123}). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"my-ip"}) + + expOut := "Floating IP 123 unassigned\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/image/disable_protection_test.go b/internal/cmd/image/disable_protection_test.go new file mode 100644 index 00000000..8d2d905e --- /dev/null +++ b/internal/cmd/image/disable_protection_test.go @@ -0,0 +1,40 @@ +package image + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestDisableProtection(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := DisableProtectionCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.ImageClient.EXPECT(). + ChangeProtection(gomock.Any(), &hcloud.Image{ID: 123}, hcloud.ImageChangeProtectionOpts{ + Delete: hcloud.Ptr(false), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "delete"}) + + expOut := "Resource protection disabled for image 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/image/enable_protection_test.go b/internal/cmd/image/enable_protection_test.go new file mode 100644 index 00000000..7b0663f5 --- /dev/null +++ b/internal/cmd/image/enable_protection_test.go @@ -0,0 +1,40 @@ +package image + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestEnableProtection(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := EnableProtectionCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.ImageClient.EXPECT(). + ChangeProtection(gomock.Any(), &hcloud.Image{ID: 123}, hcloud.ImageChangeProtectionOpts{ + Delete: hcloud.Ptr(true), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "delete"}) + + expOut := "Resource protection enabled for image 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/add_service_test.go b/internal/cmd/loadbalancer/add_service_test.go new file mode 100644 index 00000000..799479da --- /dev/null +++ b/internal/cmd/loadbalancer/add_service_test.go @@ -0,0 +1,50 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestAddService(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := AddServiceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + AddService(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerAddServiceOpts{ + Protocol: hcloud.LoadBalancerServiceProtocolHTTP, + ListenPort: hcloud.Ptr(80), + DestinationPort: hcloud.Ptr(8080), + HTTP: &hcloud.LoadBalancerAddServiceOptsHTTP{ + StickySessions: hcloud.Ptr(false), + RedirectHTTP: hcloud.Ptr(false), + }, + Proxyprotocol: hcloud.Ptr(false), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--protocol", "http", "--listen-port", "80", "--destination-port", "8080"}) + + expOut := "Service was added to Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/add_target_test.go b/internal/cmd/loadbalancer/add_target_test.go new file mode 100644 index 00000000..36a6a9f7 --- /dev/null +++ b/internal/cmd/loadbalancer/add_target_test.go @@ -0,0 +1,111 @@ +package loadbalancer + +import ( + "context" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestAddTargetServer(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := AddTargetCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.ServerClient.EXPECT(). + Get(gomock.Any(), "my-server"). + Return(&hcloud.Server{ID: 321}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + AddServerTarget(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerAddServerTargetOpts{ + Server: &hcloud.Server{ID: 321}, + UsePrivateIP: hcloud.Ptr(false), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--server", "my-server"}) + + expOut := "Target added to Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} + +func TestAddTargetLabelSelector(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := AddTargetCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + AddLabelSelectorTarget(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerAddLabelSelectorTargetOpts{ + Selector: "my-label", + UsePrivateIP: hcloud.Ptr(false), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--label-selector", "my-label"}) + + expOut := "Target added to Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} + +func TestAddTargetIP(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := AddTargetCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + AddIPTarget(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerAddIPTargetOpts{ + IP: net.ParseIP("192.168.2.1"), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--ip", "192.168.2.1"}) + + expOut := "Target added to Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/attach_to_network_test.go b/internal/cmd/loadbalancer/attach_to_network_test.go new file mode 100644 index 00000000..bcd8506a --- /dev/null +++ b/internal/cmd/loadbalancer/attach_to_network_test.go @@ -0,0 +1,46 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestAttachToNetwork(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := AttachToNetworkCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.NetworkClient.EXPECT(). + Get(gomock.Any(), "my-network"). + Return(&hcloud.Network{ID: 321}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + AttachToNetwork(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerAttachToNetworkOpts{ + Network: &hcloud.Network{ID: 321}, + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--network", "my-network"}) + + expOut := "Load Balancer 123 attached to network 321\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/change_algorithm_test.go b/internal/cmd/loadbalancer/change_algorithm_test.go new file mode 100644 index 00000000..2d8eb9fa --- /dev/null +++ b/internal/cmd/loadbalancer/change_algorithm_test.go @@ -0,0 +1,43 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestChangeAlgorithm(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := ChangeAlgorithmCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + ChangeAlgorithm(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerChangeAlgorithmOpts{ + Type: hcloud.LoadBalancerAlgorithmTypeLeastConnections, + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--algorithm-type", "least_connections"}) + + expOut := "Algorithm for Load Balancer 123 was changed\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/change_type_test.go b/internal/cmd/loadbalancer/change_type_test.go new file mode 100644 index 00000000..426af526 --- /dev/null +++ b/internal/cmd/loadbalancer/change_type_test.go @@ -0,0 +1,48 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestChangeType(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := ChangeTypeCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + lbType := &hcloud.LoadBalancerType{ID: 321, Name: "lb21"} + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerTypeClient.EXPECT(). + Get(gomock.Any(), "lb21"). + Return(lbType, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + ChangeType(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerChangeTypeOpts{ + LoadBalancerType: lbType, + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "lb21"}) + + expOut := "LoadBalancer 123 changed to type lb21\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/delete_service_test.go b/internal/cmd/loadbalancer/delete_service_test.go new file mode 100644 index 00000000..bb264fe4 --- /dev/null +++ b/internal/cmd/loadbalancer/delete_service_test.go @@ -0,0 +1,38 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestDeleteService(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := DeleteServiceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + DeleteService(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, 80). + Return(&hcloud.Action{ID: 123}, nil, nil) + + out, _, err := fx.Run(cmd, []string{"123", "--listen-port", "80"}) + + expOut := "Service on port 80 deleted from Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/detach_from_network_test.go b/internal/cmd/loadbalancer/detach_from_network_test.go new file mode 100644 index 00000000..a482f47d --- /dev/null +++ b/internal/cmd/loadbalancer/detach_from_network_test.go @@ -0,0 +1,46 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestDetachFromNetwork(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := DetachFromNetworkCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.NetworkClient.EXPECT(). + Get(gomock.Any(), "my-network"). + Return(&hcloud.Network{ID: 321}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + DetachFromNetwork(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerDetachFromNetworkOpts{ + Network: &hcloud.Network{ID: 321}, + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--network", "my-network"}) + + expOut := "Load Balancer 123 detached from Network 321\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/disable_protection_test.go b/internal/cmd/loadbalancer/disable_protection_test.go new file mode 100644 index 00000000..a24769cc --- /dev/null +++ b/internal/cmd/loadbalancer/disable_protection_test.go @@ -0,0 +1,43 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestDisableProtection(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := DisableProtectionCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + ChangeProtection(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerChangeProtectionOpts{ + Delete: hcloud.Ptr(false), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "delete"}) + + expOut := "Resource protection disabled for Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/disable_public_interface_test.go b/internal/cmd/loadbalancer/disable_public_interface_test.go new file mode 100644 index 00000000..c6b590b2 --- /dev/null +++ b/internal/cmd/loadbalancer/disable_public_interface_test.go @@ -0,0 +1,41 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestDisablePublicInterface(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := DisablePublicInterfaceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + DisablePublicInterface(gomock.Any(), &hcloud.LoadBalancer{ID: 123}). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123"}) + + expOut := "Public interface of Load Balancer 123 was disabled\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/enable_protection_test.go b/internal/cmd/loadbalancer/enable_protection_test.go new file mode 100644 index 00000000..f894cb98 --- /dev/null +++ b/internal/cmd/loadbalancer/enable_protection_test.go @@ -0,0 +1,43 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestEnableProtection(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := EnableProtectionCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + ChangeProtection(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerChangeProtectionOpts{ + Delete: hcloud.Ptr(true), + }). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "delete"}) + + expOut := "Resource protection enabled for Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/enable_public_interface_test.go b/internal/cmd/loadbalancer/enable_public_interface_test.go new file mode 100644 index 00000000..65bff975 --- /dev/null +++ b/internal/cmd/loadbalancer/enable_public_interface_test.go @@ -0,0 +1,41 @@ +package loadbalancer + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestEnablePublicInterface(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := EnablePublicInterfaceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + EnablePublicInterface(gomock.Any(), &hcloud.LoadBalancer{ID: 123}). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123"}) + + expOut := "Public interface of Load Balancer 123 was enabled\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/metrics_test.go b/internal/cmd/loadbalancer/metrics_test.go new file mode 100644 index 00000000..b6d86a60 --- /dev/null +++ b/internal/cmd/loadbalancer/metrics_test.go @@ -0,0 +1,103 @@ +package loadbalancer + +import ( + "context" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestMetrics(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := MetricsCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + start := time.Date(2022, 11, 1, 0, 0, 0, 0, time.UTC) + end := start.Add(time.Hour) + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + GetMetrics(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, hcloud.LoadBalancerGetMetricsOpts{ + Start: start, + End: end, + Types: []hcloud.LoadBalancerMetricType{hcloud.LoadBalancerMetricOpenConnections}, + }). + Return(&hcloud.LoadBalancerMetrics{ + TimeSeries: map[string][]hcloud.LoadBalancerMetricsValue{ + "open_connections": { + { + Timestamp: float64(start.Add(0*time.Minute).UnixMilli() / 1000.0), + Value: "2", + }, + { + Timestamp: float64(start.Add(10*time.Minute).UnixMilli() / 1000.0), + Value: "4", + }, + { + Timestamp: float64(start.Add(20*time.Minute).UnixMilli() / 1000.0), + Value: "2", + }, + { + Timestamp: float64(start.Add(30*time.Minute).UnixMilli() / 1000.0), + Value: "1", + }, + { + Timestamp: float64(start.Add(40*time.Minute).UnixMilli() / 1000.0), + Value: "6", + }, + { + Timestamp: float64(start.Add(50*time.Minute).UnixMilli() / 1000.0), + Value: "4", + }, + { + Timestamp: float64(start.Add(60*time.Minute).UnixMilli() / 1000.0), + Value: "2", + }, + }, + }, + }, nil, nil) + + out, _, err := fx.Run(cmd, []string{"123", "--type", "open_connections", "--start", "2022-11-01T00:00:00Z", "--end", "2022-11-01T01:00:00Z"}) + + expOut := `Load Balancer: Metric: open_connections Start: 0001-01-01 00:00:00 +0000 UTC End: 0001-01-01 00:00:00 +0000 UTC + 6.00 ┤ ╭─╮ + 5.75 ┤ ╭╯ ╰─╮ + 5.50 ┤ ╭╯ ╰─╮ + 5.25 ┤ │ ╰─╮ + 5.01 ┤ ╭╯ ╰─╮ + 4.76 ┤ ╭╯ ╰─╮ + 4.51 ┤ ╭╯ ╰─╮ + 4.26 ┤ ╭╯ ╰─╮ + 4.01 ┤ ╭─╮ ╭╯ ╰─╮ + 3.76 ┤ ╭─╯ ╰─╮ │ ╰─╮ + 3.52 ┤ ╭─╯ ╰─╮ ╭╯ ╰─╮ + 3.27 ┤ ╭─╯ ╰─╮ ╭╯ ╰─╮ + 3.02 ┤ ╭─╯ ╰─╮ ╭╯ ╰─╮ + 2.77 ┤ ╭─╯ ╰─╮ ╭╯ ╰─╮ + 2.52 ┤ ╭──╯ ╰──╮ ╭╯ ╰──╮ + 2.27 ┤╭─╯ ╰─╮ │ ╰─╮ + 2.02 ┼╯ ╰──╮ ╭╯ ╰ + 1.78 ┤ ╰───╮ ╭╯ + 1.53 ┤ ╰───╮ ╭╯ + 1.28 ┤ ╰───╮ ╭╯ + 1.03 ┤ ╰─╯ + + +` + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/remove_target_test.go b/internal/cmd/loadbalancer/remove_target_test.go new file mode 100644 index 00000000..3d7f2a3e --- /dev/null +++ b/internal/cmd/loadbalancer/remove_target_test.go @@ -0,0 +1,103 @@ +package loadbalancer + +import ( + "context" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestRemoveTargetServer(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := RemoveTargetCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.ServerClient.EXPECT(). + Get(gomock.Any(), "my-server"). + Return(&hcloud.Server{ID: 321}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + RemoveServerTarget(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, &hcloud.Server{ID: 321}). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--server", "my-server"}) + + expOut := "Target removed from Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} + +func TestRemoveTargetLabelSelector(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := RemoveTargetCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + RemoveLabelSelectorTarget(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, "my-label"). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--label-selector", "my-label"}) + + expOut := "Target removed from Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} + +func TestRemoveTargetIP(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := RemoveTargetCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + RemoveIPTarget(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, net.ParseIP("192.168.2.1")). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"123", "--ip", "192.168.2.1"}) + + expOut := "Target removed from Load Balancer 123\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/set_rdns_test.go b/internal/cmd/loadbalancer/set_rdns_test.go new file mode 100644 index 00000000..625d47d2 --- /dev/null +++ b/internal/cmd/loadbalancer/set_rdns_test.go @@ -0,0 +1,51 @@ +package loadbalancer + +import ( + "context" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestSetRDNS(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := SetRDNSCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + loadBalancer := &hcloud.LoadBalancer{ + ID: 123, + PublicNet: hcloud.LoadBalancerPublicNet{ + IPv4: hcloud.LoadBalancerPublicNetIPv4{ + IP: net.ParseIP("192.168.2.1"), + }, + }, + } + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "test"). + Return(loadBalancer, nil, nil) + fx.Client.RDNSClient.EXPECT(). + ChangeDNSPtr(gomock.Any(), loadBalancer, loadBalancer.PublicNet.IPv4.IP, hcloud.Ptr("example.com")). + Return(&hcloud.Action{ID: 123}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{"--hostname", "example.com", "test"}) + + expOut := "Reverse DNS of Load Balancer test changed\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +} diff --git a/internal/cmd/loadbalancer/update_service_test.go b/internal/cmd/loadbalancer/update_service_test.go new file mode 100644 index 00000000..83786dab --- /dev/null +++ b/internal/cmd/loadbalancer/update_service_test.go @@ -0,0 +1,88 @@ +package loadbalancer + +import ( + "context" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/hetznercloud/cli/internal/testutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud" +) + +func TestUpdateService(t *testing.T) { + fx := testutil.NewFixture(t) + defer fx.Finish() + + cmd := UpdateServiceCmd.CobraCommand( + context.Background(), + fx.Client, + fx.TokenEnsurer, + fx.ActionWaiter) + fx.ExpectEnsureToken() + + fx.Client.LoadBalancerClient.EXPECT(). + Get(gomock.Any(), "123"). + Return(&hcloud.LoadBalancer{ID: 123}, nil, nil) + fx.Client.LoadBalancerClient.EXPECT(). + UpdateService(gomock.Any(), &hcloud.LoadBalancer{ID: 123}, 80, hcloud.LoadBalancerUpdateServiceOpts{ + DestinationPort: hcloud.Ptr(8080), + Protocol: hcloud.LoadBalancerServiceProtocolTCP, + Proxyprotocol: hcloud.Ptr(true), + HTTP: &hcloud.LoadBalancerUpdateServiceOptsHTTP{ + RedirectHTTP: hcloud.Ptr(true), + StickySessions: hcloud.Ptr(true), + CookieName: hcloud.Ptr("test"), + CookieLifetime: hcloud.Ptr(10 * time.Minute), + Certificates: []*hcloud.Certificate{{ID: 1}}, + }, + HealthCheck: &hcloud.LoadBalancerUpdateServiceOptsHealthCheck{ + Protocol: hcloud.LoadBalancerServiceProtocolTCP, + Port: hcloud.Ptr(8080), + Interval: hcloud.Ptr(10 * time.Second), + Timeout: hcloud.Ptr(5 * time.Second), + Retries: hcloud.Ptr(2), + HTTP: &hcloud.LoadBalancerUpdateServiceOptsHealthCheckHTTP{ + Domain: hcloud.Ptr("example.com"), + Path: hcloud.Ptr("/health"), + StatusCodes: []string{"200"}, + Response: hcloud.Ptr("OK"), + TLS: hcloud.Ptr(true), + }, + }, + }). + Return(&hcloud.Action{ID: 321}, nil, nil) + fx.ActionWaiter.EXPECT(). + ActionProgress(gomock.Any(), &hcloud.Action{ID: 321}). + Return(nil) + + out, _, err := fx.Run(cmd, []string{ + "123", + "--listen-port", "80", + "--destination-port", "8080", + "--protocol", "tcp", + "--proxy-protocol=true", + "--http-redirect-http=true", + "--http-sticky-sessions=true", + "--http-cookie-name", "test", + "--http-cookie-lifetime", "10m", + "--http-certificates", "1", + "--health-check-protocol", "tcp", + "--health-check-port", "8080", + "--health-check-interval", "10s", + "--health-check-timeout", "5s", + "--health-check-retries", "2", + "--health-check-http-domain", "example.com", + "--health-check-http-path", "/health", + "--health-check-http-status-codes", "200", + "--health-check-http-response", "OK", + "--health-check-http-tls=true", + }) + + expOut := "Service 80 on Load Balancer 123 was updated\n" + + assert.NoError(t, err) + assert.Equal(t, expOut, out) +}