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

select relevant third-party tests to run their tests with garble on CI #240

Closed
mvdan opened this issue Feb 27, 2021 · 6 comments · Fixed by #537
Closed

select relevant third-party tests to run their tests with garble on CI #240

mvdan opened this issue Feb 27, 2021 · 6 comments · Fixed by #537
Milestone

Comments

@mvdan
Copy link
Member

mvdan commented Feb 27, 2021

For example, #190 shows us that programs using basic protobuf-generated code panic at init time. We could (and probably should) try to minimize the failure into a test case in garble, but we should also ensure that garble test ./... in a recent version of protobuf succeeds.

I propose this short list of projects as a start:

If this works well, we can add more. The selection criteria should roughly be:

  • Popularity - estimated, at this time
  • Quality - modules whose tests fail at times or take too long aren't useful
  • Diversity - a second CLI framework is less likely to introduce more edge cases
  • Past bugs - those libraries which have surfaced garble bugs before, like protobuf

I think we could have a nested module for this, like testdata/libraries/go.mod. A libs.go file would import at least one package from each module, to keep go mod tidy happy. We could then use GOPRIVATE='*' garble test all or somesuch, to run obfuscated versions of all tests in direct and indirect dependencies.

Some notes:

  • We probably want to use test's -short flag to save time, at least as a start.
  • We should check that go test all succeeds first, to reduce confusion if one of the tests is just broken.
  • Are we interested in running the tests of indirect dependencies? Probably yes, as test failures in those could break the direct dependencies.
  • Ideally, the CI check would run everywhere, including pushes to master and PRs. In practice, we'll see how fast or slow it ends up being. Maybe we end up using a subset of the tests, or -short, for PRs.
@mvdan
Copy link
Member Author

mvdan commented Feb 27, 2021

Also, this is blocked by #241.

@mvdan
Copy link
Member Author

mvdan commented Feb 28, 2021

I forgot to say what is perhaps obvious; garble test std should be at the top of the list, because standard library packages are by far the most commonly used.

We already kind of cover this in goprivate.txt, since we do garble build std, but that's not running any tests.

@mvdan
Copy link
Member Author

mvdan commented Mar 7, 2021

Here's a complication: by design, some tests will fail when obfuscated:

$ wgo1 garble test -short runtime/debug
allocating objects
starting gc
starting dump
done dump
--- FAIL: TestStack (0.00s)
    stack_test.go:63: expected "src/runtime/debug/stack.go" in "\truntime/debug/stack.go:24 +0x9f"
    stack_test.go:63: expected "src/runtime/debug/stack_test.go" in "\truntime/debug_test/stack_test.go:16"
    stack_test.go:63: expected "src/runtime/debug/stack_test.go" in "\truntime/debug_test/stack_test.go:19"
    stack_test.go:63: expected "src/runtime/debug/stack_test.go" in "\truntime/debug_test/stack_test.go:41 +0x36"
    stack_test.go:63: expected "src/testing/testing.go" in "\ttesting/testing.go:1194 +0xef"
FAIL
FAIL	runtime/debug	0.026s

Unfortunately there isn't an opposite to -run. It wouldn't really help either, as it doesn't allow selecting test names from specific packages.

Another option might be to use garble test -json, process the OK/FAIL results, and have a table of known-to-break tests which we expect to fail instead of succeed.

@mvdan
Copy link
Member Author

mvdan commented Apr 25, 2021

As a first goal, this should check that the third party packages build. #310 is a good example of when we can't even build due to garble bugs.

mvdan added a commit to mvdan/garble-fork that referenced this issue Apr 25, 2021
Packages P1 and P2 can define identical struct types T1 and T2, and one
can convert from type T1 to T2 or vice versa.

The spec defines two identical struct types as:

	Two struct types are identical if they have the same sequence of
	fields, and if corresponding fields have the same names, and
	identical types, and identical tags. Non-exported field names
	from different packages are always different.

Unfortunately, garble broke this: since we obfuscated field names
differently depending on the package, cross-package conversions like the
case above would result in typechecking errors.

To fix this, implement Joe Tsai's idea: hash struct field names with the
string representation of the entire struct. This way, identical struct
types will have their field names obfuscated in the same way in all
packages across a build.

