--- /dev/null
+package org.simantics.db.tests.regression.bugs;
+
+import org.junit.Test;
+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.WriteOnlyResultRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.AssumptionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.InvalidResourceReferenceException;
+import org.simantics.db.impl.query.QuerySupport;
+import org.simantics.db.service.SerialisationSupport;
+import org.simantics.db.service.XSupport;
+import org.simantics.db.testing.cases.FreshDatabaseTest;
+
+public class Issue3108Test1 extends FreshDatabaseTest {
+ private static final boolean DEBUG = false;
+ static class TestGetResourceId extends WriteRequest {
+ final int key;
+ public TestGetResourceId(int clusterIndex, int resourceIndex) {
+ this.key = (clusterIndex << 16) + resourceIndex;
+ }
+ @SuppressWarnings("deprecation") // Using createRandomAccessId to simulate error while loading non existing cluster.
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ SerialisationSupport ss = graph.getService(SerialisationSupport.class);
+ QuerySupport gs = graph.getService(QuerySupport.class);
+ Resource r = gs.getResource(key);
+ try {
+// This used to throw RuntimeDatabaseException when loading illegal cluster failed
+// but now the implementation has changed and this does not try to load cluster.
+// long id = r.getResourceId();
+// if (0 == id)
+// throw new AssumptionException("Illegal resource returned zero as expected.");
+ if (DEBUG)
+ System.out.println("DEBBUG: resource key=" + key + " r="+ r);
+ ss.getResourceSerializer().createRandomAccessId(r);
+ } catch (InvalidResourceReferenceException e) {
+ if (DEBUG)
+ System.out.println("Catched InvalidResourceReferenceException:" + e.getMessage());
+ throw new AssumptionException("Illegal resource threw runtime error.", e);
+ }
+ }
+ }
+ @Test
+ public void testIssue3108Test1() throws Exception {
+ final Session session = getSession();
+ // This simulates the situation in Apros bug 4210.
+ // We have an illegal entry in cluster table and we want to handle it
+ // gracefully.
+ boolean exceptionThrown = false;
+ try {
+ XSupport xs = (XSupport)session.getService(XSupport.class);
+ long illegalClusterId1 = 666666;
+ int clusterIndex = xs.corruptClusterTable(illegalClusterId1);
+ session.syncRequest(new TestGetResourceId(clusterIndex, 666));
+ } catch (Exception e) {
+ exceptionThrown = true;
+ if (DEBUG)
+ System.out.println("Catched Exception as excepected:" + e.getMessage());
+ } catch (Throwable e) {
+ fail("Write transaction threw an unknown exception " + e);
+ }
+ assertTrue("Failed to throw exception as expected.", exceptionThrown);
+ // Here we have an illegal resource id without proxy in cluster table.
+ exceptionThrown = false;
+ try {
+ session.syncRequest(new TestGetResourceId(666, 666));
+ } catch (AssumptionException e) {
+ exceptionThrown = true;
+ if (DEBUG)
+ System.out.println("Catched AssumptionException as excepected:" + e.getMessage());
+ } catch (Throwable e) {
+ fail("Write transaction threw an unknown exception " + e);
+ }
+ assertTrue("Failed to throw exception as expected.", exceptionThrown);
+ // Here we have an illegal resource index with valid cluster proxy.
+ // Note that in this case the invalid resource index is not reported.
+ try {
+ session.syncRequest(new TestGetResourceId(1, 6666));
+ } catch (Throwable e) {
+ fail("Write transaction threw an unknown exception " + e);
+ }
+ }
+ static class TestWriteOnly extends WriteOnlyResultRequest<Long> {
+ public long id = 0;
+ public int key = 0;
+ @Override
+ public Long perform(WriteOnlyGraph graph) throws DatabaseException {
+ graph.flushCluster();
+ XSupport xs = (XSupport)graph.getService(XSupport.class);
+ xs.setClusterStreamOff(true);
+ Resource r = graph.newResource();
+ id = r.getResourceId();
+ SerialisationSupport ss = graph.getService(SerialisationSupport.class);
+ key = ss.getTransientId(id);
+ xs.setClusterStreamOff(false);
+ return id;
+ }
+ }
+}