001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.db4ounit.common.acid;
022:
023: import java.io.*;
024:
025: import com.db4o.*;
026: import com.db4o.db4ounit.common.assorted.*;
027: import com.db4o.foundation.*;
028: import com.db4o.foundation.io.*;
029: import com.db4o.internal.*;
030: import com.db4o.io.*;
031: import com.db4o.query.*;
032:
033: import db4ounit.*;
034: import db4ounit.extensions.fixtures.*;
035:
036: public class CrashSimulatingTestCase implements TestCase, OptOutCS {
037:
038: public String _name;
039:
040: public CrashSimulatingTestCase _next;
041:
042: static final boolean LOG = false;
043:
044: public CrashSimulatingTestCase() {
045: }
046:
047: public CrashSimulatingTestCase(CrashSimulatingTestCase next_,
048: String name) {
049: _next = next_;
050: _name = name;
051: }
052:
053: private boolean hasLockFileThread() {
054: if (!Platform4.hasLockFileThread()) {
055: return false;
056: }
057: return !Platform4.hasNio();
058: }
059:
060: public void test() throws IOException {
061: if (hasLockFileThread()) {
062: System.out
063: .println("CrashSimulatingTestCase is ignored on platforms with lock file thread.");
064: return;
065: }
066:
067: String path = Path4.combine(Path4.getTempPath(),
068: "crashSimulate");
069: String fileName = Path4.combine(path, "cs");
070:
071: File4.delete(fileName);
072: File4.mkdirs(path);
073:
074: Db4o
075: .configure()
076: .reflectWith(
077: Platform4
078: .reflectorForType(CrashSimulatingTestCase.class));
079: Db4o.configure().bTreeNodeSize(4);
080:
081: createFile(fileName);
082:
083: CrashSimulatingIoAdapter adapterFactory = new CrashSimulatingIoAdapter(
084: new RandomAccessFileAdapter());
085: Db4o.configure().io(adapterFactory);
086:
087: ObjectContainer oc = Db4o.openFile(fileName);
088:
089: ObjectSet objectSet = oc.get(new CrashSimulatingTestCase(null,
090: "three"));
091: oc.delete(objectSet.next());
092:
093: oc.set(new CrashSimulatingTestCase(null, "four"));
094: oc.set(new CrashSimulatingTestCase(null, "five"));
095: oc.set(new CrashSimulatingTestCase(null, "six"));
096: oc.set(new CrashSimulatingTestCase(null, "seven"));
097: oc.set(new CrashSimulatingTestCase(null, "eight"));
098: oc.set(new CrashSimulatingTestCase(null, "nine"));
099: oc.set(new CrashSimulatingTestCase(null, "10"));
100: oc.set(new CrashSimulatingTestCase(null, "11"));
101: oc.set(new CrashSimulatingTestCase(null, "12"));
102: oc.set(new CrashSimulatingTestCase(null, "13"));
103: oc.set(new CrashSimulatingTestCase(null, "14"));
104:
105: oc.commit();
106:
107: Query q = oc.query();
108: q.constrain(CrashSimulatingTestCase.class);
109: objectSet = q.execute();
110: while (objectSet.hasNext()) {
111: CrashSimulatingTestCase cst = (CrashSimulatingTestCase) objectSet
112: .next();
113: if (!(cst._name.equals("10") || cst._name.equals("13"))) {
114: oc.delete(cst);
115: }
116: }
117:
118: oc.commit();
119:
120: oc.close();
121:
122: Db4o.configure().io(new RandomAccessFileAdapter());
123:
124: int count = adapterFactory.batch.writeVersions(fileName);
125:
126: checkFiles(fileName, "R", adapterFactory.batch.numSyncs());
127: checkFiles(fileName, "W", count);
128: if (LOG) {
129: System.out.println("Total versions: " + count);
130: }
131: }
132:
133: private void checkFiles(String fileName, String infix, int count) {
134: for (int i = 1; i <= count; i++) {
135: if (LOG) {
136: System.out.println("Checking " + infix + i);
137: }
138: String versionedFileName = fileName + infix + i;
139: ObjectContainer oc = Db4o.openFile(versionedFileName);
140: try {
141: if (!stateBeforeCommit(oc)) {
142: if (!stateAfterFirstCommit(oc)) {
143: Assert.isTrue(stateAfterSecondCommit(oc));
144: }
145: }
146: } finally {
147: oc.close();
148: }
149: }
150: }
151:
152: private boolean stateBeforeCommit(ObjectContainer oc) {
153: return expect(oc, new String[] { "one", "two", "three" });
154: }
155:
156: private boolean stateAfterFirstCommit(ObjectContainer oc) {
157: return expect(oc, new String[] { "one", "two", "four", "five",
158: "six", "seven", "eight", "nine", "10", "11", "12",
159: "13", "14" });
160: }
161:
162: private boolean stateAfterSecondCommit(ObjectContainer oc) {
163: return expect(oc, new String[] { "10", "13" });
164: }
165:
166: private boolean expect(ObjectContainer container, String[] names) {
167: Collection4 expected = new Collection4(names);
168: ObjectSet actual = container
169: .query(CrashSimulatingTestCase.class);
170: while (actual.hasNext()) {
171: CrashSimulatingTestCase current = (CrashSimulatingTestCase) actual
172: .next();
173: if (null == expected.remove(current._name)) {
174: return false;
175: }
176: }
177: return expected.isEmpty();
178: }
179:
180: private void createFile(String fileName) throws IOException {
181: ObjectContainer oc = Db4o.openFile(fileName);
182: try {
183: populate(oc);
184: } finally {
185: oc.close();
186: }
187: File4.copy(fileName, fileName + "0");
188: }
189:
190: private void populate(ObjectContainer container) {
191: for (int i = 0; i < 10; i++) {
192: container.set(new SimplestPossibleItem("delme"));
193: }
194: CrashSimulatingTestCase one = new CrashSimulatingTestCase(null,
195: "one");
196: CrashSimulatingTestCase two = new CrashSimulatingTestCase(one,
197: "two");
198: CrashSimulatingTestCase three = new CrashSimulatingTestCase(
199: one, "three");
200: container.set(one);
201: container.set(two);
202: container.set(three);
203: container.commit();
204: ObjectSet objectSet = container
205: .query(SimplestPossibleItem.class);
206: while (objectSet.hasNext()) {
207: container.delete(objectSet.next());
208: }
209: }
210:
211: public String toString() {
212: return _name + " -> " + _next;
213: }
214:
215: }
|