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

Add smoke tests to validate use of the starter in a vanilla application #51

Closed
snicoll opened this issue Aug 28, 2019 · 9 comments
Closed
Assignees
Labels
Milestone

Comments

@snicoll
Copy link
Member

snicoll commented Aug 28, 2019

In the recent past, a number of issues were discovered adding the spring-geode-starter to a vanilla Spring Boot application. Given that this project built successfully and a release was made with those issues, I think a number of integration/smoke tests are missing.

The two recent examples I have in mind are:

  • With the 1.1 line adding the starter alone was working but combining the starter with any other starter would break without an explicit library exclusion (see Logging should reuse existing logging format rather that overwriting it #42)
  • With the 1.2 line adding the starter alone would break as both spring-mvc and servlet-api were present in the classpath, triggering an embedded application server bootstrap.

While both theses issues are actually located outside of this project (and workarounds have been swiftly applied), the integration in a Spring Boot application was broken and having an automated way of discovering such issue prior of a release is necessary.

I don't know how easy that's going to be. Perhaps testcontainers can help to make sure a vanilla geode instance is running for such tests.

@jxblum
Copy link
Contributor

jxblum commented Aug 28, 2019

@snicoll - Will think on this. Thanks for the feedback.

@jxblum
Copy link
Contributor

jxblum commented Aug 28, 2019

Correction to:

With the 1.2 line adding the starter alone would break as both spring-mvc and servlet-api were present in the classpath, triggering an embedded application server bootstrap.

To my knowledge, SBDG, through transitive dependencies, only brought in the javax.servlet-api, not spring-webmvc. I never saw spring-webmvc in the dependency graph with the SBDG spring-geode-starter was on the classpath of a Spring Boot application.

It is true that SBDG has a direct dependency on SDG, which in turn has a dependency on the spring-web, but spring-web was not enough for Spring Boot to decide that the application should be a "Web application" with an embedded Servlet Container (e.g. Tomcat, Jetty) bootstrapped by Spring Boot on startup.

Never-the-less, I feel that having smoke tests to catch/prevent these type of situations going forward are important, even if it is largely due some transitive dependency (e.g. Apache Geode 1.6, which caused logging issues in SBDG 1.1, and again, Apache Geode 1.9, which forced the application to be a Web application by Spring Boot in SBDG 1.2).

I take full responsibility.

@jxblum jxblum self-assigned this Aug 28, 2019
@snicoll
Copy link
Member Author

snicoll commented Aug 28, 2019

I meant to write spring-web and I wrote spring-mvc, that's all.

@jxblum jxblum added this to the 1.2.0.RC1 milestone Sep 28, 2019
jxblum added a commit to jxblum/spring-boot-data-geode that referenced this issue Sep 28, 2019
jxblum added a commit to jxblum/spring-boot-data-geode that referenced this issue Sep 28, 2019
jxblum added a commit to jxblum/spring-boot-data-geode that referenced this issue Sep 28, 2019
…A and an HSQLDB database as the application System of Record (SOR) and Apache Geode as the caching provider in Spring's Cache Abstraction.

Resolves spring-projectsgh-51.
@jxblum
Copy link
Contributor

jxblum commented Sep 28, 2019

I have added 2 Smoke Tests to the SBDG project.

  1. The first smoke test tests and asserts that a Spring for Apache Geode project generated and created with Spring Initializer at start.spring.io works as expected. That is, it creates a standard, non-Webapp, Spring Boot application and that it can interact with Apache Geode using basic functions, a put(key, value) followed by a get(key). I generated a project using the Initializer then copied the contents of the generated Gradle build file into the smoke test module's Gradle build file. Essentially, the spring-initializer smoke test module resolves the org.springframework.geode:spring-geode-starter dependency in the same way as a Spring for Apache Geode project would when created/generated from Spring Initializer.

  2. The second smoke test tests and asserts that a Spring Data multi-store project works as expected when using the Spring for Apache Geode as resolved from a project generated from Spring Initializer. This smoke test module includes both the spring-geode-starter as well as the spring-boot-starter-data-jpa module in Spring Boot core. spring-boot-starter-data-jpa pulls in several other Spring Boot core modules as well (e.g. spring-boot-starter-logging, spring-boot-starter-jdbc, etc). The test goes on to assert the proper behavior of SD multi-store support, ensuring that SD JPA can properly persist data to a backend HSQLDB database while using Apache Geode as a caching provider in Spring's Cache Abstraction, without interference to any of Spring [Boot] module on the application classpath.

While this effort is not an exhaustive list, it does cover the 2 scenarios highlighted above to a degree.

Also, as any new problems or scenarios come to our attention, we will continue to add additional smoke tests to cover as many UCs as possible and ensure SBDG is behaving correctly in all contexts, playing nicely with other Spring Boot modules, working for the intended UCs, and so on and so forth.

Therefore, please do not take the closure of this Issues as final. It is just the beginning of much more.

jxblum added a commit to jxblum/spring-boot-data-geode that referenced this issue Sep 28, 2019
…A and an HSQLDB database as the application System of Record (SOR) and Apache Geode as the caching provider in Spring's Cache Abstraction.

Resolves spring-projectsgh-51.
jxblum added a commit to jxblum/spring-boot-data-geode that referenced this issue Sep 28, 2019
…oot application classpath.

Experiment with adding SD for Apache Geode's @region mapping annotation as well as SD MongoDB's @document mapping annotation and the effects on Spring Boot's auto-configuration support for SD Repositories when multiple data store providers are on the Spring Boot application classpath.

Resolves spring-projectsgh-51.
@jxblum jxblum closed this as completed in 9aa8a86 Sep 29, 2019
@snicoll
Copy link
Member Author

snicoll commented Sep 29, 2019

Thanks for this @jxblum, I had a quick look at this so I might be missing something. Can you please share how that zip file in etc is going to be updated?

In the current form and, as far as I understood, I can see that it uses 1.2.0.M3 so it isn't building against the current code. I am afraid that it's not guarding from a release to be shipped with a broken use case as the smoke tests run against an (older) fixed version.

Have you considering having a project with the starter (in the latest snapshot form) and run tests against that. The smoke tests in Spring Boot work that way and since they inherit from the current build, they can use whatever dependency that is managed in the project, i.e. these dependencies bring the code that was just built. In your case, just providing the starter is all that would be required. Another smoke test project that brings the web starter could validate the integration with the rest of the ecosystem (though secondary).

@jxblum
Copy link
Contributor

jxblum commented Sep 30, 2019

Hi @snicoll - Thanks for the feedback.

Can you please share how that zip file in etc is going to be updated?

Good question! It will be manually updated for now.

Presently, I simply wanted to put together any kind of test, which was better than having no tests. So, I went to start.spring.io, generated a "Spring for Apache Geode" Spring Boot 2.2, Gradle project and then used the contents of the generated Gradle file as a basis for the spring-initializer Smoke Tests Gradle build file. This isn't ideal, but it essentially mimicked the product that a user would get as generated by Spring Initializer when creating a "Spring for Apache Geode" project.

This is accomplished by 1) declaring the repos from which the artifact (e.g. spring-geode-starter) would be resolved (copied from the Gradle file produced by Initializer) and 2) declaring a dependency on the fully qualified artifact (i.e. org.springframework.geode:spring-geode-starter, as produced by Initializer, minus the version) rather than pulling in, for example, compile project('spring-geode-starter').

