Skip to content

Commit 45d7df5

Browse files
Add tests for controlsvc control types (#865)
1 parent 5f5094f commit 45d7df5

File tree

11 files changed

+595
-69
lines changed

11 files changed

+595
-69
lines changed

pkg/controlsvc/connect.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ import (
99
)
1010

1111
type (
12-
connectCommandType struct{}
13-
connectCommand struct {
12+
ConnectCommandType struct{}
13+
ConnectCommand struct {
1414
targetNode string
1515
targetService string
1616
tlsConfigName string
1717
}
1818
)
1919

20-
func (t *connectCommandType) InitFromString(params string) (ControlCommand, error) {
20+
func (t *ConnectCommandType) InitFromString(params string) (ControlCommand, error) {
2121
tokens := strings.Split(params, " ")
2222
if len(tokens) < 2 {
2323
return nil, fmt.Errorf("no connect target")
@@ -29,7 +29,7 @@ func (t *connectCommandType) InitFromString(params string) (ControlCommand, erro
2929
if len(tokens) == 3 {
3030
tlsConfigName = tokens[2]
3131
}
32-
c := &connectCommand{
32+
c := &ConnectCommand{
3333
targetNode: tokens[0],
3434
targetService: tokens[1],
3535
tlsConfigName: tlsConfigName,
@@ -38,7 +38,7 @@ func (t *connectCommandType) InitFromString(params string) (ControlCommand, erro
3838
return c, nil
3939
}
4040

41-
func (t *connectCommandType) InitFromJSON(config map[string]interface{}) (ControlCommand, error) {
41+
func (t *ConnectCommandType) InitFromJSON(config map[string]interface{}) (ControlCommand, error) {
4242
targetNode, ok := config["node"]
4343
if !ok {
4444
return nil, fmt.Errorf("no connect target node")
@@ -65,7 +65,7 @@ func (t *connectCommandType) InitFromJSON(config map[string]interface{}) (Contro
6565
} else {
6666
tlsConfigStr = ""
6767
}
68-
c := &connectCommand{
68+
c := &ConnectCommand{
6969
targetNode: targetNodeStr,
7070
targetService: targetServiceStr,
7171
tlsConfigName: tlsConfigStr,
@@ -74,7 +74,7 @@ func (t *connectCommandType) InitFromJSON(config map[string]interface{}) (Contro
7474
return c, nil
7575
}
7676

77-
func (c *connectCommand) ControlFunc(_ context.Context, nc NetceptorForControlCommand, cfo ControlFuncOperations) (map[string]interface{}, error) {
77+
func (c *ConnectCommand) ControlFunc(_ context.Context, nc NetceptorForControlCommand, cfo ControlFuncOperations) (map[string]interface{}, error) {
7878
tlscfg, err := nc.GetClientTLSConfig(c.tlsConfigName, c.targetNode, netceptor.ExpectedHostnameTypeReceptor)
7979
if err != nil {
8080
return nil, err

pkg/controlsvc/connect_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package controlsvc_test
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
"github.com/ansible/receptor/pkg/controlsvc"
9+
"github.com/ansible/receptor/pkg/controlsvc/mock_controlsvc"
10+
"github.com/ansible/receptor/pkg/logger"
11+
"github.com/golang/mock/gomock"
12+
)
13+
14+
func CheckExpectedError(expectedError bool, errorMessage string, t *testing.T, err error) {
15+
if expectedError && errorMessage != err.Error() {
16+
t.Errorf("expected: %s , received: %s", errorMessage, err)
17+
}
18+
19+
if !expectedError && err != nil {
20+
t.Error(err)
21+
}
22+
}
23+
24+
func TestConnectInitFromString(t *testing.T) {
25+
connectCommandType := controlsvc.ConnectCommandType{}
26+
27+
initFromStringTestCases := []struct {
28+
name string
29+
expectedError bool
30+
errorMessage string
31+
input string
32+
}{
33+
{
34+
name: "no connect target",
35+
expectedError: true,
36+
errorMessage: "no connect target",
37+
input: "",
38+
},
39+
{
40+
name: "too many parameters",
41+
expectedError: true,
42+
errorMessage: "too many parameters",
43+
input: "one two three four",
44+
},
45+
{
46+
name: "three params - pass",
47+
expectedError: false,
48+
errorMessage: "",
49+
input: "one two three",
50+
},
51+
}
52+
53+
for _, testCase := range initFromStringTestCases {
54+
t.Run(testCase.name, func(t *testing.T) {
55+
_, err := connectCommandType.InitFromString(testCase.input)
56+
57+
CheckExpectedError(testCase.expectedError, testCase.errorMessage, t, err)
58+
})
59+
}
60+
}
61+
62+
func TestConnectInitFromJSON(t *testing.T) {
63+
connectCommandType := controlsvc.ConnectCommandType{}
64+
65+
initFromJSONTestCases := []struct {
66+
name string
67+
expectedError bool
68+
errorMessage string
69+
input map[string]interface{}
70+
}{
71+
BuildInitFromJSONTestCases("no connect target node", true, "no connect target node", map[string]interface{}{}),
72+
BuildInitFromJSONTestCases("connect target node must be string 1", true, "connect target node must be string", map[string]interface{}{"node": 7}),
73+
BuildInitFromJSONTestCases("no connect target service", true, "no connect target service", map[string]interface{}{"node": "node1"}),
74+
BuildInitFromJSONTestCases("connect target service must be string1", true, "connect target service must be string", map[string]interface{}{"node": "node2", "service": 7}),
75+
BuildInitFromJSONTestCases("connect tls name be string", true, "connect tls name must be string", map[string]interface{}{"node": "node3", "service": "service1", "tls": 7}),
76+
BuildInitFromJSONTestCases("pass with empty tls config", false, "connect target service must be string", map[string]interface{}{"node": "node4", "service": "service2"}),
77+
BuildInitFromJSONTestCases("pass with all targets and tls config", false, "", map[string]interface{}{"node": "node4", "service": "service3", "tls": "tls1"}),
78+
}
79+
80+
for _, testCase := range initFromJSONTestCases {
81+
t.Run(testCase.name, func(t *testing.T) {
82+
_, err := connectCommandType.InitFromJSON(testCase.input)
83+
CheckExpectedError(testCase.expectedError, testCase.errorMessage, t, err)
84+
})
85+
}
86+
}
87+
88+
func TestConnectControlFunc(t *testing.T) {
89+
connectCommand := controlsvc.ConnectCommand{}
90+
ctrl := gomock.NewController(t)
91+
mockNetceptor := mock_controlsvc.NewMockNetceptorForControlsvc(ctrl)
92+
mockControlFunc := mock_controlsvc.NewMockControlFuncOperations(ctrl)
93+
logger := logger.NewReceptorLogger("")
94+
95+
controlFuncTestCases := []struct {
96+
name string
97+
expectedError bool
98+
errorMessage string
99+
expectedCalls func()
100+
}{
101+
{
102+
name: "tls config error",
103+
expectedError: true,
104+
errorMessage: "terminated tls",
105+
expectedCalls: func() {
106+
mockNetceptor.EXPECT().GetClientTLSConfig(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("terminated tls"))
107+
},
108+
},
109+
{
110+
name: "dial error",
111+
errorMessage: "terminated dial",
112+
expectedError: true,
113+
expectedCalls: func() {
114+
mockNetceptor.EXPECT().GetClientTLSConfig(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil)
115+
mockNetceptor.EXPECT().Dial(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("terminated dial"))
116+
},
117+
},
118+
{
119+
name: "bridge conn error",
120+
errorMessage: "terminated bridge conn",
121+
expectedError: true,
122+
expectedCalls: func() {
123+
mockNetceptor.EXPECT().GetClientTLSConfig(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil)
124+
mockNetceptor.EXPECT().Dial(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil)
125+
mockControlFunc.EXPECT().BridgeConn(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("terminated bridge conn"))
126+
mockNetceptor.EXPECT().GetLogger().Return(logger)
127+
},
128+
},
129+
{
130+
name: "control func pass",
131+
errorMessage: "",
132+
expectedError: false,
133+
expectedCalls: func() {
134+
mockNetceptor.EXPECT().GetClientTLSConfig(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil)
135+
mockNetceptor.EXPECT().Dial(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil)
136+
mockControlFunc.EXPECT().BridgeConn(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
137+
mockNetceptor.EXPECT().GetLogger().Return(logger)
138+
},
139+
},
140+
}
141+
142+
for _, testCase := range controlFuncTestCases {
143+
t.Run(testCase.name, func(t *testing.T) {
144+
testCase.expectedCalls()
145+
_, err := connectCommand.ControlFunc(context.Background(), mockNetceptor, mockControlFunc)
146+
147+
CheckExpectedError(testCase.expectedError, testCase.errorMessage, t, err)
148+
})
149+
}
150+
}

pkg/controlsvc/controlsvc.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,11 @@ func New(stdServices bool, nc NetceptorForControlsvc) *Server {
168168
serverTLS: &TLS{},
169169
}
170170
if stdServices {
171-
s.controlTypes["ping"] = &pingCommandType{}
172-
s.controlTypes["status"] = &statusCommandType{}
173-
s.controlTypes["connect"] = &connectCommandType{}
174-
s.controlTypes["traceroute"] = &tracerouteCommandType{}
175-
s.controlTypes["reload"] = &reloadCommandType{}
171+
s.controlTypes["ping"] = &PingCommandType{}
172+
s.controlTypes["status"] = &StatusCommandType{}
173+
s.controlTypes["connect"] = &ConnectCommandType{}
174+
s.controlTypes["traceroute"] = &TracerouteCommandType{}
175+
s.controlTypes["reload"] = &ReloadCommandType{}
176176
}
177177

178178
return s

pkg/controlsvc/mock_controlsvc/interfaces.go

Lines changed: 29 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)