-
Notifications
You must be signed in to change notification settings - Fork 23
/
listening_ports.go
135 lines (107 loc) · 4.5 KB
/
listening_ports.go
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package suites
import (
"sort"
"time"
"github.com/stackrox/collector/integration-tests/pkg/collector"
"github.com/stackrox/collector/integration-tests/pkg/common"
"github.com/stackrox/collector/integration-tests/pkg/config"
"github.com/stackrox/collector/integration-tests/pkg/types"
"github.com/stretchr/testify/assert"
)
type ProcessListeningOnPortTestSuite struct {
IntegrationTestSuiteBase
serverContainer string
}
func (s *ProcessListeningOnPortTestSuite) SetupSuite() {
s.RegisterCleanup("process-ports")
s.StartContainerStats()
collectorOptions := collector.StartupOptions{
Config: map[string]any{
"turnOffScrape": false,
"scrapeInterval": 1,
},
Env: map[string]string{
"ROX_PROCESSES_LISTENING_ON_PORT": "true",
},
}
s.StartCollector(false, &collectorOptions)
processImage := getProcessListeningOnPortsImage()
containerID, err := s.launchContainer("process-ports", "-v", "/tmp:/tmp", processImage)
s.Require().NoError(err)
s.serverContainer = common.ContainerShortID(containerID)
actionFile := "/tmp/action_file.txt"
_, err = s.executor.Exec("sh", "-c", "rm "+actionFile+" || true")
_, err = s.executor.Exec("sh", "-c", "echo open 8081 > "+actionFile)
err = s.waitForFileToBeDeleted(actionFile)
s.Require().NoError(err)
_, err = s.executor.Exec("sh", "-c", "echo open 9091 > "+actionFile)
err = s.waitForFileToBeDeleted(actionFile)
s.Require().NoError(err)
time.Sleep(6 * time.Second)
_, err = s.executor.Exec("sh", "-c", "echo close 8081 > "+actionFile)
err = s.waitForFileToBeDeleted(actionFile)
s.Require().NoError(err)
_, err = s.executor.Exec("sh", "-c", "echo close 9091 > "+actionFile)
err = s.waitForFileToBeDeleted(actionFile)
s.Require().NoError(err)
}
func (s *ProcessListeningOnPortTestSuite) TearDownSuite() {
s.StopCollector()
s.cleanupContainers("process-ports")
s.WritePerfResults()
}
func (s *ProcessListeningOnPortTestSuite) TestProcessListeningOnPort() {
processes := s.Sensor().ExpectProcessesN(s.T(), s.serverContainer, 30*time.Second, 2)
endpoints := s.Sensor().ExpectEndpointsN(s.T(), s.serverContainer, 30*time.Second, 4)
// sort by name to ensure processes[0] is the plop process (the other
// is the shell)
// All of these asserts check against the processes information of that program.
sort.Slice(processes, func(i, j int) bool {
return processes[i].Name < processes[j].Name
})
process := processes[0]
possiblePorts := []int{8081, 9091}
// First verify that all endpoints have the expected metadata, that
// they are the correct protocol and come from the expected Originator
// process.
for _, endpoint := range endpoints {
assert.Equal(s.T(), "L4_PROTOCOL_TCP", endpoint.Protocol)
assert.Equal(s.T(), endpoint.Originator.ProcessName, process.Name)
assert.Equal(s.T(), endpoint.Originator.ProcessExecFilePath, process.ExePath)
assert.Equal(s.T(), endpoint.Originator.ProcessArgs, process.Args)
// assert that we haven't got any unexpected ports - further checking
// of this data will occur subsequently
assert.Contains(s.T(), possiblePorts, endpoint.Address.Port)
}
// We can't guarantee the order in which collector reports the endpoints.
// Check that we have precisely two pairs of endpoints, for opening
// and closing the port. A closed port will have a populated CloseTimestamp
endpoints8081 := make([]types.EndpointInfo, 0)
endpoints9091 := make([]types.EndpointInfo, 0)
for _, endpoint := range endpoints {
if endpoint.Address.Port == 8081 {
endpoints8081 = append(endpoints8081, endpoint)
} else {
endpoints9091 = append(endpoints9091, endpoint)
}
// other ports cannot exist at this point due to previous assertions
}
// This helper simplifies the assertions a fair bit, by checking that
// the recorded endpoints have an open event (CloseTimestamp == nil) and
// a close event (CloseTimestamp != nil) and not two close events or two open
// events.
//
// It is also agnostic to the order in which the events are reported.
hasOpenAndClose := func(infos []types.EndpointInfo) bool {
if !assert.Len(s.T(), infos, 2) {
return false
}
return infos[0].CloseTimestamp != infos[1].CloseTimestamp &&
(infos[0].CloseTimestamp == types.NilTimestamp || infos[1].CloseTimestamp == types.NilTimestamp)
}
assert.True(s.T(), hasOpenAndClose(endpoints8081), "Did not capture open and close events for port 8081")
assert.True(s.T(), hasOpenAndClose(endpoints9091), "Did not capture open and close events for port 9091")
}
func getProcessListeningOnPortsImage() string {
return config.Images().QaImageByKey("qa-plop")
}