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

implement integration tests #96

Merged
merged 3 commits into from
Jan 13, 2020

Conversation

hasheddan
Copy link
Member

@hasheddan hasheddan commented Nov 15, 2019

Description of your changes

Initial implementation of basic integration tests that simply install CRDs, start the stack controller, and create instances of the classes defined in examples/

Checklist

I have:

  • Run make reviewable to ensure this PR is ready for review.
  • Ensured this PR contains a neat, self documenting set of commits.
  • Updated any relevant documentation, examples, or release notes.
  • Updated the dependencies in app.yaml to include any new role permissions.

@hasheddan hasheddan force-pushed the inttestsinitial branch 3 times, most recently from c663b12 to 4a2b945 Compare November 15, 2019 22:39
@upbound-bot
Copy link
Collaborator

66% (0.0%) vs master 66%

@upbound-bot
Copy link
Collaborator

66% (0.0%) vs master 66%

Copy link
Member

@negz negz left a comment

Choose a reason for hiding this comment

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

We have to install core Crossplane CRD's for the stack managers to be able to run. However, it is likely undesirable to have them actually exist in this repo as I do here. I would support adding the ability to specify remote locations in the CRD paths passed to athodyd.

Would anything discussed in crossplane/crossplane#1085 help with this at all? I agree supporting remote locations (I assume you mean for example HTTP) is preferable to duplicating them in each stack, though we'd still need to play the game of keeping the referenced CRD files aligned with the code level definitions we imported.

How often do we want these to be run initially? I would support once daily using a Jenkins pipeline to start out.

That seems reasonable. It would be nice to allow maintainers to trigger integration tests via Tiller-style commands, but we could add that later. I'd still like to see us running these tests (or a subset thereof) against fake cloud provider APIs for every PR, eventually.

Can we move all examples for each stack to their respective repos? That we we could actually run integration tests using the examples by creating resources from the raw yaml.

I think we should just do this. We'll need to check for and figure out a solution to references to examples from the documentation, though.

test/integration/createProvider_test.go Outdated Show resolved Hide resolved
test/integration/createProvider_test.go Outdated Show resolved Hide resolved
limitations under the License.
*/

package integration
Copy link
Member

Choose a reason for hiding this comment

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

Is there an advantage to having a distinct integration test package? Could we instead keep the integration tests closer to the controllers they're testing, and perhaps gate them behind a build tag?

Copy link
Member Author

Choose a reason for hiding this comment

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

I like this idea! However, I do think we will likely have many of our integration tests span multiple controllers, so we may want a general location as well. For instance, if we wanted to test deploying Wordpress on GCP or something on the more complex side like that (not intending to do so in initial implementation) it would be useful to have something like an e2e directory.

@hasheddan
Copy link
Member Author

@negz while sorting out the dependencies for this implementation, I began to think that it may be useful to just include what is currently encompassed and will be implemented in the future in athodyd as a package in crossplane-runtime. This, along with some discussion on crossplane/crossplane#1085 suggests that stacks could eventually only depend on crossplane-runtime in the crossplane ecosystem. If the claim types are eventually included in crossplane-runtime that would also solve loading them into the test environment as we could just have an option of something like WithCrossplaneCRDs(). Any thoughts?

@negz
Copy link
Member

negz commented Nov 21, 2019

Any thoughts?

I think it makes sense to include athodyd in crossplane-runtime, perhaps under pkg/test/integration or similar. I'm a little wary of introducing testing dependencies on a relatively new library in a personal org.

I don't think it's a sure thing that claims will move into crossplane-runtime. They fit better there than in crossplane core, but I'm not yet convinced they don't belong in a separate API package.

@hasheddan
Copy link
Member Author

@negz sounds good! I'll open a PR to add current work in athodyd to crossplane-runtime :)

@upbound-bot
Copy link
Collaborator

66% (0.0%) vs master 66%

@upbound-bot
Copy link
Collaborator

66% (-0.02%) vs master 66%

@upbound-bot
Copy link
Collaborator

66% (-0.02%) vs master 66%

@upbound-bot
Copy link
Collaborator

61% (0.0%) vs master 61%

@upbound-bot
Copy link
Collaborator

61% (0.0%) vs master 61%

@upbound-bot
Copy link
Collaborator

61% (0.0%) vs master 61%

@upbound-bot
Copy link
Collaborator

61% (0.0%) vs master 61%

@hasheddan hasheddan force-pushed the inttestsinitial branch 2 times, most recently from bd46ff0 to a805f08 Compare January 9, 2020 19:28
Signed-off-by: hasheddan <georgedanielmangum@gmail.com>
@hasheddan hasheddan marked this pull request as ready for review January 9, 2020 20:05
@hasheddan hasheddan requested review from negz and jbw976 January 9, 2020 20:05
@upbound-bot
Copy link
Collaborator

61% (0.0%) vs master 61%

Copy link
Member Author

@hasheddan hasheddan left a comment

Choose a reason for hiding this comment

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

@negz @jbw976 I think this is ready. For the time being, we are utilizing a long-running cluster and the tests are only run ad-hoc via user invocation on Jenkins. While it is desirable to spin up net new clusters for integration tests in the future (probably using Crossplane), we can continue to build out the tests in the actual repos while that system is being designed, then switch over when ready without having to rewrite.

Comment on lines +195 to +200
cfg, err := clientcmd.BuildConfigFromFlags("", "../../kubeconfig.yaml")
if err != nil {
t.Fatal(err)
}

if err := os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "../../sa.json"); err != nil {
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: we look for these specific files that Jenkins drops into the project directory. Falling back on local kubeconfig was discussed but given that these test could eventually spin up new infrastructure, I actually like that a specific file path is hard coded.

Copy link
Member

@negz negz left a comment

Choose a reason for hiding this comment

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

@hasheddan I'm not sure how I feel about these integration tests being defined so separately from the code they're testing. That said, I'm conscious that this PR has been open a long time so I'd feel comfortable merging it and then assessing whether we should refactor it a little later.

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
Copy link
Member

Choose a reason for hiding this comment

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

Should we use a build tag to ensure these tests are not run by folks attempting to run unit tests?

https://mickey.dev/posts/go-build-tags-testing/

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, great point! I will add that. Another safe-guard here is the way that the k8s client is configured: you have to literally drop a kubeconfig.yaml into the project dir, it will not just use your local configuration automatically.

"CreateProvider": {
reason: "A GCP Provider should be created without error.",
test: func(c client.Client) error {
dat, err := ioutil.ReadFile("../../examples/gcp-provider.yaml")
Copy link
Member

Choose a reason for hiding this comment

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

I like that we're testing our examples, but I'm a little worried that it might not be obvious to folks that these examples are tied to the integration tests. Is there something we could do to bring them closer together? How will we know which examples are used by integration tests and which are just examples?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ideally we would always validate all examples in our integration tests. Therefore, if someone makes a change to examples/ then integration tests should also be updated. If we need to enforce this in the PR process that could be an option to make sure we do not get out of sync.

return c.Create(context.Background(), p)
},
},
"CreateBucketClass": {
Copy link
Member

Choose a reason for hiding this comment

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

What is the thinking around having one integration test that creates all extant resource class kinds, vs having an integration test alongside each of the existing unit tests? Would it be better if we tested code closer to where it was defined, like Go unit tests do?

Copy link
Member Author

Choose a reason for hiding this comment

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

This create_classes_test.go is a bit of a one-off. I think that most tests will not necessarily make sense to be next to a specific piece of code like unit tests. For example, I have a local test that creates a Provider, GKECluster, CloudSQLInstance, KubernetesCluster claim, MySQLInstance claim, and a KubernetesApplication. I don't think there is a specific set of code that it should be associated with.

Signed-off-by: hasheddan <georgedanielmangum@gmail.com>
@hasheddan
Copy link
Member Author

@negz updated with build tags, I want to manually execute Jenkins pipeline again before merge though

Signed-off-by: hasheddan <georgedanielmangum@gmail.com>
@upbound-bot
Copy link
Collaborator

61% (0.0%) vs master 61%

Copy link
Member Author

@hasheddan hasheddan left a comment

Choose a reason for hiding this comment

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

limitations under the License.
*/

package integration
Copy link
Member Author

Choose a reason for hiding this comment

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

Adding this doc.go was required for the generate target to run successfully.

@negz negz merged commit 3690e4c into crossplane-contrib:master Jan 13, 2020
@anitsh
Copy link

anitsh commented Feb 4, 2021

Hi @hasheddan,
The link examples leads to 404 page not found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants