001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.poifs.storage;
019:
020: import java.io.*;
021:
022: import java.util.*;
023:
024: import junit.framework.*;
025:
026: import org.apache.poi.util.LittleEndian;
027: import org.apache.poi.util.LittleEndianConsts;
028:
029: /**
030: * Class to test BlockListImpl functionality
031: *
032: * @author Marc Johnson
033: */
034:
035: public class TestBlockListImpl extends TestCase {
036:
037: /**
038: * Constructor TestBlockListImpl
039: *
040: * @param name
041: */
042:
043: public TestBlockListImpl(String name) {
044: super (name);
045: }
046:
047: /**
048: * test zap method
049: *
050: * @exception IOException
051: */
052:
053: public void testZap() throws IOException {
054: BlockListImpl list = new BlockListImpl();
055:
056: // verify that you can zap anything
057: for (int j = -2; j < 10; j++) {
058: list.zap(j);
059: }
060: RawDataBlock[] blocks = new RawDataBlock[5];
061:
062: for (int j = 0; j < 5; j++) {
063: blocks[j] = new RawDataBlock(new ByteArrayInputStream(
064: new byte[512]));
065: }
066: list.setBlocks(blocks);
067: for (int j = -2; j < 10; j++) {
068: list.zap(j);
069: }
070:
071: // verify that all blocks are gone
072: for (int j = 0; j < 5; j++) {
073: try {
074: list.remove(j);
075: fail("removing item " + j
076: + " should not have succeeded");
077: } catch (IOException ignored) {
078: }
079: }
080: }
081:
082: /**
083: * test remove method
084: *
085: * @exception IOException
086: */
087:
088: public void testRemove() throws IOException {
089: BlockListImpl list = new BlockListImpl();
090: RawDataBlock[] blocks = new RawDataBlock[5];
091: byte[] data = new byte[512 * 5];
092:
093: for (int j = 0; j < 5; j++) {
094: Arrays.fill(data, j * 512, (j * 512) + 512, (byte) j);
095: }
096: ByteArrayInputStream stream = new ByteArrayInputStream(data);
097:
098: for (int j = 0; j < 5; j++) {
099: blocks[j] = new RawDataBlock(stream);
100: }
101: list.setBlocks(blocks);
102:
103: // verify that you can't remove illegal indices
104: for (int j = -2; j < 10; j++) {
105: if ((j < 0) || (j >= 5)) {
106: try {
107: list.remove(j);
108: fail("removing item " + j + " should have failed");
109: } catch (IOException ignored) {
110: }
111: }
112: }
113:
114: // verify we can safely and correctly remove all blocks
115: for (int j = 0; j < 5; j++) {
116: byte[] output = list.remove(j).getData();
117:
118: for (int k = 0; k < 512; k++) {
119: assertEquals("testing block " + j + ", index " + k,
120: data[(j * 512) + k], output[k]);
121: }
122: }
123:
124: // verify that all blocks are gone
125: for (int j = 0; j < 5; j++) {
126: try {
127: list.remove(j);
128: fail("removing item " + j
129: + " should not have succeeded");
130: } catch (IOException ignored) {
131: }
132: }
133: }
134:
135: /**
136: * test setBAT
137: *
138: * @exception IOException
139: */
140:
141: public void testSetBAT() throws IOException {
142: BlockListImpl list = new BlockListImpl();
143:
144: list.setBAT(null);
145: list.setBAT(new BlockAllocationTableReader());
146: try {
147: list.setBAT(new BlockAllocationTableReader());
148: fail("second attempt should have failed");
149: } catch (IOException ignored) {
150: }
151: }
152:
153: /**
154: * Test fetchBlocks
155: *
156: * @exception IOException
157: */
158:
159: public void testFetchBlocks() throws IOException {
160:
161: // strategy:
162: //
163: // 1. set up a single BAT block from which to construct a
164: // BAT. create nonsense blocks in the raw data block list
165: // corresponding to the indices in the BAT block.
166: // 2. The indices will include very short documents (0 and 1
167: // block in length), longer documents, and some screwed up
168: // documents (one with a loop, one that will peek into
169: // another document's data, one that includes an unused
170: // document, one that includes a reserved (BAT) block, one
171: // that includes a reserved (XBAT) block, and one that
172: // points off into space somewhere
173: BlockListImpl list = new BlockListImpl();
174: List raw_blocks = new ArrayList();
175: byte[] data = new byte[512];
176: int offset = 0;
177:
178: LittleEndian.putInt(data, offset, -3); // for the BAT block itself
179: offset += LittleEndianConsts.INT_SIZE;
180:
181: // document 1: is at end of file already; start block = -2
182: // document 2: has only one block; start block = 1
183: LittleEndian.putInt(data, offset, -2);
184: offset += LittleEndianConsts.INT_SIZE;
185:
186: // document 3: has a loop in it; start block = 2
187: LittleEndian.putInt(data, offset, 2);
188: offset += LittleEndianConsts.INT_SIZE;
189:
190: // document 4: peeks into document 2's data; start block = 3
191: LittleEndian.putInt(data, offset, 4);
192: offset += LittleEndianConsts.INT_SIZE;
193: LittleEndian.putInt(data, offset, 1);
194: offset += LittleEndianConsts.INT_SIZE;
195:
196: // document 5: includes an unused block; start block = 5
197: LittleEndian.putInt(data, offset, 6);
198: offset += LittleEndianConsts.INT_SIZE;
199: LittleEndian.putInt(data, offset, -1);
200: offset += LittleEndianConsts.INT_SIZE;
201:
202: // document 6: includes a BAT block; start block = 7
203: LittleEndian.putInt(data, offset, 8);
204: offset += LittleEndianConsts.INT_SIZE;
205: LittleEndian.putInt(data, offset, 0);
206: offset += LittleEndianConsts.INT_SIZE;
207:
208: // document 7: includes an XBAT block; start block = 9
209: LittleEndian.putInt(data, offset, 10);
210: offset += LittleEndianConsts.INT_SIZE;
211: LittleEndian.putInt(data, offset, -4);
212: offset += LittleEndianConsts.INT_SIZE;
213:
214: // document 8: goes off into space; start block = 11;
215: LittleEndian.putInt(data, offset, 1000);
216: offset += LittleEndianConsts.INT_SIZE;
217:
218: // document 9: no screw ups; start block = 12;
219: int index = 13;
220:
221: for (; offset < 508; offset += LittleEndianConsts.INT_SIZE) {
222: LittleEndian.putInt(data, offset, index++);
223: }
224: LittleEndian.putInt(data, offset, -2);
225: raw_blocks
226: .add(new RawDataBlock(new ByteArrayInputStream(data)));
227: for (int j = raw_blocks.size(); j < 128; j++) {
228: raw_blocks.add(new RawDataBlock(new ByteArrayInputStream(
229: new byte[0])));
230: }
231: list.setBlocks((RawDataBlock[]) raw_blocks
232: .toArray(new RawDataBlock[0]));
233: int[] blocks = { 0 };
234: BlockAllocationTableReader table = new BlockAllocationTableReader(
235: 1, blocks, 0, -2, list);
236: int[] start_blocks = { -2, 1, 2, 3, 5, 7, 9, 11, 12 };
237: int[] expected_length = { 0, 1, -1, -1, -1, -1, -1, -1, 116 };
238:
239: for (int j = 0; j < start_blocks.length; j++) {
240: try {
241: ListManagedBlock[] dataBlocks = list
242: .fetchBlocks(start_blocks[j]);
243:
244: if (expected_length[j] == -1) {
245: fail("document " + j + " should have failed");
246: } else {
247: assertEquals(expected_length[j], dataBlocks.length);
248: }
249: } catch (IOException e) {
250: if (expected_length[j] == -1) {
251:
252: // no problem, we expected a failure here
253: } else {
254: throw e;
255: }
256: }
257: }
258: }
259:
260: /**
261: * main method to run the unit tests
262: *
263: * @param ignored_args
264: */
265:
266: public static void main(String[] ignored_args) {
267: System.out
268: .println("Testing org.apache.poi.poifs.storage.BlockListImpl");
269: junit.textui.TestRunner.run(TestBlockListImpl.class);
270: }
271: }
|