Repository: kubernetes-sigs/azurefile-csi-driver
Pull request #515 (2021-01-04 03:43:56)

test: refine windows ut
<!--  Thanks for sending a pull request!  Here are some tips for you:

1. If this is your first time, please read our contributor guidelines: https://git.k8s.io/community/contributors/guide#your-first-contribution and developer guide https://git.k8s.io/community/contributors/devel/development.md#development-guide
2. Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request. For reference on required PR/issue labels, read here:
https://git.k8s.io/community/contributors/devel/release.md#issue-kind-label
3. Ensure you have added or ran the appropriate tests for your PR: https://git.k8s.io/community/contributors/devel/testing.md
4. If you want *faster* PR reviews, read how: https://git.k8s.io/community/contributors/guide/pull-requests.md#best-practices-for-faster-reviews
5. Follow the instructions for writing a release note: https://git.k8s.io/community/contributors/guide/release-notes.md
6. If the PR is unfinished, see how to mark it: https://git.k8s.io/community/contributors/guide/pull-requests.md#marking-unfinished-pull-requests
-->

**What type of PR is this?**
/kind test

**What this PR does / why we need it**:
test: refine windows ut

**Which issue(s) this PR fixes**:
<!-- 
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
Fixes #

**Requirements**:
- [ ] uses [conventional commit messages](https://www.conventionalcommits.org/)
  <!-- Common commit types:
        build: Build 🏭
        chore: Maintenance 🔧
        ci: Continuous Integration 💜
        docs: Documentation 📘
        feat: Features 🌈
        fix: Bug Fixes 🐞
        perf: Performance Improvements 🚀
        refactor: Code Refactoring 💎
        revert: Revert Change ◀️
        style: Code Style 🎶
        security: Security Fix 🛡️
        test: Testing 💚 -->
- [ ] includes documentation
- [ ] adds unit tests
- [ ] tested upgrade from previous version

**Special notes for your reviewer**:


**Release note**:
```
none
```


k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/azurefile-csi-driver/pull/515#" title="Author self-approved">andyzhangx</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fazurefile-csi-driver).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/azurefile-csi-driver/blob/master/OWNERS)~~ [andyzhangx]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
k8s-ci-robot: @andyzhangx: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-azurefile-csi-driver-verify | c589ee4eb880c09193ccd902a9cfbcb51dd3b698 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_azurefile-csi-driver/515/pull-azurefile-csi-driver-verify/1345938995053334528) | `/test pull-azurefile-csi-driver-verify`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=azurefile-csi-driver&pr=515). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aandyzhangx). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/azurefile-csi-driver/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @andyzhangx: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-azurefile-csi-driver-verify | c589ee4eb880c09193ccd902a9cfbcb51dd3b698 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_azurefile-csi-driver/515/pull-azurefile-csi-driver-verify/1345938995053334528) | `/test pull-azurefile-csi-driver-verify`
pull-azurefile-csi-driver-unit | c589ee4eb880c09193ccd902a9cfbcb51dd3b698 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_azurefile-csi-driver/515/pull-azurefile-csi-driver-unit/1345938995074306048) | `/test pull-azurefile-csi-driver-unit`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=azurefile-csi-driver&pr=515). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aandyzhangx). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/azurefile-csi-driver/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/pkg/azurefile/fake_mounter.go b/pkg/azurefile/fake_mounter.go
index 8b794ee40..9e026d06d 100644
--- a/pkg/azurefile/fake_mounter.go
+++ b/pkg/azurefile/fake_mounter.go
@@ -18,9 +18,11 @@ package azurefile
 
 import (
 	"fmt"
+	"runtime"
 	"strings"
 
 	"k8s.io/utils/mount"
+	"sigs.k8s.io/azurefile-csi-driver/pkg/mounter"
 )
 
 type fakeMounter struct {
@@ -59,3 +61,13 @@ func (f *fakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
 	}
 	return true, nil
 }
+
+//NewFakeMounter fake mounter
+func NewFakeMounter() (*mount.SafeFormatAndMount, error) {
+	if runtime.GOOS == "windows" {
+		return mounter.NewSafeMounter()
+	}
+	return &mount.SafeFormatAndMount{
+		Interface: &fakeMounter{},
+	}, nil
+}


