Skip to content

Commit 0171b19

Browse files
committed
Tests refactoring
1 parent 943f3b7 commit 0171b19

File tree

13 files changed

+198
-206
lines changed

13 files changed

+198
-206
lines changed

build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description = "Experiments with Java"
99

1010
allprojects {
1111
group = "io.github.mfvanek"
12-
version = "0.3.0"
12+
version = "0.3.1"
1313

1414
repositories {
1515
mavenLocal()
@@ -19,7 +19,7 @@ allprojects {
1919

2020
tasks {
2121
wrapper {
22-
gradleVersion = "8.12"
22+
gradleVersion = "8.12.1"
2323
}
2424
}
2525

docker/docker-compose-base.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ services:
8686

8787
postgres:
8888
container_name: postgres
89-
image: postgres:17.0
89+
image: postgres:17.2
9090
shm_size: "2gb"
9191
environment:
9292
POSTGRES_DB: "otel_demo_db"

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

spring-boot-2-demo-app/src/test/java/io/github/mfvanek/spring/boot2/test/IndexesMaintenanceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class IndexesMaintenanceTest extends TestBase {
3131
void checkPostgresVersion() {
3232
final String pgVersion = jdbcTemplate.queryForObject("select version();", String.class);
3333
assertThat(pgVersion)
34-
.startsWith("PostgreSQL 17.0");
34+
.startsWith("PostgreSQL 17.2");
3535
}
3636

3737
@Test

spring-boot-2-demo-app/src/test/java/io/github/mfvanek/spring/boot2/test/controllers/TimeControllerTest.java

Lines changed: 29 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77

88
package io.github.mfvanek.spring.boot2.test.controllers;
99

10-
import io.github.mfvanek.spring.boot2.test.service.dto.CurrentTime;
1110
import io.github.mfvanek.spring.boot2.test.service.dto.ParsedDateTime;
1211
import io.github.mfvanek.spring.boot2.test.support.KafkaConsumerUtils;
1312
import io.github.mfvanek.spring.boot2.test.support.TestBase;
14-
import lombok.SneakyThrows;
1513
import org.apache.kafka.clients.consumer.ConsumerRecord;
1614
import org.apache.kafka.common.header.Header;
1715
import org.awaitility.Awaitility;
@@ -31,22 +29,16 @@
3129
import java.nio.charset.StandardCharsets;
3230
import java.time.Duration;
3331
import java.time.LocalDateTime;
34-
import java.time.ZoneId;
3532
import java.util.Arrays;
3633
import java.util.List;
3734
import java.util.Map;
3835
import java.util.Objects;
39-
import java.util.TimeZone;
4036
import java.util.UUID;
4137
import java.util.concurrent.BlockingQueue;
4238
import java.util.concurrent.LinkedBlockingQueue;
4339
import java.util.concurrent.TimeUnit;
4440
import javax.annotation.Nonnull;
4541

46-
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
47-
import static com.github.tomakehurst.wiremock.client.WireMock.get;
48-
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
49-
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
5042
import static io.github.mfvanek.spring.boot2.test.filters.TraceIdInResponseServletFilter.TRACE_ID_HEADER_NAME;
5143
import static org.assertj.core.api.Assertions.assertThat;
5244

@@ -78,17 +70,10 @@ void cleanUpDatabase() {
7870
jdbcTemplate.execute("truncate table otel_demo.storage");
7971
}
8072

81-
@SneakyThrows
8273
@Test
83-
void spanShouldBeReportedInLogs(@Nonnull final CapturedOutput output) {
84-
final String zoneNames = TimeZone.getDefault().getID();
85-
final ParsedDateTime parsedDateTime = ParsedDateTime.from(LocalDateTime.now(ZoneId.systemDefault()).minusDays(1));
86-
final CurrentTime currentTime = new CurrentTime(parsedDateTime);
87-
stubFor(get(urlPathMatching("/" + zoneNames))
88-
.willReturn(aResponse()
89-
.withStatus(200)
90-
.withBody(objectMapper.writeValueAsString(currentTime))
91-
));
74+
void spanShouldBeReportedInLogs(@Nonnull final CapturedOutput output) throws Exception {
75+
stubOkResponse(ParsedDateTime.from(LocalDateTime.now(clock).minusDays(1)));
76+
9277
final EntityExchangeResult<LocalDateTime> result = webTestClient.get()
9378
.uri(uriBuilder -> uriBuilder.path("current-time")
9479
.build())
@@ -107,27 +92,10 @@ void spanShouldBeReportedInLogs(@Nonnull final CapturedOutput output) {
10792

10893
final ConsumerRecord<UUID, String> received = consumerRecords.poll(10, TimeUnit.SECONDS);
10994
assertThat(received).isNotNull();
110-
assertThat(received.value()).startsWith("Current time = ");
111-
final Header[] headers = received.headers().toArray();
112-
final List<String> headerNames = Arrays.stream(headers)
113-
.map(Header::key)
114-
.toList();
115-
assertThat(headerNames)
116-
.hasSize(2)
117-
.containsExactlyInAnyOrder("traceparent", "b3");
118-
final List<String> headerValues = Arrays.stream(headers)
119-
.map(Header::value)
120-
.map(v -> new String(v, StandardCharsets.UTF_8))
121-
.toList();
122-
assertThat(headerValues)
123-
.hasSameSizeAs(headerNames)
124-
.allSatisfy(h -> assertThat(h).contains(traceId));
95+
assertThatTraceIdPresentInKafkaHeaders(received, traceId);
96+
97+
awaitStoringIntoDatabase();
12598

126-
Awaitility
127-
.await()
128-
.atMost(10, TimeUnit.SECONDS)
129-
.pollInterval(Duration.ofMillis(500L))
130-
.until(() -> countRecordsInTable() >= 1L);
13199
assertThat(output.getAll())
132100
.contains("Received record: " + received.value() + " with traceId " + traceId);
133101
final String messageFromDb = namedParameterJdbcTemplate.queryForObject("select message from otel_demo.storage where trace_id = :traceId",
@@ -141,17 +109,10 @@ private long countRecordsInTable() {
141109
return Objects.requireNonNullElse(queryResult, 0L);
142110
}
143111

144-
@SneakyThrows
145112
@Test
146-
void mdcValuesShouldBeReportedInLogs(@Nonnull final CapturedOutput output) {
147-
final String zoneNames = TimeZone.getDefault().getID();
148-
final ParsedDateTime parsedDateTime = ParsedDateTime.from(LocalDateTime.now(ZoneId.systemDefault()).minusDays(1));
149-
final CurrentTime currentTime = new CurrentTime(parsedDateTime);
150-
stubFor(get(urlPathMatching("/" + zoneNames))
151-
.willReturn(aResponse()
152-
.withStatus(200)
153-
.withBody(objectMapper.writeValueAsString(currentTime))
154-
));
113+
void mdcValuesShouldBeReportedInLogs(@Nonnull final CapturedOutput output) throws Exception {
114+
stubOkResponse(ParsedDateTime.from(LocalDateTime.now(clock).minusDays(1)));
115+
155116
webTestClient.get()
156117
.uri(uriBuilder -> uriBuilder.path("current-time")
157118
.build())
@@ -168,16 +129,9 @@ void mdcValuesShouldBeReportedInLogs(@Nonnull final CapturedOutput output) {
168129
.contains("\"tenant.name\":\"ru-a1-private\"");
169130
}
170131

171-
@SneakyThrows
172132
@Test
173-
void spanAndMdcShouldBeReportedWhenRetry(@Nonnull final CapturedOutput output) {
174-
final String zoneNames = TimeZone.getDefault().getID();
175-
final RuntimeException exception = new RuntimeException("Retries exhausted");
176-
stubFor(get(urlPathMatching("/" + zoneNames))
177-
.willReturn(aResponse()
178-
.withStatus(500)
179-
.withBody(objectMapper.writeValueAsString(exception))
180-
));
133+
void spanAndMdcShouldBeReportedWhenRetry(@Nonnull final CapturedOutput output) throws Exception {
134+
final String zoneNames = stubErrorResponse();
181135

182136
final EntityExchangeResult<LocalDateTime> result = webTestClient.get()
183137
.uri(uriBuilder -> uriBuilder.path("current-time")
@@ -195,6 +149,21 @@ void spanAndMdcShouldBeReportedWhenRetry(@Nonnull final CapturedOutput output) {
195149

196150
final ConsumerRecord<UUID, String> received = consumerRecords.poll(10, TimeUnit.SECONDS);
197151
assertThat(received).isNotNull();
152+
assertThatTraceIdPresentInKafkaHeaders(received, traceId);
153+
154+
awaitStoringIntoDatabase();
155+
156+
assertThat(output.getAll())
157+
.contains(
158+
"Received record: " + received.value() + " with traceId " + traceId,
159+
"Retrying request to ",
160+
"Retries exhausted",
161+
"\"instance_timezone\":\"" + zoneNames + "\""
162+
);
163+
}
164+
165+
private void assertThatTraceIdPresentInKafkaHeaders(@Nonnull final ConsumerRecord<UUID, String> received,
166+
@Nonnull final String expectedTraceId) {
198167
assertThat(received.value()).startsWith("Current time = ");
199168
final Header[] headers = received.headers().toArray();
200169
final List<String> headerNames = Arrays.stream(headers)
@@ -209,19 +178,14 @@ void spanAndMdcShouldBeReportedWhenRetry(@Nonnull final CapturedOutput output) {
209178
.toList();
210179
assertThat(headerValues)
211180
.hasSameSizeAs(headerNames)
212-
.allSatisfy(h -> assertThat(h).contains(traceId));
181+
.allSatisfy(h -> assertThat(h).contains(expectedTraceId));
182+
}
213183

184+
private void awaitStoringIntoDatabase() {
214185
Awaitility
215186
.await()
216187
.atMost(10, TimeUnit.SECONDS)
217188
.pollInterval(Duration.ofMillis(500L))
218189
.until(() -> countRecordsInTable() >= 1L);
219-
assertThat(output.getAll())
220-
.contains(
221-
"Received record: " + received.value() + " with traceId " + traceId,
222-
"Retrying request to ",
223-
"Retries exhausted",
224-
"\"instance_timezone\":\"" + zoneNames + "\""
225-
);
226190
}
227191
}

spring-boot-2-demo-app/src/test/java/io/github/mfvanek/spring/boot2/test/service/PublicApiServiceTest.java

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
package io.github.mfvanek.spring.boot2.test.service;
99

10-
import com.fasterxml.jackson.core.JsonProcessingException;
11-
import io.github.mfvanek.spring.boot2.test.service.dto.CurrentTime;
1210
import io.github.mfvanek.spring.boot2.test.service.dto.ParsedDateTime;
1311
import io.github.mfvanek.spring.boot2.test.support.TestBase;
1412
import org.junit.jupiter.api.Test;
@@ -18,16 +16,10 @@
1816
import org.springframework.boot.test.system.OutputCaptureExtension;
1917

2018
import java.time.LocalDateTime;
21-
import java.time.ZoneId;
2219
import java.time.temporal.ChronoUnit;
23-
import java.util.TimeZone;
2420
import javax.annotation.Nonnull;
2521

26-
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
27-
import static com.github.tomakehurst.wiremock.client.WireMock.get;
2822
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
29-
import static com.github.tomakehurst.wiremock.client.WireMock.resetAllRequests;
30-
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
3123
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
3224
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
3325
import static org.assertj.core.api.Assertions.assertThat;
@@ -39,46 +31,35 @@ class PublicApiServiceTest extends TestBase {
3931
private PublicApiService publicApiService;
4032

4133
@Test
42-
void getZonedTimeSuccessfully(@Nonnull final CapturedOutput output) throws JsonProcessingException {
43-
final String zoneNames = TimeZone.getDefault().getID();
44-
final LocalDateTime localDateTimeNow = LocalDateTime.now(ZoneId.systemDefault());
45-
final ParsedDateTime parsedDateTime = ParsedDateTime.from(localDateTimeNow);
46-
final CurrentTime currentTime = new CurrentTime(parsedDateTime);
47-
stubFor(get(urlPathMatching("/" + zoneNames))
48-
.willReturn(aResponse()
49-
.withStatus(200)
50-
.withBody(objectMapper.writeValueAsString(currentTime))
51-
));
34+
void getZonedTimeSuccessfully(@Nonnull final CapturedOutput output) {
35+
final LocalDateTime localDateTimeNow = LocalDateTime.now(clock);
36+
final String zoneNames = stubOkResponse(ParsedDateTime.from(localDateTimeNow));
5237

5338
final LocalDateTime result = publicApiService.getZonedTime();
5439
verify(getRequestedFor(urlPathMatching("/" + zoneNames)));
5540

5641
assertThat(result).isNotNull();
5742
assertThat(result.truncatedTo(ChronoUnit.MINUTES))
5843
.isEqualTo(localDateTimeNow.truncatedTo(ChronoUnit.MINUTES));
59-
assertThat(output.getAll()).doesNotContain(
60-
"Retrying request to ",
61-
"Retries exhausted",
62-
"Failed to convert response ",
63-
"timezone");
44+
assertThat(output.getAll())
45+
.contains("Request received:")
46+
.doesNotContain(
47+
"Retrying request to ",
48+
"Retries exhausted",
49+
"Failed to convert response ",
50+
"timezone");
6451
}
6552

6653
@Test
67-
void retriesOnceToGetZonedTime(@Nonnull final CapturedOutput output) throws JsonProcessingException {
68-
resetAllRequests();
69-
final String zoneNames = TimeZone.getDefault().getID();
70-
final RuntimeException exception = new RuntimeException("Retries exhausted");
71-
stubFor(get(urlPathMatching("/" + zoneNames))
72-
.willReturn(aResponse()
73-
.withStatus(500)
74-
.withBody(objectMapper.writeValueAsString(exception))
75-
));
54+
void retriesOnceToGetZonedTime(@Nonnull final CapturedOutput output) {
55+
final String zoneNames = stubErrorResponse();
7656

7757
final LocalDateTime result = publicApiService.getZonedTime();
7858
verify(2, getRequestedFor(urlPathMatching("/" + zoneNames)));
7959

8060
assertThat(result).isNull();
81-
assertThat(output.getAll()).contains("Retrying request to ", "Retries exhausted", "\"instance_timezone\":\"" + zoneNames + "\"");
82-
assertThat(output.getAll()).doesNotContain("Failed to convert response ");
61+
assertThat(output.getAll())
62+
.contains("Retrying request to ", "Retries exhausted", "\"instance_timezone\":\"" + zoneNames + "\"")
63+
.doesNotContain("Failed to convert response ");
8364
}
8465
}

spring-boot-2-demo-app/src/test/java/io/github/mfvanek/spring/boot2/test/support/PostgresInitializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
public class PostgresInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
1919

20-
private static final DockerImageName IMAGE = DockerImageName.parse("postgres:17.0");
20+
private static final DockerImageName IMAGE = DockerImageName.parse("postgres:17.2");
2121
private static final Network NETWORK = Network.newNetwork();
2222
private static final PostgreSQLContainer<?> CONTAINER = new PostgreSQLContainer<>(IMAGE);
2323

spring-boot-2-demo-app/src/test/java/io/github/mfvanek/spring/boot2/test/support/TestBase.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
package io.github.mfvanek.spring.boot2.test.support;
99

1010
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import com.github.tomakehurst.wiremock.client.WireMock;
12+
import io.github.mfvanek.spring.boot2.test.service.dto.CurrentTime;
13+
import io.github.mfvanek.spring.boot2.test.service.dto.ParsedDateTime;
14+
import lombok.SneakyThrows;
15+
import org.junit.jupiter.api.BeforeEach;
1116
import org.springframework.beans.factory.annotation.Autowired;
1217
import org.springframework.boot.test.context.SpringBootTest;
1318
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
@@ -18,6 +23,13 @@
1823
import org.springframework.test.web.reactive.server.WebTestClient;
1924

2025
import java.time.Clock;
26+
import java.util.TimeZone;
27+
import javax.annotation.Nonnull;
28+
29+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
30+
import static com.github.tomakehurst.wiremock.client.WireMock.get;
31+
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
32+
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
2133

2234
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
2335
@ContextConfiguration(initializers = {KafkaInitializer.class, JaegerInitializer.class, PostgresInitializer.class})
@@ -35,4 +47,43 @@ public abstract class TestBase {
3547
protected ObjectMapper objectMapper;
3648
@Autowired
3749
protected Clock clock;
50+
51+
@BeforeEach
52+
void resetExternalMocks() {
53+
WireMock.resetAllRequests();
54+
}
55+
56+
@Nonnull
57+
protected String stubOkResponse(@Nonnull final ParsedDateTime parsedDateTime) {
58+
final String zoneNames = TimeZone.getDefault().getID();
59+
stubOkResponse(zoneNames, parsedDateTime);
60+
return zoneNames;
61+
}
62+
63+
@SneakyThrows
64+
private void stubOkResponse(@Nonnull final String zoneNames, @Nonnull final ParsedDateTime parsedDateTime) {
65+
final CurrentTime currentTime = new CurrentTime(parsedDateTime);
66+
stubFor(get(urlPathMatching("/" + zoneNames))
67+
.willReturn(aResponse()
68+
.withStatus(200)
69+
.withBody(objectMapper.writeValueAsString(currentTime))
70+
));
71+
}
72+
73+
@Nonnull
74+
protected String stubErrorResponse() {
75+
final String zoneNames = TimeZone.getDefault().getID();
76+
final RuntimeException exception = new RuntimeException("Retries exhausted");
77+
stubErrorResponse(zoneNames, exception);
78+
return zoneNames;
79+
}
80+
81+
@SneakyThrows
82+
private void stubErrorResponse(@Nonnull final String zoneNames, @Nonnull final RuntimeException errorForResponse) {
83+
stubFor(get(urlPathMatching("/" + zoneNames))
84+
.willReturn(aResponse()
85+
.withStatus(500)
86+
.withBody(objectMapper.writeValueAsString(errorForResponse))
87+
));
88+
}
3889
}

spring-boot-3-demo-app/src/test/java/io/github/mfvanek/spring/boot3/test/IndexesMaintenanceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class IndexesMaintenanceTest extends TestBase {
3131
void checkPostgresVersion() {
3232
final String pgVersion = jdbcTemplate.queryForObject("select version();", String.class);
3333
assertThat(pgVersion)
34-
.startsWith("PostgreSQL 17.0");
34+
.startsWith("PostgreSQL 17.2");
3535
}
3636

3737
@Test

0 commit comments

Comments
 (0)