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.util.Arrays;
18 import org.junit.Test;
19 import org.simantics.databoard.Bindings;
20 import org.simantics.db.ExternalValueSupport;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.Session;
24 import org.simantics.db.WriteGraph;
25 import org.simantics.db.common.request.ReadRequest;
26 import org.simantics.db.common.request.WriteRequest;
27 import org.simantics.db.common.request.WriteResultRequest;
28 import org.simantics.db.exception.DatabaseException;
29 import org.simantics.db.exception.ExternalValueException;
30 import org.simantics.db.service.UndoRedoSupport;
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 Issue3176Test1 extends ExistingDatabaseTest {
36 static final boolean DEBUG = false;
39 throws DatabaseException {
41 int nBlocks = Configuration.get().i3176BlockCount;
42 int[] blockSize = { 1024, 0xFFFF, 1<<20 };
43 final int LENGTH = blockSize.length;
44 for (int i=0; i<LENGTH; ++i) {
45 testRaw1(blockSize[i], nBlocks);
46 testRaw2(blockSize[i], nBlocks);
47 testRaw3(blockSize[i], nBlocks);
49 int nBlocksBig = Configuration.get().i3176BigBlockCount;
50 testRaw4(blockSize[blockSize.length - 1], nBlocksBig);
51 } catch (DatabaseException e) {
52 fail("Test failed with exception.", e);
55 public void testRaw1(int blockSize, int nBlocks)
56 throws DatabaseException {
57 RawTest test = new RawTest(getSession(), DEBUG, blockSize, nBlocks);
58 Resource r = test.createResource();
60 test.createRaw(r, 0, -1);
61 test.checkLiteralValue(r);
62 test.validateRaw(r, 0, -1);
64 test.validateRaw(r, 1, -1);
66 test.validateRaw(r, 0, -1);
70 public void testRaw2(int blockSize, int nBlocks)
71 throws DatabaseException {
72 final RawTest test = new RawTest(getSession(), DEBUG, blockSize, nBlocks);
73 Resource r = test.createResource();
74 test.createRaw(r, 0, -1);
75 test.validateRaw(r, 0, -1);
76 for (int i=1; i<10; ++i) {
78 test.validateRaw(r, i, -1);
81 test.validateRaw(r, 0, -1);
85 public void testRaw3(int blockSize, int nBlocks)
86 throws DatabaseException {
87 final RawTest test = new RawTest(getSession(), DEBUG, blockSize, nBlocks);
88 Resource r = test.createResource();
89 test.createRaw(r, 0, -1);
90 test.validateRaw(r, 0, -1);
91 test.truncateRaw(r, 1);
92 test.validateRaw(r, 0, 1);
94 public void testRaw4(int blockSize, int nBlocks)
95 throws DatabaseException {
96 final RawTest test = new RawTest(getSession(), DEBUG, blockSize, nBlocks);
97 Resource r = test.createResource();
98 test.createRaw(r, 0, -1);
99 test.validateRaw(r, 0, -1);
100 test.modifyRaw(r, 1);
101 test.validateRaw(r, 1, -1);
102 test.truncateRaw(r, 1);
103 test.validateRaw(r, 1, 1);
106 class Issue3176Test {
107 protected final boolean VERBOSE;
108 protected final long LIMIT = 10 * 1000 * 1000;
109 protected final Session session;
110 protected final boolean DEBUG;
111 protected final int BLOCK_SIZE;
112 protected final int N_BLOCKS;
113 Issue3176Test(final Session session, boolean DEBUG, int blockSize, int nBlocks)
114 throws DatabaseException {
116 this.BLOCK_SIZE = blockSize;
117 this.N_BLOCKS = nBlocks;
119 this.session = session;
121 protected Resource createResource()
122 throws DatabaseException {
123 return session.syncRequest(new WriteResultRequest<Resource>() {
125 public Resource perform(WriteGraph g) throws DatabaseException {
127 Layer0 b = Layer0.getInstance(g);
128 Resource resource = g.newResource();
129 g.claim(resource, b.InstanceOf, b.Entity);
134 protected void checkLiteralValue(final Resource resource)
135 throws DatabaseException {
136 session.syncRequest(new ReadRequest() {
138 public void run(ReadGraph graph) throws DatabaseException {
139 Layer0 l0 = Layer0.getInstance(graph);
140 Resource literal = graph.getSingleObject(resource, l0.Literal);
141 // Note that graph.hasValue actually fetches the value from server.
142 // This is highly inefficient and thus do not use this kind of code!
143 if (!graph.hasValue(literal))
144 throw new DatabaseException("Graph resource " + resource + " has no value.");
148 protected void undoModi(final Resource resource, int n)
149 throws DatabaseException {
150 final UndoRedoSupport support = session.getService(UndoRedoSupport.class);
151 support.undo(session, n);
153 protected byte[] createBlock(int size, int inc) {
154 final byte block[] = new byte[size];
155 for (int i = 0; i < block.length; ++i)
156 block[i] = (byte)(i+inc);
159 protected void removeLiteralValue(final Resource resource)
160 throws DatabaseException {
161 session.syncRequest(new WriteRequest() {
163 public void perform(WriteGraph graph) throws DatabaseException {
164 graph.markUndoPoint();
165 Layer0 l0 = Layer0.getInstance(graph);
166 Resource literal = graph.getSingleObject(resource, l0.Literal);
167 graph.denyValue(literal);
172 class RawTest extends Issue3176Test {
173 private final ExternalValueSupport rds;
174 RawTest(final Session session, boolean DEBUG, int blockSize, int nBlocks)
175 throws DatabaseException {
176 super(session, DEBUG, blockSize, nBlocks);
177 this.rds = session.getService(ExternalValueSupport.class);
179 void createRaw(final Resource resource, final int inc, int aBlocks)
180 throws DatabaseException {
183 final int T_BLOCKS = aBlocks;
184 session.syncRequest(new WriteRequest() {
186 public void perform(WriteGraph graph) throws DatabaseException {
187 graph.markUndoPoint();
188 Layer0 b = Layer0.getInstance(graph);
189 graph.claimLiteral(resource, b.Literal, new byte[0], Bindings.BYTE_ARRAY);
190 Resource literal = graph.getSingleObject(resource, b.Literal);
192 for (int i=0, j=inc; i<T_BLOCKS; ++i, ++j) {
193 byte[] block = createBlock(BLOCK_SIZE, j);
196 System.out.println("Processing block=" + i);
197 long offset = (long)i * block.length;
198 rds.writeValue(graph, literal, offset, block.length, block);
199 count += block.length;
202 rds.wait4RequestsLess(1);
204 } catch (DatabaseException e) {
205 throw new DatabaseException("Failed to add block=" + i);
211 void modifyRaw(final Resource resource, final int inc)
212 throws DatabaseException {
213 session.syncRequest(new WriteRequest() {
215 public void perform(WriteGraph graph) throws DatabaseException {
216 graph.markUndoPoint();
217 Layer0 l0 = Layer0.getInstance(graph);
218 Resource literal = graph.getSingleObject(resource, l0.Literal);
220 for (int i=0, j=inc; i<N_BLOCKS; ++i, ++j) {
221 byte[] blockOut = createBlock(BLOCK_SIZE, j);
224 System.out.println("Processing block=" + i);
225 long offset = (long)i * blockOut.length;
226 rds.writeValue(graph, literal, offset, blockOut.length, blockOut);
227 count += blockOut.length;
230 rds.wait4RequestsLess(1);
233 } catch (DatabaseException e) {
234 throw new DatabaseException("Failed to add block=" + i);
240 void truncateRaw(final Resource resource, final int nBlocks)
241 throws DatabaseException {
242 session.syncRequest(new WriteRequest() {
244 public void perform(WriteGraph graph) throws DatabaseException {
245 graph.markUndoPoint();
246 Layer0 l0 = Layer0.getInstance(graph);
247 Resource literal = graph.getSingleObject(resource, l0.Literal);
248 long len = (long)BLOCK_SIZE * nBlocks;
249 rds.writeValue(graph, literal, len, 0, new byte[0]);
253 void removeRaw(final Resource resource)
254 throws DatabaseException {
255 session.syncRequest(new WriteRequest() {
257 public void perform(WriteGraph graph) throws DatabaseException {
258 graph.markUndoPoint();
259 Layer0 l0 = Layer0.getInstance(graph);
260 Resource literal = graph.getSingleObject(resource, l0.Literal);
261 rds.removeValue(graph, literal);
263 rds.getValueSize(graph, literal);
264 } catch (ExternalValueException e) {
265 return; // Assuming this is because there is no value.
267 throw new DatabaseException("Failed to delete value. Resource=" + literal);
271 void checkNoRaw(final Resource resource)
272 throws DatabaseException {
273 session.syncRequest(new WriteRequest() {
275 public void perform(WriteGraph graph) throws DatabaseException {
276 graph.markUndoPoint();
277 Layer0 l0 = Layer0.getInstance(graph);
278 Resource literal = graph.getPossibleObject(resource, l0.Literal);
282 rds.getValueSize(graph, literal);
283 } catch (DatabaseException e) {
284 return; // Assuming this is because there is no value.
286 throw new DatabaseException("Resource=" + literal + " has raw value.");
290 void validateRaw(final Resource resource, final int inc, int aBlocks)
291 throws DatabaseException {
292 final int T_BLOCKS = aBlocks < 0 ? N_BLOCKS : aBlocks;
293 session.syncRequest(new ReadRequest() {
295 public void run(ReadGraph graph) throws DatabaseException {
296 Layer0 l0 = Layer0.getInstance(graph);
297 Resource literal = graph.getSingleObject(resource, l0.Literal);
299 for (int i=0, j=inc; i<T_BLOCKS; ++i, ++j) {
300 byte[] blockOut = createBlock(BLOCK_SIZE, j);
301 long offset = (long)i * blockOut.length;
302 byte[] blockIn = rds.readValue(graph, literal, offset, blockOut.length);
303 assertTrue(blockIn.length == blockOut.length);
304 assertTrue("Failed with block=" + i, Arrays.equals(blockOut, blockIn));
306 count += blockIn.length;
310 System.out.println("Read block=" + i);
314 assertTrue(rds.getValueSize(graph, literal) == (long)T_BLOCKS * BLOCK_SIZE);