2018-10-08 22:02:29 -04:00
/ *
Copyright 2018 The Kubernetes Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2021-02-23 15:24:24 -05:00
package node
2018-10-08 22:02:29 -04:00
import (
2020-02-07 21:16:47 -05:00
"context"
2018-10-08 22:02:29 -04:00
"fmt"
"time"
2019-08-25 03:20:50 -04:00
v1 "k8s.io/api/core/v1"
2020-11-13 14:54:32 -05:00
nodev1 "k8s.io/api/node/v1"
2019-11-12 03:18:59 -05:00
apierrors "k8s.io/apimachinery/pkg/api/errors"
2022-03-15 19:38:33 -04:00
"k8s.io/apimachinery/pkg/api/resource"
2018-10-08 22:02:29 -04:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
2022-03-15 19:38:33 -04:00
"k8s.io/apimachinery/pkg/labels"
2020-11-13 14:54:32 -05:00
types "k8s.io/apimachinery/pkg/types"
2018-10-08 22:02:29 -04:00
"k8s.io/apimachinery/pkg/util/wait"
2020-11-13 14:54:32 -05:00
"k8s.io/apimachinery/pkg/watch"
2018-10-08 22:02:29 -04:00
"k8s.io/kubernetes/pkg/kubelet/events"
runtimeclasstest "k8s.io/kubernetes/pkg/kubelet/runtimeclass/testing"
"k8s.io/kubernetes/test/e2e/framework"
2019-10-28 00:04:43 -04:00
e2eevents "k8s.io/kubernetes/test/e2e/framework/events"
2023-01-18 21:37:12 -05:00
e2eruntimeclass "k8s.io/kubernetes/test/e2e/framework/node/runtimeclass"
2019-05-07 20:09:50 -04:00
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
2021-09-06 19:17:11 -04:00
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
2023-06-20 04:27:14 -04:00
"k8s.io/kubernetes/test/e2e/nodefeature"
2022-01-30 07:37:24 -05:00
admissionapi "k8s.io/pod-security-admission/api"
2018-10-08 22:02:29 -04:00
2022-03-29 02:12:12 -04:00
"github.com/onsi/ginkgo/v2"
2023-07-21 03:20:09 -04:00
"github.com/onsi/gomega"
2018-10-08 22:02:29 -04:00
)
2021-02-23 15:24:24 -05:00
var _ = SIGDescribe ( "RuntimeClass" , func ( ) {
2018-10-08 22:02:29 -04:00
f := framework . NewDefaultFramework ( "runtimeclass" )
2023-05-10 09:38:10 -04:00
f . NamespacePodSecurityLevel = admissionapi . LevelPrivileged
2018-10-08 22:02:29 -04:00
2022-03-15 19:38:33 -04:00
/ *
Release : v1 .20
Testname : Pod with the non - existing RuntimeClass is rejected .
Description : The Pod requesting the non - existing RuntimeClass must be rejected .
* /
2023-06-20 04:27:14 -04:00
framework . ConformanceIt ( "should reject a Pod requesting a non-existent RuntimeClass" , f . WithNodeConformance ( ) , func ( ctx context . Context ) {
2018-10-08 22:02:29 -04:00
rcName := f . Namespace . Name + "-nonexistent"
2023-01-18 21:37:12 -05:00
expectPodRejection ( ctx , f , e2eruntimeclass . NewRuntimeClassPod ( rcName ) )
2018-10-08 22:02:29 -04:00
} )
2022-03-15 19:38:33 -04:00
// The test CANNOT be made a Conformance as it depends on a container runtime to have a specific handler not being installed.
2023-06-20 04:27:14 -04:00
f . It ( "should reject a Pod requesting a RuntimeClass with an unconfigured handler" , nodefeature . RuntimeHandler , func ( ctx context . Context ) {
2018-10-08 22:02:29 -04:00
handler := f . Namespace . Name + "-handler"
2022-12-12 04:11:10 -05:00
rcName := createRuntimeClass ( ctx , f , "unconfigured-handler" , handler , nil )
2022-12-11 12:51:37 -05:00
ginkgo . DeferCleanup ( deleteRuntimeClass , f , rcName )
2023-01-18 21:37:12 -05:00
pod := e2epod . NewPodClient ( f ) . Create ( ctx , e2eruntimeclass . NewRuntimeClassPod ( rcName ) )
2021-04-25 10:18:50 -04:00
eventSelector := fields . Set {
"involvedObject.kind" : "Pod" ,
"involvedObject.name" : pod . Name ,
"involvedObject.namespace" : f . Namespace . Name ,
"reason" : events . FailedCreatePodSandBox ,
} . AsSelector ( ) . String ( )
// Events are unreliable, don't depend on the event. It's used only to speed up the test.
2022-12-12 04:11:10 -05:00
err := e2eevents . WaitTimeoutForEvent ( ctx , f . ClientSet , f . Namespace . Name , eventSelector , handler , framework . PodEventTimeout )
2021-04-25 10:18:50 -04:00
if err != nil {
framework . Logf ( "Warning: did not get event about FailedCreatePodSandBox. Err: %v" , err )
}
// Check the pod is still not running
2022-12-12 04:11:10 -05:00
p , err := f . ClientSet . CoreV1 ( ) . Pods ( f . Namespace . Name ) . Get ( ctx , pod . Name , metav1 . GetOptions { } )
2021-04-25 10:18:50 -04:00
framework . ExpectNoError ( err , "could not re-read the pod after event (or timeout)" )
2023-07-21 03:20:09 -04:00
gomega . Expect ( p . Status . Phase ) . To ( gomega . Equal ( v1 . PodPending ) , "Pod phase isn't pending" )
2018-10-08 22:02:29 -04:00
} )
2022-07-19 05:51:18 -04:00
// This test requires that the PreconfiguredRuntimeClassHandler has already been set up on nodes.
2022-03-15 19:38:33 -04:00
// The test CANNOT be made a Conformance as it depends on a container runtime to have a specific handler installed and working.
2023-06-20 04:27:14 -04:00
f . It ( "should run a Pod requesting a RuntimeClass with a configured handler" , nodefeature . RuntimeHandler , func ( ctx context . Context ) {
2023-01-18 21:37:12 -05:00
if err := e2eruntimeclass . NodeSupportsPreconfiguredRuntimeClassHandler ( ctx , f ) ; err != nil {
e2eskipper . Skipf ( "Skipping test as node does not have E2E runtime class handler preconfigured in container runtime config: %v" , err )
}
2021-09-06 19:17:11 -04:00
2023-01-18 21:37:12 -05:00
rcName := createRuntimeClass ( ctx , f , "preconfigured-handler" , e2eruntimeclass . PreconfiguredRuntimeClassHandler , nil )
2022-12-11 12:51:37 -05:00
ginkgo . DeferCleanup ( deleteRuntimeClass , f , rcName )
2023-01-18 21:37:12 -05:00
pod := e2epod . NewPodClient ( f ) . Create ( ctx , e2eruntimeclass . NewRuntimeClassPod ( rcName ) )
2022-12-12 04:11:10 -05:00
expectPodSuccess ( ctx , f , pod )
2019-02-28 18:51:44 -05:00
} )
2022-03-15 19:38:33 -04:00
/ *
Release : v1 .20
Testname : Can schedule a pod requesting existing RuntimeClass .
Description : The Pod requesting the existing RuntimeClass must be scheduled .
This test doesn ' t validate that the Pod will actually start because this functionality
depends on container runtime and preconfigured handler . Runtime - specific functionality
is not being tested here .
* /
2023-06-20 04:27:14 -04:00
framework . ConformanceIt ( "should schedule a Pod requesting a RuntimeClass without PodOverhead" , f . WithNodeConformance ( ) , func ( ctx context . Context ) {
2023-01-18 21:37:12 -05:00
rcName := createRuntimeClass ( ctx , f , "preconfigured-handler" , e2eruntimeclass . PreconfiguredRuntimeClassHandler , nil )
2022-12-11 12:51:37 -05:00
ginkgo . DeferCleanup ( deleteRuntimeClass , f , rcName )
2023-01-18 21:37:12 -05:00
pod := e2epod . NewPodClient ( f ) . Create ( ctx , e2eruntimeclass . NewRuntimeClassPod ( rcName ) )
2022-03-15 19:38:33 -04:00
// there is only one pod in the namespace
label := labels . SelectorFromSet ( labels . Set ( map [ string ] string { } ) )
2022-12-12 04:11:10 -05:00
pods , err := e2epod . WaitForPodsWithLabelScheduled ( ctx , f . ClientSet , f . Namespace . Name , label )
2022-03-15 19:38:33 -04:00
framework . ExpectNoError ( err , "Failed to schedule Pod with the RuntimeClass" )
2023-07-21 03:20:09 -04:00
gomega . Expect ( pods . Items ) . To ( gomega . HaveLen ( 1 ) )
2022-03-15 19:38:33 -04:00
scheduledPod := & pods . Items [ 0 ]
2023-07-21 03:20:09 -04:00
gomega . Expect ( scheduledPod . Name ) . To ( gomega . Equal ( pod . Name ) )
2022-03-15 19:38:33 -04:00
// Overhead should not be set
2023-07-21 03:20:09 -04:00
gomega . Expect ( scheduledPod . Spec . Overhead ) . To ( gomega . BeEmpty ( ) )
2022-03-15 19:38:33 -04:00
} )
/ *
Release : v1 .24
Testname : RuntimeClass Overhead field must be respected .
Description : The Pod requesting the existing RuntimeClass must be scheduled .
This test doesn ' t validate that the Pod will actually start because this functionality
depends on container runtime and preconfigured handler . Runtime - specific functionality
is not being tested here .
* /
2023-06-20 04:27:14 -04:00
framework . ConformanceIt ( "should schedule a Pod requesting a RuntimeClass and initialize its Overhead" , f . WithNodeConformance ( ) , func ( ctx context . Context ) {
2023-01-18 21:37:12 -05:00
rcName := createRuntimeClass ( ctx , f , "preconfigured-handler" , e2eruntimeclass . PreconfiguredRuntimeClassHandler , & nodev1 . Overhead {
2022-03-15 19:38:33 -04:00
PodFixed : v1 . ResourceList {
v1 . ResourceName ( v1 . ResourceCPU ) : resource . MustParse ( "10m" ) ,
v1 . ResourceName ( v1 . ResourceMemory ) : resource . MustParse ( "1Mi" ) ,
} ,
} )
2022-12-11 12:51:37 -05:00
ginkgo . DeferCleanup ( deleteRuntimeClass , f , rcName )
2023-01-18 21:37:12 -05:00
pod := e2epod . NewPodClient ( f ) . Create ( ctx , e2eruntimeclass . NewRuntimeClassPod ( rcName ) )
2022-03-15 19:38:33 -04:00
// there is only one pod in the namespace
label := labels . SelectorFromSet ( labels . Set ( map [ string ] string { } ) )
2022-12-12 04:11:10 -05:00
pods , err := e2epod . WaitForPodsWithLabelScheduled ( ctx , f . ClientSet , f . Namespace . Name , label )
2022-03-15 19:38:33 -04:00
framework . ExpectNoError ( err , "Failed to schedule Pod with the RuntimeClass" )
2023-07-21 03:20:09 -04:00
gomega . Expect ( pods . Items ) . To ( gomega . HaveLen ( 1 ) )
2022-03-15 19:38:33 -04:00
scheduledPod := & pods . Items [ 0 ]
2023-07-21 03:20:09 -04:00
gomega . Expect ( scheduledPod . Name ) . To ( gomega . Equal ( pod . Name ) )
2022-03-15 19:38:33 -04:00
2023-07-21 03:20:09 -04:00
gomega . Expect ( scheduledPod . Spec . Overhead [ v1 . ResourceCPU ] ) . To ( gomega . Equal ( resource . MustParse ( "10m" ) ) )
gomega . Expect ( scheduledPod . Spec . Overhead [ v1 . ResourceMemory ] ) . To ( gomega . Equal ( resource . MustParse ( "1Mi" ) ) )
2022-03-15 19:38:33 -04:00
} )
/ *
Release : v1 .20
Testname : Pod with the deleted RuntimeClass is rejected .
Description : Pod requesting the deleted RuntimeClass must be rejected .
* /
2023-06-20 04:27:14 -04:00
framework . ConformanceIt ( "should reject a Pod requesting a deleted RuntimeClass" , f . WithNodeConformance ( ) , func ( ctx context . Context ) {
2022-12-12 04:11:10 -05:00
rcName := createRuntimeClass ( ctx , f , "delete-me" , "runc" , nil )
2020-11-11 14:22:32 -05:00
rcClient := f . ClientSet . NodeV1 ( ) . RuntimeClasses ( )
2018-10-08 22:02:29 -04:00
2019-05-14 02:10:31 -04:00
ginkgo . By ( "Deleting RuntimeClass " + rcName , func ( ) {
2022-12-12 04:11:10 -05:00
err := rcClient . Delete ( ctx , rcName , metav1 . DeleteOptions { } )
2018-10-08 22:02:29 -04:00
framework . ExpectNoError ( err , "failed to delete RuntimeClass %s" , rcName )
2019-05-14 02:10:31 -04:00
ginkgo . By ( "Waiting for the RuntimeClass to disappear" )
2018-10-08 22:02:29 -04:00
framework . ExpectNoError ( wait . PollImmediate ( framework . Poll , time . Minute , func ( ) ( bool , error ) {
2022-12-12 04:11:10 -05:00
_ , err := rcClient . Get ( ctx , rcName , metav1 . GetOptions { } )
2019-11-12 03:43:58 -05:00
if apierrors . IsNotFound ( err ) {
2018-10-08 22:02:29 -04:00
return true , nil // done
}
if err != nil {
return true , err // stop wait with error
}
return false , nil
} ) )
} )
2023-01-18 21:37:12 -05:00
expectPodRejection ( ctx , f , e2eruntimeclass . NewRuntimeClassPod ( rcName ) )
2018-10-08 22:02:29 -04:00
} )
2020-11-13 14:54:32 -05:00
/ *
Release : v1 .20
Testname : RuntimeClass API
Description :
The node . k8s . io API group MUST exist in the / apis discovery document .
The node . k8s . io / v1 API group / version MUST exist in the / apis / mode . k8s . io discovery document .
The runtimeclasses resource MUST exist in the / apis / node . k8s . io / v1 discovery document .
The runtimeclasses resource must support create , get , list , watch , update , patch , delete , and deletecollection .
* /
2023-09-28 08:41:20 -04:00
framework . ConformanceIt ( "should support RuntimeClasses API operations" , func ( ctx context . Context ) {
2020-11-13 14:54:32 -05:00
// Setup
rcVersion := "v1"
rcClient := f . ClientSet . NodeV1 ( ) . RuntimeClasses ( )
// This is a conformance test that must configure opaque handlers to validate CRUD operations.
// Test should not use any existing handler like gVisor or runc
//
// All CRUD operations in this test are limited to the objects with the label test=f.UniqueName
rc := runtimeclasstest . NewRuntimeClass ( f . UniqueName + "-handler" , f . UniqueName + "-conformance-runtime-class" )
rc . SetLabels ( map [ string ] string { "test" : f . UniqueName } )
rc2 := runtimeclasstest . NewRuntimeClass ( f . UniqueName + "-handler2" , f . UniqueName + "-conformance-runtime-class2" )
rc2 . SetLabels ( map [ string ] string { "test" : f . UniqueName } )
rc3 := runtimeclasstest . NewRuntimeClass ( f . UniqueName + "-handler3" , f . UniqueName + "-conformance-runtime-class3" )
rc3 . SetLabels ( map [ string ] string { "test" : f . UniqueName } )
// Discovery
ginkgo . By ( "getting /apis" )
{
discoveryGroups , err := f . ClientSet . Discovery ( ) . ServerGroups ( )
framework . ExpectNoError ( err )
found := false
for _ , group := range discoveryGroups . Groups {
if group . Name == nodev1 . GroupName {
for _ , version := range group . Versions {
if version . Version == rcVersion {
found = true
break
}
}
}
}
2022-05-17 02:54:03 -04:00
if ! found {
framework . Failf ( "expected RuntimeClass API group/version, got %#v" , discoveryGroups . Groups )
}
2020-11-13 14:54:32 -05:00
}
ginkgo . By ( "getting /apis/node.k8s.io" )
{
group := & metav1 . APIGroup { }
2022-12-12 04:11:10 -05:00
err := f . ClientSet . Discovery ( ) . RESTClient ( ) . Get ( ) . AbsPath ( "/apis/node.k8s.io" ) . Do ( ctx ) . Into ( group )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
found := false
for _ , version := range group . Versions {
if version . Version == rcVersion {
found = true
break
}
}
2022-05-17 02:54:03 -04:00
if ! found {
framework . Failf ( "expected RuntimeClass API version, got %#v" , group . Versions )
}
2020-11-13 14:54:32 -05:00
}
ginkgo . By ( "getting /apis/node.k8s.io/" + rcVersion )
{
resources , err := f . ClientSet . Discovery ( ) . ServerResourcesForGroupVersion ( nodev1 . SchemeGroupVersion . String ( ) )
framework . ExpectNoError ( err )
found := false
for _ , resource := range resources . APIResources {
switch resource . Name {
case "runtimeclasses" :
found = true
}
}
2022-05-17 02:54:03 -04:00
if ! found {
framework . Failf ( "expected runtimeclasses, got %#v" , resources . APIResources )
}
2020-11-13 14:54:32 -05:00
}
// Main resource create/read/update/watch operations
ginkgo . By ( "creating" )
2022-12-12 04:11:10 -05:00
createdRC , err := rcClient . Create ( ctx , rc , metav1 . CreateOptions { } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2022-12-12 04:11:10 -05:00
_ , err = rcClient . Create ( ctx , rc , metav1 . CreateOptions { } )
2022-05-17 02:54:03 -04:00
if ! apierrors . IsAlreadyExists ( err ) {
framework . Failf ( "expected 409, got %#v" , err )
}
2022-12-12 04:11:10 -05:00
_ , err = rcClient . Create ( ctx , rc2 , metav1 . CreateOptions { } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
ginkgo . By ( "watching" )
framework . Logf ( "starting watch" )
2022-12-12 04:11:10 -05:00
rcWatch , err := rcClient . Watch ( ctx , metav1 . ListOptions { LabelSelector : "test=" + f . UniqueName } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
// added for a watch
2022-12-12 04:11:10 -05:00
_ , err = rcClient . Create ( ctx , rc3 , metav1 . CreateOptions { } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
ginkgo . By ( "getting" )
2022-12-12 04:11:10 -05:00
gottenRC , err := rcClient . Get ( ctx , rc . Name , metav1 . GetOptions { } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2023-07-21 03:20:09 -04:00
gomega . Expect ( gottenRC . UID ) . To ( gomega . Equal ( createdRC . UID ) )
2020-11-13 14:54:32 -05:00
ginkgo . By ( "listing" )
2022-12-12 04:11:10 -05:00
rcs , err := rcClient . List ( ctx , metav1 . ListOptions { LabelSelector : "test=" + f . UniqueName } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2023-07-21 03:20:09 -04:00
gomega . Expect ( rcs . Items ) . To ( gomega . HaveLen ( 3 ) , "filtered list should have 3 items" )
2020-11-13 14:54:32 -05:00
ginkgo . By ( "patching" )
2022-12-12 04:11:10 -05:00
patchedRC , err := rcClient . Patch ( ctx , createdRC . Name , types . MergePatchType , [ ] byte ( ` { "metadata": { "annotations": { "patched":"true"}}} ` ) , metav1 . PatchOptions { } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2023-07-21 03:20:09 -04:00
gomega . Expect ( patchedRC . Annotations ) . To ( gomega . HaveKeyWithValue ( "patched" , "true" ) , "patched object should have the applied annotation" )
2020-11-13 14:54:32 -05:00
ginkgo . By ( "updating" )
csrToUpdate := patchedRC . DeepCopy ( )
csrToUpdate . Annotations [ "updated" ] = "true"
2022-12-12 04:11:10 -05:00
updatedRC , err := rcClient . Update ( ctx , csrToUpdate , metav1 . UpdateOptions { } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2023-07-21 03:20:09 -04:00
gomega . Expect ( updatedRC . Annotations ) . To ( gomega . HaveKeyWithValue ( "updated" , "true" ) , "updated object should have the applied annotation" )
2020-11-13 14:54:32 -05:00
framework . Logf ( "waiting for watch events with expected annotations" )
for sawAdded , sawPatched , sawUpdated := false , false , false ; ! sawAdded && ! sawPatched && ! sawUpdated ; {
select {
case evt , ok := <- rcWatch . ResultChan ( ) :
2022-05-17 02:54:03 -04:00
if ! ok {
framework . Fail ( "watch channel should not close" )
}
2020-11-13 14:54:32 -05:00
if evt . Type == watch . Modified {
watchedRC , isRC := evt . Object . ( * nodev1 . RuntimeClass )
2022-05-17 02:54:03 -04:00
if ! isRC {
framework . Failf ( "expected RC, got %T" , evt . Object )
}
2020-11-13 14:54:32 -05:00
if watchedRC . Annotations [ "patched" ] == "true" {
framework . Logf ( "saw patched annotations" )
sawPatched = true
} else if watchedRC . Annotations [ "updated" ] == "true" {
framework . Logf ( "saw updated annotations" )
sawUpdated = true
} else {
framework . Logf ( "missing expected annotations, waiting: %#v" , watchedRC . Annotations )
}
} else if evt . Type == watch . Added {
_ , isRC := evt . Object . ( * nodev1 . RuntimeClass )
2022-05-17 02:54:03 -04:00
if ! isRC {
framework . Failf ( "expected RC, got %T" , evt . Object )
}
2020-11-13 14:54:32 -05:00
sawAdded = true
}
case <- time . After ( wait . ForeverTestTimeout ) :
framework . Fail ( "timed out waiting for watch event" )
}
}
rcWatch . Stop ( )
// main resource delete operations
ginkgo . By ( "deleting" )
2022-12-12 04:11:10 -05:00
err = rcClient . Delete ( ctx , createdRC . Name , metav1 . DeleteOptions { } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2022-12-12 04:11:10 -05:00
_ , err = rcClient . Get ( ctx , createdRC . Name , metav1 . GetOptions { } )
2022-05-17 02:54:03 -04:00
if ! apierrors . IsNotFound ( err ) {
framework . Failf ( "expected 404, got %#v" , err )
}
2022-12-12 04:11:10 -05:00
rcs , err = rcClient . List ( ctx , metav1 . ListOptions { LabelSelector : "test=" + f . UniqueName } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2023-07-21 03:20:09 -04:00
gomega . Expect ( rcs . Items ) . To ( gomega . HaveLen ( 2 ) , "filtered list should have 2 items" )
2020-11-13 14:54:32 -05:00
ginkgo . By ( "deleting a collection" )
2022-12-12 04:11:10 -05:00
err = rcClient . DeleteCollection ( ctx , metav1 . DeleteOptions { } , metav1 . ListOptions { LabelSelector : "test=" + f . UniqueName } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2022-12-12 04:11:10 -05:00
rcs , err = rcClient . List ( ctx , metav1 . ListOptions { LabelSelector : "test=" + f . UniqueName } )
2020-11-13 14:54:32 -05:00
framework . ExpectNoError ( err )
2023-07-21 03:20:09 -04:00
gomega . Expect ( rcs . Items ) . To ( gomega . BeEmpty ( ) , "filtered list should have 0 items" )
2020-11-13 14:54:32 -05:00
} )
2018-10-08 22:02:29 -04:00
} )
2022-12-12 04:11:10 -05:00
func deleteRuntimeClass ( ctx context . Context , f * framework . Framework , name string ) {
err := f . ClientSet . NodeV1 ( ) . RuntimeClasses ( ) . Delete ( ctx , name , metav1 . DeleteOptions { } )
2021-06-25 04:21:30 -04:00
framework . ExpectNoError ( err , "failed to delete RuntimeClass resource" )
}
2018-10-08 22:02:29 -04:00
// createRuntimeClass generates a RuntimeClass with the desired handler and a "namespaced" name,
2019-01-24 14:08:19 -05:00
// synchronously creates it, and returns the generated name.
2022-12-12 04:11:10 -05:00
func createRuntimeClass ( ctx context . Context , f * framework . Framework , name , handler string , overhead * nodev1 . Overhead ) string {
2018-10-08 22:02:29 -04:00
uniqueName := fmt . Sprintf ( "%s-%s" , f . Namespace . Name , name )
2019-01-24 14:08:19 -05:00
rc := runtimeclasstest . NewRuntimeClass ( uniqueName , handler )
2022-03-15 19:38:33 -04:00
rc . Overhead = overhead
2022-12-12 04:11:10 -05:00
rc , err := f . ClientSet . NodeV1 ( ) . RuntimeClasses ( ) . Create ( ctx , rc , metav1 . CreateOptions { } )
2018-10-08 22:02:29 -04:00
framework . ExpectNoError ( err , "failed to create RuntimeClass resource" )
return rc . GetName ( )
}
2022-12-12 04:11:10 -05:00
func expectPodRejection ( ctx context . Context , f * framework . Framework , pod * v1 . Pod ) {
_ , err := f . ClientSet . CoreV1 ( ) . Pods ( f . Namespace . Name ) . Create ( ctx , pod , metav1 . CreateOptions { } )
2023-08-30 22:05:55 -04:00
gomega . Expect ( err ) . To ( gomega . HaveOccurred ( ) , "should be forbidden" )
2022-05-17 02:54:03 -04:00
if ! apierrors . IsForbidden ( err ) {
framework . Failf ( "expected forbidden error, got %#v" , err )
}
2018-10-08 22:02:29 -04:00
}
// expectPodSuccess waits for the given pod to terminate successfully.
2022-12-12 04:11:10 -05:00
func expectPodSuccess ( ctx context . Context , f * framework . Framework , pod * v1 . Pod ) {
2019-05-07 20:09:50 -04:00
framework . ExpectNoError ( e2epod . WaitForPodSuccessInNamespace (
2022-12-12 04:11:10 -05:00
ctx , f . ClientSet , pod . Name , f . Namespace . Name ) )
2018-10-08 22:02:29 -04:00
}