k8s.io/kubernetes@v1.29.3/pkg/volume/secret/secret_test.go (about) 1 /* 2 Copyright 2015 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 secret 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "os" 23 "path/filepath" 24 "reflect" 25 "runtime" 26 "strings" 27 "testing" 28 29 "k8s.io/api/core/v1" 30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 "k8s.io/apimachinery/pkg/types" 32 clientset "k8s.io/client-go/kubernetes" 33 "k8s.io/client-go/kubernetes/fake" 34 "k8s.io/kubernetes/pkg/volume" 35 "k8s.io/kubernetes/pkg/volume/emptydir" 36 volumetest "k8s.io/kubernetes/pkg/volume/testing" 37 "k8s.io/kubernetes/pkg/volume/util" 38 39 "github.com/stretchr/testify/assert" 40 ) 41 42 func TestMakePayload(t *testing.T) { 43 caseMappingMode := int32(0400) 44 cases := []struct { 45 name string 46 mappings []v1.KeyToPath 47 secret *v1.Secret 48 mode int32 49 optional bool 50 payload map[string]util.FileProjection 51 success bool 52 }{ 53 { 54 name: "no overrides", 55 secret: &v1.Secret{ 56 Data: map[string][]byte{ 57 "foo": []byte("foo"), 58 "bar": []byte("bar"), 59 }, 60 }, 61 mode: 0644, 62 payload: map[string]util.FileProjection{ 63 "foo": {Data: []byte("foo"), Mode: 0644}, 64 "bar": {Data: []byte("bar"), Mode: 0644}, 65 }, 66 success: true, 67 }, 68 { 69 name: "basic 1", 70 mappings: []v1.KeyToPath{ 71 { 72 Key: "foo", 73 Path: "path/to/foo.txt", 74 }, 75 }, 76 secret: &v1.Secret{ 77 Data: map[string][]byte{ 78 "foo": []byte("foo"), 79 "bar": []byte("bar"), 80 }, 81 }, 82 mode: 0644, 83 payload: map[string]util.FileProjection{ 84 "path/to/foo.txt": {Data: []byte("foo"), Mode: 0644}, 85 }, 86 success: true, 87 }, 88 { 89 name: "subdirs", 90 mappings: []v1.KeyToPath{ 91 { 92 Key: "foo", 93 Path: "path/to/1/2/3/foo.txt", 94 }, 95 }, 96 secret: &v1.Secret{ 97 Data: map[string][]byte{ 98 "foo": []byte("foo"), 99 "bar": []byte("bar"), 100 }, 101 }, 102 mode: 0644, 103 payload: map[string]util.FileProjection{ 104 "path/to/1/2/3/foo.txt": {Data: []byte("foo"), Mode: 0644}, 105 }, 106 success: true, 107 }, 108 { 109 name: "subdirs 2", 110 mappings: []v1.KeyToPath{ 111 { 112 Key: "foo", 113 Path: "path/to/1/2/3/foo.txt", 114 }, 115 }, 116 secret: &v1.Secret{ 117 Data: map[string][]byte{ 118 "foo": []byte("foo"), 119 "bar": []byte("bar"), 120 }, 121 }, 122 mode: 0644, 123 payload: map[string]util.FileProjection{ 124 "path/to/1/2/3/foo.txt": {Data: []byte("foo"), Mode: 0644}, 125 }, 126 success: true, 127 }, 128 { 129 name: "subdirs 3", 130 mappings: []v1.KeyToPath{ 131 { 132 Key: "foo", 133 Path: "path/to/1/2/3/foo.txt", 134 }, 135 { 136 Key: "bar", 137 Path: "another/path/to/the/esteemed/bar.bin", 138 }, 139 }, 140 secret: &v1.Secret{ 141 Data: map[string][]byte{ 142 "foo": []byte("foo"), 143 "bar": []byte("bar"), 144 }, 145 }, 146 mode: 0644, 147 payload: map[string]util.FileProjection{ 148 "path/to/1/2/3/foo.txt": {Data: []byte("foo"), Mode: 0644}, 149 "another/path/to/the/esteemed/bar.bin": {Data: []byte("bar"), Mode: 0644}, 150 }, 151 success: true, 152 }, 153 { 154 name: "non existent key", 155 mappings: []v1.KeyToPath{ 156 { 157 Key: "zab", 158 Path: "path/to/foo.txt", 159 }, 160 }, 161 secret: &v1.Secret{ 162 Data: map[string][]byte{ 163 "foo": []byte("foo"), 164 "bar": []byte("bar"), 165 }, 166 }, 167 mode: 0644, 168 success: false, 169 }, 170 { 171 name: "mapping with Mode", 172 mappings: []v1.KeyToPath{ 173 { 174 Key: "foo", 175 Path: "foo.txt", 176 Mode: &caseMappingMode, 177 }, 178 { 179 Key: "bar", 180 Path: "bar.bin", 181 Mode: &caseMappingMode, 182 }, 183 }, 184 secret: &v1.Secret{ 185 Data: map[string][]byte{ 186 "foo": []byte("foo"), 187 "bar": []byte("bar"), 188 }, 189 }, 190 mode: 0644, 191 payload: map[string]util.FileProjection{ 192 "foo.txt": {Data: []byte("foo"), Mode: caseMappingMode}, 193 "bar.bin": {Data: []byte("bar"), Mode: caseMappingMode}, 194 }, 195 success: true, 196 }, 197 { 198 name: "mapping with defaultMode", 199 mappings: []v1.KeyToPath{ 200 { 201 Key: "foo", 202 Path: "foo.txt", 203 }, 204 { 205 Key: "bar", 206 Path: "bar.bin", 207 }, 208 }, 209 secret: &v1.Secret{ 210 Data: map[string][]byte{ 211 "foo": []byte("foo"), 212 "bar": []byte("bar"), 213 }, 214 }, 215 mode: 0644, 216 payload: map[string]util.FileProjection{ 217 "foo.txt": {Data: []byte("foo"), Mode: 0644}, 218 "bar.bin": {Data: []byte("bar"), Mode: 0644}, 219 }, 220 success: true, 221 }, 222 { 223 name: "optional non existent key", 224 mappings: []v1.KeyToPath{ 225 { 226 Key: "zab", 227 Path: "path/to/foo.txt", 228 }, 229 }, 230 secret: &v1.Secret{ 231 Data: map[string][]byte{ 232 "foo": []byte("foo"), 233 "bar": []byte("bar"), 234 }, 235 }, 236 mode: 0644, 237 optional: true, 238 payload: map[string]util.FileProjection{}, 239 success: true, 240 }, 241 } 242 243 for _, tc := range cases { 244 actualPayload, err := MakePayload(tc.mappings, tc.secret, &tc.mode, tc.optional) 245 if err != nil && tc.success { 246 t.Errorf("%v: unexpected failure making payload: %v", tc.name, err) 247 continue 248 } 249 250 if err == nil && !tc.success { 251 t.Errorf("%v: unexpected success making payload", tc.name) 252 continue 253 } 254 255 if !tc.success { 256 continue 257 } 258 259 if e, a := tc.payload, actualPayload; !reflect.DeepEqual(e, a) { 260 t.Errorf("%v: expected and actual payload do not match", tc.name) 261 } 262 } 263 } 264 265 func newTestHost(t *testing.T, clientset clientset.Interface) (string, volume.VolumeHost) { 266 tempDir, err := ioutil.TempDir("", "secret_volume_test.") 267 if err != nil { 268 t.Fatalf("can't make a temp rootdir: %v", err) 269 } 270 271 return tempDir, volumetest.NewFakeVolumeHost(t, tempDir, clientset, emptydir.ProbeVolumePlugins()) 272 } 273 274 func TestCanSupport(t *testing.T) { 275 pluginMgr := volume.VolumePluginMgr{} 276 tempDir, host := newTestHost(t, nil) 277 defer os.RemoveAll(tempDir) 278 pluginMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) 279 280 plugin, err := pluginMgr.FindPluginByName(secretPluginName) 281 if err != nil { 282 t.Fatal("Can't find the plugin by name") 283 } 284 if plugin.GetPluginName() != secretPluginName { 285 t.Errorf("Wrong name: %s", plugin.GetPluginName()) 286 } 287 if !plugin.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{Secret: &v1.SecretVolumeSource{SecretName: ""}}}}) { 288 t.Errorf("Expected true") 289 } 290 if plugin.CanSupport(&volume.Spec{}) { 291 t.Errorf("Expected false") 292 } 293 } 294 295 func TestPlugin(t *testing.T) { 296 var ( 297 testPodUID = types.UID("test_pod_uid") 298 testVolumeName = "test_volume_name" 299 testNamespace = "test_secret_namespace" 300 testName = "test_secret_name" 301 302 volumeSpec = volumeSpec(testVolumeName, testName, 0644) 303 secret = secret(testNamespace, testName) 304 client = fake.NewSimpleClientset(&secret) 305 pluginMgr = volume.VolumePluginMgr{} 306 rootDir, host = newTestHost(t, client) 307 ) 308 defer os.RemoveAll(rootDir) 309 pluginMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) 310 311 plugin, err := pluginMgr.FindPluginByName(secretPluginName) 312 if err != nil { 313 t.Fatal("Can't find the plugin by name") 314 } 315 316 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}} 317 mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) 318 if err != nil { 319 t.Errorf("Failed to make a new Mounter: %v", err) 320 } 321 if mounter == nil { 322 t.Fatalf("Got a nil Mounter") 323 } 324 325 volumePath := mounter.GetPath() 326 if !hasPathSuffix(volumePath, "pods/test_pod_uid/volumes/kubernetes.io~secret/test_volume_name") { 327 t.Errorf("Got unexpected path: %s", volumePath) 328 } 329 330 err = mounter.SetUp(volume.MounterArgs{}) 331 if err != nil { 332 t.Errorf("Failed to setup volume: %v", err) 333 } 334 if _, err := os.Stat(volumePath); err != nil { 335 if os.IsNotExist(err) { 336 t.Errorf("SetUp() failed, volume path not created: %s", volumePath) 337 } else { 338 t.Errorf("SetUp() failed: %v", err) 339 } 340 } 341 342 // secret volume should create its own empty wrapper path 343 podWrapperMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid/plugins/kubernetes.io~empty-dir/wrapped_test_volume_name", rootDir) 344 345 if _, err := os.Stat(podWrapperMetadataDir); err != nil { 346 if os.IsNotExist(err) { 347 t.Errorf("SetUp() failed, empty-dir wrapper path is not created: %s", podWrapperMetadataDir) 348 } else { 349 t.Errorf("SetUp() failed: %v", err) 350 } 351 } 352 doTestSecretDataInVolume(volumePath, secret, t) 353 defer doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t) 354 355 // Metrics only supported on linux 356 metrics, err := mounter.GetMetrics() 357 if runtime.GOOS == "linux" { 358 assert.NotEmpty(t, metrics) 359 assert.NoError(t, err) 360 } else { 361 t.Skipf("Volume metrics not supported on %s", runtime.GOOS) 362 } 363 } 364 365 func TestInvalidPathSecret(t *testing.T) { 366 var ( 367 testPodUID = types.UID("test_pod_uid") 368 testVolumeName = "test_volume_name" 369 testNamespace = "test_secret_namespace" 370 testName = "test_secret_name" 371 372 volumeSpec = volumeSpec(testVolumeName, testName, 0644) 373 secret = secret(testNamespace, testName) 374 client = fake.NewSimpleClientset(&secret) 375 pluginMgr = volume.VolumePluginMgr{} 376 rootDir, host = newTestHost(t, client) 377 ) 378 volumeSpec.Secret.Items = []v1.KeyToPath{ 379 {Key: "missing", Path: "missing"}, 380 } 381 382 defer os.RemoveAll(rootDir) 383 pluginMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) 384 385 plugin, err := pluginMgr.FindPluginByName(secretPluginName) 386 if err != nil { 387 t.Fatal("Can't find the plugin by name") 388 } 389 390 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}} 391 mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) 392 if err != nil { 393 t.Errorf("Failed to make a new Mounter: %v", err) 394 } 395 if mounter == nil { 396 t.Fatalf("Got a nil Mounter") 397 } 398 399 volumePath := mounter.GetPath() 400 if !hasPathSuffix(volumePath, "pods/test_pod_uid/volumes/kubernetes.io~secret/test_volume_name") { 401 t.Errorf("Got unexpected path: %s", volumePath) 402 } 403 404 var mounterArgs volume.MounterArgs 405 err = mounter.SetUp(mounterArgs) 406 if err == nil { 407 t.Errorf("Expected error while setting up secret") 408 } 409 410 _, err = os.Stat(volumePath) 411 if err == nil { 412 t.Errorf("Expected path %s to not exist", volumePath) 413 } 414 } 415 416 // Test the case where the plugin's ready file exists, but the volume dir is not a 417 // mountpoint, which is the state the system will be in after reboot. The dir 418 // should be mounter and the secret data written to it. 419 func TestPluginReboot(t *testing.T) { 420 var ( 421 testPodUID = types.UID("test_pod_uid3") 422 testVolumeName = "test_volume_name" 423 testNamespace = "test_secret_namespace" 424 testName = "test_secret_name" 425 426 volumeSpec = volumeSpec(testVolumeName, testName, 0644) 427 secret = secret(testNamespace, testName) 428 client = fake.NewSimpleClientset(&secret) 429 pluginMgr = volume.VolumePluginMgr{} 430 rootDir, host = newTestHost(t, client) 431 ) 432 defer os.RemoveAll(rootDir) 433 pluginMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) 434 435 plugin, err := pluginMgr.FindPluginByName(secretPluginName) 436 if err != nil { 437 t.Fatal("Can't find the plugin by name") 438 } 439 440 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}} 441 mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) 442 if err != nil { 443 t.Errorf("Failed to make a new Mounter: %v", err) 444 } 445 if mounter == nil { 446 t.Fatalf("Got a nil Mounter") 447 } 448 449 podMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid3/plugins/kubernetes.io~secret/test_volume_name", rootDir) 450 util.SetReady(podMetadataDir) 451 volumePath := mounter.GetPath() 452 if !hasPathSuffix(volumePath, "pods/test_pod_uid3/volumes/kubernetes.io~secret/test_volume_name") { 453 t.Errorf("Got unexpected path: %s", volumePath) 454 } 455 456 err = mounter.SetUp(volume.MounterArgs{}) 457 if err != nil { 458 t.Errorf("Failed to setup volume: %v", err) 459 } 460 if _, err := os.Stat(volumePath); err != nil { 461 if os.IsNotExist(err) { 462 t.Errorf("SetUp() failed, volume path not created: %s", volumePath) 463 } else { 464 t.Errorf("SetUp() failed: %v", err) 465 } 466 } 467 468 doTestSecretDataInVolume(volumePath, secret, t) 469 doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t) 470 } 471 472 func TestPluginOptional(t *testing.T) { 473 var ( 474 testPodUID = types.UID("test_pod_uid") 475 testVolumeName = "test_volume_name" 476 testNamespace = "test_secret_namespace" 477 testName = "test_secret_name" 478 trueVal = true 479 480 volumeSpec = volumeSpec(testVolumeName, testName, 0644) 481 client = fake.NewSimpleClientset() 482 pluginMgr = volume.VolumePluginMgr{} 483 rootDir, host = newTestHost(t, client) 484 ) 485 volumeSpec.Secret.Optional = &trueVal 486 defer os.RemoveAll(rootDir) 487 pluginMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) 488 489 plugin, err := pluginMgr.FindPluginByName(secretPluginName) 490 if err != nil { 491 t.Fatal("Can't find the plugin by name") 492 } 493 494 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}} 495 mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) 496 if err != nil { 497 t.Errorf("Failed to make a new Mounter: %v", err) 498 } 499 if mounter == nil { 500 t.Errorf("Got a nil Mounter") 501 } 502 503 volumePath := mounter.GetPath() 504 if !hasPathSuffix(volumePath, "pods/test_pod_uid/volumes/kubernetes.io~secret/test_volume_name") { 505 t.Errorf("Got unexpected path: %s", volumePath) 506 } 507 508 err = mounter.SetUp(volume.MounterArgs{}) 509 if err != nil { 510 t.Errorf("Failed to setup volume: %v", err) 511 } 512 if _, err := os.Stat(volumePath); err != nil { 513 if os.IsNotExist(err) { 514 t.Errorf("SetUp() failed, volume path not created: %s", volumePath) 515 } else { 516 t.Errorf("SetUp() failed: %v", err) 517 } 518 } 519 520 // secret volume should create its own empty wrapper path 521 podWrapperMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid/plugins/kubernetes.io~empty-dir/wrapped_test_volume_name", rootDir) 522 523 if _, err := os.Stat(podWrapperMetadataDir); err != nil { 524 if os.IsNotExist(err) { 525 t.Errorf("SetUp() failed, empty-dir wrapper path is not created: %s", podWrapperMetadataDir) 526 } else { 527 t.Errorf("SetUp() failed: %v", err) 528 } 529 } 530 531 datadirSymlink := filepath.Join(volumePath, "..data") 532 datadir, err := os.Readlink(datadirSymlink) 533 if err != nil && os.IsNotExist(err) { 534 t.Fatalf("couldn't find volume path's data dir, %s", datadirSymlink) 535 } else if err != nil { 536 t.Fatalf("couldn't read symlink, %s", datadirSymlink) 537 } 538 datadirPath := filepath.Join(volumePath, datadir) 539 540 infos, err := ioutil.ReadDir(volumePath) 541 if err != nil { 542 t.Fatalf("couldn't find volume path, %s", volumePath) 543 } 544 if len(infos) != 0 { 545 for _, fi := range infos { 546 if fi.Name() != "..data" && fi.Name() != datadir { 547 t.Errorf("empty data volume directory, %s, is not empty. Contains: %s", datadirSymlink, fi.Name()) 548 } 549 } 550 } 551 552 infos, err = ioutil.ReadDir(datadirPath) 553 if err != nil { 554 t.Fatalf("couldn't find volume data path, %s", datadirPath) 555 } 556 if len(infos) != 0 { 557 t.Errorf("empty data directory, %s, is not empty. Contains: %s", datadirSymlink, infos[0].Name()) 558 } 559 560 defer doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t) 561 } 562 563 func TestPluginOptionalKeys(t *testing.T) { 564 var ( 565 testPodUID = types.UID("test_pod_uid") 566 testVolumeName = "test_volume_name" 567 testNamespace = "test_secret_namespace" 568 testName = "test_secret_name" 569 trueVal = true 570 571 volumeSpec = volumeSpec(testVolumeName, testName, 0644) 572 secret = secret(testNamespace, testName) 573 client = fake.NewSimpleClientset(&secret) 574 pluginMgr = volume.VolumePluginMgr{} 575 rootDir, host = newTestHost(t, client) 576 ) 577 volumeSpec.VolumeSource.Secret.Items = []v1.KeyToPath{ 578 {Key: "data-1", Path: "data-1"}, 579 {Key: "data-2", Path: "data-2"}, 580 {Key: "data-3", Path: "data-3"}, 581 {Key: "missing", Path: "missing"}, 582 } 583 volumeSpec.Secret.Optional = &trueVal 584 defer os.RemoveAll(rootDir) 585 pluginMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, host) 586 587 plugin, err := pluginMgr.FindPluginByName(secretPluginName) 588 if err != nil { 589 t.Fatal("Can't find the plugin by name") 590 } 591 592 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}} 593 mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{}) 594 if err != nil { 595 t.Errorf("Failed to make a new Mounter: %v", err) 596 } 597 if mounter == nil { 598 t.Errorf("Got a nil Mounter") 599 } 600 601 volumePath := mounter.GetPath() 602 if !hasPathSuffix(volumePath, "pods/test_pod_uid/volumes/kubernetes.io~secret/test_volume_name") { 603 t.Errorf("Got unexpected path: %s", volumePath) 604 } 605 606 err = mounter.SetUp(volume.MounterArgs{}) 607 if err != nil { 608 t.Errorf("Failed to setup volume: %v", err) 609 } 610 if _, err := os.Stat(volumePath); err != nil { 611 if os.IsNotExist(err) { 612 t.Errorf("SetUp() failed, volume path not created: %s", volumePath) 613 } else { 614 t.Errorf("SetUp() failed: %v", err) 615 } 616 } 617 618 // secret volume should create its own empty wrapper path 619 podWrapperMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid/plugins/kubernetes.io~empty-dir/wrapped_test_volume_name", rootDir) 620 621 if _, err := os.Stat(podWrapperMetadataDir); err != nil { 622 if os.IsNotExist(err) { 623 t.Errorf("SetUp() failed, empty-dir wrapper path is not created: %s", podWrapperMetadataDir) 624 } else { 625 t.Errorf("SetUp() failed: %v", err) 626 } 627 } 628 doTestSecretDataInVolume(volumePath, secret, t) 629 defer doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t) 630 631 // Metrics only supported on linux 632 metrics, err := mounter.GetMetrics() 633 if runtime.GOOS == "linux" { 634 assert.NotEmpty(t, metrics) 635 assert.NoError(t, err) 636 } else { 637 t.Skipf("Volume metrics not supported on %s", runtime.GOOS) 638 } 639 } 640 641 func volumeSpec(volumeName, secretName string, defaultMode int32) *v1.Volume { 642 return &v1.Volume{ 643 Name: volumeName, 644 VolumeSource: v1.VolumeSource{ 645 Secret: &v1.SecretVolumeSource{ 646 SecretName: secretName, 647 DefaultMode: &defaultMode, 648 }, 649 }, 650 } 651 } 652 653 func secret(namespace, name string) v1.Secret { 654 return v1.Secret{ 655 ObjectMeta: metav1.ObjectMeta{ 656 Namespace: namespace, 657 Name: name, 658 }, 659 Data: map[string][]byte{ 660 "data-1": []byte("value-1"), 661 "data-2": []byte("value-2"), 662 "data-3": []byte("value-3"), 663 }, 664 } 665 } 666 667 func doTestSecretDataInVolume(volumePath string, secret v1.Secret, t *testing.T) { 668 for key, value := range secret.Data { 669 secretDataHostPath := filepath.Join(volumePath, key) 670 if _, err := os.Stat(secretDataHostPath); err != nil { 671 t.Fatalf("SetUp() failed, couldn't find secret data on disk: %v", secretDataHostPath) 672 } else { 673 actualSecretBytes, err := ioutil.ReadFile(secretDataHostPath) 674 if err != nil { 675 t.Fatalf("Couldn't read secret data from: %v", secretDataHostPath) 676 } 677 678 actualSecretValue := string(actualSecretBytes) 679 if string(value) != actualSecretValue { 680 t.Errorf("Unexpected value; expected %q, got %q", value, actualSecretValue) 681 } 682 } 683 } 684 } 685 686 func doTestCleanAndTeardown(plugin volume.VolumePlugin, podUID types.UID, testVolumeName, volumePath string, t *testing.T) { 687 unmounter, err := plugin.NewUnmounter(testVolumeName, podUID) 688 if err != nil { 689 t.Errorf("Failed to make a new Unmounter: %v", err) 690 } 691 if unmounter == nil { 692 t.Fatalf("Got a nil Unmounter") 693 } 694 695 if err := unmounter.TearDown(); err != nil { 696 t.Errorf("Expected success, got: %v", err) 697 } 698 if _, err := os.Stat(volumePath); err == nil { 699 t.Errorf("TearDown() failed, volume path still exists: %s", volumePath) 700 } else if !os.IsNotExist(err) { 701 t.Errorf("TearDown() failed: %v", err) 702 } 703 } 704 705 func hasPathSuffix(s, suffix string) bool { 706 return strings.HasSuffix(s, filepath.FromSlash(suffix)) 707 }