From 8287659b3d51c72d152f78c640410c58b6e44ebd Mon Sep 17 00:00:00 2001 From: Gilles Sadowski Date: Sat, 21 Jul 2012 12:47:04 +0000 Subject: [PATCH] MATH-797 Added unit test. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1364075 13f79535-47bb-0310-9956-ffa450edef68 --- .../gauss/BaseRuleFactoryTest.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/test/java/org/apache/commons/math3/analysis/integration/gauss/BaseRuleFactoryTest.java diff --git a/src/test/java/org/apache/commons/math3/analysis/integration/gauss/BaseRuleFactoryTest.java b/src/test/java/org/apache/commons/math3/analysis/integration/gauss/BaseRuleFactoryTest.java new file mode 100644 index 000000000..6de395d98 --- /dev/null +++ b/src/test/java/org/apache/commons/math3/analysis/integration/gauss/BaseRuleFactoryTest.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math3.analysis.integration.gauss; + +import java.util.List; +import java.util.ArrayList; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.math3.util.Pair; +import org.junit.Test; +import org.junit.Assert; + +/** + * Test for {@link BaseRuleFactory}. + * + * @version $Id$ + */ +public class BaseRuleFactoryTest { + /** + * Tests that a given rule rule will be computed and added once to the cache + * whatever the number of times this rule is called concurrently. + */ + @Test + public void testConcurrentCreation() throws InterruptedException { + // Number of times the same rule will be called. + final int numTasks = 20; + + final ThreadPoolExecutor exec + = new ThreadPoolExecutor(3, numTasks, 1, TimeUnit.SECONDS, + new ArrayBlockingQueue(2)); + + final List tasks = new ArrayList(); + for (int i = 0; i < numTasks; i++) { + tasks.add(new RuleBuilder()); + } + + List>> results = exec.invokeAll(tasks); + + // Assertion would fail if "getRuleInternal" were not "synchronized". + final int n = RuleBuilder.getNumberOfCalls(); + Assert.assertEquals("Rule computation was called " + n + " times", 1, n); + } +} + +class RuleBuilder implements Callable> { + private static final DummyRuleFactory factory = new DummyRuleFactory(); + + public Pair call() { + final int dummy = 2; // Always request the same rule. + return factory.getRule(dummy); + } + + public static int getNumberOfCalls() { + return factory.getNumberOfCalls(); + } +} + +class DummyRuleFactory extends BaseRuleFactory { + /** Rule computations counter. */ + private static AtomicInteger nCalls = new AtomicInteger(); + + @Override + protected Pair computeRule(int order) { + // Tracks whether this computation has been called more than once. + nCalls.getAndIncrement(); + + try { + // Sleep to simulate computation time. + Thread.sleep(20); + } catch (InterruptedException e) { + Assert.fail("Unexpected interruption"); + } + + // Dummy rule (but contents must exist). + return new Pair(new Double[order], + new Double[order]); + } + + public int getNumberOfCalls() { + return nCalls.get(); + } +}