/** * **************************************************************************** * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * <p/> * Contributors: * Marcel Valovy - initial API and implementation * **************************************************************************** */ package org.eclipse.persistence.testing.tests.cache; import org.eclipse.persistence.internal.cache.AdvancedProcessor; import org.eclipse.persistence.internal.cache.ComputableTask; import org.eclipse.persistence.internal.cache.Memoizer; import org.eclipse.persistence.testing.framework.TestCase; import java.lang.reflect.Field; import java.util.Iterator; import java.util.Map; /** * @author Marcel Valovy - marcelv3612@gmail.com */ public class AdvancedProcessorTestCase extends TestCase { public void test() throws Exception { testCompute(); testExpire(); } private AdvancedProcessor processor; private MutableComputableTask<Integer, Integer> computableTask; public void testCompute() throws Exception { assertEquals(processor.compute(computableTask.setArg(5), 5), (Integer) 10); Field fieldOnProcessor = AdvancedProcessor.class.getDeclaredField("memoizer"); fieldOnProcessor.setAccessible(true); //noinspection unchecked Memoizer<Object, Object> memoizer = (Memoizer<Object, Object>) fieldOnProcessor.get(processor); Field fieldOnMemoizer = Memoizer.class.getDeclaredField("cache"); fieldOnMemoizer.setAccessible(true); Map memoizerCache = (Map) fieldOnMemoizer.get(memoizer); Object futureAfterFirstComputation = memoizerCache.values().iterator().next(); processor.compute(computableTask.setArg(5), 5); Object futureAfterSecondComputation = memoizerCache.values().iterator().next(); assertTrue(memoizerCache.values().size() == 1); assertTrue(futureAfterFirstComputation == futureAfterSecondComputation); fieldOnProcessor.setAccessible(false); fieldOnMemoizer.setAccessible(false); } public void testExpire() throws Exception { assertEquals(processor.compute(computableTask.setArg(5), 5), (Integer) 10); Field fieldOnProcessor = AdvancedProcessor.class.getDeclaredField("memoizer"); fieldOnProcessor.setAccessible(true); //noinspection unchecked Memoizer<Object, Object> memoizer = (Memoizer<Object, Object>) fieldOnProcessor.get(processor); Field fieldOnMemoizer = Memoizer.class.getDeclaredField("cache"); fieldOnMemoizer.setAccessible(true); Map memoizerCache = (Map) fieldOnMemoizer.get(memoizer); Object futureAfterFirstComputation = memoizerCache.values().iterator().next(); processor.clear(); processor.compute(computableTask.setArg(5), 5); final Iterator iteratorAfterSecondComputation = memoizerCache.values().iterator(); // we still have just one element in cache, because we called processor.clear() Object futureAfterSecondComputation = iteratorAfterSecondComputation.next(); assertFalse(futureAfterFirstComputation == futureAfterSecondComputation); fieldOnProcessor.setAccessible(false); fieldOnMemoizer.setAccessible(false); assertEquals(processor.compute(computableTask.setArg(7), 5), (Integer) 12); } public void setUp() { processor = new AdvancedProcessor(); computableTask = new Task<>(); } static class Task<A, V> implements MutableComputableTask<A, V> { private A a; @Override public V compute(A arg) throws InterruptedException { //noinspection unchecked return (V)(Object)((Integer) a + (Integer) arg); } @Override public MutableComputableTask<A, V> setArg(A arg) { a = arg; return this; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Task task = (Task) o; if (a != null ? !a.equals(task.a) : task.a != null) return false; return true; } @Override public int hashCode() { return a != null ? a.hashCode() : 0; } } private interface MutableComputableTask<A, V> extends ComputableTask<A, V> { MutableComputableTask<A, V> setArg(A arg); } }