-
Notifications
You must be signed in to change notification settings - Fork 47
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
Add Exe matcher for Windows releases. #46
Conversation
hey!, thx for the contribution. Mind adding a test for this case here?. https://github.com/marcosnils/bin/blob/main/pkg/assets/assets_test.go#L7 Thx! |
Just realized that we already had a test case for this. Is this ready to be merged @interpeix ? LMK so I can merge and release |
Sorry @marcosnils , I made a mistake and push another change related to fix the .cmd file generated by the docker provider in the same branch with this PR still opened. How do you want me to proceed? Close this one and open another two PR? |
It's not really necessary, we can include it here also.
Hmm that makes sense.. Since I didn't have any tests when I first started the project I wasn't thinking a lot about running tests in windows. Is there a chance you can help me with that? |
I can try to find a way to test it. Maybe not in an elegant way, but i promise to do my best 😄 . |
Ignore the vscode devcontainer configuration
@marcosnils take a look at my latest changes to be able to test in both platforms. |
pkg/assets/assets_test.go
Outdated
//TODO: For sure there will be a better option to divide/adapt tests based on OS | ||
//with this first iteration we can declare scenarios for windows and other OS | ||
//without modifiying the core code of the test. | ||
if runtime.GOOS == "windows" { |
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.
Just wondering if there's a reason of not using build flags and doing this instead 🤔
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.
You're right, I have read a bit about it before propose this. I'm not yet confident using those flags. Let me dig a bit more on that idea, or if you have any recommendation feel free to give me some advice 😄
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 me dig a bit more on that idea, or if you have any recommendation feel free to give me some advice
Sure, if you check the stdlib, there are several examples on how they use build flags for tests on different platforms. i.e https://github.com/golang/go/blob/master/src/os/error_windows_test.go
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.
Ok, IIRC we can use build tags and build flags.
With flags we can do something like this:
var windows = flag.Bool("windows", false, "only perform windows tests")
func TestSanitizeName(t *testing.T) {
type sample struct {
in string
v string
out string
}
var cases []sample
//TODO: For sure there will be a better option to divide/adapt tests based on OS
//with this first iteration we can declare scenarios for windows and other OS
//without modifiying the core code of the test.
if *windows {
cases = []sample{
{"bin_0.0.1_Windows_x86_64.exe","0.0.1","bin.exe"},
}
} else {
what it's more like the previous solution using a conditional.
With tags we need to make two separate test files, for example: assets_test.go and assets_windows_test.go and put the special comment at the top of the file.
assets_test.go
//+build !windows
assets_windows_test.go
//+build windows
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.
With tags we need to make two separate test files, for example: assets_test.go and assets_windows_test.go and put the special comment at the top of the file.
assets_test.go
This is what I originally was referring to when I mentioned build flags. This is usually the standard way of doing multi-os tests in golang generally
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.
Lol..just realized I was actually typing "build flags" when what I actually meant is "build tags" as you're correctly pointing out. My apologies for the confusion. Build tags is definitely the way to go.
Also, I'm not sure if this should be the test that we should be actually splitting using tags. @interpeix when you were originally stating that current bin
tests don't run in windows. Why is it actually failing? I don't see any windows specific code on this file that it would require having a specific build tag.
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.
Lol..just realized I was actually typing "build flags" when what I actually meant is "build tags" as you're correctly pointing out. My apologies for the confusion. Build tags is definitely the way to go.
No worries 😄, I saw what you mean
Regarding the tests here is what is happening in my windows machine when I run it:
go test ./...
? github.com/marcosnils/bin [no test files]
? github.com/marcosnils/bin/cmd [no test files]
--- FAIL: TestSanitizeName (0.00s)
assets_test.go:22: Error replacing bin_amd64_linux: bin_linux does not match bin
Multiple matches found, please select one:
[1] bin_0.0.1_linux_x86_64
[2] bin_0.0.1_darwin_x86_64
Select an option: --- FAIL: TestFilterAssets (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x18 pc=0x124cb92]
goroutine 7 [running]:
testing.tRunner.func1.2(0x127f840, 0x1481480)
C:/Program Files/Go/src/testing/testing.go:1144 +0x345
testing.tRunner.func1(0xc000039500)
C:/Program Files/Go/src/testing/testing.go:1147 +0x4b6
panic(0x127f840, 0x1481480)
C:/Program Files/Go/src/runtime/panic.go:965 +0x1c7
github.com/marcosnils/bin/pkg/assets.TestFilterAssets(0xc000039500)
D:/projects/bin-fork/pkg/assets/assets_test.go:70 +0x832
testing.tRunner(0xc000039500, 0x12d7270)
C:/Program Files/Go/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
C:/Program Files/Go/src/testing/testing.go:1239 +0x2b3
FAIL github.com/marcosnils/bin/pkg/assets 0.058s
? github.com/marcosnils/bin/pkg/config [no test files]
? github.com/marcosnils/bin/pkg/options [no test files]
ok github.com/marcosnils/bin/pkg/providers (cached)
? github.com/marcosnils/bin/pkg/strings [no test files]
FAIL
Debugging the test I think the problem is at:
for _, c := range cases {
if n := SanitizeName(c.in, c.v); n != c.out {
t.Fatalf("Error replacing %s: %s does not match %s", c.in, n, c.out)
}
}
Inside the SanitizeName function there is a GetOS call:
func SanitizeName(name, version string) string {
name = strings.ToLower(name)
replacements := []string{}
// TODO maybe instead of doing this put everything in a map (set) and then
// generate the replacements? IDK.
firstPass := true
for _, osName := range config.GetOS() {
And the GetOS function:
func GetOS() []string {
return []string{runtime.GOOS}
}
So, the Test wants that GetOS function return "linux", but in my system that case is impossible, it always return "windows"
Maybe I made something wrong, what do you think?
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 just spent a bit more time into this and we should definitely not have to use build tags to improve these tests. The tests are effectively checking the name sanitization and the filtering, so we should be able to test this independently of the OS and Arch that they're being executed on. I'll send an update today to make this code more testable by including a mock of the GetOS and GetArch resolvers 🙏
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.
Cool!, I think that will be a better solution.
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.
Done, check #47
* Remove binaries by name * Reuse logic for finding binary path * make getBinPath check if arg is a path Co-authored-by: Cristian Dominguez <cristiand391@users.noreply.github.com>
Mock resolver
@marcosnils do you want me to change the base of the PR to feat/mock-server? |
Allow to mock OS and Arch for asset filtering tests
#47 is merged now so you should be able to rebase on the default branch (currently "master") to get the new mock :) |
Add .Exe to extensions matcher function, to be able to download windows releases.