Of course, now that I think about it, not sure if that quite does the same thing?? I then set the "version" to match whatever version the SBDG project is currently building at (e.g. 1.2.0.BUILD-SNAPSHOT). However, there is a problem with my versioning scheme.

The version (e.g. 1.3.0.BUILD-SNAPSHOT) may not currently be available in the targeted repos before the Smoke Tests run since the build would need to initially run and upload the artifacts (e.g. 1.3.0.BUILD-SNAPSHOT when the version changes) to snapshot repo before the Smoke Test runs (just after the version change). Otherwise, the artifacts would not yet be available and the build would fail thereby never uploading the new version (e.g. 1.3.0.BUILD-SNAPSHOT). I have created a chicken and egg problem. Damn, didn't think of that.

Also, if the contents of the generated Spring Initializer product ever changes, then it won't quite be testing what Initializer is doing when a user generates a "Spring for Apache Geode" project, :(

Let me digest your additional comments more and then figure out next steps. For now, I just wanted to share what my original (flawed) thinking was.

@jxblum
Copy link
Contributor

jxblum commented Sep 30, 2019

I verified and the spring-initializer Smoke Test is pulling in the project version, in the same manner as Spring Boot Smoke Tests do. That is, if the project version is set to 1.2.0.BUILD-SNAPSHOT, then the spring-geode-starter declared in the spring-initializer Smoke Test would resolve to 1.2.0.BUILD-SNAPSHOT. It would not just be the latest version of the spring-geode-starter on Spring Initializer, which at the time of this comment is 1.2.0.M3.

