integration/plugin/authz: port tests from integration-cli#34941
integration/plugin/authz: port tests from integration-cli#34941vdemeester merged 3 commits intomoby:masterfrom
Conversation
|
Thanks! Looks like there's some linting failures; |
a3b3dad to
77ce78c
Compare
|
Yes, I've just fixed those. For some reason, |
77ce78c to
ae5696c
Compare
|
#34911 should make it a lot more obvious about what is run by CI. Needs another LGTM to merge
If you encounter this again please let me know |
dnephin
left a comment
There was a problem hiding this comment.
Thanks for porting this test suite. Mostly looks good, but I don't think integration/internal/api/ should exist. Most of these functions are ` line wrappers around the api client which just hides the context. We should be testing the API more directly, not wrapping our client library with these helpers.
In a few cases there is some logic that can be extracted into factories for building the options struct, or helpers for transforming the responses, but I don't think they should wrap the client.
I think it's also better that we keep these as unexported. There should be very little re-use of these between test suites because each suite should be focused on just the component under test.
There was a problem hiding this comment.
It seems strange to panic here, especially on a timeout.
How about add a t LogT argument to this function and do this instead:
t.Logf("Timeout ...")
return falseThere was a problem hiding this comment.
This comes directly from https://github.com/moby/moby/blob/master/integration-cli/requirements_test.go#L106 which I did not write. I don't think tests that require hub connectivity should allow test runs to pass by skipping them and emitting a logging message that will be missed/ignored in the thousands of lines of spew.
There was a problem hiding this comment.
We should fix these problem instead of carrying them over into the new test suite.
I don't think tests that require hub connectivity should allow test runs to pass by skipping them and emitting a logging message that will be missed/ignored in the thousands of lines of spew.
If you think this should be a fatal error you can use t.Fatal(), but the purpose of these helpers is to detect state and skip tests that can't be run, so I don't think that's really appropriate. Skipping the test is the right behaviour. There is no reason to panic here.
integration/testdata/main_test.go
Outdated
There was a problem hiding this comment.
I don't think testdata should be a package. If this is because hack/make/test-integration tries to run this as a test package how about we just add testdata to the exclude list?
There was a problem hiding this comment.
also doesn't need to be a package
There was a problem hiding this comment.
Shouldn't we clean even if d == nil ?
There was a problem hiding this comment.
This is how https://github.com/moby/moby/blob/master/integration-cli/docker_cli_authz_unix_test.go#L77 and https://github.com/moby/moby/blob/master/integration-cli/docker_cli_authz_plugin_v2_test.go#L43 are written. I've moved the cleanup out of the conditional in a subsequent commit.
There was a problem hiding this comment.
We merged a PR recently that added a ProtectAll() I think that should be used now. We should unexport the rest of these Protect*() method so it's more obvious.
There was a problem hiding this comment.
If we used ProtectAll, wouldn't that negate the use of testEnv.Clean? I think that containers and plugins should probably be cleaned up after these tests, no?
There was a problem hiding this comment.
ProtectAll() is maybe a misleading name. All it does is get a list of all the existing objects, so that Clean() doesn't remove them later. This is important for testing EE because it has system containers that it needs to keep running.
Clean() will still remove anything created by the tests.
integration/internal/main_test.go
Outdated
There was a problem hiding this comment.
internal shouldn't need a main_test.go
There was a problem hiding this comment.
We should not be maintaining an abstraction over the APIClient for tests. Please remove this file. The only logic that really needs to be a new function is namesFromVolumes() which can be an unexported helper next to the one place it is used.
There was a problem hiding this comment.
While it may be desirable in the long term to not have any abstraction over APIClient for tests, this design makes porting CLI tests much easier and reduces incidental complexity significantly. To maintain correctness, I recommend not attempting to simultaneously port tests and radically change them or instill new best practices.
Across existing tests, similar functionality will be required:
$ git grep "volume\", \"ls\")" integration-cli/ | wc -l
13
$ git grep "volume\", \"ls" integration-cli/ | wc -l
42
As this functionality is in integration/internal, golang's magic export scoping rules for internal will prevent users outside of this repository.
There was a problem hiding this comment.
Please delete, this doesn't need to exist, just call client.ServerVersion() directly.
There was a problem hiding this comment.
This exists to provide a homogeneous CLI replacement interface.
There was a problem hiding this comment.
This is exactly the problem. We should not be testing as if we had a CLI. We need to test the API as directly as possible, not mimic CLI behaviour.
There was a problem hiding this comment.
As explained in my PR comment, that is a laudable possible goal for the future but these tests were written against the CLI.
There was a problem hiding this comment.
I guess I don't understand why we're moving these tests to integration/ if they are going to be nearly identical to the integration-cli tests
There was a problem hiding this comment.
My understanding is that we're moving the tests to eliminate the moby/moby ➡️ docker/cli dependency and unblock additional test contributions as integration-cli/ is now deprecated.
There was a problem hiding this comment.
This can be an unexported helper next to the one place it is used.
There was a problem hiding this comment.
It won't be used in one place for long. The integration-cli test suite has significant machinery for event stream handling.
There was a problem hiding this comment.
We should only be testing events from the integration/system package, so it doesn't need to be exported.
There was a problem hiding this comment.
A past authz test author clearly felt that it was necessary to test the interaction between events and authz plugins. In the future, it may be an improvement to move this test elsewhere but in the meantime it seems prudent test the integration between disparate components with the more complicated to test component. Once integation-cli/ has been eliminated, it should be easy to review all the places where event functionality is used.
There was a problem hiding this comment.
This can be an unexported helper in the one file where it is used.
The rest of the file should be removed, they are one line wrappers around the client.
There was a problem hiding this comment.
This will be used by other test suites -- at least mount point plugins. The other functions in this file exist to provide 1:1 mapping to the command line without depending on docker/cli. The client library imposes significant incidental complexity (contexts, options, questionable semantic decisions like in PluginInstall, etc) that a developer writing or porting a test shouldn't have to be subjected to. If, eventually, there is actually no benefit to fixing up the APIClient interface for test suite users, great. Until that time, this design makes it much easier to work with by e.g. not requiring questions like "Is there a utility function for this or is this one of the annoying APIClient functions?"
There was a problem hiding this comment.
1:1 mapping to the command line
This is exactly what we do not want. If we were going to provide a 1:1 mapping to the CLI there would be little value in removing the CLI from the test suite.
If there are helpers that will be shared between the plugin suite then maybe create an integration/plugin/internal ?
dnephin
left a comment
There was a problem hiding this comment.
Test helpers which accept t *testing.T as the first argument instead of returning error are also really nice. If we keep some of these helpers I would suggest passing in testing.T, which will help keep the tests readable and not distract from the relevant lines in the test.
There was a problem hiding this comment.
This can be replaced with a ImageImportOptionsFromPath(path string) types.ImageImportOptions
There was a problem hiding this comment.
git grep ImageImportOptionsFromPath returns no results for me. It also doesn't look like it has a compatible signature. These functions are intended to be analogous to CLI invocations.
There was a problem hiding this comment.
Can be replaced with a saveToPath(source io.Reader, path string) err
There was a problem hiding this comment.
It's not clear to me where saveToPath is implemented or how it can be a replacement with such a different signature.
There was a problem hiding this comment.
Looks like the same saveToPath() ?
There was a problem hiding this comment.
It's not clear to me where saveToPath is implemented or how it can be a replacement with such a different signature.
There was a problem hiding this comment.
I was thinking it would be implemented in integration/plugin/authz as an unexported helper. Sorry I didn't provide the full signature:
savetoPath(t *testing.T, content io.ReadCloser) stringThe return value is the path to the file.
There was a problem hiding this comment.
I think all of these can be replaced with helpers that return container.Config() instead.
There was a problem hiding this comment.
This would break the predictable homogeneity and make invocations of what used to be docker run much more verbose.
The tests being ported are CLI tests. These wrappers homogenize the API client interface to make it behave more like the CLI interface and improve the porting experience.
Why not? The tests do not demand most of the functionality that the API offers and which would clutter the tests with irrelevant noise.
As the CLI -> API library is located in Do you have a document describing the Could you show me an |
Exactly, that's the problem.
These are tests of the API. If you hide how the API is called the test loses a lot of value, because it's no longer clear what you are testing. The helpers may even silently break the test by masking the actual API behaviour. I agree that implementation details (like complex setup, and complex assertions) should be hidden from the testcase function, but the actual API call needs to be there, because that is what is being tested.
Another major problem that will hopefully be fixed in the
There are a couple, but I will admit they are probably not as thorough as they could be. It is hard to enumerate all the problems with the old suite.
https://github.com/moby/moby/blob/master/integration/service/inspect_test.go there is also a test for version, but it is a very simple case. Testing plugins seems to be more involved because it requires a daemon to be started with specific flags (which is not true of most of the other API endpoints). An important detail is that the API endpoint that is being tested is central to the test, and any setup/teardown is (as much as possible) extracted out into helpers with appropriately descriptive names. I think for the most part the tests here fit that criteria, the only different is the abstraction over the API calls. If there are some common helpers that will be used between plugins, |
|
The plugin tests are also a very different case because they are actually testing API calls into other components. Some of these helpers for plugins are appropriate, but if we expose them to all of The ideal way to test these plugins would really be to re-use the test suite for the actual component. If we had the tests annotated correctly we could spin up a daemon that has the plugin loaded and then trigger the component test suite against that daemon. With the right test requirements/skips setup we wouldn't have to write a second test suite. We would have just a couple extra test cases for the "disallowed by plugin" case, which would get skipped when run against a non-plugin daemon. I think that's probably unlikely to happen, so this suite is necessary. |
|
It sounds like you have a lot of ideas for how
I think it's great that we have some ideas about how to improve the test suite in the future. In the present, having a mostly empty 'new' test suite and a large but deprecated 'old' test suite is negative for the project's health. The existing tests are CLI tests (written as such) even if they should be testing the API or we want equivalent API tests. Actually testing the API directly will almost certainly look different from the current CLI tests and has its trade-offs. Couching CLI tests in the guise of API tests doesn't actually improve the tests but porting CLI tests to use the API under the hood does deliver the above benefits. Additionally, it seems to me that an ideal test suite would allow both 'low-level' API-style tests and 'high-level' CLI-style tests. As you note, some functionality like the plugins system greatly benefits from high-level tests. It seems to me that any large scale improvement of the test suite should be done incrementally. Demanding that tests directly ported from |
I don't believe that design is feasible as these plugin tests target the plugin system's functionality that extends beyond a single plugin or accept/reject behavior. Examine the tests for daemon start failure or the instrumentation of authz v1 plugins in this PR for evidence. |
By not passing |
810ebeb to
924c517
Compare
Signed-off-by: David Sheets <dsheets@docker.com>
I strongly disagree with the design of this pull request. Signed-off-by: David Sheets <dsheets@docker.com>
924c517 to
1574d91
Compare
|
I have rebased, squashed, and made the changes you requested. I strongly disagree with this design. Please review and merge ASAP. |
Also skip.IfCondition directly from the test, so that the skip message is correct Signed-off-by: Daniel Nephin <dnephin@docker.com>
dnephin
left a comment
There was a problem hiding this comment.
I pushed a small change to the integration path exclude list regex, and moved skip.IfCondition() into the test.
LGTM
|
So when can this be merged? |
|
Needs another LGTM |
- What I did
I ported the authz plugin tests from
integration-cliusing the CLI tointegration/plugin/authzusing the API.At least some of this work is required for #33658 and #33375.
- How I did it
I mechanically changed the structure of the tests to fit the new API test style, replaced CLI use with API helper utility function calls, and then fixed up build and test failures.
- How to verify it
The tests execute and pass. Side-by-side visual comparison can demonstrate that they test the functionally equivalent behaviors.
- Description for the changelog
N/A
- A picture of a cute animal (not mandatory but encouraged)
Planigale ingrami, or the long-tailed planigale, is believed to be the smallest marsupial on Earth. It is native to Australia's Top End where it is abundant but rarely seen. The average weight for males is 4.2g and for females is 4.3g.
/cc @dnephin @thaJeztah