k8s.io/kubernetes@v1.29.3/pkg/kubelet/pluginmanager/cache/desired_state_of_world_test.go (about) 1 /* 2 Copyright 2019 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 cache 18 19 import ( 20 "runtime" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 ) 25 26 // Calls AddOrUpdatePlugin() to add a plugin 27 // Verifies newly added plugin exists in GetPluginsToRegister() 28 // Verifies newly added plugin returns true for PluginExists() 29 func Test_DSW_AddOrUpdatePlugin_Positive_NewPlugin(t *testing.T) { 30 dsw := NewDesiredStateOfWorld() 31 socketPath := "/var/lib/kubelet/device-plugins/test-plugin.sock" 32 err := dsw.AddOrUpdatePlugin(socketPath) 33 // Assert 34 if err != nil { 35 t.Fatalf("AddOrUpdatePlugin failed. Expected: <no error> Actual: <%v>", err) 36 } 37 38 // Get pluginsToRegister and check the newly added plugin is there 39 dswPlugins := dsw.GetPluginsToRegister() 40 if len(dswPlugins) != 1 { 41 t.Fatalf("Desired state of world length should be one but it's %d", len(dswPlugins)) 42 } 43 if dswPlugins[0].SocketPath != socketPath { 44 t.Fatalf("Expected\n%s\nin desired state of world, but got\n%v\n", socketPath, dswPlugins[0]) 45 } 46 47 // Check PluginExists returns true 48 if !dsw.PluginExists(socketPath) { 49 t.Fatalf("PluginExists returns false for the newly added plugin") 50 } 51 } 52 53 // Calls AddOrUpdatePlugin() to update timestamp of an existing plugin 54 // Verifies the timestamp the existing plugin is updated 55 // Verifies newly added plugin returns true for PluginExists() 56 func Test_DSW_AddOrUpdatePlugin_Positive_ExistingPlugin(t *testing.T) { 57 // Skip tests that fail on Windows, as discussed during the SIG Testing meeting from January 10, 2023 58 if runtime.GOOS == "windows" { 59 t.Skip("Skipping test that fails on Windows") 60 } 61 62 dsw := NewDesiredStateOfWorld() 63 socketPath := "/var/lib/kubelet/device-plugins/test-plugin.sock" 64 // Adding the plugin for the first time 65 err := dsw.AddOrUpdatePlugin(socketPath) 66 if err != nil { 67 t.Fatalf("AddOrUpdatePlugin failed. Expected: <no error> Actual: <%v>", err) 68 } 69 70 // Get pluginsToRegister and check the newly added plugin is there, and get the old timestamp 71 dswPlugins := dsw.GetPluginsToRegister() 72 if len(dswPlugins) != 1 { 73 t.Fatalf("Desired state of world length should be one but it's %d", len(dswPlugins)) 74 } 75 if dswPlugins[0].SocketPath != socketPath { 76 t.Fatalf("Expected\n%s\nin desired state of world, but got\n%v\n", socketPath, dswPlugins[0]) 77 } 78 oldTimestamp := dswPlugins[0].Timestamp 79 80 // Adding the plugin again so that the timestamp will be updated 81 err = dsw.AddOrUpdatePlugin(socketPath) 82 if err != nil { 83 t.Fatalf("AddOrUpdatePlugin failed. Expected: <no error> Actual: <%v>", err) 84 } 85 newDswPlugins := dsw.GetPluginsToRegister() 86 if len(newDswPlugins) != 1 { 87 t.Fatalf("Desired state of world length should be one but it's %d", len(newDswPlugins)) 88 } 89 if newDswPlugins[0].SocketPath != socketPath { 90 t.Fatalf("Expected\n%s\nin desired state of world, but got\n%v\n", socketPath, newDswPlugins[0]) 91 } 92 93 // Verify that the new timestamp is newer than the old timestamp 94 if !newDswPlugins[0].Timestamp.After(oldTimestamp) { 95 t.Fatal("New timestamp is not newer than the old timestamp", newDswPlugins[0].Timestamp, oldTimestamp) 96 } 97 98 } 99 100 // Calls AddOrUpdatePlugin() to add an empty string for socket path 101 // Verifies the plugin does not exist in GetPluginsToRegister() after AddOrUpdatePlugin() 102 // Verifies the plugin returns false for PluginExists() 103 func Test_DSW_AddOrUpdatePlugin_Negative_PluginMissingInfo(t *testing.T) { 104 dsw := NewDesiredStateOfWorld() 105 socketPath := "" 106 err := dsw.AddOrUpdatePlugin(socketPath) 107 require.EqualError(t, err, "socket path is empty") 108 109 // Get pluginsToRegister and check the newly added plugin is there 110 dswPlugins := dsw.GetPluginsToRegister() 111 if len(dswPlugins) != 0 { 112 t.Fatalf("Desired state of world length should be zero but it's %d", len(dswPlugins)) 113 } 114 115 // Check PluginExists returns false 116 if dsw.PluginExists(socketPath) { 117 t.Fatalf("PluginExists returns true for the plugin that should not have been registered") 118 } 119 } 120 121 // Calls RemovePlugin() to remove a plugin 122 // Verifies newly removed plugin no longer exists in GetPluginsToRegister() 123 // Verifies newly removed plugin returns false for PluginExists() 124 func Test_DSW_RemovePlugin_Positive(t *testing.T) { 125 // First, add a plugin 126 dsw := NewDesiredStateOfWorld() 127 socketPath := "/var/lib/kubelet/device-plugins/test-plugin.sock" 128 err := dsw.AddOrUpdatePlugin(socketPath) 129 // Assert 130 if err != nil { 131 t.Fatalf("AddOrUpdatePlugin failed. Expected: <no error> Actual: <%v>", err) 132 } 133 134 // Try removing this plugin 135 dsw.RemovePlugin(socketPath) 136 137 // Get pluginsToRegister and check the newly added plugin is there 138 dswPlugins := dsw.GetPluginsToRegister() 139 if len(dswPlugins) != 0 { 140 t.Fatalf("Desired state of world length should be zero but it's %d", len(dswPlugins)) 141 } 142 143 // Check PluginExists returns false 144 if dsw.PluginExists(socketPath) { 145 t.Fatalf("PluginExists returns true for the removed plugin") 146 } 147 }