k8s.io/kubernetes@v1.29.3/test/e2e/windows/device_plugin.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package windows
    18  
    19  import (
    20  	"context"
    21  	"time"
    22  
    23  	v1 "k8s.io/api/core/v1"
    24  	"k8s.io/apimachinery/pkg/api/resource"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	clientset "k8s.io/client-go/kubernetes"
    27  	"k8s.io/kubernetes/test/e2e/feature"
    28  	"k8s.io/kubernetes/test/e2e/framework"
    29  	e2edaemonset "k8s.io/kubernetes/test/e2e/framework/daemonset"
    30  	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
    31  	e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
    32  	e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
    33  	imageutils "k8s.io/kubernetes/test/utils/image"
    34  	admissionapi "k8s.io/pod-security-admission/api"
    35  
    36  	"github.com/onsi/ginkgo/v2"
    37  )
    38  
    39  const (
    40  	testSlowMultiplier = 60
    41  )
    42  
    43  var _ = sigDescribe(feature.GPUDevicePlugin, "Device Plugin", skipUnlessWindows(func() {
    44  	f := framework.NewDefaultFramework("device-plugin")
    45  	f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
    46  
    47  	var cs clientset.Interface
    48  
    49  	ginkgo.BeforeEach(func() {
    50  		//Only for Windows containers
    51  		e2eskipper.SkipUnlessNodeOSDistroIs("windows")
    52  		cs = f.ClientSet
    53  	})
    54  	ginkgo.It("should be able to create a functioning device plugin for Windows", func(ctx context.Context) {
    55  		ginkgo.By("creating Windows device plugin daemonset")
    56  		dsName := "directx-device-plugin"
    57  		daemonsetNameLabel := "daemonset-name"
    58  		image := "e2eteam/k8s-directx-device-plugin:0.9.0-1809"
    59  		mountName := "device-plugin"
    60  		mountPath := "/var/lib/kubelet/device-plugins"
    61  		labels := map[string]string{
    62  			daemonsetNameLabel: dsName,
    63  		}
    64  		volumes := []v1.Volume{
    65  			{
    66  				Name: mountName,
    67  				VolumeSource: v1.VolumeSource{
    68  					HostPath: &v1.HostPathVolumeSource{
    69  						Path: mountPath,
    70  					},
    71  				},
    72  			},
    73  		}
    74  		mounts := []v1.VolumeMount{
    75  			{
    76  				Name:      mountName,
    77  				MountPath: mountPath,
    78  			},
    79  		}
    80  		ds := e2edaemonset.NewDaemonSet(dsName, image, labels, volumes, mounts, nil)
    81  		ds.Spec.Template.Spec.PriorityClassName = "system-node-critical"
    82  		ds.Spec.Template.Spec.Tolerations = []v1.Toleration{
    83  			{
    84  				Key:      "CriticalAddonsOnly",
    85  				Operator: "Exists",
    86  			},
    87  		}
    88  		ds.Spec.Template.Spec.NodeSelector = map[string]string{
    89  			"kubernetes.io/os": "windows",
    90  		}
    91  		ds.Spec.Template.Spec.Containers[0].Env = []v1.EnvVar{
    92  			{
    93  				Name:  "DIRECTX_GPU_MATCH_NAME",
    94  				Value: " ",
    95  			},
    96  		}
    97  
    98  		sysNs := "kube-system"
    99  		_, err := cs.AppsV1().DaemonSets(sysNs).Create(ctx, ds, metav1.CreateOptions{})
   100  		framework.ExpectNoError(err)
   101  
   102  		ginkgo.By("creating Windows testing Pod")
   103  		windowsPod := createTestPod(f, imageutils.GetE2EImage(imageutils.WindowsServer), windowsOS)
   104  		windowsPod.Spec.Containers[0].Args = []string{"powershell.exe", "Start-Sleep", "3600"}
   105  		windowsPod.Spec.Containers[0].Resources.Limits = v1.ResourceList{
   106  			"microsoft.com/directx": resource.MustParse("1"),
   107  		}
   108  		windowsPod, err = cs.CoreV1().Pods(f.Namespace.Name).Create(ctx, windowsPod, metav1.CreateOptions{})
   109  		framework.ExpectNoError(err)
   110  		ginkgo.By("Waiting for the pod Running")
   111  		err = e2epod.WaitTimeoutForPodRunningInNamespace(ctx, cs, windowsPod.Name, f.Namespace.Name, testSlowMultiplier*framework.PodStartTimeout)
   112  		framework.ExpectNoError(err)
   113  
   114  		ginkgo.By("verifying device access in Windows testing Pod")
   115  		dxdiagCommand := []string{"cmd.exe", "/c", "dxdiag", "/t", "dxdiag_output.txt", "&", "type", "dxdiag_output.txt"}
   116  		//If DirectX version issues caused by supsequent windows releases occur, these tests need to do version checks
   117  		//based on  the windows version running the test.
   118  		dxdiagDirectxVersion := "DirectX Version: DirectX 12"
   119  		defaultNs := f.Namespace.Name
   120  		_, dxdiagDirectxVersionErr := e2eoutput.LookForStringInPodExec(defaultNs, windowsPod.Name, dxdiagCommand, dxdiagDirectxVersion, time.Minute)
   121  		framework.ExpectNoError(dxdiagDirectxVersionErr, "failed: didn't find directX version dxdiag output.")
   122  
   123  		dxdiagDdiVersion := "DDI Version: 12"
   124  		_, dxdiagDdiVersionErr := e2eoutput.LookForStringInPodExec(defaultNs, windowsPod.Name, dxdiagCommand, dxdiagDdiVersion, time.Minute)
   125  		framework.ExpectNoError(dxdiagDdiVersionErr, "failed: didn't find DDI version in dxdiag output.")
   126  
   127  		dxdiagVendorID := "Vendor ID: 0x"
   128  		_, dxdiagVendorIDErr := e2eoutput.LookForStringInPodExec(defaultNs, windowsPod.Name, dxdiagCommand, dxdiagVendorID, time.Minute)
   129  		framework.ExpectNoError(dxdiagVendorIDErr, "failed: didn't find vendorID in dxdiag output.")
   130  
   131  		envVarCommand := []string{"cmd.exe", "/c", "set", "DIRECTX_GPU_Name"}
   132  		envVarDirectxGpuName := "DIRECTX_GPU_Name="
   133  		_, envVarDirectxGpuNameErr := e2eoutput.LookForStringInPodExec(defaultNs, windowsPod.Name, envVarCommand, envVarDirectxGpuName, time.Minute)
   134  		framework.ExpectNoError(envVarDirectxGpuNameErr, "failed: didn't find expected environment variable.")
   135  	})
   136  }))