mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 03:11:40 +00:00
unit tests: Skip Windows-unrelated tests on Windows
Some of the unit tests cannot pass on Windows due to various reasons: - fsnotify does not have a Windows implementation. - Proxy Mode IPVS not supported on Windows. - Seccomp not supported on Windows. - VolumeMode=Block is not supported on Windows. - iSCSI volumes are mounted differently on Windows, and iscsiadm is a Linux utility.
This commit is contained in:
parent
83415e5c9e
commit
af77381e01
@ -20,9 +20,14 @@ limitations under the License.
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -622,3 +627,119 @@ func resolveDualStackLocalDetectors(t *testing.T) func(localDetector proxyutilip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigChange(t *testing.T) {
|
||||
setUp := func() (*os.File, string, error) {
|
||||
tempDir, err := os.MkdirTemp("", "kubeproxy-config-change")
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unable to create temporary directory: %v", err)
|
||||
}
|
||||
fullPath := filepath.Join(tempDir, "kube-proxy-config")
|
||||
file, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unexpected error when creating temp file: %v", err)
|
||||
}
|
||||
|
||||
_, err = file.WriteString(`apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
contentType: application/vnd.kubernetes.protobuf
|
||||
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
|
||||
qps: 5
|
||||
clusterCIDR: 10.244.0.0/16
|
||||
configSyncPeriod: 15m0s
|
||||
conntrack:
|
||||
maxPerCore: 32768
|
||||
min: 131072
|
||||
tcpCloseWaitTimeout: 1h0m0s
|
||||
tcpEstablishedTimeout: 24h0m0s
|
||||
enableProfiling: false
|
||||
healthzBindAddress: 0.0.0.0:10256
|
||||
hostnameOverride: ""
|
||||
iptables:
|
||||
masqueradeAll: false
|
||||
masqueradeBit: 14
|
||||
minSyncPeriod: 0s
|
||||
syncPeriod: 30s
|
||||
ipvs:
|
||||
excludeCIDRs: null
|
||||
minSyncPeriod: 0s
|
||||
scheduler: ""
|
||||
syncPeriod: 30s
|
||||
kind: KubeProxyConfiguration
|
||||
metricsBindAddress: 127.0.0.1:10249
|
||||
mode: ""
|
||||
nodePortAddresses: null
|
||||
oomScoreAdj: -999
|
||||
portRange: ""
|
||||
detectLocalMode: "BridgeInterface"`)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unexpected error when writing content to temp kube-proxy config file: %v", err)
|
||||
}
|
||||
|
||||
return file, tempDir, nil
|
||||
}
|
||||
|
||||
tearDown := func(file *os.File, tempDir string) {
|
||||
file.Close()
|
||||
os.RemoveAll(tempDir)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
proxyServer proxyRun
|
||||
append bool
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "update config file",
|
||||
proxyServer: new(fakeProxyServerLongRun),
|
||||
append: true,
|
||||
expectedErr: "content of the proxy server's configuration file was updated",
|
||||
},
|
||||
{
|
||||
name: "fake error",
|
||||
proxyServer: new(fakeProxyServerError),
|
||||
expectedErr: "mocking error from ProxyServer.Run()",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
file, tempDir, err := setUp()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when setting up environment: %v", err)
|
||||
}
|
||||
|
||||
opt := NewOptions()
|
||||
opt.ConfigFile = file.Name()
|
||||
err = opt.Complete()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
opt.proxyServer = tc.proxyServer
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
errCh <- opt.runLoop()
|
||||
}()
|
||||
|
||||
if tc.append {
|
||||
file.WriteString("append fake content")
|
||||
}
|
||||
|
||||
select {
|
||||
case err := <-errCh:
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), tc.expectedErr) {
|
||||
t.Errorf("[%s] Expected error containing %v, got %v", tc.name, tc.expectedErr, err)
|
||||
}
|
||||
}
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Errorf("[%s] Timeout: unable to get any events or internal timeout.", tc.name)
|
||||
}
|
||||
tearDown(file, tempDir)
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ package app
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
@ -408,122 +406,6 @@ func TestProcessHostnameOverrideFlag(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigChange(t *testing.T) {
|
||||
setUp := func() (*os.File, string, error) {
|
||||
tempDir, err := os.MkdirTemp("", "kubeproxy-config-change")
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unable to create temporary directory: %v", err)
|
||||
}
|
||||
fullPath := filepath.Join(tempDir, "kube-proxy-config")
|
||||
file, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unexpected error when creating temp file: %v", err)
|
||||
}
|
||||
|
||||
_, err = file.WriteString(`apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: 0.0.0.0
|
||||
bindAddressHardFail: false
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 10
|
||||
contentType: application/vnd.kubernetes.protobuf
|
||||
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
|
||||
qps: 5
|
||||
clusterCIDR: 10.244.0.0/16
|
||||
configSyncPeriod: 15m0s
|
||||
conntrack:
|
||||
maxPerCore: 32768
|
||||
min: 131072
|
||||
tcpCloseWaitTimeout: 1h0m0s
|
||||
tcpEstablishedTimeout: 24h0m0s
|
||||
enableProfiling: false
|
||||
healthzBindAddress: 0.0.0.0:10256
|
||||
hostnameOverride: ""
|
||||
iptables:
|
||||
masqueradeAll: false
|
||||
masqueradeBit: 14
|
||||
minSyncPeriod: 0s
|
||||
syncPeriod: 30s
|
||||
ipvs:
|
||||
excludeCIDRs: null
|
||||
minSyncPeriod: 0s
|
||||
scheduler: ""
|
||||
syncPeriod: 30s
|
||||
kind: KubeProxyConfiguration
|
||||
metricsBindAddress: 127.0.0.1:10249
|
||||
mode: ""
|
||||
nodePortAddresses: null
|
||||
oomScoreAdj: -999
|
||||
portRange: ""
|
||||
detectLocalMode: "BridgeInterface"`)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unexpected error when writing content to temp kube-proxy config file: %v", err)
|
||||
}
|
||||
|
||||
return file, tempDir, nil
|
||||
}
|
||||
|
||||
tearDown := func(file *os.File, tempDir string) {
|
||||
file.Close()
|
||||
os.RemoveAll(tempDir)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
proxyServer proxyRun
|
||||
append bool
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "update config file",
|
||||
proxyServer: new(fakeProxyServerLongRun),
|
||||
append: true,
|
||||
expectedErr: "content of the proxy server's configuration file was updated",
|
||||
},
|
||||
{
|
||||
name: "fake error",
|
||||
proxyServer: new(fakeProxyServerError),
|
||||
expectedErr: "mocking error from ProxyServer.Run()",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
file, tempDir, err := setUp()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when setting up environment: %v", err)
|
||||
}
|
||||
|
||||
opt := NewOptions()
|
||||
opt.ConfigFile = file.Name()
|
||||
err = opt.Complete()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
opt.proxyServer = tc.proxyServer
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
errCh <- opt.runLoop()
|
||||
}()
|
||||
|
||||
if tc.append {
|
||||
file.WriteString("append fake content")
|
||||
}
|
||||
|
||||
select {
|
||||
case err := <-errCh:
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), tc.expectedErr) {
|
||||
t.Errorf("[%s] Expected error containing %v, got %v", tc.name, tc.expectedErr, err)
|
||||
}
|
||||
}
|
||||
case <-time.After(10 * time.Second):
|
||||
t.Errorf("[%s] Timeout: unable to get any events or internal timeout.", tc.name)
|
||||
}
|
||||
tearDown(file, tempDir)
|
||||
}
|
||||
}
|
||||
|
||||
type fakeProxyServerLongRun struct{}
|
||||
|
||||
// Run runs the specified ProxyServer.
|
||||
|
@ -17,13 +17,28 @@ limitations under the License.
|
||||
package kuberuntime
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func seccompLocalhostRef(profileName string) string {
|
||||
return filepath.Join(fakeSeccompProfileRoot, profileName)
|
||||
}
|
||||
|
||||
func seccompLocalhostPath(profileName string) string {
|
||||
return "localhost/" + seccompLocalhostRef(profileName)
|
||||
}
|
||||
|
||||
func TestMilliCPUToQuota(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
msg string
|
||||
@ -201,3 +216,457 @@ func TestMilliCPUToQuotaWithCustomCPUCFSQuotaPeriod(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldProfile(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
scmpProfile *v1.SeccompProfile
|
||||
rootPath string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccompProfile should return empty",
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "type localhost without profile should return empty",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "unknown type should return empty",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: "",
|
||||
},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeRuntimeDefault should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeRuntimeDefault,
|
||||
},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeUnconfined should return unconfined",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeUnconfined,
|
||||
},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeLocalhost should return localhost",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
LocalhostProfile: utilpointer.StringPtr("profile.json"),
|
||||
},
|
||||
rootPath: "/test/",
|
||||
expectedProfile: "localhost//test/profile.json",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, false)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldProfileDefaultSeccomp(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
scmpProfile *v1.SeccompProfile
|
||||
rootPath string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccompProfile should return runtime/default",
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "type localhost without profile should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "unknown type should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: "",
|
||||
},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeRuntimeDefault should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeRuntimeDefault,
|
||||
},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeUnconfined should return unconfined",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeUnconfined,
|
||||
},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeLocalhost should return localhost",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
LocalhostProfile: utilpointer.StringPtr("profile.json"),
|
||||
},
|
||||
rootPath: "/test/",
|
||||
expectedProfile: "localhost//test/profile.json",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, true)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfilePath(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return empty",
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "annotations: no seccomp with containerName should return empty",
|
||||
containerName: "container1",
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: seccompLocalhostPath("filename"),
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns empty",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns empty",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: seccompLocalhostPath("filename2"),
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, false)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return runtime/default",
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "annotations: no seccomp with containerName should return runtime/default",
|
||||
containerName: "container1",
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: seccompLocalhostPath("filename"),
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: seccompLocalhostPath("filename2"),
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, true)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfile(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
unconfinedProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Unconfined,
|
||||
}
|
||||
|
||||
runtimeDefaultProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile *runtimeapi.SecurityProfile
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return unconfined",
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename2"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
|
||||
containerName: "container1",
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("field-cont-profile.json"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, false)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfileDefaultSeccomp(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
unconfinedProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Unconfined,
|
||||
}
|
||||
|
||||
runtimeDefaultProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile *runtimeapi.SecurityProfile
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return RuntimeDefault",
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename2"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
|
||||
containerName: "container1",
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("field-cont-profile.json"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, true)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func getLocal(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
@ -17,28 +17,17 @@ limitations under the License.
|
||||
package kuberuntime
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
runtimetesting "k8s.io/cri-api/pkg/apis/testing"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func seccompLocalhostRef(profileName string) string {
|
||||
return filepath.Join(fakeSeccompProfileRoot, profileName)
|
||||
}
|
||||
|
||||
func seccompLocalhostPath(profileName string) string {
|
||||
return "localhost/" + seccompLocalhostRef(profileName)
|
||||
}
|
||||
|
||||
func TestIsInitContainerFailed(t *testing.T) {
|
||||
tests := []struct {
|
||||
status *kubecontainer.Status
|
||||
@ -235,457 +224,3 @@ func TestGetImageUser(t *testing.T) {
|
||||
assert.Equal(t, test.expectedImageUserValues.username, username, "TestCase[%d]", j)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldProfile(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
scmpProfile *v1.SeccompProfile
|
||||
rootPath string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccompProfile should return empty",
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "type localhost without profile should return empty",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "unknown type should return empty",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: "",
|
||||
},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeRuntimeDefault should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeRuntimeDefault,
|
||||
},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeUnconfined should return unconfined",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeUnconfined,
|
||||
},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeLocalhost should return localhost",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
LocalhostProfile: utilpointer.StringPtr("profile.json"),
|
||||
},
|
||||
rootPath: "/test/",
|
||||
expectedProfile: "localhost//test/profile.json",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, false)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldProfileDefaultSeccomp(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
scmpProfile *v1.SeccompProfile
|
||||
rootPath string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccompProfile should return runtime/default",
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "type localhost without profile should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "unknown type should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: "",
|
||||
},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeRuntimeDefault should return runtime/default",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeRuntimeDefault,
|
||||
},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeUnconfined should return unconfined",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeUnconfined,
|
||||
},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "SeccompProfileTypeLocalhost should return localhost",
|
||||
scmpProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileTypeLocalhost,
|
||||
LocalhostProfile: utilpointer.StringPtr("profile.json"),
|
||||
},
|
||||
rootPath: "/test/",
|
||||
expectedProfile: "localhost//test/profile.json",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, true)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfilePath(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return empty",
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "annotations: no seccomp with containerName should return empty",
|
||||
containerName: "container1",
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: seccompLocalhostPath("filename"),
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns empty",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns empty",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: "",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: seccompLocalhostPath("filename2"),
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, false)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile string
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return runtime/default",
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "annotations: no seccomp with containerName should return runtime/default",
|
||||
containerName: "container1",
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: "unconfined",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: seccompLocalhostPath("filename"),
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: seccompLocalhostPath("filename2"),
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: "runtime/default",
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, true)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfile(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
unconfinedProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Unconfined,
|
||||
}
|
||||
|
||||
runtimeDefaultProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile *runtimeapi.SecurityProfile
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return unconfined",
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename2"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
|
||||
containerName: "container1",
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("field-cont-profile.json"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, false)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeccompProfileDefaultSeccomp(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
require.NoError(t, err)
|
||||
|
||||
unconfinedProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Unconfined,
|
||||
}
|
||||
|
||||
runtimeDefaultProfile := &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
description string
|
||||
annotation map[string]string
|
||||
podSc *v1.PodSecurityContext
|
||||
containerSc *v1.SecurityContext
|
||||
containerName string
|
||||
expectedProfile *runtimeapi.SecurityProfile
|
||||
}{
|
||||
{
|
||||
description: "no seccomp should return RuntimeDefault",
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to unconfined returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||
expectedProfile: unconfinedProfile,
|
||||
},
|
||||
{
|
||||
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("filename2"),
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||
expectedProfile: runtimeDefaultProfile,
|
||||
},
|
||||
{
|
||||
description: "prioritise container field over pod field",
|
||||
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
|
||||
containerName: "container1",
|
||||
expectedProfile: &runtimeapi.SecurityProfile{
|
||||
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||
LocalhostRef: seccompLocalhostRef("field-cont-profile.json"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, true)
|
||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||
}
|
||||
}
|
||||
|
||||
func getLocal(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
@ -24,6 +27,7 @@ import (
|
||||
)
|
||||
|
||||
func TestGetMetricsBlockInvalid(t *testing.T) {
|
||||
// TODO: Enable this on Windows once support VolumeMode=Block is added.
|
||||
metrics := NewMetricsBlock("")
|
||||
actual, err := metrics.GetMetrics()
|
||||
expected := &Metrics{}
|
Loading…
Reference in New Issue
Block a user