Test patch:
diff --git a/pkg/azurefile/nodeserver_test.go b/pkg/azurefile/nodeserver_test.go
index 9bdf7fb14..7d132b608 100644
--- a/pkg/azurefile/nodeserver_test.go
+++ b/pkg/azurefile/nodeserver_test.go
@@ -23,6 +23,7 @@ import (
 	"os"
 	"reflect"
 	"runtime"
+	"strings"
 	"syscall"
 	"testing"
 
@@ -52,6 +53,17 @@ type ExecArgs struct {
 	err     error
 }
 
+func matchFlakyWindowsError(mainError error, substr string) bool {
+	var errorMessage string
+	if mainError == nil {
+		errorMessage = ""
+	} else {
+		errorMessage = mainError.Error()
+	}
+
+	return strings.Contains(errorMessage, substr)
+}
+
 func TestNodeGetInfo(t *testing.T) {
 	d := NewFakeDriver()
 
@@ -326,6 +338,7 @@ func TestNodeStageVolume(t *testing.T) {
 		shareNameField:  "test_sharename",
 		serverNameField: "test_servername",
 	}
+	errorSource := "\\\\\\\\test_servername\\\\test_sharename"
 
 	secrets := map[string]string{
 		"accountname": "k8s",
@@ -338,6 +351,13 @@ func TestNodeStageVolume(t *testing.T) {
 		execScripts  []ExecArgs
 		skipOnDarwin bool
 		expectedErr  testutil.TestError
+		// use this field only when Windows
+		// gives flaky error messages due
+		// to CSI proxy
+		// This field holds the base error message
+		// that is common amongst all other flaky
+		// error messages
+		flakyWindowsErrorMessage string
 	}{
 		{
 			desc:        "[Error] Volume ID missing",
@@ -397,9 +417,11 @@ func TestNodeStageVolume(t *testing.T) {
 				VolumeContext:    volContext,
 				Secrets:          secrets},
 			skipOnDarwin: true,
+			flakyWindowsErrorMessage: fmt.Sprintf("volume(vol_1##) mount \"%s\" on %#v failed "+
+				"with smb mapping failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.",
+				errorSource, errorMountSensSource),
 			expectedErr: testutil.TestError{
 				DefaultError: status.Errorf(codes.Internal, fmt.Sprintf("volume(vol_1##) mount \"//test_servername/test_sharename\" on %#v failed with fake MountSensitive: target error", errorMountSensSource)),
-				WindowsError: fmt.Errorf("prepare stage path failed for %s with error: could not cast to csi proxy class", errorMountSensSource),
 			},
 		},
 		{
@@ -413,9 +435,11 @@ func TestNodeStageVolume(t *testing.T) {
 				{"mkfs.ext4", []string{"-F", "-m0", testDiskPath}, "", fmt.Errorf("formatting failed")},
 			},
 			skipOnDarwin: true,
+			flakyWindowsErrorMessage: fmt.Sprintf("volume(vol_1##) mount \"%s\" on %#v failed with "+
+				"smb mapping failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.",
+				errorSource, proxyMountPath),
 			expectedErr: testutil.TestError{
 				DefaultError: status.Errorf(codes.Internal, "could not format %#v and mount it at %#v", sourceTest, testDiskPath),
-				WindowsError: fmt.Errorf("prepare stage path failed for %s with error: could not cast to csi proxy class", proxyMountPath),
 			},
 		},
 		{
@@ -424,9 +448,10 @@ func TestNodeStageVolume(t *testing.T) {
 				VolumeCapability: &stdVolCap,
 				VolumeContext:    volContext,
 				Secrets:          secrets},
-			expectedErr: testutil.TestError{
-				WindowsError: fmt.Errorf("prepare stage path failed for %s with error: could not cast to csi proxy class", sourceTest),
-			},
+			flakyWindowsErrorMessage: fmt.Sprintf("volume(vol_1##) mount \"%s\" on %#v failed with "+
+				"smb mapping failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.",
+				errorSource, sourceTest),
+			expectedErr: testutil.TestError{},
 		},
 		{
 			desc: "[Success] Valid request with share name empty",
@@ -434,9 +459,10 @@ func TestNodeStageVolume(t *testing.T) {
 				VolumeCapability: &stdVolCap,
 				VolumeContext:    volContextEmptyShareName,
 				Secrets:          secrets},
-			expectedErr: testutil.TestError{
-				WindowsError: fmt.Errorf("prepare stage path failed for %s with error: could not cast to csi proxy class", sourceTest),
-			},
+			flakyWindowsErrorMessage: fmt.Sprintf("volume(vol_1##) mount \"\\\\\\\\k8s.file.test_suffix\\\\test_sharename\" on %#v failed with "+
+				"smb mapping failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.",
+				sourceTest),
+			expectedErr: testutil.TestError{},
 		},
 		{
 			desc: "[Success] Valid request with fsType as nfs",
@@ -444,9 +470,10 @@ func TestNodeStageVolume(t *testing.T) {
 				VolumeCapability: &stdVolCap,
 				VolumeContext:    volContextNfs,
 				Secrets:          secrets},
-			expectedErr: testutil.TestError{
-				WindowsError: fmt.Errorf("prepare stage path failed for %s with error: could not cast to csi proxy class", sourceTest),
-			},
+			flakyWindowsErrorMessage: fmt.Sprintf("volume(vol_1##) mount \"%s\" on %#v failed with "+
+				"smb mapping failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.",
+				errorSource, sourceTest),
+			expectedErr: testutil.TestError{},
 		},
 		{
 			desc: "[Success] Valid request with supported fsType disk",
@@ -458,9 +485,10 @@ func TestNodeStageVolume(t *testing.T) {
 				{"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", testDiskPath}, "", nil},
 				{"mkfs.ext4", []string{"-F", "-m0", testDiskPath}, "", nil},
 			},
-			expectedErr: testutil.TestError{
-				WindowsError: fmt.Errorf("prepare stage path failed for %s with error: could not cast to csi proxy class", proxyMountPath),
-			},
+			flakyWindowsErrorMessage: fmt.Sprintf("volume(vol_1##) mount \"%s\" on %#v failed with "+
+				"smb mapping failed with error: rpc error: code = Unknown desc = NewSmbGlobalMapping failed.",
+				errorSource, proxyMountPath),
+			expectedErr: testutil.TestError{},
 		},
 	}
 
@@ -471,30 +499,39 @@ func TestNodeStageVolume(t *testing.T) {
 		if test.skipOnDarwin && runtime.GOOS == "darwin" {
 			continue
 		}
-		fakeMounter := &fakeMounter{}
-		fakeExec := &testingexec.FakeExec{ExactOrder: true}
-
-		for _, script := range test.execScripts {
-			fakeCmd := &testingexec.FakeCmd{}
-			cmdAction := makeFakeCmd(fakeCmd, script.command, script.args...)
-			outputAction := makeFakeOutput(script.output, script.err)
-			fakeCmd.CombinedOutputScript = append(fakeCmd.CombinedOutputScript, outputAction)
-			fakeExec.CommandScript = append(fakeExec.CommandScript, cmdAction)
+		mounter, err := NewFakeMounter()
+		if err != nil {
+			t.Fatalf(fmt.Sprintf("failed to get fake mounter: %v", err))
 		}
 
-		d.mounter = &mount.SafeFormatAndMount{
-			Interface: fakeMounter,
-			Exec:      fakeExec,
+		if runtime.GOOS != "windows" {
+			fakeExec := &testingexec.FakeExec{ExactOrder: true}
+			for _, script := range test.execScripts {
+				fakeCmd := &testingexec.FakeCmd{}
+				cmdAction := makeFakeCmd(fakeCmd, script.command, script.args...)
+				outputAction := makeFakeOutput(script.output, script.err)
+				fakeCmd.CombinedOutputScript = append(fakeCmd.CombinedOutputScript, outputAction)
+				fakeExec.CommandScript = append(fakeExec.CommandScript, cmdAction)
+			}
+			mounter.Exec = fakeExec
 		}
+
+		d.mounter = mounter
 		d.cloud = &azure.Cloud{
 			Environment: azure2.Environment{StorageEndpointSuffix: "test_suffix"},
 		}
 
-		_, err := d.NodeStageVolume(context.Background(), &test.req)
-		if !testutil.AssertError(err, &test.expectedErr) {
-			t.Errorf("Desc: %s\nUnexpected error: %v\nExpected: %v", test.desc, err, test.expectedErr.GetExpectedError())
+		_, err = d.NodeStageVolume(context.Background(), &test.req)
+		// separate assertion for flaky error messages
+		if test.flakyWindowsErrorMessage != "" && runtime.GOOS == "windows" {
+			if !matchFlakyWindowsError(err, test.flakyWindowsErrorMessage) {
+				t.Errorf("test case: %s, \nUnexpected error: %v\nExpected error: %v", test.desc, err, test.flakyWindowsErrorMessage)
+			}
+		} else {
+			if !testutil.AssertError(err, &test.expectedErr) {
+				t.Errorf("test case: %s, \nUnexpected error: %v\nExpected error: %v", test.desc, err, test.expectedErr.GetExpectedError())
+			}
 		}
-
 	}
 
 	// Clean up