Note that we had to refactor "reverse" a bit to start using transformer,
since now it needs to keep track of struct types as well.

This failure was affecting the build of google.golang.org/protobuf,
since it makes regular use of cross-package struct conversions.

Note that the protobuf module still fails to build, but for other
reasons. The package that used to fail now succeeds, so the build gets a
bit further than before. burrowers#240 tracks adding relevant third-party Go
modules to CI, so we'll track the other remaining failures there.

Fixes burrowers#310.
lu4p pushed a commit that referenced this issue Apr 25, 2021
Packages P1 and P2 can define identical struct types T1 and T2, and one
can convert from type T1 to T2 or vice versa.

The spec defines two identical struct types as:

	Two struct types are identical if they have the same sequence of
	fields, and if corresponding fields have the same names, and
	identical types, and identical tags. Non-exported field names
	from different packages are always different.

Unfortunately, garble broke this: since we obfuscated field names
differently depending on the package, cross-package conversions like the
case above would result in typechecking errors.

To fix this, implement Joe Tsai's idea: hash struct field names with the
string representation of the entire struct. This way, identical struct
types will have their field names obfuscated in the same way in all
packages across a build.

Note that we had to refactor "reverse" a bit to start using transformer,
since now it needs to keep track of struct types as well.

This failure was affecting the build of google.golang.org/protobuf,
since it makes regular use of cross-package struct conversions.

Note that the protobuf module still fails to build, but for other
reasons. The package that used to fail now succeeds, so the build gets a
bit further than before. #240 tracks adding relevant third-party Go
modules to CI, so we'll track the other remaining failures there.

Fixes #310.
@mvdan
Copy link
Member Author

mvdan commented Nov 16, 2021

Another important point is that, for these relevant third-party codebases, we should try building them with a variety of GOOS/GOARCH targets that CI doesn't directly cover. For example:

  • plan9/386 (uncommon OS, plus 32-bit arch)
  • js/wasm (fairly different platform overall)
  • freebsd/arm64 (relatively common OS and arch, but not covered by CI)

For instance, the first of those three would have caught #417 just by using GOPRIVATE=* garble build std.

@mvdan
Copy link
Member Author

mvdan commented Feb 3, 2022

From #410, it seems like Wireguard (the Go implementation) should also be in the list of relevant third-party tests.

mvdan added a commit to mvdan/garble-fork that referenced this issue May 13, 2022
Our tests should already be pretty extensive,
and any bug fixes should result in more regression test cases,
but testing against a few diverse and popular third party modules
will help prevent unintended regressions while developing garble.

The list is short for now. More can be added later.
This adds protobuf and wireguard from the original issue,
but not cobra and logrus, as they aren't particularly complex nor add
significant variety on top of protobuf and wireguard.

While here, we remove the job that only runs crlf-test.sh,
as we don't really need a separate job for a tiny script.

Fixes burrowers#240.
mvdan added a commit to mvdan/garble-fork that referenced this issue May 13, 2022
Our tests should already be pretty extensive,
and any bug fixes should result in more regression test cases,
but testing against a few diverse and popular third party modules
will help prevent unintended regressions while developing garble.

The list is short for now. More can be added later.
This adds protobuf and wireguard from the original issue,
but not cobra and logrus, as they aren't particularly complex nor add
significant variety on top of protobuf and wireguard.

While here, we remove the job that only runs crlf-test.sh,
as we don't really need a separate job for a tiny script.

Fixes burrowers#240.
mvdan added a commit that referenced this issue May 14, 2022
Our tests should already be pretty extensive,
and any bug fixes should result in more regression test cases,
but testing against a few diverse and popular third party modules
will help prevent unintended regressions while developing garble.

The list is short for now. More can be added later.
This adds protobuf and wireguard from the original issue,
but not cobra and logrus, as they aren't particularly complex nor add
significant variety on top of protobuf and wireguard.

While here, we remove the job that only runs crlf-test.sh,
as we don't really need a separate job for a tiny script.

Fixes #240.
@mvdan mvdan added this to the v0.6.0 milestone May 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant