-
Notifications
You must be signed in to change notification settings - Fork 1k
test harness should be able to expect errors #319
Conversation
@tro3 thanks for the feedback, have moved to this PR as I did something wrong with git. I feel as though we should have a test case for the scenario when you have a manifest file already when calling
It looks like stderr gets the correct error message then dep exits with |
Actually, I think I need to look at the output of |
Agreed that parsing stderr would be preferable, if robust.
Perhaps it would make sense to merge this as a first pass, then I could update my PR to include the error handling json update. With both merged, the stderr parsing could be a new PR. @sdboyer, thoughts?
|
@@ -57,7 +57,8 @@ The `testcase.json` file has the following format: | |||
"github.com/sdboyer/deptestdos", | |||
"github.com/sdboyer/deptesttres", | |||
"github.com/sdboyer/deptestquatro" | |||
] | |||
], | |||
"error-expected":"something went wrong" |
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.
nit: space between colon and initial quote around value
Seems to me like right thing to do here is to only allow for an error on the final command in the list. If we don't make that assumption, then we pretty much have to allow for multiple errors to be specified. If we do think we should allow errors from commands other than the final one, then rather than adding a new key to the JSON format, I think I'd prefer to see the command declaration elements themselves become 2-tuples, where the first element is the command and the second element is the (optional) error. That groups them together both logically and visually. |
I agree that only the final command error need be checked. |
OK, let's refactor that loop accordingly, then - it's an immediate failure if anything other than the final command reports an error. |
I agree, I think we should only expect a single error from the final command. Will do it in a min. |
Should now only look at the error on the final command, going to see if I can now use |
My implementation may be a little naive so would appreciate feedback, I've basically done a Also, simplified the error from When running the test I do need to make sure a |
Down this path, we can't add auto update to the testcase.json file. I'm okay with this, subject to @sdboyer |
This last commit means we will not be forced to have |
cmd/dep/integration_test.go
Outdated
for i, args := range testCase.Commands { | ||
err = testProj.DoRun(args) | ||
if err != nil { | ||
if i+1 != len(testCase.Commands) { |
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.
A sylistic nit, but I'd make this one statement if err != nil && i < len(testCase.commands)-1
to cut back on indentation lvls, and change the message to just "unexpected error raised: $s" (ie ditch the "non-final" bit).
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.
Will do 😃 thanks
@@ -0,0 +1 @@ | |||
{} |
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.
What is this?
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.
Empty manifest in final, thought it was needed if we pass the exception test will double check and remove if not needed.
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.
I like the "don't check a nonexistent file" plan you proposed, in which case its not needed.
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.
My question was more about the wierd symbol in the Files Changed area. Likely a "no ending newline" meaning.
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.
Your right i think I can remove it when i get the non existing file issue sorted.
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.
I thought it was probably best to keep this just to make sure that the manifest didn't change as it shouldn't have in this scenario.
test/test.go
Outdated
@@ -505,6 +505,10 @@ func (h *Helper) Path(name string) string { | |||
joined = filepath.Join(h.tempdir, name) | |||
} | |||
|
|||
if _, err := os.Stat(joined); os.IsNotExist(err) { | |||
return "" | |||
} |
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.
If this is to help with nonexistent final
files, I think I'd move this to CompareFile. I'm ok changing the logic there to be "don't check file if not in final
".
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.
Yeah, so we can take out lock.json
and poss (as above) the manifest.json
if not needed in the final
folder.
Reason I put it here (not that it feels right) is that we don't get into CompareFile
as symlink check below fails.
We take another look in the morning at how I might be able to move this but recommendations welcome.
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.
What do you mean by "symlink check fails"?
test/test.go
Outdated
if _, err := os.Stat(joined); os.IsNotExist(err) { | ||
return "" | ||
} | ||
|
||
// Ensure it's the absolute, symlink-less path we're returning | ||
abs, err := filepath.EvalSymlinks(joined) |
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.
@tro3 this line returns err
if a file that it expects in final
does not exist.
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.
For which test case? When I remove final/manifest.json
from a test and run it, I only get a proper "manifest created where none was expected" error from CompareFile. If this error was ignored, you'd get the effect you're looking for without the need for the above, no?
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.
If i remove the check and run the manifest-exists test i get an error as before going into CompareFile it tries to get the path to the lock in
final.
Will run again and share the stack trace from the error in the morning.
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.
Oh, I see - ProjPath (which calls TestHelper.Path) is getting called. I'd be comfortable rewriting ProjPath to be just what I had originally intended: $TMPDIR + ROOT + path, rather than running the symlink check. @sdboyer, does the symlink check called by TestHelper.Path really need to be done for these temp projects where all contents were copied over from testdata?
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.
@sdboyer this is the initial reason i moved out the symlink check ... looking now if i can do it a different way 👍
Not sure why Travis is unhappy, the error is:
|
Travis doesn't like something about the formatting in your |
Thank you 👍 I am a total noob and relied on Atom to run |
I'm a bit of a noob myself, so I'll defer to @sdboyer for the professional review. My only comments:
|
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.
good progress! mostly nits, but a couple things to fix.
cmd/dep/integration_test.go
Outdated
for i, args := range testCase.Commands { | ||
err = testProj.DoRun(args) | ||
if err != nil && i < len(testCase.Commands)-1 { | ||
t.Fatalf("unexpected error raised: %s", err.Error()) |
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.
Let's include additional context here by also printing the name of the command that errored.
8. Check the `vendor` directory for the projects listed under `vendor-final` | ||
9. Check that there were no changes to `src` listings | ||
10. Clean up | ||
7. Check that only an expected error was raised from the final command |
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.
This wording here is a bit confusing. How about this:
"Ensure that, if any errors are raised, it is only by the final command and their string output matches error-expected
"
test/integration_testcase.go
Outdated
} | ||
|
||
wantExists, want := len(tc.ErrorExpected) > 0, tc.ErrorExpected | ||
gotExists, got := len(stderr) > 0, stderr |
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.
It's more idiomatic to compare to the empty string, rather than checking string length: tc.ErrorExpected != ""
test/integration_testcase.go
Outdated
return false, "", nil | ||
} | ||
|
||
f, err := ioutil.ReadFile(abs) |
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.
Is this change actually needed? I believe ioutil.ReadFile()
will traverse symlinks itself, if needed.
Or is it just so that we can differentiate the return values with the first parameter?
I realize this function isn't being introduced in this PR, but let's please add at least some named return values in order to clarify what's happening with those values: (exists bool, contents string, err error)
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.
tbh, I am unsure if that symlink was needed so will remove it for the moment. As mentioned in the above comment I removed it from a different file as it caused the tests to fail when no lock.json
was in the final
dir.
test/integration_testcase.go
Outdated
@@ -118,7 +140,14 @@ func getFile(path string) (bool, string, error) { | |||
if err != nil { | |||
return false, "", nil | |||
} | |||
f, err := ioutil.ReadFile(path) | |||
|
|||
// Ensure it's the absolute, symlink-less path we're returning |
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.
This comment does not seem to match with the actual goal of what's happening here - is it copied from elsewhere?
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.
So I removed this from Path
in test.go
here as in my final
I didnt have a lock.json
(is some discussion above).
Will remove it from here as well for the moment.
What is the opinion on passing stderr as a |
No strong opinion from me. I need to see the system in action first anyway, so my preference would be to merge it and tweak after that fact. |
@sdboyer have made suggested changes, I'm not sure why |
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.
SO sorry for such a long delay 😢
Let's just encapsulate those symlink changes in a way that doesn't change any relevant conditions for other, non-harness tests, and then I think this is ready to go.
@@ -506,12 +506,7 @@ func (h *Helper) Path(name string) string { | |||
joined = filepath.Join(h.tempdir, name) | |||
} | |||
|
|||
// Ensure it's the absolute, symlink-less path we're returning | |||
abs, err := filepath.EvalSymlinks(joined) |
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.
I'm not sure this is the best idea, as other tests with potentially different assumptions rely on it. If we really need to drop this for the harness' purposes, then could we introduce a separate method without the symlink call that the harness can use?
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.
Yep no problem, am away in Flanders this weekend so will fix it up as soon as I'm home 👍
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.
In the test TestIntegration/init/manifest-exists
it doesnt like doing the SymLinks checkas the lock
file doesnt exist in final and so the code I removes gives me this error:
lstat /private/var/folders/q9/jmtltdhs5hd8574dpdqgn40c0000gn/T/gotest220558389/src/github.com/golang/notexist/lock.json: no such file or directory
However, adding that file in /github.com/golang/dep/cmd/dep/testdata/harness_tests/init/manifest-exists/final
seems abit counter intuative as when the tests ends it shouldnt be there as we are testing that if a manifest already exists for a reason we error before generating a lock
file.
If I created a new method we would have to change the line https://github.com/golang/dep/blob/master/cmd/dep/integration_test.go#L60 so that it got to call the new method that handled the files not existing.
We could however just return an empty string if we got an error in from EvalSymlinks
.
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.
Would be good to have a bit of a shove in the right direction with how to choose to fix this one up.
Will look at merging in master to this branch and see how its looking, or maybe just do a new PR whichever is easier. @sdboyer any thoughts on the direction I should be going with the symlink issue? |
@domgreen sorry for delay - honestly, it's because symlinks are kinda crushing my soul right now 😱 With how long this has been open and running, and if you're willing, it might be best to start a fresh PR rather than having all this history. Hopefully then I can cajole myself into diving down another symlink rabbit hole 😛 Again, sorry for the delay, and I appreciate your patience and continued effort on this so, so much! |
@sdboyer no probs, will do 😄 |
replaced with #402 |
Initial PR was #317 I seemed to have messed up my branch 😢