I also tested what would happen if I superfically changed the "version" (again, here) to, for example, 1.3.0.BUILD-SNAPSHOT, and sure enough...

$ gradlew --no-daemon :spring-geode-smoke-tests-initializer:build
> Task :spring-geode-smoke-tests-initializer:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':spring-geode-smoke-tests-initializer:compileJava'.
> Could not resolve all files for configuration ':spring-geode-smoke-tests-initializer:compileClasspath'.
   > Could not find org.springframework.geode:spring-geode-starter:1.3.0.BUILD-SNAPSHOT.
     Required by:
         project :spring-geode-smoke-tests-initializer

This also happens when I run the entire project build. Everything builds fine up to the Smoke Tests (the last thing to run), which then fail.

$ gradlew --no-daemon clean build install
...
..
.

> Task :spring-geode-smoke-tests-initializer:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':spring-geode-smoke-tests-initializer:compileJava'.
> Could not resolve all files for configuration ':spring-geode-smoke-tests-initializer:compileClasspath'.
   > Could not find org.springframework.geode:spring-geode-starter:1.3.0.BUILD-SNAPSHOT.
     Required by:
         project :spring-geode-smoke-tests-initializer

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

I am an idiot.

However, what this does mean is, the build is properly trying to resolve the org.springframework.geode:spring-geode-starter:1.3.0.BUILD-SNAPSHOT from the declared repos in the Gradle build file from the spring-initializer Smoke Tests, the same as a "Spring for Apache Geode" project generated with Spring Initializer at start.spring.io would do, as opposed to pulling the dependency from the project, or locally.

I clearly need to rethink this, though.

@snicoll
Copy link
Member Author

snicoll commented Oct 1, 2019

If you don't have a particular opinion, I'd align to what we've done for our smoke tests in Spring Boot (link above).

The setup from start.spring.io is not what we should be testing here IMO (it's our problem making sure that if we generated a build.gradle, Gradle will be able to download the bits based on the repo we've defined.

Rather we should have a simple @SpringBootApplication class and some test repository perhaps with as less code as possible (i.e. I would move those assertions in the test itself). And the simplest gradle build possible (just declaring the starter. If you need more dependencies to cover another smoke test such as actuator, I'd recommend to create another smoke test as you did to cover the fact the integration works with only the core starter). Then the tests can start the context and exercise the app. @SpringBootTest should cover most cases IMO. Maybe another smoke test with the web starter to validate it works fine in a web application?

If dependency management is configured as it should in your gradle build, you could just refer to your starter without a version and it will use whatever bits were built locally. That way, if a regression occurs in the code, the smoke test can break and prevent the bits to be deployed on a repo. I don't know enough gradle to help you investigate that part though, sorry.

@jxblum
Copy link
Contributor

jxblum commented Oct 1, 2019

Thanks for the feedback and ideas/thoughts, @snicoll. I will think on this more and follow-up with comments later.

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

No branches or pull requests

2 participants