--- /dev/null
+/*******************************************************************************
+ * 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.tests.regression.bugs;
+
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.accessor.ArrayAccessor;
+import org.simantics.databoard.accessor.error.AccessorException;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.testing.base.ExistingDatabaseTest;
+import org.simantics.db.testing.impl.Configuration;
+import org.simantics.layer0.Layer0;
+
+public class Issue3176Test3 extends ExistingDatabaseTest {
+
+ @Test
+ public void testAccessor() {
+ try {
+ int nBlocks = Configuration.get().i3176BlockCount;
+ int[] blockSize = { 1024, 0xFFFF, 1<<20 };
+ final int LENGTH = blockSize.length - 2; // too slow
+ for (int i=0; i<LENGTH; ++i) {
+ testAccessor1(blockSize[i], nBlocks);
+ testAccessor2(blockSize[i], nBlocks);
+ testAccessor3(blockSize[i], nBlocks);
+ }
+ int nBlocksBig = Configuration.get().i3176BigBlockCount / 10; // too slow
+ nBlocksBig = Math.max(2, nBlocksBig);
+ testAccessor4(blockSize[blockSize.length - 2], nBlocksBig); // too slow
+ } catch (DatabaseException e) {
+ fail("Test failed with exception " + e);
+ }
+ }
+ public void testAccessor1(int blockSize, int nBlocks)
+ throws DatabaseException {
+ final AccessorTest test = new AccessorTest(getSession(), DEBUG, blockSize, nBlocks);
+ Resource r = test.createResource();
+ test.checkNoAccessor(r);
+ test.createAccessor(r);
+ test.checkLiteralValue(r);
+ test.validateAccessor(r, 0, -1);
+ test.modifyAccessor(r, 1, false);
+ test.validateAccessor(r, 1, -1);
+ test.undoModi(r, 1);
+ test.validateAccessor(r, 0, -1);
+ test.removeLiteralValue(r);
+ test.checkNoAccessor(r);
+ }
+ public void testAccessor2(int blockSize, int nBlocks)
+ throws DatabaseException {
+ final AccessorTest test = new AccessorTest(getSession(), DEBUG, blockSize, nBlocks);
+ Resource r = test.createResource();
+ test.checkNoAccessor(r);
+ test.createAccessor(r);
+ test.validateAccessor(r, 0, -1);
+ final int N=10;
+ for (int i=1; i<N+1; ++i) {
+ test.modifyAccessor(r, i, false);
+ test.validateAccessor(r, i, -1);
+ }
+ test.undoModi(r, N);
+ test.validateAccessor(r, 0, -1);
+ test.removeLiteralValue(r);
+ test.checkNoAccessor(r);
+ }
+ public void testAccessor3(int blockSize, int nBlocks)
+ throws DatabaseException {
+ final AccessorTest test = new AccessorTest(getSession(), DEBUG, blockSize, nBlocks);
+ Resource r = test.createResource();
+ test.checkNoAccessor(r);
+ test.createAccessor(r);
+ test.validateAccessor(r, 0, -1);
+ test.modifyAccessor(r, 1, false);
+ test.validateAccessor(r, 1, -1);
+ test.truncateAccessor(r, 1, 1);
+ test.validateAccessor(r, 1, 1);
+ }
+ public void testAccessor4(int blockSize, int nBlocks)
+ throws DatabaseException {
+ final AccessorTest test = new AccessorTest(getSession(), DEBUG, blockSize, nBlocks);
+ Resource r = test.createResource();
+ test.createAccessor(r);
+ test.validateAccessor(r, 0, -1);
+ test.modifyAccessor(r, 1, false);
+ test.validateAccessor(r, 1, -1);
+ }
+}
+class AccessorTest extends Issue3176Test {
+ AccessorTest(final Session session, boolean DEBUG, int blockSize, int nBlocks)
+ throws DatabaseException {
+ super(session, DEBUG, blockSize, nBlocks);
+ }
+ void createAccessor(final Resource resource)
+ throws DatabaseException {
+ session.syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.markUndoPoint();
+ Layer0 b = Layer0.getInstance(graph);
+ ArrayAccessor ra = graph.newLiteral(resource, b.Literal, Bindings.BYTE_ARRAY.type(), null);
+ for (int i=0; i<N_BLOCKS; ++i) {
+ try {
+ for (int j=0; j<BLOCK_SIZE; ++j) {
+ if (DEBUG && VERBOSE)
+ System.out.println("DEBUG: created value for index " + (i*BLOCK_SIZE+j) + "=" + (byte)j);
+ ra.add(i*BLOCK_SIZE+j, Bindings.BYTE, (byte)j);
+ }
+ } catch (AccessorException e) {
+ throw new DatabaseException("Failed to add block=" + i + ".");
+ }
+ }
+ }
+ });
+ }
+ void modifyAccessor(final Resource resource, final int inc, final boolean validate)
+ throws DatabaseException {
+ session.syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.markUndoPoint();
+ Layer0 l0 = Layer0.getInstance(graph);
+ Resource literal = graph.getSingleObject(resource, l0.Literal);
+ ArrayAccessor a = graph.getAccessor(literal);
+ for (int i=0; i<N_BLOCKS; ++i) {
+ for (int j=0; j<BLOCK_SIZE; ++j) {
+ try {
+ a.set(i*BLOCK_SIZE+j, Bindings.BYTE, (byte)(j+inc));
+ } catch (AccessorException e) {
+ throw new DatabaseException("Failed to add byte i=" + i + " j=" + j + ".");
+ }
+ }
+ }
+ if (!validate)
+ return;
+ try {
+ if (a.size() != N_BLOCKS * BLOCK_SIZE)
+ throw new DatabaseException("Failed to validate block size.");
+ for (int i=0; i<N_BLOCKS; ++i) {
+ for (int j=0; j<BLOCK_SIZE; ++j) {
+ byte b = (Byte)a.get(i*BLOCK_SIZE + j, Bindings.BYTE);
+ if (b != (byte)(j+inc))
+ throw new DatabaseException("Failed to validate modifications. i=" + i + " j)" + j);
+ }
+ }
+ } catch (AccessorException e) {
+ throw new DatabaseException("Failed to validate modifications.", e);
+ }
+ }
+ });
+ }
+ void truncateAccessor(final Resource resource, final int inc, final int newBlocks)
+ throws DatabaseException {
+ assertTrue(N_BLOCKS > newBlocks);
+ session.syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.markUndoPoint();
+ Layer0 l0 = Layer0.getInstance(graph);
+ Resource literal = graph.getSingleObject(resource, l0.Literal);
+ ArrayAccessor a = graph.getAccessor(literal);
+ for (int i=0; i<newBlocks; ++i) {
+ for (int j=0; j<BLOCK_SIZE; ++j) {
+ try {
+ a.set(i*BLOCK_SIZE+j, Bindings.BYTE, (byte)(j+inc));
+ } catch (AccessorException e) {
+ throw new DatabaseException("Failed to add byte i=" + i + " j=" + j + ".");
+ }
+ }
+ }
+ int index = newBlocks * BLOCK_SIZE;
+ int count = (N_BLOCKS - newBlocks) * BLOCK_SIZE;
+ try {
+ a.remove(index, count);
+ } catch (AccessorException e) {
+ throw new DatabaseException("Failed to truncate.", e);
+ }
+ }
+ });
+ }
+ void validateAccessor(final Resource resource, final int inc, final int nBlocks)
+ throws DatabaseException {
+ session.syncRequest(new ReadRequest() {
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ Layer0 l0 = Layer0.getInstance(graph);
+ Resource literal = graph.getSingleObject(resource, l0.Literal);
+ ArrayAccessor a = graph.getAccessor(literal);
+ final int T_BLOCKS = nBlocks < 0 ? N_BLOCKS : nBlocks;
+ try {
+ if (a.size() != T_BLOCKS * BLOCK_SIZE)
+ throw new DatabaseException("Failed to validate block size.");
+ for (int i=0; i<T_BLOCKS; ++i) {
+ for (int j=0; j<BLOCK_SIZE; ++j) {
+ byte b = (Byte)a.get(i*BLOCK_SIZE + j, Bindings.BYTE);
+ if (b != (byte)(j+inc))
+ throw new DatabaseException("Failed to validate modified file contents. i=" + i + " j=" + j);
+ }
+ }
+ } catch (AccessorException e) {
+ throw new DatabaseException(e);
+ }
+ }
+ });
+ }
+ void checkNoAccessor(final Resource resource)
+ throws DatabaseException {
+ session.syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.markUndoPoint();
+ Layer0 l0 = Layer0.getInstance(graph);
+ Resource literal = graph.getPossibleObject(resource, l0.Literal);
+ if (null == literal)
+ return;
+ if (!graph.hasValue(literal))
+ return;
+ try {
+ graph.getAccessor(literal);
+ } catch (DatabaseException e) {
+ return; // no accessor
+ }
+ throw new DatabaseException("Literal=" + literal + " has accessor.");
+ }
+ });
+ }
+}
\ No newline at end of file