Copilot commented on code in PR #15961:
URL: https://github.com/apache/grails-core/pull/15961#discussion_r3560654626


##########
grails-cache/src/test/groovy/grails/plugin/cache/GrailsConcurrentLinkedMapCacheTests.groovy:
##########
@@ -18,107 +18,138 @@
  */
 package grails.plugin.cache
 
+import java.util.concurrent.ConcurrentMap
+
 import org.springframework.cache.support.SimpleValueWrapper
-import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap
-import org.junit.Test
+import spock.lang.Specification
 
 /**
  * @author Jakob Drangmeister
  */
-class GrailsConcurrentLinkedMapCacheTests {
-
-    @Test
-   void testCreateCache() {
-      GrailsConcurrentLinkedMapCache smallCache = new 
GrailsConcurrentLinkedMapCache("smallCache", 1000)
+class GrailsConcurrentLinkedMapCacheTests extends Specification {
+
+   void 'creates caches with configured capacity and null value policy'() {
+      when:
+      GrailsConcurrentLinkedMapCache smallCache = new 
GrailsConcurrentLinkedMapCache('smallCache', 1000)
+
+      then:
+      smallCache.name == 'smallCache'
+      smallCache.nativeCache instanceof ConcurrentMap
+      smallCache.capacity == 1000
+      smallCache.allowNullValues
+
+      when:
+      GrailsConcurrentLinkedMapCache bigCache = new 
GrailsConcurrentLinkedMapCache('bigCache', 5000000, false)
+
+      then:
+      bigCache.name == 'bigCache'
+      bigCache.nativeCache instanceof ConcurrentMap
+      bigCache.capacity == 5000000
+      !bigCache.allowNullValues
+   }
 
-      assert smallCache.getName() == "smallCache"
-      assert smallCache.getNativeCache() instanceof ConcurrentLinkedHashMap
-      assert smallCache.getCapacity() == 1000
-      assert smallCache.isAllowNullValues() == true
+   void 'exposes Caffeine native cache as concurrent map'() {
+      given:
+      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache('cache', 10, true)
 
-      GrailsConcurrentLinkedMapCache bigCache = new 
GrailsConcurrentLinkedMapCache("bigCache", 5000000, false)
+      when:
+      cache.put("key", "value")
 
-      assert bigCache.getName() == "bigCache"
-      assert bigCache.getNativeCache() instanceof ConcurrentLinkedHashMap
-      assert bigCache.getCapacity() == 5000000
-      assert bigCache.isAllowNullValues() == false
+      then:
+      cache.nativeCache.get('key') == 'value'
+      
cache.nativeCache.getClass().name.startsWith('com.github.benmanes.caffeine.cache.')

Review Comment:
   This assertion depends on the concrete implementation class name returned by 
Caffeine's asMap() view. That is not part of Caffeine's API contract and may 
change across versions, making the test brittle for no functional gain. Prefer 
asserting observable behavior (e.g., that hottestKeys includes the inserted 
key).



##########
grails-doc/src/en/guide/cache/cacheUsage/cacheConfiguration.adoc:
##########
@@ -28,7 +28,7 @@ There are a few configuration options for the plugin; these 
are specified in
 *Property*,*Default*,*Description*
 grails.cache.enabled,`true`,Whether to enable the plugin
 grails.cache.clearAtStartup,`false`,Whether to clear all caches at startup
-grails.cache.cacheManager,GrailsConcurrentMapCacheManager,Cache Manager to 
use. Default cache manager uses Spring Frameworks ConcurrentMapCache which 
might grow limitless. If you cannot predict how many cache entries you are 
going to generate use "GrailsConcurrentLinkedMapCacheManager" instead which 
uses com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap and limits 
by default to 10000 entries per cache.
+grails.cache.cacheManager,GrailsConcurrentMapCacheManager,Cache Manager to 
use. Default cache manager uses Spring Frameworks ConcurrentMapCache which 
might grow limitless. If you cannot predict how many cache entries you are 
going to generate use "GrailsConcurrentLinkedMapCacheManager" instead. In 
Grails 8.1 this manager keeps the public Grails cache API while using 
Caffeine-backed bounded caches; the old concurrentlinkedhashmap-lru dependency 
path is deprecated.

Review Comment:
   The docs mention "In Grails 8.1" even though this change is being merged 
into the current branch; tying behavior to a specific future version makes the 
guide inaccurate for the version these docs ship with. Also "Spring Frameworks" 
is missing the possessive apostrophe. Consider phrasing this 
version-agnostically and fixing the grammar.



##########
grails-cache/src/test/groovy/grails/plugin/cache/GrailsConcurrentLinkedMapCacheTests.groovy:
##########
@@ -18,107 +18,138 @@
  */
 package grails.plugin.cache
 
+import java.util.concurrent.ConcurrentMap
+
 import org.springframework.cache.support.SimpleValueWrapper
-import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap
-import org.junit.Test
+import spock.lang.Specification
 
 /**
  * @author Jakob Drangmeister
  */
-class GrailsConcurrentLinkedMapCacheTests {
-
-    @Test
-   void testCreateCache() {
-      GrailsConcurrentLinkedMapCache smallCache = new 
GrailsConcurrentLinkedMapCache("smallCache", 1000)
+class GrailsConcurrentLinkedMapCacheTests extends Specification {
+
+   void 'creates caches with configured capacity and null value policy'() {
+      when:
+      GrailsConcurrentLinkedMapCache smallCache = new 
GrailsConcurrentLinkedMapCache('smallCache', 1000)
+
+      then:
+      smallCache.name == 'smallCache'
+      smallCache.nativeCache instanceof ConcurrentMap
+      smallCache.capacity == 1000
+      smallCache.allowNullValues
+
+      when:
+      GrailsConcurrentLinkedMapCache bigCache = new 
GrailsConcurrentLinkedMapCache('bigCache', 5000000, false)
+
+      then:
+      bigCache.name == 'bigCache'
+      bigCache.nativeCache instanceof ConcurrentMap
+      bigCache.capacity == 5000000
+      !bigCache.allowNullValues
+   }
 
-      assert smallCache.getName() == "smallCache"
-      assert smallCache.getNativeCache() instanceof ConcurrentLinkedHashMap
-      assert smallCache.getCapacity() == 1000
-      assert smallCache.isAllowNullValues() == true
+   void 'exposes Caffeine native cache as concurrent map'() {
+      given:
+      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache('cache', 10, true)
 
-      GrailsConcurrentLinkedMapCache bigCache = new 
GrailsConcurrentLinkedMapCache("bigCache", 5000000, false)
+      when:
+      cache.put("key", "value")
 
-      assert bigCache.getName() == "bigCache"
-      assert bigCache.getNativeCache() instanceof ConcurrentLinkedHashMap
-      assert bigCache.getCapacity() == 5000000
-      assert bigCache.isAllowNullValues() == false
+      then:
+      cache.nativeCache.get('key') == 'value'
+      
cache.nativeCache.getClass().name.startsWith('com.github.benmanes.caffeine.cache.')
    }
 
-   @Test
-   void testPutAndGet() {
-      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache("cache", 1000, true)
+   void 'puts and gets cache entries'() {
+      given:
+      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache('cache', 1000, true)
 
-      cache.put("key", "value");
+      when:
+      cache.put('key', 'value')
 
-      assert cache.getSize() == 1
+      then:
+      cache.size == 1
       GrailsValueWrapper value = cache.get("key")
-      assert value.get().equals("value")
+      value.get() == 'value'
    }
 
-   @Test
-   void testPutIfAbsent() {
-      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache("cache", 1000, true)
-      cache.put("key", "value")
-      cache.putIfAbsent("key", "value") instanceof SimpleValueWrapper
-      assert cache.getSize() == 1
+   void 'putIfAbsent keeps existing cache value'() {
+      given:
+      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache('cache', 1000, true)
+      cache.put('key', 'value')
+
+      expect:
+      cache.putIfAbsent('key', 'value') instanceof SimpleValueWrapper
+      cache.size == 1
    }
 
-   @Test
-   void testEvict() {
-      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache("cache", 10, true)
-      cache.put("key", "value");
-      assert cache.getSize() == 1
+   void 'evicts cache entries'() {
+      given:
+      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache('cache', 10, true)
+      cache.put('key', 'value')
 
-      cache.evict("key")
-      assert cache.getSize() == 0
+      expect:
+      cache.size == 1
 
+      when:
+      cache.evict('key')
+
+      then:
+      cache.size == 0
    }
 
-   @Test
-   void testCacheCapacity() {
-      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache("cache", 1000, true)
-      assert cache.getCapacity() == 1000
+   void 'limits cache size to configured capacity'() {
+      given:
+      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache('cache', 1000, true)
 
-      for(int i = 0; i < 2000; i++) {
-         cache.put(i, i)
+      when:
+      for (int i = 0; i < 2000; i++) {
+          cache.put(i, i)
       }
 
-      assert cache.getSize() == 1000
+      then:
+      cache.capacity == 1000
+      cache.size == 1000
    }
 
-   @Test
-   void testCacheGetHottestKeys() {
-      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache("cache", 10, true)
+   void 'returns hottest keys from cache eviction policy'() {
+      given:
+      GrailsConcurrentLinkedMapCache cache = new 
GrailsConcurrentLinkedMapCache('cache', 10, true)
 
-      for(int i = 0; i < 10; i++) {
-         cache.put(i, i);
+      for (int i = 0; i < 10; i++) {
+         cache.put(i, i)
       }
 
+      when:
       cache.get(1)
       cache.get(2)
 

Review Comment:
   This test relies on Caffeine's eviction/admission heuristics to keep key `2` 
resident after many new inserts, but the current access pattern (single 
`get(2)`) can be borderline and may become flaky across Caffeine versions. 
Making `2` meaningfully hotter (e.g., repeated reads) will stabilize the intent 
of the test.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to