github.com/cilium/cilium@v1.16.2/pkg/cgroups/manager/provider_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package manager
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"os"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/cilium/cilium/pkg/cgroups"
    15  	v1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/core/v1"
    16  )
    17  
    18  var (
    19  	fsMockDefault = fsMock{
    20  		getFullPath(defaultCgroupBasePath): struct{}{},
    21  	}
    22  	fsMockSystemd = fsMock{
    23  		getFullPath(systemdCgroupBasePath): struct{}{},
    24  	}
    25  	fsMockNested = fsMock{
    26  		getFullPath(nestedCgroupBasePath): struct{}{},
    27  	}
    28  	fsMockSystemdNested = fsMock{
    29  		getFullPath(nestedSystemdCgroupBasePath): struct{}{},
    30  	}
    31  	cgroupRoot             = cgroups.GetCgroupRoot()
    32  	cDefaultPath           = cgroupRoot + "/kubepods/burstable/pod1858680e-b044-4fd5-9dd4-f137e30e2180/" + c1Id
    33  	cDefaultGuaranteedPath = cgroupRoot + "/kubepods/pod1858680e-b044-4fd5-9dd4-f137e30e2180/" + c1Id
    34  	cSystemdPath           = cgroupRoot + "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod1858680e_b044_4fd5_9dd4_f137e30e2180.slice/" + "cri-containerd-" + c1Id + ".scope"
    35  	cSystemdGuaranteedPath = cgroupRoot + "/kubepods.slice/kubepods-pod1858680e_b044_4fd5_9dd4_f137e30e2180.slice/" + "crio-" + c1Id + ".scope"
    36  	cNestedPath            = cgroupRoot + "/kubelet/kubepods/burstable/pod1858680e-b044-4fd5-9dd4-f137e30e2180/" + c1Id
    37  	cSystemdNestedPath     = cgroupRoot + "/kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-burstable.slice/kubelet-kubepods-burstable-pod1858680e_b044_4fd5_9dd4_f137e30e2180.slice/" + "cri-containerd-" + c1Id + ".scope"
    38  )
    39  
    40  type fsMock map[string]struct{}
    41  
    42  func (fs fsMock) Stat(file string) (info os.FileInfo, err error) {
    43  	if _, ok := fs[file]; ok {
    44  		return nil, nil
    45  	}
    46  
    47  	return nil, errors.New("")
    48  }
    49  
    50  func TestGetBasePath(t *testing.T) {
    51  	type test struct {
    52  		input fs
    53  		want  string
    54  	}
    55  	tests := []test{
    56  		{input: fsMockDefault, want: getFullPath(defaultCgroupBasePath)},
    57  		{input: fsMockSystemd, want: getFullPath(systemdCgroupBasePath)},
    58  		{input: fsMockNested, want: getFullPath(nestedCgroupBasePath)},
    59  		{input: fsMockSystemdNested, want: getFullPath(nestedSystemdCgroupBasePath)},
    60  	}
    61  
    62  	for i, tt := range tests {
    63  		t.Run(fmt.Sprintf("Test index %d", i), func(t *testing.T) {
    64  			initProviderTest(tt.input)
    65  			got, err := getCgroupPathProvider()
    66  			require.NoError(t, err)
    67  			require.NotNil(t, got)
    68  			path, err := got.getBasePath()
    69  			require.NoError(t, err)
    70  			require.Equal(t, tt.want, path)
    71  		})
    72  
    73  	}
    74  }
    75  
    76  type inputParams struct {
    77  	provider    cgroupPathProvider
    78  	podId       string
    79  	containerId string
    80  	qos         v1.PodQOSClass
    81  	fsMock      fs
    82  }
    83  
    84  func getTestInput() *inputParams {
    85  	return &inputParams{
    86  		provider:    newDefaultProvider(),
    87  		podId:       string(pod1.ObjectMeta.UID),
    88  		containerId: c1Id,
    89  		qos:         pod1.Status.QOSClass,
    90  		fsMock: fsMock{
    91  			cgroupRoot + defaultCgroupBasePath: struct{}{},
    92  			cDefaultPath:                       struct{}{},
    93  		},
    94  	}
    95  }
    96  
    97  func TestGetContainerPath(t *testing.T) {
    98  	tests := []struct {
    99  		name    string
   100  		input   func(input *inputParams)
   101  		want    string
   102  		wantErr bool
   103  	}{
   104  		{
   105  			name: "default provider",
   106  			want: cDefaultPath,
   107  		},
   108  		{
   109  			name: "default provider + guaranteed qos pod",
   110  			input: func(input *inputParams) {
   111  				input.qos = v1.PodQOSGuaranteed
   112  				input.fsMock = fsMock{
   113  					cgroupRoot + defaultCgroupBasePath: struct{}{},
   114  					cDefaultGuaranteedPath:             struct{}{},
   115  				}
   116  			},
   117  			want: cDefaultGuaranteedPath,
   118  		},
   119  		{
   120  			name: "systemd provider",
   121  			input: func(input *inputParams) {
   122  				input.provider = newSystemdProvider()
   123  				input.fsMock = fsMock{
   124  					cgroupRoot + systemdCgroupBasePath: struct{}{},
   125  					cSystemdPath:                       struct{}{},
   126  				}
   127  			},
   128  			want: cSystemdPath,
   129  		},
   130  		{
   131  			name: "systemd provider + guaranteed qos pod + crio",
   132  			input: func(input *inputParams) {
   133  				input.provider = newSystemdProvider()
   134  				input.qos = v1.PodQOSGuaranteed
   135  				input.fsMock = fsMock{
   136  					cgroupRoot + systemdCgroupBasePath: struct{}{},
   137  					cSystemdGuaranteedPath:             struct{}{},
   138  				}
   139  			},
   140  			want: cSystemdGuaranteedPath,
   141  		},
   142  		{
   143  			name: "nested provider",
   144  			input: func(input *inputParams) {
   145  				input.provider = newNestedProvider()
   146  				input.fsMock = fsMock{
   147  					cgroupRoot + nestedCgroupBasePath: struct{}{},
   148  					cNestedPath:                       struct{}{},
   149  				}
   150  			},
   151  			want: cNestedPath,
   152  		},
   153  		{
   154  			name: "nested systemd provider",
   155  			input: func(input *inputParams) {
   156  				input.provider = newNestedSystemdProvider()
   157  				input.fsMock = fsMock{
   158  					cgroupRoot + nestedSystemdCgroupBasePath: struct{}{},
   159  					cSystemdNestedPath:                       struct{}{},
   160  				}
   161  			},
   162  			want: cSystemdNestedPath,
   163  		},
   164  		{
   165  			name: "default provider + no valid path",
   166  			input: func(input *inputParams) {
   167  				input.fsMock = fsMock{
   168  					cgroupRoot + defaultCgroupBasePath: struct{}{},
   169  					cgroupRoot + "/foo":                struct{}{},
   170  				}
   171  			},
   172  			want:    "",
   173  			wantErr: true,
   174  		},
   175  		{
   176  			name: "systemd provider + no valid path",
   177  			input: func(input *inputParams) {
   178  				input.provider = newSystemdProvider()
   179  				input.fsMock = fsMock{
   180  					cgroupRoot + systemdCgroupBasePath: struct{}{},
   181  					cgroupRoot + "/foo":                struct{}{},
   182  				}
   183  			},
   184  			want:    "",
   185  			wantErr: true,
   186  		},
   187  		{
   188  			name: "nested systemd provider + no valid path",
   189  			input: func(input *inputParams) {
   190  				input.provider = newNestedSystemdProvider()
   191  				input.fsMock = fsMock{
   192  					cgroupRoot + nestedSystemdCgroupBasePath: struct{}{},
   193  					cgroupRoot + "/foo":                      struct{}{},
   194  				}
   195  			},
   196  			want:    "",
   197  			wantErr: true,
   198  		},
   199  	}
   200  
   201  	for _, tt := range tests {
   202  		t.Run(tt.name, func(t *testing.T) {
   203  			ti := getTestInput()
   204  			if tt.input != nil {
   205  				tt.input(ti)
   206  			}
   207  			initProviderTest(ti.fsMock)
   208  
   209  			got, err := ti.provider.getContainerPath(ti.podId, ti.containerId, ti.qos)
   210  
   211  			if !tt.wantErr {
   212  				require.NoError(t, err)
   213  				require.Equal(t, tt.want, got)
   214  			} else {
   215  				require.Error(t, err)
   216  			}
   217  		})
   218  	}
   219  }