Skip to content
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

lib/ignore: Centralize handling of temporary filenames (fixes #3899) #3901

Closed
wants to merge 3 commits into from

Conversation

imsodin
Copy link
Member

@imsodin imsodin commented Jan 13, 2017

For purpose see #3899, short recap:
Creating temporary names and testing whether a name is temporary is a "static" test, meaning it is set at init() and never changed again. Passing it around from the models module is overly complicated and pointless. So this PR centralizes these functions in the ignore package for easy access for all libraries.

I also refactored the function shouldIgnore in models.go: The part that checks whether the filename is either internal, temporary or ignored is handled by ShouldIgnore in the ignores package. This might seem unnecessary, as it is currently only used in models.go, but it contextually belongs there and such a function will be needed in fswatcher as well. Shouldn't hurt, right?

The model tests (in specific rwfolder_test.go) use static test data with temporary windows prefixes. These were set in init() of the test itself, which worked as the prefix is an internal variable of the same package. Now it is an internal variable of the ignore package. I resolved this by adding an exported function to the ignore package, that manually sets the prefix to the windows type. I considered this less bad than exporting the prefix itself.
Is there any better way to both protect this variable in production and allow to set it for tests?

// SetWindowsPrefix is entirely reserved for testing, it should never be called
// in production code.
// It is needed to allow static test files independent from underlying os.
func SetWindowsPrefix() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me except for this method which is ugly and clobbers any other usage of temp files after usage, in tests by other packages for example. Better alternatives imho are exporting the variables themselves, or a more general setprefixes method that can be called before and after tests to restor.

@@ -25,9 +26,9 @@ func init() {
// We do this to make sure that the temp file required for the tests
// does not get removed during the tests. Also set the prefix so it's
// found correctly regardless of platform.
defTempNamer.prefix = windowsTempPrefix
ignore.SetWindowsPrefix()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use some reflect hack to access private methods or use the monkey patching library here.

I am not cool with exposing public API just for the sake of tests

@@ -418,3 +418,19 @@ func IsInternal(file string) bool {
}
return false
}

// ShouldIgnore returns true when a file is temporary, internal or ignored
func ShouldIgnore(filename string, matcher *Matcher) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels that matcher should have a ShouldIgnore mehod instead which does Match and other stuff internally.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@AudriusButkevicius
Copy link
Member

God damn github with it's new "oh I really want to comment" button that I keep forgetting to press.

@imsodin
Copy link
Member Author

imsodin commented Jan 15, 2017

@AudriusButkevicius I was already wondering about your strangely long silence xD

Regarding the testing uglyness: I can easily go ahead with calmh's proposition, but I agree with AudriusButkevicius: Ideally there should not be any exported function just for testing. Unfortunately I don't know the reflect hack or the monkey patching library, and google wasn't educating. Any hints?

@AudriusButkevicius
Copy link
Member

Or actuall, as @calmh suggests, just expose the variable.

@imsodin
Copy link
Member Author

imsodin commented Jan 15, 2017

Monkey (in its current form) would be pointless, as it can neither replace internal stuff nor variables, only exposed functions.
So I will expose the variable.

Regarding @calmh's comment

Looks good to me except for this method which is ugly and clobbers any other usage of temp files after usage, in tests by other packages for example.

Are imported packages only loaded (i.e. init() called) once or whenever they are explicitly imported?
In case of the former, resetting to the original prefix should not be necessary, right? If it is, is there any way to run a function that resets the prefix to the original value on exiting tests (sort of like the opposite of init())?

@AudriusButkevicius
Copy link
Member

AudriusButkevicius commented Jan 15, 2017

They are called once per binary invocation, which happens once for all tests I suspect.

So you need:

originalPrefix = package.Prefix
package.Prefix = "X"
defer func() {
  package.Prefix = originalPrefix
}()

@imsodin
Copy link
Member Author

imsodin commented Jan 15, 2017

I rubberducked it and found TestMain (and didn't read Audrius' comment early enough), thus did it through that. Is it ok?
I also exported the const vars WindowsTempPrefix and UnixTempPrefix for ease of use in testing and consistency.

@calmh
Copy link
Member

calmh commented Jan 17, 2017

@st-review lgtm

@st-review
Copy link

@calmh: Noted! Need another LGTM or explicit merge command.

@AudriusButkevicius
Copy link
Member

@st-review lgtm

@st-review
Copy link

👌 Merged as dbb3a34. Thanks, @imsodin!

@st-review st-review closed this Jan 17, 2017
st-review pushed a commit that referenced this pull request Jan 17, 2017
GitHub-Pull-Request: #3901
LGTM: calmh, AudriusButkevicius
@st-review st-review added the pr-merged Legacy label used in the past for pull requests merged to the main tree label Jan 15, 2018
@st-review st-review added the frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion label Jul 15, 2018
@syncthing syncthing locked and limited conversation to collaborators Jul 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion pr-merged Legacy label used in the past for pull requests merged to the main tree
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants