Update spring-boot-actuator to use docker-test plugin

See gh-41228
This commit is contained in:
Andy Wilkinson
2024-06-25 17:22:41 +01:00
parent 9f166f2c85
commit ba053dbaac
5 changed files with 12 additions and 4 deletions

View File

@@ -1,141 +0,0 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
package org.springframework.boot.actuate.metrics.cache;
import java.util.UUID;
import java.util.function.BiConsumer;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.testsupport.container.RedisContainer;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RedisCacheMetrics}.
*
* @author Stephane Nicoll
*/
@Testcontainers(disabledWithoutDocker = true)
class RedisCacheMetricsTests {
@Container
static final RedisContainer redis = TestImage.container(RedisContainer.class);
private static final Tags TAGS = Tags.of("app", "test").and("cache", "test");
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class, CacheAutoConfiguration.class))
.withUserConfiguration(CachingConfiguration.class)
.withPropertyValues("spring.data.redis.host=" + redis.getHost(),
"spring.data.redis.port=" + redis.getFirstMappedPort(), "spring.cache.type=redis",
"spring.cache.redis.enable-statistics=true");
@Test
void cacheStatisticsAreExposed() {
this.contextRunner.run(withCacheMetrics((cache, meterRegistry) -> {
assertThat(meterRegistry.find("cache.size").tags(TAGS).functionCounter()).isNull();
assertThat(meterRegistry.find("cache.gets").tags(TAGS.and("result", "hit")).functionCounter()).isNotNull();
assertThat(meterRegistry.find("cache.gets").tags(TAGS.and("result", "miss")).functionCounter()).isNotNull();
assertThat(meterRegistry.find("cache.gets").tags(TAGS.and("result", "pending")).functionCounter())
.isNotNull();
assertThat(meterRegistry.find("cache.evictions").tags(TAGS).functionCounter()).isNull();
assertThat(meterRegistry.find("cache.puts").tags(TAGS).functionCounter()).isNotNull();
assertThat(meterRegistry.find("cache.removals").tags(TAGS).functionCounter()).isNotNull();
assertThat(meterRegistry.find("cache.lock.duration").tags(TAGS).timeGauge()).isNotNull();
}));
}
@Test
void cacheHitsAreExposed() {
this.contextRunner.run(withCacheMetrics((cache, meterRegistry) -> {
String key = UUID.randomUUID().toString();
cache.put(key, "test");
cache.get(key);
cache.get(key);
assertThat(meterRegistry.get("cache.gets").tags(TAGS.and("result", "hit")).functionCounter().count())
.isEqualTo(2.0d);
}));
}
@Test
void cacheMissesAreExposed() {
this.contextRunner.run(withCacheMetrics((cache, meterRegistry) -> {
String key = UUID.randomUUID().toString();
cache.get(key);
cache.get(key);
cache.get(key);
assertThat(meterRegistry.get("cache.gets").tags(TAGS.and("result", "miss")).functionCounter().count())
.isEqualTo(3.0d);
}));
}
@Test
void cacheMetricsMatchCacheStatistics() {
this.contextRunner.run((context) -> {
RedisCache cache = getTestCache(context);
RedisCacheMetrics cacheMetrics = new RedisCacheMetrics(cache, TAGS);
assertThat(cacheMetrics.hitCount()).isEqualTo(cache.getStatistics().getHits());
assertThat(cacheMetrics.missCount()).isEqualTo(cache.getStatistics().getMisses());
assertThat(cacheMetrics.putCount()).isEqualTo(cache.getStatistics().getPuts());
assertThat(cacheMetrics.size()).isNull();
assertThat(cacheMetrics.evictionCount()).isNull();
});
}
private ContextConsumer<AssertableApplicationContext> withCacheMetrics(
BiConsumer<RedisCache, MeterRegistry> stats) {
return (context) -> {
RedisCache cache = getTestCache(context);
SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry();
new RedisCacheMetrics(cache, Tags.of("app", "test")).bindTo(meterRegistry);
stats.accept(cache, meterRegistry);
};
}
private RedisCache getTestCache(AssertableApplicationContext context) {
assertThat(context).hasSingleBean(RedisCacheManager.class);
RedisCacheManager cacheManager = context.getBean(RedisCacheManager.class);
RedisCache cache = (RedisCache) cacheManager.getCache("test");
assertThat(cache).isNotNull();
return cache;
}
@Configuration(proxyBeanMethods = false)
@EnableCaching
static class CachingConfiguration {
}
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
package org.springframework.boot.actuate.mongo;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
import com.mongodb.ServerApi;
import com.mongodb.ServerApiVersion;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.data.mongodb.core.MongoTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link MongoHealthIndicator}.
*
* @author Andy Wilkinson
*/
@Testcontainers(disabledWithoutDocker = true)
class MongoHealthIndicatorIntegrationTests {
@Container
static MongoDBContainer mongo = TestImage.container(MongoDBContainer.class);
@Test
void standardApi() {
Health health = mongoHealth();
assertThat(health.getStatus()).isEqualTo(Status.UP);
}
@Test
void strictV1Api() {
Health health = mongoHealth(ServerApi.builder().strict(true).version(ServerApiVersion.V1).build());
assertThat(health.getStatus()).isEqualTo(Status.UP);
}
private Health mongoHealth() {
return mongoHealth(null);
}
private Health mongoHealth(ServerApi serverApi) {
Builder settingsBuilder = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(mongo.getConnectionString()));
if (serverApi != null) {
settingsBuilder.serverApi(serverApi);
}
MongoClientSettings settings = settingsBuilder.build();
MongoClient mongoClient = MongoClients.create(settings);
MongoHealthIndicator healthIndicator = new MongoHealthIndicator(new MongoTemplate(mongoClient, "db"));
return healthIndicator.getHealth(true);
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
package org.springframework.boot.actuate.mongo;
import java.time.Duration;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
import com.mongodb.ServerApi;
import com.mongodb.ServerApiVersion;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.boot.actuate.data.mongo.MongoReactiveHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link MongoReactiveHealthIndicator}.
*
* @author Andy Wilkinson
*/
@Testcontainers(disabledWithoutDocker = true)
class MongoReactiveHealthIndicatorIntegrationTests {
@Container
static MongoDBContainer mongo = TestImage.container(MongoDBContainer.class);
@Test
void standardApi() {
Health health = mongoHealth();
assertThat(health.getStatus()).isEqualTo(Status.UP);
}
@Test
void strictV1Api() {
Health health = mongoHealth(ServerApi.builder().strict(true).version(ServerApiVersion.V1).build());
assertThat(health.getStatus()).isEqualTo(Status.UP);
}
private Health mongoHealth() {
return mongoHealth(null);
}
private Health mongoHealth(ServerApi serverApi) {
Builder settingsBuilder = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(mongo.getConnectionString()));
if (serverApi != null) {
settingsBuilder.serverApi(serverApi);
}
MongoClientSettings settings = settingsBuilder.build();
MongoClient mongoClient = MongoClients.create(settings);
MongoReactiveHealthIndicator healthIndicator = new MongoReactiveHealthIndicator(
new ReactiveMongoTemplate(mongoClient, "db"));
return healthIndicator.getHealth(true).block(Duration.ofSeconds(30));
}
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
package org.springframework.boot.actuate.neo4j;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link Neo4jReactiveHealthIndicator}.
*
* @author Phillip Webb
*/
@SpringBootTest
@Testcontainers(disabledWithoutDocker = true)
class Neo4jReactiveHealthIndicatorIntegrationTests {
// gh-33428
@Container
private static final Neo4jContainer<?> neo4jServer = TestImage.container(Neo4jContainer.class);
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", neo4jServer::getBoltUrl);
registry.add("spring.neo4j.authentication.username", () -> "neo4j");
registry.add("spring.neo4j.authentication.password", neo4jServer::getAdminPassword);
}
@Autowired
private Neo4jReactiveHealthIndicator healthIndicator;
@Test
void health() {
Health health = this.healthIndicator.getHealth(true).block(Duration.ofSeconds(20));
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).containsEntry("edition", "community");
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(Neo4jAutoConfiguration.class)
@Import(Neo4jReactiveHealthIndicator.class)
static class TestConfiguration {
}
}