1d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// Copyright 2016 Google Inc. All rights reserved.
2d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden//
3d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// Licensed under the Apache License, Version 2.0 (the "License");
4d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// you may not use this file except in compliance with the License.
5d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// You may obtain a copy of the License at
6d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden//
7d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden//     http://www.apache.org/licenses/LICENSE-2.0
8d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden//
9d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// Unless required by applicable law or agreed to in writing, software
10d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// distributed under the License is distributed on an "AS IS" BASIS,
11d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// See the License for the specific language governing permissions and
13d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden// limitations under the License.
14d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
15d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenpackage com.google.archivepatcher.shared;
16d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
17d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport org.junit.After;
18d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport org.junit.Assert;
19d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport org.junit.Before;
20d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport org.junit.Test;
21d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport org.junit.runner.RunWith;
22d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport org.junit.runners.JUnit4;
23d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
24d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport java.io.ByteArrayOutputStream;
25d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport java.io.File;
26d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport java.io.FileOutputStream;
27d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport java.io.IOException;
28d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenimport java.io.RandomAccessFile;
29d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
30d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden/**
31d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden * Tests for {@link RandomAccessFileInputStream}.
32d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden */
33d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden@RunWith(JUnit4.class)
34d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden@SuppressWarnings("javadoc")
35d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Haydenpublic class RandomAccessFileInputStreamTest {
36d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  /**
37d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden   * The object under test.
38d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden   */
39d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  private RandomAccessFileInputStream stream = null;
40d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
41d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  /**
42d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden   * Test data written to the file.
43d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden   */
44d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  private byte[] testData = null;
45d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
46d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  /**
47d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden   * The temp file.
48d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden   */
49d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  private File tempFile = null;
50d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
51d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Before
52d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void setup() throws IOException {
53d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    testData = new byte[128];
54d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    for (int x = 0; x < 128; x++) {
55d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      testData[x] = (byte) x;
56d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
57d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    tempFile = File.createTempFile("ra-fist", "tmp");
58d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    tempFile.deleteOnExit();
59d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    try {
60d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      FileOutputStream out = new FileOutputStream(tempFile);
61d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      out.write(testData);
62d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      out.flush();
63d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      out.close();
64d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    } catch (IOException e) {
65d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      try {
66d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        tempFile.delete();
67d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      } catch (Exception ignoreD) {
68d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        // Nothing
69d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      }
70d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      throw new RuntimeException(e);
71d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
72d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream = new RandomAccessFileInputStream(tempFile);
73d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
74d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
75d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @After
76d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void tearDown() {
77d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    try {
78d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      stream.close();
79d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    } catch (Exception ignored) {
80d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      // Nothing to do
81d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
82d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    try {
83d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      tempFile.delete();
84d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    } catch (Exception ignored) {
85d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      // Nothing to do
86d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
87d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
88d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
89d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
90d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testRead_OneByte() throws IOException {
91d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    for (int x = 0; x < testData.length; x++) {
92d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      Assert.assertEquals(x, stream.read());
93d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
94d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(-1, stream.read());
95d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
96d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
97d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
98d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testRead_WithBuffer() throws IOException {
99d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    int bytesLeft = testData.length;
100d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    ByteArrayOutputStream out = new ByteArrayOutputStream();
101d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    byte[] buffer = new byte[10];
102d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    while (bytesLeft > 0) {
103d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      int numRead = stream.read(buffer);
104d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      if (numRead > 0) {
105d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        bytesLeft -= numRead;
106d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        out.write(buffer, 0, numRead);
107d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      }
108d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
109d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(-1, stream.read(buffer, 0, 1));
110d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertArrayEquals(testData, out.toByteArray());
111d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
112d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
113d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
114d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testRead_WithBuffer_NegativeLength() throws IOException {
115d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(0, stream.read(new byte[] {}, 0, -1));
116d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
117d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
118d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
119d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testRead_WithPartialBuffer() throws IOException {
120d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    int bytesLeft = testData.length;
121d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    ByteArrayOutputStream out = new ByteArrayOutputStream();
122d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    byte[] buffer = new byte[10];
123d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    while (bytesLeft > 0) {
124d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      int numRead = stream.read(buffer, 0, 2); // At most 2 bytes of the buffer can be used
125d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      if (numRead > 0) {
126d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        bytesLeft -= numRead;
127d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        out.write(buffer, 0, numRead);
128d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      }
129d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
130d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(-1, stream.read());
131d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertArrayEquals(testData, out.toByteArray());
132d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
133d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
134d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
135d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testMarkSupported() {
136d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertTrue(stream.markSupported());
137d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
138d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
139d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
140d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testMarkAndReset_WithOffsetFile() throws IOException {
141d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // Reset the stream, this time one byte in to exercise non-zero offset values
142d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.close();
143d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream = new RandomAccessFileInputStream(tempFile, 1, testData.length - 2);
144d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // Set a mark after the first byte, which should be 1. Read a second byte, which should be 2.
145d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(1, stream.read());
146d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.mark(1337 /* any value here, it is ignored */);
147d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(2, stream.read());
148d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // Reset the stream, it should be back to 1 now.
149d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.reset();
150d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(2, stream.read());
151d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
152d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
153d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
154d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testSkip() throws IOException {
155d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // Skip values <= 0 should always produce 0 and not actually skip anything.
156d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(0, stream.skip(-1));
157d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(0, stream.skip(0));
158d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // Skip the first 5 bytes and read the 6th, which should have the value 5.
159d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(5, stream.skip(5));
160d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(5, stream.read());
161d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // 6 bytes have been read, so the max skip is testDataLength - 6. Ensure this is true.
162d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(testData.length - 5 - 1, stream.skip(testData.length));
163d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // At the end of the file, skip should always return 0.
164d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(0, stream.skip(17));
165d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
166d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
167d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
168d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testAvailable() throws IOException {
169d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // Available always knows the answer precisely unless the file length exceeds Integer.MAX_VALUE
170d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(testData.length, stream.available());
171d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.read(new byte[17]);
172d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(testData.length - 17, stream.available());
173d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.read(new byte[testData.length]);
174d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(0, stream.available());
175d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.read();
176d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(0, stream.available());
177d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
178d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
179d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
180d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testSetRange() throws IOException {
181d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    // Mess with the stream range multiple times
182d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.setRange(1, 3);
183d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(1, stream.read());
184d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(2, stream.read());
185d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(3, stream.read());
186d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(-1, stream.read());
187d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.setRange(99, 2);
188d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(99, stream.read());
189d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(100, stream.read());
190d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(-1, stream.read());
191d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
192d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
193d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test(expected = IllegalArgumentException.class)
194d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testSetRange_TooLong() throws IOException {
195d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.setRange(0, testData.length + 1);
196d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
197d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
198d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test(expected = IllegalArgumentException.class)
199d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testSetRange_NegativeOffset() throws IOException {
200d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.setRange(-1, testData.length);
201d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
202d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
203d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test(expected = IllegalArgumentException.class)
204d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testSetRange_NegativeLength() throws IOException {
205d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.setRange(0, -1);
206d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
207d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
208d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test(expected = IllegalArgumentException.class)
209d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testSetRange_LongOverflow() throws IOException {
210d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.setRange(Long.MAX_VALUE, 1); // Oh dear.
211d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
212d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
213d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test(expected = IOException.class)
214d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testReset_NoMarkSet() throws IOException {
215d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.reset();
216d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
217d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
218d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
219d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testMark_IOExceptionInRaf() throws IOException {
220d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream =
221d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        new RandomAccessFileInputStream(tempFile, 0, testData.length) {
222d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden          @Override
223d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden          protected RandomAccessFile getRandomAccessFile(File file) throws IOException {
224d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden            return new RandomAccessFile(file, "r") {
225d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden              @Override
226d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden              public long getFilePointer() throws IOException {
227d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden                throw new IOException("Blah314159");
228d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden              }
229d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden            };
230d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden          }
231d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden        };
232d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    try {
233d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      stream.mark(0);
234d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      Assert.fail("Executed code that should have failed.");
235d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    } catch (Exception e) {
236d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      Assert.assertEquals("Blah314159", e.getCause().getMessage());
237d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
238d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
239d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
240d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
241d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testClose() throws IOException {
242d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.close();
243d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    try {
244d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      stream.read();
245d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      Assert.fail("read after close");
246d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    } catch (IOException expected) {
247d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden      // Good.
248d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    }
249d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
250d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
251d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
252d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testLength() {
253d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(testData.length, stream.length());
254d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
255d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
256d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
257d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testConstructorWithSpecificLength() throws IOException {
258d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream = new RandomAccessFileInputStream(tempFile, 5, 2);
259d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(5, stream.read());
260d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(6, stream.read());
261d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(-1, stream.read());
262d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
263d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden
264d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  @Test
265d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  public void testGetPosition() throws IOException {
266d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream = new RandomAccessFileInputStream(tempFile, 5, 2);
267d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(5, stream.getPosition());
268d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.read();
269d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(6, stream.getPosition());
270d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    stream.setRange(0, 1);
271d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden    Assert.assertEquals(0, stream.getPosition());
272d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden  }
273d84e46c30d0ea027d047ee4c75c040a173ec9ffcAndrew Hayden}
274