Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Test support module #2357

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft

Test support module #2357

wants to merge 24 commits into from

Conversation

dmitry-s
Copy link
Contributor

@dmitry-s dmitry-s commented May 7, 2020

Add test module and introduce spanner emulator helper tools.

fixes #2318 fixes #2351

cc/ @elefeint

@codecov
Copy link

codecov bot commented May 7, 2020

Codecov Report

Merging #2357 into master will decrease coverage by 7.75%.
The diff coverage is 50.28%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #2357      +/-   ##
============================================
- Coverage     81.10%   73.35%   -7.76%     
+ Complexity     2315     2124     -191     
============================================
  Files           259      267       +8     
  Lines          7563     7750     +187     
  Branches        785      797      +12     
============================================
- Hits           6134     5685     -449     
- Misses         1103     1693     +590     
- Partials        326      372      +46     
Flag Coverage Δ Complexity Δ
#integration ? ?
#unittests 73.35% <50.28%> (-0.69%) 2124.00 <28.00> (+26.00) ⬇️
Impacted Files Coverage Δ Complexity Δ
...ework/cloud/gcp/test/EmulatorRuntimeException.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...mework/cloud/gcp/test/spanner/SpannerEmulator.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...st/spanner/SpannerEmulatorSpringConfiguration.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...springframework/cloud/gcp/test/EmulatorDriver.java 57.72% <57.72%> (ø) 19.00 <19.00> (?)
...ramework/cloud/gcp/test/pubsub/PubSubEmulator.java 61.53% <61.53%> (ø) 4.00 <4.00> (?)
...g/springframework/cloud/gcp/test/EmulatorRule.java 87.50% <87.50%> (ø) 3.00 <3.00> (?)
...a/org/springframework/cloud/gcp/test/Emulator.java 100.00% <100.00%> (ø) 2.00 <2.00> (?)
...gcp/secretmanager/SecretManagerPropertySource.java 0.00% <0.00%> (-100.00%) 0.00% <0.00%> (-4.00%)
...a/spanner/repository/query/SpannerQueryMethod.java 0.00% <0.00%> (-100.00%) 0.00% <0.00%> (-6.00%)
...retmanager/SecretManagerPropertySourceLocator.java 0.00% <0.00%> (-100.00%) 0.00% <0.00%> (-2.00%)
... and 70 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7582692...10a1019. Read the comment docs.

Copy link
Contributor

@meltsufin meltsufin left a comment

Choose a reason for hiding this comment

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

Please try to address the Sonar findings where it makes sense.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PubSubEmulatorHelper extends AbstractEmulatorHelper {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we please refactor this not to use inheritance?
You can try turning all of the abstract methods of AbstractEmulatorHelper into an interface that each emulator would implement and then a final EmulatorHelper can be customized by.
Alternatively, you can make EmulatorHelper a generic helper that any implementation of an emulator can re-use.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why though? Sincerely curious; this seems like a reasonable case for inheritance.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm sure if you search for "inheritance is evil", lots of reasons will pop up.
From Effective Java 3rd edition:
See:
Item 18: Favor composition over inheritance
Item 19: Design and document for inheritance or else prohibit it
Item 20: Prefer interfaces to abstract classes

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't do religious wars.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think it's the same as tabs vs spaces? 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep. Each side can be justified with rational arguments, and yet, the disagreement lives on. We'll have to do a PR converting Spring tabs into Google spaces soon...

@@ -0,0 +1,48 @@
/*
* Copyright 2017-2018 the original author or authors.
Copy link
Contributor

Choose a reason for hiding this comment

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

update copyright's year

public class PubSubEmulatorHelper extends AbstractEmulatorHelper {
private static final Log LOGGER = LogFactory.getLog(PubSubEmulatorHelper.class);

String getGatingPropertyName() {
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if this should be provided

docs/src/main/asciidoc/test.adoc Outdated Show resolved Hide resolved
docs/src/main/asciidoc/test.adoc Outdated Show resolved Hide resolved
docs/src/main/asciidoc/test.adoc Outdated Show resolved Hide resolved
docs/src/main/asciidoc/test.adoc Outdated Show resolved Hide resolved
docs/src/main/asciidoc/test.adoc Outdated Show resolved Hide resolved

@BeforeClass
public static void enableTests() {
Assumptions.assumeThat(System.getProperty("it.emulator"))
Copy link
Contributor

Choose a reason for hiding this comment

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

It should be -Dit.pubsub-emulator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's keep it like this until we update Travis CI configuration. Otherwise CI would fail.

import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.gcp.autoconfigure.core.GcpContextAutoConfiguration;
import org.springframework.cloud.gcp.autoconfigure.pubsub.GcpPubSubAutoConfiguration;
import org.springframework.cloud.gcp.autoconfigure.pubsub.GcpPubSubEmulatorAutoConfiguration;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we deprecate GcpPubSubEmulatorAutoConfiguration and move it to the test module?

Copy link
Contributor

Choose a reason for hiding this comment

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

We should still support the manual path where someone starts an emulator themselves, and then runs an application relying on our pubsub starter, providing an emulator property.

}

@Test
public void testCreatePublishPullNextAndDelete() {
Copy link
Contributor

Choose a reason for hiding this comment

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

How are you verifying that it's actually the emulator that you are using vs. the real service?
Maybe check the host or something?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's done inside the context below -- assertThat(transportChannelProvider.getTransportChannel().toString()).contains("target=dns:///localhost:8085");


@BeforeClass
public static void checkToRun() {
Assumptions.assumeThat(System.getProperty("it.emulator"))
Copy link
Contributor

Choose a reason for hiding this comment

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

It should be -Dit.spanner-emulator.
Also, can we update Travis CI config to actually run this test? What would it take?

Copy link
Contributor

Choose a reason for hiding this comment

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

We already install gcloud, so installing emulators would be more of the same. Can be a follow up PR to update Travis config -- Dmitry wanted to add it right away, but I remember how annoying testing travis config is (multiple tries, the only way to test is by committing), so I asked for a separate minimal Travis config PR.

@Configuration
@EnableTransactionManagement
@EnableSpannerRepositories
public class SpannerTestConfiguration {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we make it an auto-configuration like we have for Pub/Sub?
I imagine some folks will want to use the emulator to test the whole application, rather than just run the tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

Eddú did that in #2356, but we've created this PR before that. Perhaps a follow-up PR to switch over to official configuration?

@dmitry-s dmitry-s requested a review from meltsufin May 14, 2020 21:46
Copy link
Contributor

@elefeint elefeint left a comment

Choose a reason for hiding this comment

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

This turned out really well!

I wonder if we should create a package for "emulators", since we may want to add non-emulator test support in the future. But this can be done in the new repo.

}
----

NOTE: The class rule doesn't work for `SpannerEmulator`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we mention the workaround of setting up a custom Spanner bean and setting its destroy method to ""?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks like implementation details to me. @meltsufin what do you think?

@@ -104,6 +105,7 @@ public TradeRepositoryTransactionalService tradeRepositoryTransactionalService()
}

@Bean
@ConditionalOnMissingBean
Copy link
Contributor

Choose a reason for hiding this comment

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

Wait, remove the bean definitions entirely? There are several integration tests that go against real spanner.


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jcl</artifactId>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be optional, too? And move under the Spring Dependencies comment?


/**
* The list of command fragments that match the emulator processes to be killed.
* @param hostPort THe emulator host-port.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/THe/the

import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.gcp.autoconfigure.core.GcpContextAutoConfiguration;
import org.springframework.cloud.gcp.autoconfigure.pubsub.GcpPubSubAutoConfiguration;
import org.springframework.cloud.gcp.autoconfigure.pubsub.GcpPubSubEmulatorAutoConfiguration;
Copy link
Contributor

Choose a reason for hiding this comment

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

We should still support the manual path where someone starts an emulator themselves, and then runs an application relying on our pubsub starter, providing an emulator property.

}

@Test
public void testCreatePublishPullNextAndDelete() {
Copy link
Contributor

Choose a reason for hiding this comment

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

It's done inside the context below -- assertThat(transportChannelProvider.getTransportChannel().toString()).contains("target=dns:///localhost:8085");


@BeforeClass
public static void checkToRun() {
Assumptions.assumeThat(System.getProperty("it.emulator"))
Copy link
Contributor

Choose a reason for hiding this comment

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

We already install gcloud, so installing emulators would be more of the same. Can be a follow up PR to update Travis config -- Dmitry wanted to add it right away, but I remember how annoying testing travis config is (multiple tries, the only way to test is by committing), so I asked for a separate minimal Travis config PR.

@Configuration
@EnableTransactionManagement
@EnableSpannerRepositories
public class SpannerTestConfiguration {
Copy link
Contributor

Choose a reason for hiding this comment

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

Eddú did that in #2356, but we've created this PR before that. Perhaps a follow-up PR to switch over to official configuration?

elefeint
elefeint previously approved these changes May 15, 2020
@sonarqubecloud
Copy link

SonarCloud Quality Gate failed.

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 0 Security Hotspots to review)
Code Smell A 3 Code Smells

53.1% 53.1% Coverage
0.0% 0.0% Duplication

@dmitry-s
Copy link
Contributor Author

dmitry-s commented Oct 5, 2020

awaiting for redesign

@ttomsu ttomsu marked this pull request as draft October 12, 2020 12:55
@ttomsu
Copy link

ttomsu commented Oct 12, 2020

Converted PR to draft while we wait.

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

Successfully merging this pull request may close these issues.

Make PubSub emulator rule public Create a test rule for Spanner emulator
5 participants