]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/CommandSequenceTest.java
Added missing org.simantics.db.{tests,testing} plug-ins.
[simantics/platform.git] / bundles / org.simantics.db.testing / src / org / simantics / db / testing / base / CommandSequenceTest.java
diff --git a/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/CommandSequenceTest.java b/bundles/org.simantics.db.testing/src/org/simantics/db/testing/base/CommandSequenceTest.java
new file mode 100644 (file)
index 0000000..f1d21c4
--- /dev/null
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.testing.base;
+
+import gnu.trove.list.array.TLongArrayList;
+
+import org.apache.commons.math3.stat.regression.SimpleRegression;
+import org.junit.Test;
+import org.simantics.db.Session;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.testing.cases.FreshDatabaseTest;
+import org.simantics.db.testing.common.Command;
+import org.simantics.db.testing.common.CommandSequenceEnvironment;
+import org.simantics.db.testing.common.CommandSpec;
+
+
+/**
+ * 
+ * @author Antti Villberg <antti.villberg@semantum.fi>
+ * 
+ */
+abstract public class CommandSequenceTest extends FreshDatabaseTest implements CommandSequenceEnvironment {
+
+       private static final boolean TRACE = true;
+
+       protected TLongArrayList executionTimes = new TLongArrayList();
+
+       protected double getSlowdown() {
+
+               SimpleRegression regression = new SimpleRegression();
+               for(int i=0;i<executionTimes.size();i++) {
+                       regression.addData(i, executionTimes.getQuick(i));
+               }
+               double intercept = regression.getIntercept();
+               double slope = regression.getSlope();
+               
+               return (slope * executionTimes.size())/Math.abs(intercept);
+
+       }
+       
+       protected String getExecutionData() {
+               StringBuilder b = new StringBuilder();
+               for(int i=0;i<executionTimes.size();i++) {
+                       b.append(executionTimes.get(i) + "\n");
+               }
+               return b.toString();
+       }
+       
+       protected void printExecutionTimes() {
+               for(int i=0;i<executionTimes.size();i++) {
+                       System.err.println("" + i + ": " + executionTimes.getQuick(i));
+               }
+       }
+       
+       protected void assertSlowdown(double slowdown) {
+               assertLess(getSlowdown(), 0.1, getExecutionData());
+       }
+       
+       protected int getSequenceSize() {
+               return 0;
+       }
+       
+       protected Command[] beforeSequence(CommandSequenceEnvironment environment) throws Exception {
+               return new Command[0];
+       }
+       
+       protected Command[] afterSequence(CommandSequenceEnvironment environment) throws Exception {
+               return new Command[0];
+       }
+
+       protected CommandSpec<?>[] getFactories() {
+               return null;
+       }
+       
+       @Override
+       public Session getSession() {
+               return super.getSession();
+       }
+       
+       public int randomNatural() {
+               return (int)(Math.random() * Integer.MAX_VALUE);
+       }
+       
+       protected Command[] newSequence() throws Exception {
+               int size = getSequenceSize();
+               CommandSpec<?>[] classes = getFactories();
+               int index = 0;
+               Command[] result = new Command[size];
+               double totalWeight = 0;
+               for(CommandSpec<?> p : classes) totalWeight += p.weight;
+               double[] wts = new double[classes.length];
+               index=0;
+               double previous = 0;
+               for(CommandSpec<?> p : classes) {
+                       double weight = p.weight/totalWeight;
+                       wts[index++] = previous + weight;
+                       previous += weight;
+               }
+               
+               for(int i=0;i<size;i++) {
+                       double n = Math.random();
+                       for(int j=0;j<classes.length;j++) {
+                               if(n < wts[j]) {
+                                       result[i] = classes[j].clazz.newInstance();
+                                       break;
+                               }
+                               if(j==result.length-1) {
+                                       result[i] = classes[result.length-1].clazz.newInstance();
+                                       break;
+                               }
+                       }
+               }
+               return result;
+       }
+       
+       protected CommandSequenceEnvironment createEnvironment() {
+               return this;
+       }
+       
+       protected void initialize(CommandSequenceEnvironment environment) throws Exception {
+               
+       }
+
+       protected void analyse(CommandSequenceEnvironment environment) throws Exception {
+               
+       }
+       
+       @Test
+       public void test() throws Exception {
+
+               CommandSequenceEnvironment environment = createEnvironment();
+               
+               initialize(environment);
+               
+       for(Command command : beforeSequence(environment)) {
+               command.run(environment);
+       }
+               
+       int counter=0;
+       int lastProgress=0;
+       
+       Command[] sequence = newSequence();
+       for(Command command : sequence) {
+               if (TRACE)
+                       System.err.println("[" + counter + "/" + sequence.length +  "]: " + command.getClass().getSimpleName());
+               long start = System.nanoTime();
+               try {
+                       command.run(environment);
+               } catch (Throwable t) {
+                       if(!isAllowed(t)) {
+                               throw new AssertionError(t);
+                       }
+               }
+               long duration = System.nanoTime() - start;
+               executionTimes.add(duration);
+               int progress = 100*(counter++) / sequence.length;
+               if(progress > lastProgress) {
+                       System.err.println("[" + counter + "/" + sequence.length +  "]: " + progress + "%");
+                       lastProgress = progress;
+               }
+       }
+
+       for(Command command : afterSequence(environment)) {
+               command.run(environment);
+       }
+       
+               analyse(environment);
+       
+       }
+       
+       public void invoke(CommandSequenceEnvironment environment, Command command) {
+               try {
+                       command.run(environment);
+               } catch (Throwable t) {
+                       if(!isAllowed(t)) {
+                               throw new AssertionError(t);
+                       }
+               }
+       }
+       
+       boolean isAllowed(Throwable t) {
+               if(t instanceof AllowedThrowable) return true;
+               if(t instanceof DatabaseException) {
+                       DatabaseException d = (DatabaseException)t;
+                       if(d.getCause() instanceof AllowedThrowable) return true;
+               }
+               return false;
+       }
+       
+}