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  }