github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/internal/linux/processor_test.go (about) 1 // +build !windows 2 3 package linuxmonitor 4 5 import ( 6 "context" 7 "errors" 8 "io/ioutil" 9 "os" 10 "sync" 11 "testing" 12 13 "github.com/golang/mock/gomock" 14 . "github.com/smartystreets/goconvey/convey" 15 "go.aporeto.io/enforcerd/trireme-lib/collector" 16 "go.aporeto.io/enforcerd/trireme-lib/common" 17 "go.aporeto.io/enforcerd/trireme-lib/monitor/config" 18 "go.aporeto.io/enforcerd/trireme-lib/monitor/extractors" 19 "go.aporeto.io/enforcerd/trireme-lib/policy" 20 "go.aporeto.io/enforcerd/trireme-lib/policy/mockpolicy" 21 "go.aporeto.io/enforcerd/trireme-lib/utils/cgnetcls/mockcgnetcls" 22 ) 23 24 func testLinuxProcessor(puHandler policy.Resolver) *linuxProcessor { 25 l := New(context.Background()) 26 l.SetupHandlers(&config.ProcessorConfig{ 27 Collector: &collector.DefaultCollector{}, 28 Policy: puHandler, 29 ResyncLock: &sync.RWMutex{}, 30 }) 31 if err := l.SetupConfig(nil, &Config{ 32 EventMetadataExtractor: extractors.DefaultHostMetadataExtractor, 33 StoredPath: "/tmp", 34 ReleasePath: "./", 35 }); err != nil { 36 return nil 37 } 38 return l.proc 39 } 40 41 func TestCreate(t *testing.T) { 42 ctrl := gomock.NewController(t) 43 defer ctrl.Finish() 44 45 Convey("Given a valid processor", t, func() { 46 puHandler := mockpolicy.NewMockResolver(ctrl) 47 48 p := testLinuxProcessor(puHandler) 49 50 Convey("When I try a create event with invalid PU ID, ", func() { 51 event := &common.EventInfo{ 52 PUID: "/@#$@", 53 } 54 Convey("I should get an error", func() { 55 err := p.Create(context.Background(), event) 56 So(err, ShouldNotBeNil) 57 }) 58 }) 59 60 Convey("When I get a create event that is valid", func() { 61 event := &common.EventInfo{ 62 PUID: "1234", 63 } 64 Convey("I should get an error - create not supported", func() { 65 err := p.Create(context.Background(), event) 66 So(err, ShouldNotBeNil) 67 }) 68 }) 69 }) 70 } 71 72 func TestStop(t *testing.T) { 73 ctrl := gomock.NewController(t) 74 defer ctrl.Finish() 75 76 Convey("Given a valid processor", t, func() { 77 puHandler := mockpolicy.NewMockResolver(ctrl) 78 79 p := testLinuxProcessor(puHandler) 80 mockcls := mockcgnetcls.NewMockCgroupnetcls(ctrl) 81 p.netcls = mockcls 82 83 Convey("When I get a stop event that is valid", func() { 84 event := &common.EventInfo{ 85 PUID: "/trireme/1234", 86 } 87 88 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 89 mockcls.EXPECT().ListCgroupProcesses("/trireme/1234") 90 91 Convey("I should get the status of the upstream function", func() { 92 err := p.Stop(context.Background(), event) 93 So(err, ShouldBeNil) 94 }) 95 }) 96 97 }) 98 } 99 100 // TODO: remove nolint 101 // nolint 102 func TestDestroy(t *testing.T) { 103 ctrl := gomock.NewController(t) 104 defer ctrl.Finish() 105 dummyPUPath := "/var/run/trireme/linux/1234" 106 ioutil.WriteFile(dummyPUPath, []byte{}, 0644) // nolint 107 108 defer os.RemoveAll(dummyPUPath) // nolint 109 Convey("Given a valid processor", t, func() { 110 puHandler := mockpolicy.NewMockResolver(ctrl) 111 112 p := testLinuxProcessor(puHandler) 113 mockcls := mockcgnetcls.NewMockCgroupnetcls(ctrl) 114 p.netcls = mockcls 115 116 Convey("When I get a destroy event that is valid", func() { 117 event := &common.EventInfo{ 118 PUID: "1234", 119 } 120 mockcls.EXPECT().DeleteCgroup(gomock.Any()).Return(nil) 121 122 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 123 Convey("I should get the status of the upstream function", func() { 124 err := p.Destroy(context.Background(), event) 125 So(err, ShouldBeNil) 126 }) 127 }) 128 129 Convey("When I get a destroy event that is valid for hostpu", func() { 130 event := &common.EventInfo{ 131 PUID: "123", 132 HostService: true, 133 NetworkOnlyTraffic: true, 134 } 135 136 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 137 Convey("I should get the status of the upstream function", func() { 138 err := p.Destroy(context.Background(), event) 139 So(err, ShouldBeNil) 140 }) 141 }) 142 }) 143 } 144 145 func TestPause(t *testing.T) { 146 ctrl := gomock.NewController(t) 147 defer ctrl.Finish() 148 149 Convey("Given a valid processor", t, func() { 150 puHandler := mockpolicy.NewMockResolver(ctrl) 151 152 p := testLinuxProcessor(puHandler) 153 154 Convey("When I get a pause event that is valid", func() { 155 event := &common.EventInfo{ 156 PUID: "/trireme/1234", 157 } 158 159 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 160 Convey("I should get the status of the upstream function", func() { 161 err := p.Pause(context.Background(), event) 162 So(err, ShouldBeNil) 163 }) 164 }) 165 }) 166 } 167 168 func TestStart(t *testing.T) { 169 ctrl := gomock.NewController(t) 170 defer ctrl.Finish() 171 172 Convey("Given a valid processor", t, func() { 173 puHandler := mockpolicy.NewMockResolver(ctrl) 174 p := testLinuxProcessor(puHandler) 175 176 Convey("When I get a start event with no PUID", func() { 177 event := &common.EventInfo{ 178 PUID: "", 179 } 180 Convey("I should get an error", func() { 181 err := p.Start(context.Background(), event) 182 So(err, ShouldNotBeNil) 183 }) 184 }) 185 186 Convey("When I get a start event that is valid that fails on the generation of PU ID", func() { 187 event := &common.EventInfo{ 188 Name: "^^^", 189 } 190 Convey("I should get an error", func() { 191 err := p.Start(context.Background(), event) 192 So(err, ShouldNotBeNil) 193 }) 194 }) 195 196 Convey("When I get a start event that is valid that fails on the metadata extractor", func() { 197 event := &common.EventInfo{ 198 Name: "service", 199 Tags: []string{"badtag"}, 200 } 201 Convey("I should get an error", func() { 202 err := p.Start(context.Background(), event) 203 So(err, ShouldNotBeNil) 204 }) 205 }) 206 207 Convey("When I get a start event and the upstream returns an error ", func() { 208 event := &common.EventInfo{ 209 Name: "PU", 210 PID: 1, 211 PUID: "12345", 212 EventType: common.EventStart, 213 PUType: common.LinuxProcessPU, 214 } 215 Convey("I should get an error ", func() { 216 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error")) 217 err := p.Start(context.Background(), event) 218 So(err, ShouldNotBeNil) 219 }) 220 }) 221 222 Convey("When I get a start event and create group fails ", func() { 223 event := &common.EventInfo{ 224 Name: "PU", 225 PID: 1, 226 PUID: "12345", 227 EventType: common.EventStop, 228 PUType: common.LinuxProcessPU, 229 } 230 231 mockcls := mockcgnetcls.NewMockCgroupnetcls(ctrl) 232 p.netcls = mockcls 233 234 Convey("I should get an error ", func() { 235 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2).Return(nil) 236 mockcls.EXPECT().Creategroup(gomock.Any()).Return(errors.New("error")) 237 mockcls.EXPECT().ListCgroupProcesses("12345") 238 239 err := p.Start(context.Background(), event) 240 So(err, ShouldNotBeNil) 241 }) 242 }) 243 244 Convey("When I get a start event and the runtime options don't have a mark value", func() { 245 event := &common.EventInfo{ 246 Name: "PU", 247 PID: 1, 248 PUID: "12345", 249 EventType: common.EventStop, 250 PUType: common.LinuxProcessPU, 251 } 252 253 mockcls := mockcgnetcls.NewMockCgroupnetcls(ctrl) 254 p.netcls = mockcls 255 256 Convey("I should not get an error ", func() { 257 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2).Return(nil) 258 mockcls.EXPECT().Creategroup(gomock.Any()).Return(nil) 259 mockcls.EXPECT().AssignMark(gomock.Any(), gomock.Any()).Return(nil) 260 mockcls.EXPECT().AddProcess(gomock.Any(), gomock.Any()) 261 mockcls.EXPECT().ListCgroupProcesses("12345") 262 err := p.Start(context.Background(), event) 263 So(err, ShouldBeNil) 264 }) 265 }) 266 }) 267 } 268 269 func TestResync(t *testing.T) { 270 ctrl := gomock.NewController(t) 271 defer ctrl.Finish() 272 273 Convey("Given a valid processor", t, func() { 274 puHandler := mockpolicy.NewMockResolver(ctrl) 275 p := testLinuxProcessor(puHandler) 276 277 Convey("When I get a resync event ", func() { 278 event := &common.EventInfo{ 279 Name: "PU", 280 PID: 1, 281 PUID: "12345", 282 EventType: common.EventStart, 283 PUType: common.LinuxProcessPU, 284 } 285 286 mockcls := mockcgnetcls.NewMockCgroupnetcls(ctrl) 287 p.netcls = mockcls 288 289 Convey("I should not get an error ", func() { 290 mockcls.EXPECT().ListAllCgroups(gomock.Any()).Return([]string{"cgroup"}) 291 mockcls.EXPECT().ListCgroupProcesses(gomock.Any()).Return([]string{"procs"}, nil) 292 mockcls.EXPECT().Creategroup(gomock.Any()).Return(nil) 293 mockcls.EXPECT().AssignMark(gomock.Any(), gomock.Any()).Return(nil) 294 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 295 err := p.Resync(context.Background(), event) 296 So(err, ShouldBeNil) 297 }) 298 }) 299 300 Convey("When I get a resync event with no croup process", func() { 301 event := &common.EventInfo{ 302 Name: "PU", 303 PID: 1, 304 PUID: "12345", 305 EventType: common.EventStart, 306 PUType: common.LinuxProcessPU, 307 } 308 309 mockcls := mockcgnetcls.NewMockCgroupnetcls(ctrl) 310 p.netcls = mockcls 311 312 Convey("I should not get an error ", func() { 313 mockcls.EXPECT().ListAllCgroups(gomock.Any()).Return([]string{"cgroup"}) 314 mockcls.EXPECT().ListCgroupProcesses(gomock.Any()).Return([]string{}, nil) 315 mockcls.EXPECT().DeleteCgroup(gomock.Any()).Return(nil) 316 err := p.Resync(context.Background(), event) 317 So(err, ShouldBeNil) 318 }) 319 }) 320 321 Convey("When I get a resync event for hostservice", func() { 322 event := &common.EventInfo{ 323 Name: "PU", 324 PID: 1, 325 PUID: "12345", 326 EventType: common.EventStart, 327 HostService: true, 328 NetworkOnlyTraffic: true, 329 PUType: common.LinuxProcessPU, 330 } 331 332 Convey("I should not get an error ", func() { 333 puHandler.EXPECT().HandlePUEvent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) 334 err := p.Resync(context.Background(), event) 335 So(err, ShouldBeNil) 336 }) 337 }) 338 }) 339 }