File: command_test.go

package info (click to toggle)
receptor 1.5.5-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,772 kB
  • sloc: python: 1,643; makefile: 305; sh: 174
file content (101 lines) | stat: -rw-r--r-- 3,466 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package services

import (
	"crypto/tls"
	"errors"
	"testing"

	"github.com/ansible/receptor/pkg/logger"
	"github.com/ansible/receptor/pkg/netceptor"
	"github.com/ansible/receptor/pkg/services/mock_services"
	"go.uber.org/mock/gomock"
)

func setUpCommandMocks(ctrl *gomock.Controller) (*mock_services.MockNetCForCommandService, *mock_services.MockUtilsLib) {
	mockNetceptor := mock_services.NewMockNetCForCommandService(ctrl)
	mockUtilsLib := mock_services.NewMockUtilsLib(ctrl)
	logger := logger.NewReceptorLogger("")
	mockNetceptor.EXPECT().GetLogger().AnyTimes().Return(logger)

	return mockNetceptor, mockUtilsLib
}

func TestCommandService(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mockTCPConn := mock_services.NewMockTCPConn(ctrl)
	var mockNetceptor *mock_services.MockNetCForCommandService
	var mockUtilsLib *mock_services.MockUtilsLib

	acceptChannel := make(chan *netceptor.AcceptResult)
	doneChannel := make(chan struct{})
	neceptorListener := netceptor.Listener{AcceptChan: acceptChannel, DoneChan: doneChannel}

	type test struct {
		name         string
		service      string
		command      string
		acceptResult []*netceptor.AcceptResult
		calls        func()
	}
	tests := []test{
		{name: "No command provided"},
		{
			name:    "Fail to listen and advertise connection",
			command: "echo hello",
			calls: func() {
				mockNetceptor.EXPECT().ListenAndAdvertise(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("failed to establish a connection"))
			},
		},
		{
			name:         "Fail to accept connection",
			acceptResult: []*netceptor.AcceptResult{{Conn: nil, Err: errors.New("failed to accept connection")}},
			command:      "echo hello",
			calls: func() {
				mockNetceptor.EXPECT().ListenAndAdvertise(gomock.Any(), gomock.Any(), gomock.Any()).Return(&neceptorListener, nil)
			},
		},
		// This is a case where shlex.Split() returns an empty array
		// In order to stop execution of the CommandService() in this test we pass an error on the AcceptChannel
		{
			name:         "Malformed command",
			acceptResult: []*netceptor.AcceptResult{{Conn: mockTCPConn, Err: nil}, {Conn: nil, Err: errors.New("failed to accept connection")}},
			command:      "# nine # ten\n",
			calls: func() {
				mockNetceptor.EXPECT().ListenAndAdvertise(gomock.Any(), gomock.Any(), gomock.Any()).Return(&neceptorListener, nil)
				mockTCPConn.EXPECT().Close().AnyTimes()
			},
		},
		// Happy path
		// In order to stop execution of the CommandService() in this test we pass an error on the AcceptChannel
		{
			name:         "Test echo command",
			acceptResult: []*netceptor.AcceptResult{{Conn: mockTCPConn, Err: nil}, {Conn: mockTCPConn, Err: errors.New("failed to accept connection")}},
			command:      "echo hello",
			calls: func() {
				mockNetceptor.EXPECT().ListenAndAdvertise(gomock.Any(), gomock.Any(), gomock.Any()).Return(&neceptorListener, nil)
				mockUtilsLib.EXPECT().BridgeConns(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			mockNetceptor, mockUtilsLib = setUpCommandMocks(ctrl)

			if tt.calls != nil {
				tt.calls()
			}

			if tt.acceptResult != nil {
				go func() {
					for _, result := range tt.acceptResult {
						neceptorListener.AcceptChan <- result
					}
				}()
			}
			CommandService(mockNetceptor, tt.service, &tls.Config{}, tt.command, mockUtilsLib)
		})
	}
}