| /* |
| * Copyright (c) 2015, 2020 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 v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Marcel Valovy - initial API and implementation |
| // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| package org.eclipse.persistence.testing.tests.junit.cache; |
| |
| import java.lang.reflect.Field; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.eclipse.persistence.internal.cache.AdvancedProcessor; |
| import org.eclipse.persistence.internal.cache.ComputableTask; |
| import org.eclipse.persistence.internal.cache.Memoizer; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| /** |
| * @author Marcel Valovy - marcelv3612@gmail.com |
| */ |
| public class AdvancedProcessorTest { |
| |
| private AdvancedProcessor processor; |
| private MutableComputableTask<Integer, Integer> computableTask; |
| |
| @Before |
| public void setUp() { |
| processor = new AdvancedProcessor(); |
| computableTask = new Task<>(); |
| } |
| |
| @Test |
| public void testCompute() throws Exception { |
| Assert.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(); |
| |
| Assert.assertTrue(memoizerCache.values().size() == 1); |
| Assert.assertTrue(futureAfterFirstComputation == futureAfterSecondComputation); |
| fieldOnProcessor.setAccessible(false); |
| fieldOnMemoizer.setAccessible(false); |
| } |
| |
| public void testExpire() throws Exception { |
| |
| Assert.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(); |
| |
| Assert.assertFalse(futureAfterFirstComputation == futureAfterSecondComputation); |
| fieldOnProcessor.setAccessible(false); |
| fieldOnMemoizer.setAccessible(false); |
| |
| Assert.assertEquals(processor.compute(computableTask.setArg(7), 5), (Integer) 12); |
| } |
| |
| 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); |
| } |
| |
| } |