github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/client/pluginmanager/csimanager/fingerprint_test.go (about) 1 package csimanager 2 3 import ( 4 "context" 5 "errors" 6 "testing" 7 8 "github.com/hashicorp/nomad/nomad/structs" 9 "github.com/hashicorp/nomad/plugins/csi" 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestBuildBasicFingerprint_Node(t *testing.T) { 14 tt := []struct { 15 Name string 16 17 Capabilities *csi.PluginCapabilitySet 18 CapabilitiesErr error 19 CapabilitiesCallCount int64 20 21 NodeInfo *csi.NodeGetInfoResponse 22 NodeInfoErr error 23 NodeInfoCallCount int64 24 25 ExpectedCSIInfo *structs.CSIInfo 26 ExpectedErr error 27 }{ 28 { 29 Name: "Minimal successful response", 30 31 Capabilities: &csi.PluginCapabilitySet{}, 32 CapabilitiesCallCount: 1, 33 34 NodeInfo: &csi.NodeGetInfoResponse{ 35 NodeID: "foobar", 36 MaxVolumes: 5, 37 AccessibleTopology: nil, 38 }, 39 NodeInfoCallCount: 1, 40 41 ExpectedCSIInfo: &structs.CSIInfo{ 42 PluginID: "test-plugin", 43 Healthy: false, 44 HealthDescription: "initial fingerprint not completed", 45 NodeInfo: &structs.CSINodeInfo{ 46 ID: "foobar", 47 MaxVolumes: 5, 48 }, 49 }, 50 }, 51 { 52 Name: "Successful response with capabilities and topologies", 53 54 Capabilities: csi.NewTestPluginCapabilitySet(true, false), 55 CapabilitiesCallCount: 1, 56 57 NodeInfo: &csi.NodeGetInfoResponse{ 58 NodeID: "foobar", 59 MaxVolumes: 5, 60 AccessibleTopology: &csi.Topology{ 61 Segments: map[string]string{ 62 "com.hashicorp.nomad/node-id": "foobar", 63 }, 64 }, 65 }, 66 NodeInfoCallCount: 1, 67 68 ExpectedCSIInfo: &structs.CSIInfo{ 69 PluginID: "test-plugin", 70 Healthy: false, 71 HealthDescription: "initial fingerprint not completed", 72 73 RequiresTopologies: true, 74 75 NodeInfo: &structs.CSINodeInfo{ 76 ID: "foobar", 77 MaxVolumes: 5, 78 AccessibleTopology: &structs.CSITopology{ 79 Segments: map[string]string{ 80 "com.hashicorp.nomad/node-id": "foobar", 81 }, 82 }, 83 }, 84 }, 85 }, 86 { 87 Name: "PluginGetCapabilities Failed", 88 89 CapabilitiesErr: errors.New("request failed"), 90 CapabilitiesCallCount: 1, 91 92 NodeInfoCallCount: 0, 93 94 ExpectedCSIInfo: &structs.CSIInfo{ 95 PluginID: "test-plugin", 96 Healthy: false, 97 HealthDescription: "initial fingerprint not completed", 98 NodeInfo: &structs.CSINodeInfo{}, 99 }, 100 ExpectedErr: errors.New("request failed"), 101 }, 102 { 103 Name: "NodeGetInfo Failed", 104 105 Capabilities: &csi.PluginCapabilitySet{}, 106 CapabilitiesCallCount: 1, 107 108 NodeInfoErr: errors.New("request failed"), 109 NodeInfoCallCount: 1, 110 111 ExpectedCSIInfo: &structs.CSIInfo{ 112 PluginID: "test-plugin", 113 Healthy: false, 114 HealthDescription: "initial fingerprint not completed", 115 NodeInfo: &structs.CSINodeInfo{}, 116 }, 117 ExpectedErr: errors.New("request failed"), 118 }, 119 } 120 121 for _, test := range tt { 122 t.Run(test.Name, func(t *testing.T) { 123 client, im := setupTestNodeInstanceManager(t) 124 125 client.NextPluginGetCapabilitiesResponse = test.Capabilities 126 client.NextPluginGetCapabilitiesErr = test.CapabilitiesErr 127 128 client.NextNodeGetInfoResponse = test.NodeInfo 129 client.NextNodeGetInfoErr = test.NodeInfoErr 130 131 info, err := im.fp.buildBasicFingerprint(context.Background()) 132 133 require.Equal(t, test.ExpectedCSIInfo, info) 134 require.Equal(t, test.ExpectedErr, err) 135 136 require.Equal(t, test.CapabilitiesCallCount, client.PluginGetCapabilitiesCallCount) 137 require.Equal(t, test.NodeInfoCallCount, client.NodeGetInfoCallCount) 138 }) 139 } 140 } 141 142 func TestBuildControllerFingerprint(t *testing.T) { 143 tt := []struct { 144 Name string 145 146 Capabilities *csi.ControllerCapabilitySet 147 CapabilitiesErr error 148 CapabilitiesCallCount int64 149 150 ProbeResponse bool 151 ProbeErr error 152 ProbeCallCount int64 153 154 ExpectedControllerInfo *structs.CSIControllerInfo 155 ExpectedErr error 156 }{ 157 { 158 Name: "Minimal successful response", 159 160 Capabilities: &csi.ControllerCapabilitySet{}, 161 CapabilitiesCallCount: 1, 162 163 ProbeResponse: true, 164 ProbeCallCount: 1, 165 166 ExpectedControllerInfo: &structs.CSIControllerInfo{}, 167 }, 168 { 169 Name: "Successful response with capabilities", 170 171 Capabilities: &csi.ControllerCapabilitySet{ 172 HasListVolumes: true, 173 }, 174 CapabilitiesCallCount: 1, 175 176 ProbeResponse: true, 177 ProbeCallCount: 1, 178 179 ExpectedControllerInfo: &structs.CSIControllerInfo{ 180 SupportsListVolumes: true, 181 }, 182 }, 183 { 184 Name: "ControllerGetCapabilities Failed", 185 186 CapabilitiesErr: errors.New("request failed"), 187 CapabilitiesCallCount: 1, 188 189 ProbeResponse: true, 190 ProbeCallCount: 1, 191 192 ExpectedControllerInfo: &structs.CSIControllerInfo{}, 193 ExpectedErr: errors.New("request failed"), 194 }, 195 } 196 197 for _, test := range tt { 198 t.Run(test.Name, func(t *testing.T) { 199 client, im := setupTestNodeInstanceManager(t) 200 201 client.NextControllerGetCapabilitiesResponse = test.Capabilities 202 client.NextControllerGetCapabilitiesErr = test.CapabilitiesErr 203 204 client.NextPluginProbeResponse = test.ProbeResponse 205 client.NextPluginProbeErr = test.ProbeErr 206 207 info, err := im.fp.buildControllerFingerprint(context.Background(), &structs.CSIInfo{ControllerInfo: &structs.CSIControllerInfo{}}) 208 209 require.Equal(t, test.ExpectedControllerInfo, info.ControllerInfo) 210 require.Equal(t, test.ExpectedErr, err) 211 212 require.Equal(t, test.CapabilitiesCallCount, client.ControllerGetCapabilitiesCallCount) 213 require.Equal(t, test.ProbeCallCount, client.PluginProbeCallCount) 214 }) 215 } 216 } 217 218 func TestBuildNodeFingerprint(t *testing.T) { 219 tt := []struct { 220 Name string 221 222 Capabilities *csi.NodeCapabilitySet 223 CapabilitiesErr error 224 CapabilitiesCallCount int64 225 226 ExpectedCSINodeInfo *structs.CSINodeInfo 227 ExpectedErr error 228 }{ 229 { 230 Name: "Minimal successful response", 231 232 Capabilities: &csi.NodeCapabilitySet{}, 233 CapabilitiesCallCount: 1, 234 235 ExpectedCSINodeInfo: &structs.CSINodeInfo{ 236 RequiresNodeStageVolume: false, 237 }, 238 }, 239 { 240 Name: "Successful response with capabilities and topologies", 241 242 Capabilities: &csi.NodeCapabilitySet{ 243 HasStageUnstageVolume: true, 244 }, 245 CapabilitiesCallCount: 1, 246 247 ExpectedCSINodeInfo: &structs.CSINodeInfo{ 248 RequiresNodeStageVolume: true, 249 }, 250 }, 251 { 252 Name: "NodeGetCapabilities Failed", 253 254 CapabilitiesErr: errors.New("request failed"), 255 CapabilitiesCallCount: 1, 256 257 ExpectedCSINodeInfo: &structs.CSINodeInfo{}, 258 ExpectedErr: errors.New("request failed"), 259 }, 260 } 261 262 for _, test := range tt { 263 t.Run(test.Name, func(t *testing.T) { 264 client, im := setupTestNodeInstanceManager(t) 265 266 client.NextNodeGetCapabilitiesResponse = test.Capabilities 267 client.NextNodeGetCapabilitiesErr = test.CapabilitiesErr 268 269 info, err := im.fp.buildNodeFingerprint(context.Background(), &structs.CSIInfo{NodeInfo: &structs.CSINodeInfo{}}) 270 271 require.Equal(t, test.ExpectedCSINodeInfo, info.NodeInfo) 272 require.Equal(t, test.ExpectedErr, err) 273 274 require.Equal(t, test.CapabilitiesCallCount, client.NodeGetCapabilitiesCallCount) 275 }) 276 } 277 }