-
Notifications
You must be signed in to change notification settings - Fork 151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend NodeUnpublish test to verify cleanup of TargetPath (#336) #338
Merged
k8s-ci-robot
merged 1 commit into
kubernetes-csi:master
from
dobsonj:336-NodeUnpublish-test
May 5, 2021
+172
−2
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -164,6 +164,14 @@ type TestConfig struct { | |
// n > 0: repeat each call n times | ||
// NewTestConfig() by default enables idempotency testing. | ||
IdempotentCount int | ||
|
||
// CheckPath is a callback function to check whether the given path exists. | ||
// If this is not set, then defaultCheckPath will be used instead. | ||
CheckPath func(path string) (PathKind, error) | ||
// Command to be executed for a customized way to check a given path. | ||
CheckPathCmd string | ||
// Timeout for the executed command to check a given path. | ||
CheckPathCmdTimeout time.Duration | ||
} | ||
|
||
// TestContext gets initialized by the sanity package before each test | ||
|
@@ -194,6 +202,7 @@ func NewTestConfig() TestConfig { | |
TestVolumeAccessType: "mount", | ||
IDGen: &DefaultIDGenerator{}, | ||
IdempotentCount: 10, | ||
CheckPathCmdTimeout: 10 * time.Second, | ||
|
||
DialOptions: []grpc.DialOption{grpc.WithInsecure()}, | ||
ControllerDialOptions: []grpc.DialOption{grpc.WithInsecure()}, | ||
|
@@ -449,3 +458,89 @@ func PseudoUUID() string { | |
func UniqueString(prefix string) string { | ||
return prefix + uniqueSuffix | ||
} | ||
|
||
// Return codes for CheckPath | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please introduce a type (like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
type PathKind string | ||
|
||
const ( | ||
PathIsFile PathKind = "file" | ||
PathIsDir PathKind = "directory" | ||
PathIsNotFound PathKind = "not_found" | ||
PathIsOther PathKind = "other" | ||
) | ||
|
||
// IsPathKind validates that the input string matches one of the defined | ||
// PathKind values above. If successful, it returns the corresponding | ||
// PathKind type. Otherwise, it returns an error. | ||
func IsPathKind(in string) (PathKind, error) { | ||
pk := PathKind(in) | ||
switch pk { | ||
case PathIsFile, PathIsDir, PathIsNotFound, PathIsOther: | ||
return pk, nil | ||
default: | ||
return pk, fmt.Errorf("invalid PathType: %s", pk) | ||
} | ||
} | ||
|
||
// defaultCheckPath runs os.Stat against the provided path and returns | ||
// a code indicating whether it's a file, directory, not found, or other. | ||
// If an error occurs, it returns an empty string along with the error. | ||
func defaultCheckPath(path string) (PathKind, error) { | ||
var pk PathKind | ||
fi, err := os.Stat(path) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
return PathIsNotFound, nil | ||
} else { | ||
return "", err | ||
} | ||
} | ||
switch mode := fi.Mode(); { | ||
case mode.IsRegular(): | ||
pk = PathIsFile | ||
case mode.IsDir(): | ||
pk = PathIsDir | ||
default: | ||
pk = PathIsOther | ||
} | ||
return pk, nil | ||
} | ||
|
||
// CheckPath takes a path parameter and returns a code indicating whether | ||
// it's a file, directory, not found, or other. This can be done using a | ||
// custom command, custom function, or by the defaultCheckPath function. | ||
// If an error occurs, it returns an empty string along with the error. | ||
func CheckPath(path string, config *TestConfig) (PathKind, error) { | ||
if path == "" { | ||
return "", fmt.Errorf("path argument must not be empty") | ||
} | ||
if config == nil { | ||
return "", fmt.Errorf("config argument must not be nil") | ||
} | ||
|
||
if config.CheckPathCmd != "" { | ||
// Check the provided path using the check path command. | ||
ctx, cancel := context.WithTimeout(context.Background(), config.CheckPathCmdTimeout) | ||
defer cancel() | ||
|
||
cmd := exec.CommandContext(ctx, config.CheckPathCmd, path) | ||
cmd.Stderr = os.Stderr | ||
out, err := cmd.Output() | ||
if err != nil { | ||
return "", fmt.Errorf("check path command %s failed: %v", config.CheckPathCmd, err) | ||
} | ||
// The output of this command is expected to match the value for | ||
// PathIsFile, PathIsDir, PathIsNotFound, or PathIsOther. | ||
pk, err := IsPathKind(strings.TrimSpace(string(out))) | ||
if err != nil { | ||
return "", fmt.Errorf("check path command %s failed: %v", config.CheckPathCmd, err) | ||
} | ||
return pk, nil | ||
} else if config.CheckPath != nil { | ||
// Check the path using a custom callback function. | ||
return config.CheckPath(path) | ||
} else { | ||
// Use defaultCheckPath if no custom function was provided. | ||
return defaultCheckPath(path) | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both should always be non-nil because they have defaults.
What you need to check for here is "sc.Config.CreateTargetDir not default and sc.Config.CheckPath not default".
Also, I think this only needs to be checked when
sc.Config.CreateTargetPathCmd
is unset. Otherwise we check and usesc.Config.CheckPathCmd
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createMountTargetLocation
has 2 separate paths, one for the custom function, but if that is nil then it calls mkdir.sc.Config.CreateTargetDir
is nil by default.https://github.com/dobsonj/csi-test/blob/a2091104af4d4e1df72bc6cfa8de4d955afa411a/pkg/sanity/sanity.go#L363-L378
Originally I did try to compare
sc.Config.CheckPath != defaultCheckPath
here, but got the following compile error:Which is interesting... I think that should work fine in C, but apparently not in Go.
So I ended up changing
CheckPath
to follow the same model ascreateMountTargetLocation
and leavesc.Config.CheckPath
set to nil by default, specifically so the check on line 463 would work.https://github.com/dobsonj/csi-test/blob/a2091104af4d4e1df72bc6cfa8de4d955afa411a/pkg/sanity/sanity.go#L539-L545
If
sc.Config.CreateTargetPathCmd
is set, we should hit the skip statement on line 461 and not make it down to line 464. UnlessCreateTargetPathCmd
,CheckPathCmd
, andCreateTargetDir
are all set at the same time, which seems strange. I can add a check for that though if that's what you're pointing out.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the part that I had missed. Then the current code is fine.