gitee.com/leisunstar/runtime@v0.0.0-20200521203717-5cef3e7b53f9/virtcontainers/kata_agent_test.go (about)

     1  // Copyright (c) 2018 Intel Corporation
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  
     6  package virtcontainers
     7  
     8  import (
     9  	"bufio"
    10  	"context"
    11  	"fmt"
    12  	"io/ioutil"
    13  	"net"
    14  	"os"
    15  	"path"
    16  	"path/filepath"
    17  	"reflect"
    18  	"strings"
    19  	"syscall"
    20  	"testing"
    21  
    22  	vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
    23  
    24  	gpb "github.com/gogo/protobuf/types"
    25  	specs "github.com/opencontainers/runtime-spec/specs-go"
    26  	"github.com/stretchr/testify/assert"
    27  	"google.golang.org/grpc"
    28  
    29  	aTypes "github.com/kata-containers/agent/pkg/types"
    30  	pb "github.com/kata-containers/agent/protocols/grpc"
    31  	"github.com/kata-containers/runtime/virtcontainers/device/api"
    32  	"github.com/kata-containers/runtime/virtcontainers/device/config"
    33  	"github.com/kata-containers/runtime/virtcontainers/device/drivers"
    34  	"github.com/kata-containers/runtime/virtcontainers/device/manager"
    35  	"github.com/kata-containers/runtime/virtcontainers/persist"
    36  	"github.com/kata-containers/runtime/virtcontainers/pkg/mock"
    37  	"github.com/kata-containers/runtime/virtcontainers/pkg/rootless"
    38  	vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
    39  	"github.com/kata-containers/runtime/virtcontainers/types"
    40  )
    41  
    42  var (
    43  	testKataProxyURLTempl  = "unix://%s/kata-proxy-test.sock"
    44  	testBlockDeviceCtrPath = "testBlockDeviceCtrPath"
    45  	testPCIAddr            = "04/02"
    46  )
    47  
    48  func proxyHandlerDiscard(c net.Conn) {
    49  	buf := make([]byte, 1024)
    50  	c.Read(buf)
    51  }
    52  
    53  func testGenerateKataProxySockDir() (string, error) {
    54  	dir, err := ioutil.TempDir("", "kata-proxy-test")
    55  	if err != nil {
    56  		return "", err
    57  	}
    58  
    59  	return dir, nil
    60  }
    61  
    62  func TestKataAgentConnect(t *testing.T) {
    63  	assert := assert.New(t)
    64  	proxy := mock.ProxyUnixMock{
    65  		ClientHandler: proxyHandlerDiscard,
    66  	}
    67  
    68  	sockDir, err := testGenerateKataProxySockDir()
    69  	assert.NoError(err)
    70  	defer os.RemoveAll(sockDir)
    71  
    72  	testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
    73  	err = proxy.Start(testKataProxyURL)
    74  	assert.NoError(err)
    75  	defer proxy.Stop()
    76  
    77  	k := &kataAgent{
    78  		ctx: context.Background(),
    79  		state: KataAgentState{
    80  			URL: testKataProxyURL,
    81  		},
    82  	}
    83  
    84  	err = k.connect()
    85  	assert.NoError(err)
    86  	assert.NotNil(k.client)
    87  }
    88  
    89  func TestKataAgentDisconnect(t *testing.T) {
    90  	assert := assert.New(t)
    91  	proxy := mock.ProxyUnixMock{
    92  		ClientHandler: proxyHandlerDiscard,
    93  	}
    94  
    95  	sockDir, err := testGenerateKataProxySockDir()
    96  	assert.NoError(err)
    97  	defer os.RemoveAll(sockDir)
    98  
    99  	testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
   100  	err = proxy.Start(testKataProxyURL)
   101  	assert.NoError(err)
   102  	defer proxy.Stop()
   103  
   104  	k := &kataAgent{
   105  		ctx: context.Background(),
   106  		state: KataAgentState{
   107  			URL: testKataProxyURL,
   108  		},
   109  	}
   110  
   111  	assert.NoError(k.connect())
   112  	assert.NoError(k.disconnect())
   113  	assert.Nil(k.client)
   114  }
   115  
   116  type gRPCProxy struct{}
   117  
   118  var emptyResp = &gpb.Empty{}
   119  
   120  func (p *gRPCProxy) CreateContainer(ctx context.Context, req *pb.CreateContainerRequest) (*gpb.Empty, error) {
   121  	return emptyResp, nil
   122  }
   123  
   124  func (p *gRPCProxy) StartContainer(ctx context.Context, req *pb.StartContainerRequest) (*gpb.Empty, error) {
   125  	return emptyResp, nil
   126  }
   127  
   128  func (p *gRPCProxy) ExecProcess(ctx context.Context, req *pb.ExecProcessRequest) (*gpb.Empty, error) {
   129  	return emptyResp, nil
   130  }
   131  
   132  func (p *gRPCProxy) SignalProcess(ctx context.Context, req *pb.SignalProcessRequest) (*gpb.Empty, error) {
   133  	return emptyResp, nil
   134  }
   135  
   136  func (p *gRPCProxy) WaitProcess(ctx context.Context, req *pb.WaitProcessRequest) (*pb.WaitProcessResponse, error) {
   137  	return &pb.WaitProcessResponse{}, nil
   138  }
   139  
   140  func (p *gRPCProxy) ListProcesses(ctx context.Context, req *pb.ListProcessesRequest) (*pb.ListProcessesResponse, error) {
   141  	return &pb.ListProcessesResponse{}, nil
   142  }
   143  
   144  func (p *gRPCProxy) UpdateContainer(ctx context.Context, req *pb.UpdateContainerRequest) (*gpb.Empty, error) {
   145  	return emptyResp, nil
   146  }
   147  
   148  func (p *gRPCProxy) RemoveContainer(ctx context.Context, req *pb.RemoveContainerRequest) (*gpb.Empty, error) {
   149  	return emptyResp, nil
   150  }
   151  
   152  func (p *gRPCProxy) WriteStdin(ctx context.Context, req *pb.WriteStreamRequest) (*pb.WriteStreamResponse, error) {
   153  	return &pb.WriteStreamResponse{}, nil
   154  }
   155  
   156  func (p *gRPCProxy) ReadStdout(ctx context.Context, req *pb.ReadStreamRequest) (*pb.ReadStreamResponse, error) {
   157  	return &pb.ReadStreamResponse{}, nil
   158  }
   159  
   160  func (p *gRPCProxy) ReadStderr(ctx context.Context, req *pb.ReadStreamRequest) (*pb.ReadStreamResponse, error) {
   161  	return &pb.ReadStreamResponse{}, nil
   162  }
   163  
   164  func (p *gRPCProxy) CloseStdin(ctx context.Context, req *pb.CloseStdinRequest) (*gpb.Empty, error) {
   165  	return emptyResp, nil
   166  }
   167  
   168  func (p *gRPCProxy) TtyWinResize(ctx context.Context, req *pb.TtyWinResizeRequest) (*gpb.Empty, error) {
   169  	return emptyResp, nil
   170  }
   171  
   172  func (p *gRPCProxy) CreateSandbox(ctx context.Context, req *pb.CreateSandboxRequest) (*gpb.Empty, error) {
   173  	return emptyResp, nil
   174  }
   175  
   176  func (p *gRPCProxy) DestroySandbox(ctx context.Context, req *pb.DestroySandboxRequest) (*gpb.Empty, error) {
   177  	return emptyResp, nil
   178  }
   179  
   180  func (p *gRPCProxy) UpdateInterface(ctx context.Context, req *pb.UpdateInterfaceRequest) (*aTypes.Interface, error) {
   181  	return &aTypes.Interface{}, nil
   182  }
   183  
   184  func (p *gRPCProxy) UpdateRoutes(ctx context.Context, req *pb.UpdateRoutesRequest) (*pb.Routes, error) {
   185  	return &pb.Routes{}, nil
   186  }
   187  
   188  func (p *gRPCProxy) ListInterfaces(ctx context.Context, req *pb.ListInterfacesRequest) (*pb.Interfaces, error) {
   189  	return &pb.Interfaces{}, nil
   190  }
   191  
   192  func (p *gRPCProxy) ListRoutes(ctx context.Context, req *pb.ListRoutesRequest) (*pb.Routes, error) {
   193  	return &pb.Routes{}, nil
   194  }
   195  
   196  func (p *gRPCProxy) OnlineCPUMem(ctx context.Context, req *pb.OnlineCPUMemRequest) (*gpb.Empty, error) {
   197  	return emptyResp, nil
   198  }
   199  
   200  func (p *gRPCProxy) StatsContainer(ctx context.Context, req *pb.StatsContainerRequest) (*pb.StatsContainerResponse, error) {
   201  	return &pb.StatsContainerResponse{}, nil
   202  }
   203  
   204  func (p *gRPCProxy) Check(ctx context.Context, req *pb.CheckRequest) (*pb.HealthCheckResponse, error) {
   205  	return &pb.HealthCheckResponse{}, nil
   206  }
   207  
   208  func (p *gRPCProxy) Version(ctx context.Context, req *pb.CheckRequest) (*pb.VersionCheckResponse, error) {
   209  	return &pb.VersionCheckResponse{}, nil
   210  
   211  }
   212  
   213  func (p *gRPCProxy) PauseContainer(ctx context.Context, req *pb.PauseContainerRequest) (*gpb.Empty, error) {
   214  	return emptyResp, nil
   215  }
   216  
   217  func (p *gRPCProxy) ResumeContainer(ctx context.Context, req *pb.ResumeContainerRequest) (*gpb.Empty, error) {
   218  	return emptyResp, nil
   219  }
   220  
   221  func (p *gRPCProxy) ReseedRandomDev(ctx context.Context, req *pb.ReseedRandomDevRequest) (*gpb.Empty, error) {
   222  	return emptyResp, nil
   223  }
   224  
   225  func (p *gRPCProxy) GetGuestDetails(ctx context.Context, req *pb.GuestDetailsRequest) (*pb.GuestDetailsResponse, error) {
   226  	return &pb.GuestDetailsResponse{}, nil
   227  }
   228  
   229  func (p *gRPCProxy) SetGuestDateTime(ctx context.Context, req *pb.SetGuestDateTimeRequest) (*gpb.Empty, error) {
   230  	return &gpb.Empty{}, nil
   231  }
   232  
   233  func (p *gRPCProxy) CopyFile(ctx context.Context, req *pb.CopyFileRequest) (*gpb.Empty, error) {
   234  	return &gpb.Empty{}, nil
   235  }
   236  
   237  func (p *gRPCProxy) StartTracing(ctx context.Context, req *pb.StartTracingRequest) (*gpb.Empty, error) {
   238  	return &gpb.Empty{}, nil
   239  }
   240  
   241  func (p *gRPCProxy) StopTracing(ctx context.Context, req *pb.StopTracingRequest) (*gpb.Empty, error) {
   242  	return &gpb.Empty{}, nil
   243  }
   244  
   245  func (p *gRPCProxy) MemHotplugByProbe(ctx context.Context, req *pb.MemHotplugByProbeRequest) (*gpb.Empty, error) {
   246  	return &gpb.Empty{}, nil
   247  }
   248  
   249  func (p *gRPCProxy) GetOOMEvent(ctx context.Context, req *pb.GetOOMEventRequest) (*pb.OOMEvent, error) {
   250  	return &pb.OOMEvent{}, nil
   251  }
   252  
   253  func gRPCRegister(s *grpc.Server, srv interface{}) {
   254  	switch g := srv.(type) {
   255  	case *gRPCProxy:
   256  		pb.RegisterAgentServiceServer(s, g)
   257  		pb.RegisterHealthServer(s, g)
   258  	}
   259  }
   260  
   261  var reqList = []interface{}{
   262  	&pb.CreateSandboxRequest{},
   263  	&pb.DestroySandboxRequest{},
   264  	&pb.ExecProcessRequest{},
   265  	&pb.CreateContainerRequest{},
   266  	&pb.StartContainerRequest{},
   267  	&pb.RemoveContainerRequest{},
   268  	&pb.SignalProcessRequest{},
   269  	&pb.CheckRequest{},
   270  	&pb.WaitProcessRequest{},
   271  	&pb.StatsContainerRequest{},
   272  	&pb.SetGuestDateTimeRequest{},
   273  }
   274  
   275  func TestKataAgentSendReq(t *testing.T) {
   276  	assert := assert.New(t)
   277  
   278  	impl := &gRPCProxy{}
   279  
   280  	proxy := mock.ProxyGRPCMock{
   281  		GRPCImplementer: impl,
   282  		GRPCRegister:    gRPCRegister,
   283  	}
   284  
   285  	sockDir, err := testGenerateKataProxySockDir()
   286  	assert.Nil(err)
   287  	defer os.RemoveAll(sockDir)
   288  
   289  	testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
   290  	err = proxy.Start(testKataProxyURL)
   291  	assert.Nil(err)
   292  	defer proxy.Stop()
   293  
   294  	k := &kataAgent{
   295  		ctx: context.Background(),
   296  		state: KataAgentState{
   297  			URL: testKataProxyURL,
   298  		},
   299  	}
   300  
   301  	for _, req := range reqList {
   302  		_, err = k.sendReq(req)
   303  		assert.Nil(err)
   304  	}
   305  
   306  	sandbox := &Sandbox{}
   307  	container := &Container{}
   308  	execid := "processFooBar"
   309  
   310  	err = k.startContainer(sandbox, container)
   311  	assert.Nil(err)
   312  
   313  	err = k.signalProcess(container, execid, syscall.SIGKILL, true)
   314  	assert.Nil(err)
   315  
   316  	err = k.winsizeProcess(container, execid, 100, 200)
   317  	assert.Nil(err)
   318  
   319  	_, err = k.processListContainer(sandbox, Container{}, ProcessListOptions{})
   320  	assert.Nil(err)
   321  
   322  	err = k.updateContainer(sandbox, Container{}, specs.LinuxResources{})
   323  	assert.Nil(err)
   324  
   325  	err = k.pauseContainer(sandbox, Container{})
   326  	assert.Nil(err)
   327  
   328  	err = k.resumeContainer(sandbox, Container{})
   329  	assert.Nil(err)
   330  
   331  	err = k.onlineCPUMem(1, true)
   332  	assert.Nil(err)
   333  
   334  	_, err = k.statsContainer(sandbox, Container{})
   335  	assert.Nil(err)
   336  
   337  	err = k.check()
   338  	assert.Nil(err)
   339  
   340  	_, err = k.waitProcess(container, execid)
   341  	assert.Nil(err)
   342  
   343  	_, err = k.writeProcessStdin(container, execid, []byte{'c'})
   344  	assert.Nil(err)
   345  
   346  	err = k.closeProcessStdin(container, execid)
   347  	assert.Nil(err)
   348  
   349  	_, err = k.readProcessStdout(container, execid, []byte{})
   350  	assert.Nil(err)
   351  
   352  	_, err = k.readProcessStderr(container, execid, []byte{})
   353  	assert.Nil(err)
   354  
   355  	_, err = k.getOOMEvent()
   356  	assert.Nil(err)
   357  }
   358  
   359  func TestHandleEphemeralStorage(t *testing.T) {
   360  	k := kataAgent{}
   361  	var ociMounts []specs.Mount
   362  	mountSource := "/tmp/mountPoint"
   363  
   364  	mount := specs.Mount{
   365  		Type:   KataEphemeralDevType,
   366  		Source: mountSource,
   367  	}
   368  
   369  	ociMounts = append(ociMounts, mount)
   370  	epheStorages := k.handleEphemeralStorage(ociMounts)
   371  
   372  	epheMountPoint := epheStorages[0].GetMountPoint()
   373  	expected := filepath.Join(ephemeralPath(), filepath.Base(mountSource))
   374  	assert.Equal(t, epheMountPoint, expected,
   375  		"Ephemeral mount point didn't match: got %s, expecting %s", epheMountPoint, expected)
   376  }
   377  
   378  func TestHandleLocalStorage(t *testing.T) {
   379  	k := kataAgent{}
   380  	var ociMounts []specs.Mount
   381  	mountSource := "mountPoint"
   382  
   383  	mount := specs.Mount{
   384  		Type:   KataLocalDevType,
   385  		Source: mountSource,
   386  	}
   387  
   388  	sandboxID := "sandboxid"
   389  	rootfsSuffix := "rootfs"
   390  
   391  	ociMounts = append(ociMounts, mount)
   392  	localStorages := k.handleLocalStorage(ociMounts, sandboxID, rootfsSuffix)
   393  
   394  	assert.NotNil(t, localStorages)
   395  	assert.Equal(t, len(localStorages), 1)
   396  
   397  	localMountPoint := localStorages[0].GetMountPoint()
   398  	expected := filepath.Join(kataGuestSharedDir(), sandboxID, rootfsSuffix, KataLocalDevType, filepath.Base(mountSource))
   399  	assert.Equal(t, localMountPoint, expected)
   400  }
   401  
   402  func TestHandleBlockVolume(t *testing.T) {
   403  	k := kataAgent{}
   404  
   405  	c := &Container{
   406  		id: "100",
   407  	}
   408  	containers := map[string]*Container{}
   409  	containers[c.id] = c
   410  
   411  	// Create a VhostUserBlk device and a DeviceBlock device
   412  	vDevID := "MockVhostUserBlk"
   413  	bDevID := "MockDeviceBlock"
   414  	vDestination := "/VhostUserBlk/destination"
   415  	bDestination := "/DeviceBlock/destination"
   416  	vPCIAddr := "0001:01"
   417  	bPCIAddr := "0002:01"
   418  
   419  	vDev := drivers.NewVhostUserBlkDevice(&config.DeviceInfo{ID: vDevID})
   420  	bDev := drivers.NewBlockDevice(&config.DeviceInfo{ID: bDevID})
   421  
   422  	vDev.VhostUserDeviceAttrs = &config.VhostUserDeviceAttrs{PCIAddr: vPCIAddr}
   423  	bDev.BlockDrive = &config.BlockDrive{PCIAddr: bPCIAddr}
   424  
   425  	var devices []api.Device
   426  	devices = append(devices, vDev, bDev)
   427  
   428  	// Create a VhostUserBlk mount and a DeviceBlock mount
   429  	var mounts []Mount
   430  	vMount := Mount{
   431  		BlockDeviceID: vDevID,
   432  		Destination:   vDestination,
   433  	}
   434  	bMount := Mount{
   435  		BlockDeviceID: bDevID,
   436  		Destination:   bDestination,
   437  	}
   438  	mounts = append(mounts, vMount, bMount)
   439  
   440  	tmpDir := "/vhost/user/dir"
   441  	dm := manager.NewDeviceManager(manager.VirtioBlock, true, tmpDir, devices)
   442  
   443  	sConfig := SandboxConfig{}
   444  	sConfig.HypervisorConfig.BlockDeviceDriver = manager.VirtioBlock
   445  	sandbox := Sandbox{
   446  		id:         "100",
   447  		containers: containers,
   448  		hypervisor: &mockHypervisor{},
   449  		devManager: dm,
   450  		ctx:        context.Background(),
   451  		config:     &sConfig,
   452  	}
   453  	containers[c.id].sandbox = &sandbox
   454  	containers[c.id].mounts = mounts
   455  
   456  	volumeStorages, err := k.handleBlockVolumes(c)
   457  	assert.Nil(t, err, "Error while handling block volumes")
   458  
   459  	vStorage := &pb.Storage{
   460  		MountPoint: vDestination,
   461  		Fstype:     "bind",
   462  		Options:    []string{"bind"},
   463  		Driver:     kataBlkDevType,
   464  		Source:     vPCIAddr,
   465  	}
   466  	bStorage := &pb.Storage{
   467  		MountPoint: bDestination,
   468  		Fstype:     "bind",
   469  		Options:    []string{"bind"},
   470  		Driver:     kataBlkDevType,
   471  		Source:     bPCIAddr,
   472  	}
   473  
   474  	assert.Equal(t, vStorage, volumeStorages[0], "Error while handle VhostUserBlk type block volume")
   475  	assert.Equal(t, bStorage, volumeStorages[1], "Error while handle BlockDevice type block volume")
   476  }
   477  
   478  func TestAppendDevicesEmptyContainerDeviceList(t *testing.T) {
   479  	k := kataAgent{}
   480  
   481  	devList := []*pb.Device{}
   482  	expected := []*pb.Device{}
   483  	ctrDevices := []ContainerDevice{}
   484  
   485  	c := &Container{
   486  		sandbox: &Sandbox{
   487  			devManager: manager.NewDeviceManager("virtio-scsi", false, "", nil),
   488  		},
   489  		devices: ctrDevices,
   490  	}
   491  	updatedDevList := k.appendDevices(devList, c)
   492  	assert.True(t, reflect.DeepEqual(updatedDevList, expected),
   493  		"Device lists didn't match: got %+v, expecting %+v",
   494  		updatedDevList, expected)
   495  }
   496  
   497  func TestAppendDevices(t *testing.T) {
   498  	k := kataAgent{}
   499  
   500  	id := "test-append-block"
   501  	ctrDevices := []api.Device{
   502  		&drivers.BlockDevice{
   503  			GenericDevice: &drivers.GenericDevice{
   504  				ID: id,
   505  			},
   506  			BlockDrive: &config.BlockDrive{
   507  				PCIAddr: testPCIAddr,
   508  			},
   509  		},
   510  	}
   511  
   512  	sandboxConfig := &SandboxConfig{
   513  		HypervisorConfig: HypervisorConfig{
   514  			BlockDeviceDriver: config.VirtioBlock,
   515  		},
   516  	}
   517  
   518  	c := &Container{
   519  		sandbox: &Sandbox{
   520  			devManager: manager.NewDeviceManager("virtio-blk", false, "", ctrDevices),
   521  			config:     sandboxConfig,
   522  		},
   523  	}
   524  	c.devices = append(c.devices, ContainerDevice{
   525  		ID:            id,
   526  		ContainerPath: testBlockDeviceCtrPath,
   527  	})
   528  
   529  	devList := []*pb.Device{}
   530  	expected := []*pb.Device{
   531  		{
   532  			Type:          kataBlkDevType,
   533  			ContainerPath: testBlockDeviceCtrPath,
   534  			Id:            testPCIAddr,
   535  		},
   536  	}
   537  	updatedDevList := k.appendDevices(devList, c)
   538  	assert.True(t, reflect.DeepEqual(updatedDevList, expected),
   539  		"Device lists didn't match: got %+v, expecting %+v",
   540  		updatedDevList, expected)
   541  }
   542  
   543  func TestAppendVhostUserBlkDevices(t *testing.T) {
   544  	k := kataAgent{}
   545  
   546  	id := "test-append-vhost-user-blk"
   547  	ctrDevices := []api.Device{
   548  		&drivers.VhostUserBlkDevice{
   549  			GenericDevice: &drivers.GenericDevice{
   550  				ID: id,
   551  			},
   552  			VhostUserDeviceAttrs: &config.VhostUserDeviceAttrs{
   553  				Type:    config.VhostUserBlk,
   554  				PCIAddr: testPCIAddr,
   555  			},
   556  		},
   557  	}
   558  
   559  	sandboxConfig := &SandboxConfig{
   560  		HypervisorConfig: HypervisorConfig{
   561  			BlockDeviceDriver: config.VirtioBlock,
   562  		},
   563  	}
   564  
   565  	testVhostUserStorePath := "/test/vhost/user/store/path"
   566  	c := &Container{
   567  		sandbox: &Sandbox{
   568  			devManager: manager.NewDeviceManager("virtio-blk", true, testVhostUserStorePath, ctrDevices),
   569  			config:     sandboxConfig,
   570  		},
   571  	}
   572  	c.devices = append(c.devices, ContainerDevice{
   573  		ID:            id,
   574  		ContainerPath: testBlockDeviceCtrPath,
   575  	})
   576  
   577  	devList := []*pb.Device{}
   578  	expected := []*pb.Device{
   579  		{
   580  			Type:          kataBlkDevType,
   581  			ContainerPath: testBlockDeviceCtrPath,
   582  			Id:            testPCIAddr,
   583  		},
   584  	}
   585  	updatedDevList := k.appendDevices(devList, c)
   586  	assert.True(t, reflect.DeepEqual(updatedDevList, expected),
   587  		"Device lists didn't match: got %+v, expecting %+v",
   588  		updatedDevList, expected)
   589  }
   590  
   591  func TestConstraintGRPCSpec(t *testing.T) {
   592  	assert := assert.New(t)
   593  	expectedCgroupPath := "/foo/bar"
   594  
   595  	g := &pb.Spec{
   596  		Hooks: &pb.Hooks{},
   597  		Mounts: []pb.Mount{
   598  			{Destination: "/dev/shm"},
   599  		},
   600  		Linux: &pb.Linux{
   601  			Seccomp: &pb.LinuxSeccomp{},
   602  			Namespaces: []pb.LinuxNamespace{
   603  				{
   604  					Type: specs.NetworkNamespace,
   605  					Path: "/abc/123",
   606  				},
   607  				{
   608  					Type: specs.MountNamespace,
   609  					Path: "/abc/123",
   610  				},
   611  			},
   612  			Resources: &pb.LinuxResources{
   613  				Devices:        []pb.LinuxDeviceCgroup{},
   614  				Memory:         &pb.LinuxMemory{},
   615  				CPU:            &pb.LinuxCPU{},
   616  				Pids:           &pb.LinuxPids{},
   617  				BlockIO:        &pb.LinuxBlockIO{},
   618  				HugepageLimits: []pb.LinuxHugepageLimit{},
   619  				Network:        &pb.LinuxNetwork{},
   620  			},
   621  			CgroupsPath: "system.slice:foo:bar",
   622  			Devices: []pb.LinuxDevice{
   623  				{
   624  					Path: "/dev/vfio/1",
   625  					Type: "c",
   626  				},
   627  				{
   628  					Path: "/dev/vfio/2",
   629  					Type: "c",
   630  				},
   631  			},
   632  		},
   633  		Process: &pb.Process{
   634  			SelinuxLabel: "foo",
   635  		},
   636  	}
   637  
   638  	k := kataAgent{}
   639  	k.constraintGRPCSpec(g, true)
   640  
   641  	// check nil fields
   642  	assert.Nil(g.Hooks)
   643  	assert.NotNil(g.Linux.Seccomp)
   644  	assert.Nil(g.Linux.Resources.Devices)
   645  	assert.NotNil(g.Linux.Resources.Memory)
   646  	assert.Nil(g.Linux.Resources.Pids)
   647  	assert.Nil(g.Linux.Resources.BlockIO)
   648  	assert.Nil(g.Linux.Resources.HugepageLimits)
   649  	assert.Nil(g.Linux.Resources.Network)
   650  	assert.NotNil(g.Linux.Resources.CPU)
   651  	assert.Equal(g.Process.SelinuxLabel, "")
   652  
   653  	// check namespaces
   654  	assert.Len(g.Linux.Namespaces, 1)
   655  	assert.Empty(g.Linux.Namespaces[0].Path)
   656  
   657  	// check mounts
   658  	assert.Len(g.Mounts, 1)
   659  
   660  	// check cgroup path
   661  	assert.Equal(expectedCgroupPath, g.Linux.CgroupsPath)
   662  
   663  	// check Linux devices
   664  	assert.Empty(g.Linux.Devices)
   665  }
   666  
   667  func TestHandleShm(t *testing.T) {
   668  	assert := assert.New(t)
   669  	k := kataAgent{}
   670  	sandbox := &Sandbox{
   671  		shmSize: 8192,
   672  	}
   673  
   674  	var ociMounts []specs.Mount
   675  
   676  	mount := specs.Mount{
   677  		Type:        "bind",
   678  		Destination: "/dev/shm",
   679  	}
   680  
   681  	ociMounts = append(ociMounts, mount)
   682  	k.handleShm(ociMounts, sandbox)
   683  
   684  	assert.Len(ociMounts, 1)
   685  	assert.NotEmpty(ociMounts[0].Destination)
   686  	assert.Equal(ociMounts[0].Destination, "/dev/shm")
   687  	assert.Equal(ociMounts[0].Type, "bind")
   688  	assert.NotEmpty(ociMounts[0].Source, filepath.Join(kataGuestSharedDir(), shmDir))
   689  	assert.Equal(ociMounts[0].Options, []string{"rbind"})
   690  
   691  	sandbox.shmSize = 0
   692  	k.handleShm(ociMounts, sandbox)
   693  
   694  	assert.Len(ociMounts, 1)
   695  	assert.Equal(ociMounts[0].Destination, "/dev/shm")
   696  	assert.Equal(ociMounts[0].Type, "tmpfs")
   697  	assert.Equal(ociMounts[0].Source, "shm")
   698  	sizeOption := fmt.Sprintf("size=%d", DefaultShmSize)
   699  	assert.Equal(ociMounts[0].Options, []string{"noexec", "nosuid", "nodev", "mode=1777", sizeOption})
   700  
   701  	// In case the type of mount is ephemeral, the container mount is not
   702  	// shared with the sandbox shm.
   703  	ociMounts[0].Type = KataEphemeralDevType
   704  	mountSource := "/tmp/mountPoint"
   705  	ociMounts[0].Source = mountSource
   706  	k.handleShm(ociMounts, sandbox)
   707  
   708  	assert.Len(ociMounts, 1)
   709  	assert.Equal(ociMounts[0].Type, KataEphemeralDevType)
   710  	assert.NotEmpty(ociMounts[0].Source, mountSource)
   711  
   712  	epheStorages := k.handleEphemeralStorage(ociMounts)
   713  	epheMountPoint := epheStorages[0].GetMountPoint()
   714  	expected := filepath.Join(ephemeralPath(), filepath.Base(mountSource))
   715  	assert.Equal(epheMountPoint, expected,
   716  		"Ephemeral mount point didn't match: got %s, expecting %s", epheMountPoint, expected)
   717  
   718  }
   719  
   720  func testIsPidNamespacePresent(grpcSpec *pb.Spec) bool {
   721  	for _, ns := range grpcSpec.Linux.Namespaces {
   722  		if ns.Type == string(specs.PIDNamespace) {
   723  			return true
   724  		}
   725  	}
   726  
   727  	return false
   728  }
   729  
   730  func TestHandlePidNamespace(t *testing.T) {
   731  	assert := assert.New(t)
   732  
   733  	g := &pb.Spec{
   734  		Linux: &pb.Linux{
   735  			Namespaces: []pb.LinuxNamespace{
   736  				{
   737  					Type: specs.NetworkNamespace,
   738  					Path: "/abc/123",
   739  				},
   740  				{
   741  					Type: specs.MountNamespace,
   742  					Path: "/abc/123",
   743  				},
   744  			},
   745  		},
   746  	}
   747  
   748  	sandbox := &Sandbox{}
   749  
   750  	k := kataAgent{}
   751  
   752  	sharedPid := k.handlePidNamespace(g, sandbox)
   753  	assert.False(sharedPid)
   754  	assert.False(testIsPidNamespacePresent(g))
   755  
   756  	pidNs := pb.LinuxNamespace{
   757  		Type: string(specs.PIDNamespace),
   758  		Path: "",
   759  	}
   760  
   761  	utsNs := pb.LinuxNamespace{
   762  		Type: specs.UTSNamespace,
   763  		Path: "",
   764  	}
   765  
   766  	g.Linux.Namespaces = append(g.Linux.Namespaces, pidNs)
   767  	g.Linux.Namespaces = append(g.Linux.Namespaces, utsNs)
   768  
   769  	sharedPid = k.handlePidNamespace(g, sandbox)
   770  	assert.False(sharedPid)
   771  	assert.False(testIsPidNamespacePresent(g))
   772  
   773  	pidNs = pb.LinuxNamespace{
   774  		Type: string(specs.PIDNamespace),
   775  		Path: "/proc/112/ns/pid",
   776  	}
   777  	g.Linux.Namespaces = append(g.Linux.Namespaces, pidNs)
   778  
   779  	sharedPid = k.handlePidNamespace(g, sandbox)
   780  	assert.True(sharedPid)
   781  	assert.False(testIsPidNamespacePresent(g))
   782  }
   783  
   784  func TestAgentPathAPI(t *testing.T) {
   785  	assert := assert.New(t)
   786  
   787  	k1 := &kataAgent{}
   788  	k2 := &kataAgent{}
   789  	id := "foobar"
   790  
   791  	// getSharePath
   792  	path1 := k1.getSharePath(id)
   793  	path2 := k2.getSharePath(id)
   794  	assert.Equal(path1, path2)
   795  }
   796  
   797  func TestAgentConfigure(t *testing.T) {
   798  	assert := assert.New(t)
   799  
   800  	dir, err := ioutil.TempDir("", "kata-agent-test")
   801  	assert.Nil(err)
   802  	defer os.RemoveAll(dir)
   803  
   804  	k := &kataAgent{}
   805  	h := &mockHypervisor{}
   806  	c := KataAgentConfig{}
   807  	id := "foobar"
   808  
   809  	err = k.configure(h, id, dir, true, c)
   810  	assert.Nil(err)
   811  
   812  	err = k.configure(h, id, dir, true, c)
   813  	assert.Nil(err)
   814  	assert.Empty(k.state.URL)
   815  
   816  	err = k.configure(h, id, dir, false, c)
   817  	assert.Nil(err)
   818  }
   819  
   820  func TestCmdToKataProcess(t *testing.T) {
   821  	assert := assert.New(t)
   822  
   823  	cmd := types.Cmd{
   824  		Args:         strings.Split("foo", " "),
   825  		Envs:         []types.EnvVar{},
   826  		WorkDir:      "/",
   827  		User:         "1000",
   828  		PrimaryGroup: "1000",
   829  	}
   830  	_, err := cmdToKataProcess(cmd)
   831  	assert.Nil(err)
   832  
   833  	cmd1 := cmd
   834  	cmd1.User = "foobar"
   835  	_, err = cmdToKataProcess(cmd1)
   836  	assert.Error(err)
   837  
   838  	cmd1 = cmd
   839  	cmd1.PrimaryGroup = "foobar"
   840  	_, err = cmdToKataProcess(cmd1)
   841  	assert.Error(err)
   842  
   843  	cmd1 = cmd
   844  	cmd1.User = "foobar:1000"
   845  	_, err = cmdToKataProcess(cmd1)
   846  	assert.Error(err)
   847  
   848  	cmd1 = cmd
   849  	cmd1.User = "1000:2000"
   850  	_, err = cmdToKataProcess(cmd1)
   851  	assert.Nil(err)
   852  
   853  	cmd1 = cmd
   854  	cmd1.SupplementaryGroups = []string{"foo"}
   855  	_, err = cmdToKataProcess(cmd1)
   856  	assert.Error(err)
   857  
   858  	cmd1 = cmd
   859  	cmd1.SupplementaryGroups = []string{"4000"}
   860  	_, err = cmdToKataProcess(cmd1)
   861  	assert.Nil(err)
   862  }
   863  
   864  func TestAgentCreateContainer(t *testing.T) {
   865  	assert := assert.New(t)
   866  
   867  	sandbox := &Sandbox{
   868  		ctx: context.Background(),
   869  		id:  "foobar",
   870  		config: &SandboxConfig{
   871  			ID:             "foobar",
   872  			HypervisorType: MockHypervisor,
   873  			HypervisorConfig: HypervisorConfig{
   874  				KernelPath: "foo",
   875  				ImagePath:  "bar",
   876  			},
   877  		},
   878  		hypervisor: &mockHypervisor{},
   879  	}
   880  
   881  	newStore, err := persist.GetDriver()
   882  	assert.NoError(err)
   883  	assert.NotNil(newStore)
   884  	sandbox.newStore = newStore
   885  
   886  	container := &Container{
   887  		ctx:       sandbox.ctx,
   888  		id:        "barfoo",
   889  		sandboxID: "foobar",
   890  		sandbox:   sandbox,
   891  		state: types.ContainerState{
   892  			Fstype: "xfs",
   893  		},
   894  		config: &ContainerConfig{
   895  			CustomSpec:  &specs.Spec{},
   896  			Annotations: map[string]string{},
   897  		},
   898  	}
   899  
   900  	impl := &gRPCProxy{}
   901  
   902  	proxy := mock.ProxyGRPCMock{
   903  		GRPCImplementer: impl,
   904  		GRPCRegister:    gRPCRegister,
   905  	}
   906  
   907  	sockDir, err := testGenerateKataProxySockDir()
   908  	assert.Nil(err)
   909  	defer os.RemoveAll(sockDir)
   910  
   911  	testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
   912  	err = proxy.Start(testKataProxyURL)
   913  	assert.Nil(err)
   914  	defer proxy.Stop()
   915  
   916  	k := &kataAgent{
   917  		ctx: context.Background(),
   918  		state: KataAgentState{
   919  			URL: testKataProxyURL,
   920  		},
   921  	}
   922  
   923  	dir, err := ioutil.TempDir("", "kata-agent-test")
   924  	assert.Nil(err)
   925  	defer os.RemoveAll(dir)
   926  
   927  	err = k.configure(&mockHypervisor{}, sandbox.id, dir, true, KataAgentConfig{})
   928  	assert.Nil(err)
   929  
   930  	// We'll fail on container metadata file creation, but it helps increasing coverage...
   931  	_, err = k.createContainer(sandbox, container)
   932  	assert.Error(err)
   933  }
   934  
   935  func TestAgentNetworkOperation(t *testing.T) {
   936  	assert := assert.New(t)
   937  
   938  	impl := &gRPCProxy{}
   939  
   940  	proxy := mock.ProxyGRPCMock{
   941  		GRPCImplementer: impl,
   942  		GRPCRegister:    gRPCRegister,
   943  	}
   944  
   945  	sockDir, err := testGenerateKataProxySockDir()
   946  	assert.NoError(err)
   947  	defer os.RemoveAll(sockDir)
   948  
   949  	testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
   950  	assert.NoError(proxy.Start(testKataProxyURL))
   951  	defer proxy.Stop()
   952  
   953  	k := &kataAgent{
   954  		ctx: context.Background(),
   955  		state: KataAgentState{
   956  			URL: testKataProxyURL,
   957  		},
   958  	}
   959  
   960  	_, err = k.updateInterface(nil)
   961  	assert.Nil(err)
   962  
   963  	_, err = k.listInterfaces()
   964  	assert.Nil(err)
   965  
   966  	_, err = k.updateRoutes([]*vcTypes.Route{})
   967  	assert.Nil(err)
   968  
   969  	_, err = k.listRoutes()
   970  	assert.Nil(err)
   971  }
   972  
   973  func TestKataAgentSetProxy(t *testing.T) {
   974  	assert := assert.New(t)
   975  
   976  	k := &kataAgent{ctx: context.Background()}
   977  	p := &kataBuiltInProxy{}
   978  	s := &Sandbox{
   979  		ctx: context.Background(),
   980  		id:  "foobar",
   981  	}
   982  
   983  	err := k.setProxy(s, p, 0, "")
   984  	assert.Error(err)
   985  }
   986  
   987  func TestKataGetAgentUrl(t *testing.T) {
   988  	assert := assert.New(t)
   989  	var err error
   990  
   991  	k := &kataAgent{vmSocket: types.Socket{HostPath: "/abc"}}
   992  	assert.NoError(err)
   993  	url, err := k.getAgentURL()
   994  	assert.Nil(err)
   995  	assert.NotEmpty(url)
   996  
   997  	k.vmSocket = types.VSock{}
   998  	assert.NoError(err)
   999  	url, err = k.getAgentURL()
  1000  	assert.Nil(err)
  1001  	assert.NotEmpty(url)
  1002  }
  1003  
  1004  func TestKataCopyFile(t *testing.T) {
  1005  	assert := assert.New(t)
  1006  
  1007  	impl := &gRPCProxy{}
  1008  
  1009  	proxy := mock.ProxyGRPCMock{
  1010  		GRPCImplementer: impl,
  1011  		GRPCRegister:    gRPCRegister,
  1012  	}
  1013  
  1014  	sockDir, err := testGenerateKataProxySockDir()
  1015  	assert.NoError(err)
  1016  	defer os.RemoveAll(sockDir)
  1017  
  1018  	testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
  1019  	err = proxy.Start(testKataProxyURL)
  1020  	assert.NoError(err)
  1021  	defer proxy.Stop()
  1022  
  1023  	k := &kataAgent{
  1024  		ctx: context.Background(),
  1025  		state: KataAgentState{
  1026  			URL: testKataProxyURL,
  1027  		},
  1028  	}
  1029  
  1030  	err = k.copyFile("/abc/xyz/123", "/tmp")
  1031  	assert.Error(err)
  1032  
  1033  	src, err := ioutil.TempFile("", "src")
  1034  	assert.NoError(err)
  1035  	defer os.Remove(src.Name())
  1036  
  1037  	data := []byte("abcdefghi123456789")
  1038  	_, err = src.Write(data)
  1039  	assert.NoError(err)
  1040  	assert.NoError(src.Close())
  1041  
  1042  	dst, err := ioutil.TempFile("", "dst")
  1043  	assert.NoError(err)
  1044  	assert.NoError(dst.Close())
  1045  	defer os.Remove(dst.Name())
  1046  
  1047  	orgGrpcMaxDataSize := grpcMaxDataSize
  1048  	grpcMaxDataSize = 1
  1049  	defer func() {
  1050  		grpcMaxDataSize = orgGrpcMaxDataSize
  1051  	}()
  1052  
  1053  	err = k.copyFile(src.Name(), dst.Name())
  1054  	assert.NoError(err)
  1055  }
  1056  
  1057  func TestKataCleanupSandbox(t *testing.T) {
  1058  	assert := assert.New(t)
  1059  
  1060  	kataHostSharedDirSaved := kataHostSharedDir
  1061  	kataHostSharedDir = func() string {
  1062  		td, _ := ioutil.TempDir("", "kata-cleanup")
  1063  		return td
  1064  	}
  1065  	defer func() {
  1066  		kataHostSharedDir = kataHostSharedDirSaved
  1067  	}()
  1068  
  1069  	s := Sandbox{
  1070  		id: "testFoo",
  1071  	}
  1072  
  1073  	dir := kataHostSharedDir()
  1074  	defer os.RemoveAll(dir)
  1075  	err := os.MkdirAll(path.Join(dir, s.id), 0777)
  1076  	assert.Nil(err)
  1077  
  1078  	k := &kataAgent{ctx: context.Background()}
  1079  	k.cleanup(&s)
  1080  
  1081  	_, err = os.Stat(dir)
  1082  	assert.False(os.IsExist(err))
  1083  }
  1084  
  1085  func TestKataAgentKernelParams(t *testing.T) {
  1086  	assert := assert.New(t)
  1087  
  1088  	type testData struct {
  1089  		debug             bool
  1090  		trace             bool
  1091  		containerPipeSize uint32
  1092  		traceMode         string
  1093  		traceType         string
  1094  		expectedParams    []Param
  1095  	}
  1096  
  1097  	debugParam := Param{Key: "agent.log", Value: "debug"}
  1098  
  1099  	traceIsolatedParam := Param{Key: "agent.trace", Value: "isolated"}
  1100  	traceCollatedParam := Param{Key: "agent.trace", Value: "collated"}
  1101  
  1102  	traceFooParam := Param{Key: "agent.trace", Value: "foo"}
  1103  
  1104  	containerPipeSizeParam := Param{Key: vcAnnotations.ContainerPipeSizeKernelParam, Value: "2097152"}
  1105  
  1106  	data := []testData{
  1107  		{false, false, 0, "", "", []Param{}},
  1108  		{true, false, 0, "", "", []Param{debugParam}},
  1109  
  1110  		{false, false, 0, "foo", "", []Param{}},
  1111  		{false, false, 0, "foo", "", []Param{}},
  1112  		{false, false, 0, "", "foo", []Param{}},
  1113  		{false, false, 0, "", "foo", []Param{}},
  1114  		{false, false, 0, "foo", "foo", []Param{}},
  1115  		{false, true, 0, "foo", "foo", []Param{}},
  1116  
  1117  		{false, false, 0, agentTraceModeDynamic, "", []Param{}},
  1118  		{false, false, 0, agentTraceModeStatic, "", []Param{}},
  1119  		{false, false, 0, "", agentTraceTypeIsolated, []Param{}},
  1120  		{false, false, 0, "", agentTraceTypeCollated, []Param{}},
  1121  		{false, false, 0, "foo", agentTraceTypeIsolated, []Param{}},
  1122  		{false, false, 0, "foo", agentTraceTypeCollated, []Param{}},
  1123  
  1124  		{false, false, 0, agentTraceModeDynamic, agentTraceTypeIsolated, []Param{}},
  1125  		{false, false, 0, agentTraceModeDynamic, agentTraceTypeCollated, []Param{}},
  1126  
  1127  		{false, false, 0, agentTraceModeStatic, agentTraceTypeCollated, []Param{}},
  1128  		{false, false, 0, agentTraceModeStatic, agentTraceTypeCollated, []Param{}},
  1129  
  1130  		{false, true, 0, agentTraceModeDynamic, agentTraceTypeIsolated, []Param{}},
  1131  		{false, true, 0, agentTraceModeDynamic, agentTraceTypeCollated, []Param{}},
  1132  		{true, true, 0, agentTraceModeDynamic, agentTraceTypeCollated, []Param{debugParam}},
  1133  
  1134  		{false, true, 0, "", agentTraceTypeIsolated, []Param{}},
  1135  		{false, true, 0, "", agentTraceTypeCollated, []Param{}},
  1136  		{true, true, 0, "", agentTraceTypeIsolated, []Param{debugParam}},
  1137  		{true, true, 0, "", agentTraceTypeCollated, []Param{debugParam}},
  1138  		{false, true, 0, "foo", agentTraceTypeIsolated, []Param{}},
  1139  		{false, true, 0, "foo", agentTraceTypeCollated, []Param{}},
  1140  		{true, true, 0, "foo", agentTraceTypeIsolated, []Param{debugParam}},
  1141  		{true, true, 0, "foo", agentTraceTypeCollated, []Param{debugParam}},
  1142  
  1143  		{false, true, 0, agentTraceModeStatic, agentTraceTypeIsolated, []Param{traceIsolatedParam}},
  1144  		{false, true, 0, agentTraceModeStatic, agentTraceTypeCollated, []Param{traceCollatedParam}},
  1145  		{true, true, 0, agentTraceModeStatic, agentTraceTypeIsolated, []Param{traceIsolatedParam, debugParam}},
  1146  		{true, true, 0, agentTraceModeStatic, agentTraceTypeCollated, []Param{traceCollatedParam, debugParam}},
  1147  
  1148  		{false, true, 0, agentTraceModeStatic, "foo", []Param{traceFooParam}},
  1149  		{true, true, 0, agentTraceModeStatic, "foo", []Param{debugParam, traceFooParam}},
  1150  
  1151  		{false, false, 0, "", "", []Param{}},
  1152  		{false, false, 2097152, "", "", []Param{containerPipeSizeParam}},
  1153  	}
  1154  
  1155  	for i, d := range data {
  1156  		config := KataAgentConfig{
  1157  			Debug:             d.debug,
  1158  			Trace:             d.trace,
  1159  			TraceMode:         d.traceMode,
  1160  			TraceType:         d.traceType,
  1161  			ContainerPipeSize: d.containerPipeSize,
  1162  		}
  1163  
  1164  		count := len(d.expectedParams)
  1165  
  1166  		params := KataAgentKernelParams(config)
  1167  
  1168  		if count == 0 {
  1169  			assert.Emptyf(params, "test %d (%+v)", i, d)
  1170  			continue
  1171  		}
  1172  
  1173  		assert.Len(params, count)
  1174  
  1175  		for _, p := range d.expectedParams {
  1176  			assert.Containsf(params, p, "test %d (%+v)", i, d)
  1177  		}
  1178  	}
  1179  }
  1180  
  1181  func TestKataAgentHandleTraceSettings(t *testing.T) {
  1182  	assert := assert.New(t)
  1183  
  1184  	type testData struct {
  1185  		traceMode               string
  1186  		trace                   bool
  1187  		expectDisableVMShutdown bool
  1188  		expectDynamicTracing    bool
  1189  	}
  1190  
  1191  	data := []testData{
  1192  		{"", false, false, false},
  1193  		{"", true, false, false},
  1194  		{agentTraceModeStatic, true, true, false},
  1195  		{agentTraceModeDynamic, true, false, true},
  1196  	}
  1197  
  1198  	for i, d := range data {
  1199  		k := &kataAgent{}
  1200  
  1201  		config := KataAgentConfig{
  1202  			Trace:     d.trace,
  1203  			TraceMode: d.traceMode,
  1204  		}
  1205  
  1206  		disableVMShutdown := k.handleTraceSettings(config)
  1207  
  1208  		if d.expectDisableVMShutdown {
  1209  			assert.Truef(disableVMShutdown, "test %d (%+v)", i, d)
  1210  		} else {
  1211  			assert.Falsef(disableVMShutdown, "test %d (%+v)", i, d)
  1212  		}
  1213  
  1214  		if d.expectDynamicTracing {
  1215  			assert.Truef(k.dynamicTracing, "test %d (%+v)", i, d)
  1216  		} else {
  1217  			assert.Falsef(k.dynamicTracing, "test %d (%+v)", i, d)
  1218  		}
  1219  	}
  1220  }
  1221  
  1222  func TestKataAgentSetDefaultTraceConfigOptions(t *testing.T) {
  1223  	assert := assert.New(t)
  1224  
  1225  	type testData struct {
  1226  		traceMode              string
  1227  		traceType              string
  1228  		trace                  bool
  1229  		expectDefaultTraceMode bool
  1230  		expectDefaultTraceType bool
  1231  		expectError            bool
  1232  	}
  1233  
  1234  	data := []testData{
  1235  		{"", "", false, false, false, false},
  1236  		{agentTraceModeDynamic, agentTraceTypeCollated, false, false, false, false},
  1237  		{agentTraceModeDynamic, agentTraceTypeIsolated, false, false, false, false},
  1238  		{agentTraceModeStatic, agentTraceTypeCollated, false, false, false, false},
  1239  		{agentTraceModeStatic, agentTraceTypeIsolated, false, false, false, false},
  1240  
  1241  		{agentTraceModeDynamic, agentTraceTypeCollated, true, false, false, false},
  1242  		{agentTraceModeDynamic, agentTraceTypeIsolated, true, false, false, false},
  1243  
  1244  		{agentTraceModeStatic, agentTraceTypeCollated, true, false, false, false},
  1245  		{agentTraceModeStatic, agentTraceTypeIsolated, true, false, false, false},
  1246  
  1247  		{agentTraceModeDynamic, "", true, false, true, false},
  1248  		{agentTraceModeDynamic, "invalid", true, false, false, true},
  1249  
  1250  		{agentTraceModeStatic, "", true, false, true, false},
  1251  		{agentTraceModeStatic, "invalid", true, false, false, true},
  1252  
  1253  		{"", agentTraceTypeIsolated, true, true, false, false},
  1254  		{"invalid", agentTraceTypeIsolated, true, false, false, true},
  1255  
  1256  		{"", agentTraceTypeCollated, true, true, false, false},
  1257  		{"invalid", agentTraceTypeCollated, true, false, false, true},
  1258  
  1259  		{"", "", true, true, true, false},
  1260  		{"invalid", "invalid", true, false, false, true},
  1261  	}
  1262  
  1263  	for i, d := range data {
  1264  		config := &KataAgentConfig{
  1265  			Trace:     d.trace,
  1266  			TraceMode: d.traceMode,
  1267  			TraceType: d.traceType,
  1268  		}
  1269  
  1270  		err := KataAgentSetDefaultTraceConfigOptions(config)
  1271  		if d.expectError {
  1272  			assert.Error(err, "test %d (%+v)", i, d)
  1273  			continue
  1274  		} else {
  1275  			assert.NoError(err, "test %d (%+v)", i, d)
  1276  		}
  1277  
  1278  		if d.expectDefaultTraceMode {
  1279  			assert.Equalf(config.TraceMode, defaultAgentTraceMode, "test %d (%+v)", i, d)
  1280  		}
  1281  
  1282  		if d.expectDefaultTraceType {
  1283  			assert.Equalf(config.TraceType, defaultAgentTraceType, "test %d (%+v)", i, d)
  1284  		}
  1285  	}
  1286  }
  1287  
  1288  func TestKataAgentDirs(t *testing.T) {
  1289  	assert := assert.New(t)
  1290  
  1291  	uidmapFile, err := os.OpenFile("/proc/self/uid_map", os.O_RDONLY, 0)
  1292  	assert.NoError(err)
  1293  
  1294  	line, err := bufio.NewReader(uidmapFile).ReadBytes('\n')
  1295  	assert.NoError(err)
  1296  
  1297  	uidmap := strings.Fields(string(line))
  1298  	expectedRootless := (uidmap[0] == "0" && uidmap[1] != "0")
  1299  	assert.Equal(expectedRootless, rootless.IsRootless())
  1300  
  1301  	if expectedRootless {
  1302  		assert.Equal(kataHostSharedDir(), os.Getenv("XDG_RUNTIME_DIR")+defaultKataHostSharedDir)
  1303  		assert.Equal(kataGuestSharedDir(), os.Getenv("XDG_RUNTIME_DIR")+defaultKataGuestSharedDir)
  1304  		assert.Equal(kataGuestSandboxDir(), os.Getenv("XDG_RUNTIME_DIR")+defaultKataGuestSandboxDir)
  1305  		assert.Equal(ephemeralPath(), os.Getenv("XDG_RUNTIME_DIR")+defaultEphemeralPath)
  1306  	} else {
  1307  		assert.Equal(kataHostSharedDir(), defaultKataHostSharedDir)
  1308  		assert.Equal(kataGuestSharedDir(), defaultKataGuestSharedDir)
  1309  		assert.Equal(kataGuestSandboxDir(), defaultKataGuestSandboxDir)
  1310  		assert.Equal(ephemeralPath(), defaultEphemeralPath)
  1311  	}
  1312  }