1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.tests.regression.bugs;
14 import static org.junit.Assert.assertTrue;
16 import java.io.IOException;
18 import org.junit.Test;
19 import org.simantics.databoard.Bindings;
20 import org.simantics.databoard.binding.error.BindingConstructionException;
21 import org.simantics.databoard.type.Datatype;
22 import org.simantics.databoard.util.binary.RandomAccessBinary;
23 import org.simantics.databoard.util.binary.RandomAccessBinary.ByteSide;
24 import org.simantics.db.ReadGraph;
25 import org.simantics.db.Resource;
26 import org.simantics.db.Session;
27 import org.simantics.db.WriteGraph;
28 import org.simantics.db.common.request.ReadRequest;
29 import org.simantics.db.common.request.WriteRequest;
30 import org.simantics.db.exception.DatabaseException;
31 import org.simantics.db.testing.base.ExistingDatabaseTest;
32 import org.simantics.db.testing.impl.Configuration;
33 import org.simantics.layer0.Layer0;
35 public class Issue3176Test2 extends ExistingDatabaseTest {
38 public void testRandom() {
40 int nBlocks = Configuration.get().i3176BlockCount;
41 int[] blockSize = { 1024, 0xFFFF, 1<<20 };
42 final int LENGTH = blockSize.length;
43 for (int i=0; i<LENGTH; ++i) {
44 testRandom1(blockSize[i], nBlocks);
45 testRandom2(blockSize[i], nBlocks);
46 testRandom3(blockSize[i], nBlocks);
48 int nBlocksBig = Configuration.get().i3176BigBlockCount;
49 testRandom4(blockSize[blockSize.length - 1], nBlocksBig);
50 } catch (DatabaseException e) {
51 fail("Test failed with exception " + e);
54 public void testRandom1(int blockSize, int nBlocks)
55 throws DatabaseException {
56 final RandomTest test = new RandomTest(getSession(), DEBUG, blockSize, nBlocks);
57 Resource r = test.createResource();
58 test.checkNoRandom(r);
59 test.createRandom(r, 0, -1);
60 test.checkLiteralValue(r);
61 test.validateRandom(r, 0, -1);
62 test.modifyRandom(r, 1, -1, false);
63 test.validateRandom(r, 1, -1);
65 test.validateRandom(r, 0, -1);
66 test.removeLiteralValue(r);
67 test.checkNoRandom(r);
69 public void testRandom2(int blockSize, int nBlocks)
70 throws DatabaseException {
71 final RandomTest test = new RandomTest(getSession(), DEBUG, blockSize, nBlocks);
72 Resource r = test.createResource();
73 test.checkNoRandom(r);
74 test.createRandom(r, 0, -1);
75 test.validateRandom(r, 0, -1);
76 for (int i=1; i<10; ++i) {
77 test.modifyRandom(r, i, -1, false);
78 test.validateRandom(r, i, -1);
81 test.validateRandom(r, 0, -1);
82 test.removeLiteralValue(r);
83 test.checkNoRandom(r);
85 public void testRandom3(int blockSize, int nBlocks)
86 throws DatabaseException {
87 final RandomTest test = new RandomTest(getSession(), DEBUG, blockSize, nBlocks);
88 Resource r = test.createResource();
89 test.checkNoRandom(r);
90 test.createRandom(r, 0, -1);
91 test.validateRandom(r, 0, -1);
92 test.truncateRandom(r, 1, 1);
93 test.validateRandom(r, 1, 1);
95 public void testRandom4(int blockSize, int nBlocks)
96 throws DatabaseException {
97 final RandomTest test = new RandomTest(getSession(), DEBUG, blockSize, nBlocks);
98 Resource r = test.createResource();
99 test.createRandom(r, 0, -1);
100 test.validateRandom(r, 0, -1);
101 test.modifyRandom(r, 1, -1, false);
102 test.validateRandom(r, 1, -1);
103 test.truncateRandom(r, 1, 1);
104 test.validateRandom(r, 1, 1);
108 class RandomTest extends Issue3176Test {
109 RandomTest(final Session session, boolean DEBUG, int blockSize, int nBlocks)
110 throws DatabaseException {
111 super(session, DEBUG, blockSize, nBlocks);
113 void createRandom(final Resource resource, final int inc, final int aBlocks)
114 throws DatabaseException {
115 session.syncRequest(new WriteRequest() {
117 public void perform(WriteGraph graph) throws DatabaseException {
118 graph.markUndoPoint();
119 Layer0 l0 = Layer0.getInstance(graph);
121 RandomAccessBinary rab;
123 dt = Bindings.getBinding(byte[].class).type();
124 rab = graph.createRandomAccessBinary(resource, l0.Literal, dt, null);
126 } catch (BindingConstructionException e) {
127 throw new DatabaseException("Failed to get datatype for byte array.", e);
128 } catch (IOException e) {
129 throw new DatabaseException("Failed to get new literal for random access binary.", e);
131 byte[] block = createBlock(BLOCK_SIZE, inc);
132 int T_BLOCKS = aBlocks < 0 ? N_BLOCKS : aBlocks;
133 for (int i=0; i<T_BLOCKS; ++i) {
136 } catch (IOException e) {
137 throw new DatabaseException("Failed to add block i=" + i + ".");
143 void modifyRandom(final Resource file, final int inc, final int aBlocks, final boolean validate)
144 throws DatabaseException {
145 session.syncRequest(new WriteRequest() {
147 public void perform(WriteGraph graph) throws DatabaseException {
148 graph.markUndoPoint();
149 Layer0 l0 = Layer0.getInstance(graph);
150 Resource literal = graph.getSingleObject(file, l0.Literal);
151 RandomAccessBinary rab = graph.getRandomAccessBinary(literal);
154 byte[] block = createBlock(BLOCK_SIZE, inc);
155 int T_BLOCKS = aBlocks < 0 ? N_BLOCKS : aBlocks;
156 for (int i=0; i<T_BLOCKS; ++i) {
159 } catch (IOException e) {
160 throw new DatabaseException("Failed to modify block i=" + i + ".");
165 if (rab.length() != (long)T_BLOCKS * BLOCK_SIZE)
166 new DatabaseException("Failed to validate block size.");
168 for (int i=0; i<T_BLOCKS; ++i) {
169 rab.readFully(block);
170 for (int j=0; j<BLOCK_SIZE; ++j) {
172 if (DEBUG && VERBOSE)
173 System.out.println("DEBUG: Read pos=" + (i*BLOCK_SIZE+j) + " val=" + b);
174 if (b != (byte)(j+inc))
175 throw new DatabaseException("Failed to validate modified file contents.");
178 } catch (IOException e) {
179 throw new DatabaseException("Failed to access random binary.", e);
184 void truncateRandom(final Resource file, final int inc, final int newBlocks)
185 throws DatabaseException {
186 assertTrue(N_BLOCKS > newBlocks);
187 session.syncRequest(new WriteRequest() {
189 public void perform(WriteGraph graph) throws DatabaseException {
190 graph.markUndoPoint();
191 Layer0 l0 = Layer0.getInstance(graph);
192 Resource literal = graph.getSingleObject(file, l0.Literal);
193 RandomAccessBinary rab = graph.getRandomAccessBinary(literal);
196 final int T_BLOCKS = newBlocks < 0 ? N_BLOCKS : newBlocks;
197 byte[] block = createBlock(BLOCK_SIZE, inc);
198 for (int i=0; i<T_BLOCKS; ++i) {
201 } catch (IOException e) {
202 throw new DatabaseException("Failed to modify block i=" + i + ".");
205 long bytes = (long)(N_BLOCKS - newBlocks) * BLOCK_SIZE;
206 rab.removeBytes(bytes, ByteSide.Right);
207 } catch (IOException e) {
208 throw new DatabaseException("Failed to access random binary.", e);
213 void validateRandom(final Resource resource, final int inc, final int newBlocks)
214 throws DatabaseException {
215 session.syncRequest(new ReadRequest() {
217 public void run(ReadGraph graph) throws DatabaseException {
218 Layer0 l0 = Layer0.getInstance(graph);
219 Resource literal = graph.getSingleObject(resource, l0.Literal);
220 RandomAccessBinary rab = graph.getRandomAccessBinary(literal);
221 final long T_BLOCKS = newBlocks < 0 ? N_BLOCKS : newBlocks;
223 if (rab.length() != (long)T_BLOCKS * BLOCK_SIZE)
224 new DatabaseException("Failed to validate block size.");
226 byte[] block = new byte[BLOCK_SIZE];
227 for (int i=0; i<T_BLOCKS; ++i) {
228 rab.readFully(block);
229 for (int j=0; j<BLOCK_SIZE; ++j) {
231 if (DEBUG && VERBOSE)
232 System.out.println("DEBUG: Read pos=" + (i*BLOCK_SIZE+j) + " val=" + b);
233 if (b != (byte)(j+inc))
234 throw new DatabaseException("Failed to validate modified file contents.");
237 } catch (IOException e) {
238 throw new DatabaseException(e);
243 void checkNoRandom(final Resource resource)
244 throws DatabaseException {
245 session.syncRequest(new WriteRequest() {
247 public void perform(WriteGraph graph) throws DatabaseException {
248 graph.markUndoPoint();
249 Layer0 l0 = Layer0.getInstance(graph);
250 Resource literal = graph.getPossibleObject(resource, l0.Literal);
252 return; // No literal.
253 if (!graph.hasValue(literal))
256 graph.getRandomAccessBinary(literal);
257 } catch (DatabaseException e) {
258 return; // No random access binary.
260 throw new DatabaseException("Failed to remove literal value.");