package org.simantics.db.testing.common; /******************************************************************************* * 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 *******************************************************************************/ import java.security.Permission; import java.util.ArrayList; import java.util.UUID; import org.eclipse.core.runtime.Platform; import org.junit.After; import org.junit.Before; import org.simantics.SimanticsPlatform; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteGraph; import org.simantics.db.WriteOnlyGraph; import org.simantics.db.common.request.WriteOnlyRequest; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ServiceNotFoundException; import org.simantics.db.management.SessionContext; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.db.request.AsyncRead; import org.simantics.db.request.Read; import org.simantics.db.service.LifecycleSupport; import org.simantics.db.testing.impl.Configuration; import org.simantics.layer0.Layer0; import org.simantics.utils.FileUtils; /** * Base class for Simantics Test Cases. Assumes that ProCore is already running. * * @author Marko Luukkainen * */ abstract public class TestBase /*extends TestCase*/ { public static final boolean DEBUG = Configuration.get().debug; public static final String ROOT_LIBRARY_URI = "http:/"; private NoExitSecurityManager noExitSecurityManager; private SecurityManager securityManager; protected DatabaseState state; public Throwable exception2; protected Layer0 L0; static boolean printStart = true; public static final ArrayList initialWorkspaceFiles = FileUtils.createFileFilter(Platform.getLocation().toFile(), null); public static void printStart(Object t) { if(printStart) System.out.println("Test is " + t.getClass().getName() /*+ "." + t.getName()*/); } protected static void setPrintStart(boolean value) { printStart = value; } public Resource getProjectResource() { return SimanticsPlatform.INSTANCE.projectResource; } @Before public void setUp() throws Exception { printStart(this); securityManager = System.getSecurityManager(); noExitSecurityManager = new NoExitSecurityManager(state.getSession()); System.setSecurityManager(noExitSecurityManager); Session session = state.getSession(); L0 = Layer0.getInstance(session); } @After public void tearDown() throws Exception { if (noExitSecurityManager != null) { System.setSecurityManager(securityManager); noExitSecurityManager.dispose(); noExitSecurityManager = null; } L0 = null; state = null; exception2 = null; securityManager = null; commonTearDown(); } public static void commonTearDown() { Runtime rt = Runtime.getRuntime(); rt.gc(); rt.gc(); rt.gc(); if (DEBUG) { System.out.println("Max=" + rt.maxMemory() + " tot=" + rt.totalMemory() + " fre=" + rt.freeMemory()); } } public static String getRandomString() { return UUID.randomUUID().toString(); } protected Session getSession() throws DatabaseException { return state.getSession(); } protected SessionContext getSessionContext() { return state.getSessionContext(); } // protected Resource getRootLibrary() throws DatabaseException { // return getRootLibrary(getSession()); // } // // protected Resource getRootLibrary(Session session) throws DatabaseException { // return session.syncRequest(new ReadQuery() { // @Override // public void run(ReadGraph g) throws DatabaseException { // result = g.getResource(ROOT_LIBRARY_URI); // assertTrue(result.getResourceId() != SessionManagerSource.NullSubjectId); // } // }); // } protected abstract class ReadQuery implements Read { protected Result result = null; public abstract void run(ReadGraph graph) throws Throwable; @Override public Result perform(ReadGraph graph) { try { run(graph); return result; } catch(Throwable t) { if (DEBUG) { new Exception().printStackTrace(); t.printStackTrace(); } if (null == exception2) exception2 = t; return null; } } } protected abstract class AsyncReadQuery implements AsyncRead { protected Result result = null; public abstract void run(AsyncReadGraph graph) throws Throwable; @Override public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { try { run(graph); } catch(Throwable t) { if (DEBUG) { new Exception().printStackTrace(); t.printStackTrace(); } if (null == exception2) exception2 = t; } } } protected abstract class TestReadRequest extends ReadQuery { } protected abstract class TestAsyncReadRequest extends AsyncReadQuery { @Override public int getFlags() { // TODO Auto-generated method stub return 0; } @Override public int threadHash() { // TODO Auto-generated method stub return 0; } } protected abstract class WriteOnlyQuery extends WriteOnlyRequest { public abstract void run(WriteOnlyGraph g) throws Throwable; /** * Since some SimpleGraphRequest can only handle Exceptions, we need to wrap other Throwables inside Exceptions */ @Override public final void perform(WriteOnlyGraph g) { try { run(g); } catch(Throwable t) { new Exception().printStackTrace(); t.printStackTrace(); if (null == exception2) exception2 = t; throw new RuntimeException("Wrapping thrown non exception to exception.", t); } } public void run(WriteGraph g) throws Throwable { run((WriteOnlyGraph)g); } } protected void checkException() throws DatabaseException { if (exception2 != null) if (exception2 instanceof DatabaseException) throw (DatabaseException)exception2; else throw new DatabaseException(exception2); } protected boolean hasException() { return null != exception2; } protected Throwable getException() { return exception2; } protected static class ExitException extends SecurityException { private static final long serialVersionUID = -1982617086752946683L; public final int status; public ExitException(int status) { super("There is no escape!"); this.status = status; } } private static class NoExitSecurityManager extends SecurityManager { Session session; // Thread thread; NoExitSecurityManager(Session session) { this.session = session; // this.thread = Thread.currentThread(); } public void dispose() { session = null; } @Override public void checkPermission(Permission perm) { // allow anything. } @Override public void checkPermission(Permission perm, Object context) { // allow anything. } @Override public void checkExit(int status) { super.checkExit(status); if(session != null) { try { session.getService(LifecycleSupport.class).close(0, true); } catch (ServiceNotFoundException e) { Logger.defaultLogError(e); } catch (DatabaseException e) { Logger.defaultLogError(e); } } // if (!Thread.currentThread().equals(thread)) { // ThreadUtil.interruptThreadGroup("Query Thread Group"); // ThreadUtil.interruptThreadGroup("Session Thread Group"); // ThreadUtil.interruptThreadGroup("Connection Thread Group"); // thread.interrupt(); // throw new ExitException(status); // } } } protected String getName() { return getClass().getSimpleName(); } protected static void fail() { throw new AssertionError(); } protected void fail(String cause) { throw new AssertionError(cause); } protected void fail(String cause, Object a) { if (a instanceof Throwable) { Throwable t = (Throwable)a; Throwable c = t.getCause(); if (null != c) throw new AssertionError(new Error(t.getMessage(), c)); } throw new AssertionError(cause + " " + a); } protected void assertEquals(Object a, Object b) { if(!a.equals(b)) throw new AssertionError(); } protected void assertEquals(int a, int b) { if(a != b) throw new AssertionError(); } protected void assertEquals(double a, double b, double tolerance) { if(Math.abs(a - b) > tolerance) throw new AssertionError(); } protected void assertLess(double a, double b) { if(a >= b) throw new AssertionError(a + " is not less than " + b); } protected void assertLess(double a, double b, String info) { if(a >= b) { System.err.println("assertion info:\n" + info + "\n"); throw new AssertionError(a + " is not less than " + b); } } protected void assertEquals(String a, String b) { if(!a.equals(b)) throw new AssertionError(); } protected void assertEquals(String message, int a, int b) { if(a != b) throw new AssertionError(message); } protected void assertEquals(String message, boolean a, boolean b) { if(a != b) throw new AssertionError(message); } protected void assertNotNull(Object a) { if(a == null) throw new AssertionError(); } protected void assertNotNull(String message, Object a) { if(a == null) throw new AssertionError(message); } protected void assertTrue(String message, boolean a) { if(!a) throw new AssertionError(message); } protected void assertTrue(boolean a) { if(!a) throw new AssertionError(); } protected void assertFalse(boolean a) { if(a) throw new AssertionError(); } protected void assertFalse(String message, boolean a) { if(a) throw new AssertionError(message); } }