From 0b80d31612d99da2dd77ec023d41909cff0dd860 Mon Sep 17 00:00:00 2001 From: Nikolay Nesterov Date: Sun, 20 Mar 2016 15:44:24 +0300 Subject: [PATCH] Test for cached soft reference --- .../com/jcabi/aspects/aj/MethodCacher.java | 21 +++-- .../jcabi/aspects/aj/MethodCacherTest.java | 92 +++++++++++++++++++ 2 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 src/test/java/com/jcabi/aspects/aj/MethodCacherTest.java diff --git a/src/main/java/com/jcabi/aspects/aj/MethodCacher.java b/src/main/java/com/jcabi/aspects/aj/MethodCacher.java index 1c44d0ec..0b0d9495 100644 --- a/src/main/java/com/jcabi/aspects/aj/MethodCacher.java +++ b/src/main/java/com/jcabi/aspects/aj/MethodCacher.java @@ -258,14 +258,14 @@ protected static final class Tunnel { * When will it expire (moment in time). */ private transient long lifetime; - /** - * Cached value. - */ - private transient SoftReference cached; /** * Has non-null result? */ private transient boolean hasresult; + /** + * Cached value. + */ + private transient SoftReference cached; /** * Public ctor. @@ -362,12 +362,22 @@ public boolean expired() { public boolean asyncUpdate() { return this.async; } + + /** + * Soft reference to cached object. + * Visible only for testing. Don not use directly. + * @return Soft reference to cached object. + */ + public SoftReference getCached() { + return this.cached; + } } /** * Key of a callable target. + * @checkstyle DesignForExtensionCheck (140 lines) */ - protected static final class Key { + protected static class Key { /** * When instantiated. */ @@ -490,5 +500,4 @@ private static Object targetize(final JoinPoint point) { } } - } diff --git a/src/test/java/com/jcabi/aspects/aj/MethodCacherTest.java b/src/test/java/com/jcabi/aspects/aj/MethodCacherTest.java new file mode 100644 index 00000000..84f3a1c6 --- /dev/null +++ b/src/test/java/com/jcabi/aspects/aj/MethodCacherTest.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2012-2015, jcabi.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. 3) Neither the name of the jcabi.com nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jcabi.aspects.aj; + +import com.jcabi.aspects.Cacheable; +import java.lang.reflect.Method; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.Test; +import org.mockito.Mockito; + +/** + * Tests for {@link MethodCacher}. + * + * @author Nesterov Nikolay (nikolaynesterov@gmail.com) + * @version $Id$ + */ +public final class MethodCacherTest { + /** + * Cached result becomes expired when GC collect cached value. + * @throws Throwable If something goes wrong + * @checkstyle IllegalThrowsCheck (20 lines) + */ + @Test + public void becomesExpiredWhenCollected() throws Throwable { + final ProceedingJoinPoint point = Mockito.mock( + ProceedingJoinPoint.class + ); + Mockito.when(point.proceed()).thenReturn(new Object()); + final MethodCacher.Key key = Mockito.mock( + MethodCacher.Key.class + ); + final MethodCacher.Tunnel tunnel = new MethodCacher.Tunnel( + point, key, false + ); + final MethodSignature methodSignature = Mockito.mock( + MethodSignature.class + ); + final Method method = Buzz.class.getMethod("get"); + Mockito.when(methodSignature.getMethod()) + .thenReturn(method); + Mockito.when(point.getSignature()) + .thenReturn(methodSignature); + tunnel.through(); + MatcherAssert.assertThat(tunnel.expired(), Matchers.equalTo(false)); + tunnel.getCached().clear(); + MatcherAssert.assertThat(tunnel.expired(), Matchers.equalTo(true)); + } + + /** + * Test class for tests above. + */ + static class Buzz { + /** + * Return some object. + * @return Some object. + */ + @Cacheable(forever = true) + public Object get() { + return new Object(); + } + } +}