From 8960571da4cc36c998d35e4ea0a8af415e9cbedb Mon Sep 17 00:00:00 2001 From: Tim Yates Date: Wed, 13 Sep 2023 09:40:04 +0100 Subject: [PATCH 1/2] Add tests from micronaut-graal-tests This PR copies the tests across from the micronaut-graal-tests project for cache https://github.com/micronaut-graal-tests/micronaut-cache-graal/tree/3.10.x We can then tick it off on the issue tasks in core https://github.com/micronaut-projects/micronaut-core/issues/9083 --- test-suite-caffeine-native/build.gradle | 4 +- .../test/java/io/micronaut/cache/News.java | 37 +++++++ .../io/micronaut/cache/NewsController.java | 21 ++++ .../micronaut/cache/NewsControllerTest.java | 40 ++++++++ .../java/io/micronaut/cache/NewsService.java | 58 +++++++++++ .../io/micronaut/cache/NewsServiceTest.java | 97 +++++++++++++++++++ 6 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 test-suite-caffeine-native/src/test/java/io/micronaut/cache/News.java create mode 100644 test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsController.java create mode 100644 test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java create mode 100644 test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsService.java create mode 100644 test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsServiceTest.java diff --git a/test-suite-caffeine-native/build.gradle b/test-suite-caffeine-native/build.gradle index 203ce420f..650b58647 100644 --- a/test-suite-caffeine-native/build.gradle +++ b/test-suite-caffeine-native/build.gradle @@ -14,7 +14,9 @@ repositories { dependencies { testAnnotationProcessor(mn.micronaut.inject.java) - testImplementation projects.micronautCacheCaffeine + testAnnotationProcessor(mnSerde.micronaut.serde.processor) + testImplementation(mnSerde.micronaut.serde.api) + testImplementation(projects.micronautCacheCaffeine) testImplementation(mn.micronaut.http.server.netty) testImplementation(mn.micronaut.http.client) testImplementation(mnTest.micronaut.test.junit5) diff --git a/test-suite-caffeine-native/src/test/java/io/micronaut/cache/News.java b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/News.java new file mode 100644 index 000000000..2ebe01a94 --- /dev/null +++ b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/News.java @@ -0,0 +1,37 @@ +package io.micronaut.cache; + +import io.micronaut.serde.annotation.Serdeable; + +import java.time.Month; +import java.util.List; + +@Serdeable +public class News { + private Month month; + + private List headlines; + + public News() { + } + + public News(Month month, List headlines) { + this.month = month; + this.headlines = headlines; + } + + public Month getMonth() { + return month; + } + + public void setMonth(Month month) { + this.month = month; + } + + public List getHeadlines() { + return headlines; + } + + public void setHeadlines(List headlines) { + this.headlines = headlines; + } +} diff --git a/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsController.java b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsController.java new file mode 100644 index 000000000..c9bf0edba --- /dev/null +++ b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsController.java @@ -0,0 +1,21 @@ +package io.micronaut.cache; + +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; + +import java.time.Month; + +@Controller +public class NewsController { + + private final NewsService newsService; + + public NewsController(NewsService newsService) { + this.newsService = newsService; + } + + @Get("/{month}") + public News index(Month month) { + return new News(month, newsService.headlines(month)); + } +} diff --git a/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java new file mode 100644 index 000000000..23b8254e0 --- /dev/null +++ b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java @@ -0,0 +1,40 @@ +package io.micronaut.cache; + +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; +import io.micronaut.http.uri.UriBuilder; +import io.micronaut.runtime.server.EmbeddedServer; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import java.time.Month; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@MicronautTest +class NewsControllerTest { + + @Inject + EmbeddedServer server; + + @Inject + @Client("/") + HttpClient client; + + @Timeout(4) + @Test + void fetchingOctoberHeadlinesUsesCache() { + HttpRequest request = HttpRequest.GET(UriBuilder.of("/").path(Month.OCTOBER.toString()).build()); + + News news = client.toBlocking().retrieve(request, News.class); + String expected = "Micronaut AOP: Awesome flexibility without the complexity"; + assertEquals(List.of(expected), news.getHeadlines()); + + news = client.toBlocking().retrieve(request, News.class); + assertEquals(List.of(expected), news.getHeadlines()); + } +} diff --git a/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsService.java b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsService.java new file mode 100644 index 000000000..0b6514afa --- /dev/null +++ b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsService.java @@ -0,0 +1,58 @@ +package io.micronaut.cache; + +import io.micronaut.cache.annotation.CacheInvalidate; +import io.micronaut.cache.annotation.CachePut; +import io.micronaut.cache.annotation.Cacheable; +import jakarta.inject.Singleton; + +import java.time.Month; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Singleton +public class NewsService { + + Map> headlines = new HashMap<>(Map.of( + Month.NOVEMBER, List.of( + "Micronaut Graduates to Trial Level in Thoughtworks technology radar Vol.1", + "Micronaut AOP: Awesome flexibility without the complexity" + ), + Month.OCTOBER, Collections.singletonList("Micronaut AOP: Awesome flexibility without the complexity") + )); + + @SuppressWarnings("java:S2925") // Sleep is used for testing purposes only + @Cacheable(value = "headlines", parameters = {"month"}) + public List headlines(Month month) { + try { + TimeUnit.SECONDS.sleep(3); + return headlines.get(month); + } catch (InterruptedException e) { + return null; + } + } + + @CachePut(value = "headlines", parameters = {"month"}) + public List addHeadline(Month month, String headline) { + if (headlines.containsKey(month)) { + List l = new ArrayList<>(headlines.get(month)); + l.add(headline); + headlines.put(month, l); + } else { + headlines.put(month, Collections.singletonList(headline)); + } + return headlines.get(month); + } + + @CacheInvalidate(value = "headlines", parameters = {"month"}) + public void removeHeadline(Month month, String headline) { + if (headlines.containsKey(month)) { + List l = new ArrayList<>(headlines.get(month)); + l.remove(headline); + headlines.put(month, l); + } + } +} diff --git a/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsServiceTest.java b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsServiceTest.java new file mode 100644 index 000000000..ab82654a3 --- /dev/null +++ b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsServiceTest.java @@ -0,0 +1,97 @@ +package io.micronaut.cache; + +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.Timeout; + +import java.time.Month; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@MicronautTest +@SuppressWarnings("java:S5976") // Sonar thinks these can be parameterized +class NewsServiceTest { + + @Inject + NewsService newsService; + + @Timeout(4) + @Test + @Order(1) + void firstInvocationOfNovemberDoesNotHitCache() { + List headlines = newsService.headlines(Month.NOVEMBER); + assertEquals(2, headlines.size()); + } + + @Timeout(1) + @Test + @Order(2) + void secondInvocationOfNovemberHitsCache() { + List headlines = newsService.headlines(Month.NOVEMBER); + assertEquals(2, headlines.size()); + } + + @Timeout(4) + @Test + @Order(3) + void firstInvocationOfOctoberDoesNotHitCache() { + List headlines = newsService.headlines(Month.OCTOBER); + assertEquals(1, headlines.size()); + } + + @Timeout(1) + @Test + @Order(4) + void secondInvocationOfOctoberHitsCache() { + List headlines = newsService.headlines(Month.OCTOBER); + assertEquals(1, headlines.size()); + } + + @Timeout(1) + @Test + @Order(5) + void addingAHeadlineToNovemberUpdatesCache() { + List headlines = newsService.addHeadline(Month.NOVEMBER, "Micronaut 1.3 Milestone 1 Released"); + assertEquals(3, headlines.size()); + } + + @Timeout(1) + @Test + @Order(6) + void novemberCacheWasUpdatedByCachePutAndThusTheValueIsRetrievedFromTheCache() { + List headlines = newsService.headlines(Month.NOVEMBER); + assertEquals(3, headlines.size()); + } + + @Timeout(1) + @Test + @Order(7) + void invalidateNovemberCacheWithCacheInvalidate() { + assertDoesNotThrow(() -> { + newsService.removeHeadline(Month.NOVEMBER, "Micronaut 1.3 Milestone 1 Released"); + }); + } + + @Timeout(1) + @Test + @Order(8) + void octoberCacheIsStillValid() { + List headlines = newsService.headlines(Month.OCTOBER); + assertEquals(1, headlines.size()); + } + + @Timeout(4) + @Test + @Order(9) + void novemberCacheWasInvalidated() { + List headlines = newsService.headlines(Month.NOVEMBER); + assertEquals(2, headlines.size()); + } +} From c0f13b09a39a5bbd2c508039c753354ad4c1fe31 Mon Sep 17 00:00:00 2001 From: Tim Yates Date: Wed, 13 Sep 2023 10:11:52 +0100 Subject: [PATCH 2/2] Remove unused server --- .../src/test/java/io/micronaut/cache/NewsControllerTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java index 23b8254e0..15364740c 100644 --- a/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java +++ b/test-suite-caffeine-native/src/test/java/io/micronaut/cache/NewsControllerTest.java @@ -4,7 +4,6 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.uri.UriBuilder; -import io.micronaut.runtime.server.EmbeddedServer; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import jakarta.inject.Inject; import org.junit.jupiter.api.Test; @@ -18,9 +17,6 @@ @MicronautTest class NewsControllerTest { - @Inject - EmbeddedServer server; - @Inject @Client("/") HttpClient client;