blob: e278d972d3b2c49e6a2b02beaf4e856e05cb4347 [file] [log] [blame]
/*
* 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 freemarker.ext.beans;
import junit.framework.TestCase;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateNumberModel;
public abstract class AbstractParallelIntrospectionTest extends TestCase {
private static final int NUM_THREADS = 8;
private static final int NUM_ENTITYES = 8;
private static final int NUM_MEMBERS = 8;
private static final int ITERATIONS = 20000;
private static final double CACHE_CLEARING_CHANCE = 0.01;
private BeansWrapper beansWrapper = new BeansWrapper();
public AbstractParallelIntrospectionTest(String name) {
super(name);
}
public void testReliability() {
testReliability(ITERATIONS);
}
public void testReliability(int iterations) {
TestThread[] ts = new TestThread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
ts[i] = new TestThread(iterations);
ts[i].start();
}
for (int i = 0; i < NUM_THREADS; i++) {
try {
ts[i].join();
if (ts[i].error != null) {
throw new AssertionError(ts[i].error);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
protected abstract TemplateHashModel getWrappedEntity(int objIdx) throws TemplateModelException;
protected final BeansWrapper getBeansWrapper() {
return beansWrapper;
}
private class TestThread extends Thread {
private final int iterations;
private Throwable error;
private TestThread(int iterations) {
this.iterations = iterations;
}
@Override
public void run() {
try {
for (int i = 0; i < iterations; i++) {
if (Math.random() < CACHE_CLEARING_CHANCE) {
beansWrapper.clearClassIntrospecitonCache();
}
int objIdx = (int) (Math.random() * NUM_ENTITYES);
TemplateHashModel h = getWrappedEntity(objIdx);
int mIdx = (int) (Math.random() * NUM_MEMBERS);
testProperty(h, objIdx, mIdx);
testMethod(h, objIdx, mIdx);
}
} catch (Throwable e) {
error = e;
}
}
private void testProperty(TemplateHashModel h, int objIdx, int mIdx)
throws TemplateModelException, AssertionError {
TemplateNumberModel pv = (TemplateNumberModel) h.get("p" + mIdx);
final int expected = objIdx * 1000 + mIdx;
final int got = pv.getAsNumber().intValue();
if (got != expected) {
throw new AssertionError("Property assertation failed; " +
"expected " + expected + ", but got " + got);
}
}
private void testMethod(TemplateHashModel h, int objIdx, int mIdx)
throws TemplateModelException, AssertionError {
TemplateMethodModel pv = (TemplateMethodModel) h.get("m" + mIdx);
final int expected = objIdx * 1000 + mIdx;
final int got = ((TemplateNumberModel) pv.exec(null)).getAsNumber().intValue();
if (got != expected) {
throw new AssertionError("Method assertation failed; " +
"expected " + expected + ", but got " + got);
}
}
}
}