1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content.pm;
18
19import android.test.AndroidTestCase;
20import android.test.suitebuilder.annotation.MediumTest;
21
22import java.io.ByteArrayInputStream;
23import java.io.IOException;
24import java.io.InputStream;
25import java.util.Arrays;
26
27public class LimitedLengthInputStreamTest extends AndroidTestCase {
28    private final byte[] TEST_STRING1 = "This is a test".getBytes();
29
30    private InputStream mTestStream1;
31
32    @Override
33    protected void setUp() throws Exception {
34        super.setUp();
35
36        mTestStream1 = new ByteArrayInputStream(TEST_STRING1);
37    }
38
39    @MediumTest
40    public void testConstructor_NegativeOffset_Failure() throws Exception {
41        try {
42            InputStream is = new LimitedLengthInputStream(mTestStream1, -1, TEST_STRING1.length);
43            fail("Should throw IOException on negative index");
44        } catch (IOException e) {
45            // success
46        }
47    }
48
49    @MediumTest
50    public void testConstructor_NegativeLength_Failure() throws Exception {
51        try {
52            InputStream is = new LimitedLengthInputStream(mTestStream1, 0, -1);
53            fail("Should throw IOException on negative length");
54        } catch (IOException e) {
55            // success
56        }
57    }
58
59    @MediumTest
60    public void testConstructor_NullInputStream_Failure() throws Exception {
61        try {
62            InputStream is = new LimitedLengthInputStream(null, 0, 1);
63            fail("Should throw IOException on null input stream");
64        } catch (IOException e) {
65            // success
66        }
67    }
68
69    @MediumTest
70    public void testConstructor_OffsetLengthOverflow_Fail() throws Exception {
71        try {
72        InputStream is = new LimitedLengthInputStream(mTestStream1, Long.MAX_VALUE - 1,
73                Long.MAX_VALUE - 1);
74            fail("Should fail when offset + length is > Long.MAX_VALUE");
75        } catch (IOException e) {
76            // success
77        }
78    }
79
80    private void checkReadBytesWithOffsetAndLength_WithString1(int offset, int length)
81            throws Exception {
82        byte[] temp = new byte[TEST_STRING1.length];
83        byte[] expected = new byte[length];
84        byte[] actual = new byte[length];
85
86        System.arraycopy(TEST_STRING1, offset, expected, 0, length);
87
88        InputStream is = new LimitedLengthInputStream(mTestStream1, offset, length);
89        assertEquals(length, is.read(temp, 0, temp.length));
90
91        System.arraycopy(temp, 0, actual, 0, length);
92        assertTrue(Arrays.equals(expected, actual));
93
94        assertEquals(-1, is.read(temp, 0, temp.length));
95    }
96
97    @MediumTest
98    public void testReadBytesWithOffsetAndLength_ZeroOffset_PartialLength_Success()
99            throws Exception {
100        checkReadBytesWithOffsetAndLength_WithString1(0, 2);
101    }
102
103    @MediumTest
104    public void testReadBytesWithOffsetAndLength_NonZeroOffset_PartialLength_Success()
105            throws Exception {
106        checkReadBytesWithOffsetAndLength_WithString1(3, 2);
107    }
108
109    @MediumTest
110    public void testReadBytesWithOffsetAndLength_ZeroOffset_FullLength_Success() throws Exception {
111        checkReadBytesWithOffsetAndLength_WithString1(0, TEST_STRING1.length);
112    }
113
114    @MediumTest
115    public void testReadBytesWithOffsetAndLength_NonZeroOffset_FullLength_Success()
116            throws Exception {
117        checkReadBytesWithOffsetAndLength_WithString1(3, TEST_STRING1.length - 3);
118    }
119
120    @MediumTest
121    public void testReadBytesWithOffsetAndLength_ZeroOffset_PastEnd_Success() throws Exception {
122        byte[] temp = new byte[TEST_STRING1.length + 10];
123        InputStream is = new LimitedLengthInputStream(mTestStream1, 0, TEST_STRING1.length + 10);
124        assertEquals(TEST_STRING1.length, is.read(temp, 0, TEST_STRING1.length + 10));
125
126        byte[] actual = new byte[TEST_STRING1.length];
127        System.arraycopy(temp, 0, actual, 0, actual.length);
128        assertTrue(Arrays.equals(TEST_STRING1, actual));
129    }
130
131    private void checkReadBytes_WithString1(int offset, int length) throws Exception {
132        byte[] temp = new byte[TEST_STRING1.length];
133        byte[] expected = new byte[length];
134        byte[] actual = new byte[length];
135
136        System.arraycopy(TEST_STRING1, offset, expected, 0, length);
137
138        InputStream is = new LimitedLengthInputStream(mTestStream1, offset, length);
139        assertEquals(length, is.read(temp));
140
141        System.arraycopy(temp, 0, actual, 0, length);
142        assertTrue(Arrays.equals(expected, actual));
143
144        assertEquals(-1, is.read(temp));
145    }
146
147    @MediumTest
148    public void testReadBytes_ZeroOffset_PartialLength_Success() throws Exception {
149        checkReadBytesWithOffsetAndLength_WithString1(0, 2);
150    }
151
152    @MediumTest
153    public void testReadBytes_NonZeroOffset_PartialLength_Success() throws Exception {
154        checkReadBytesWithOffsetAndLength_WithString1(3, 2);
155    }
156
157    @MediumTest
158    public void testReadBytes_ZeroOffset_FullLength_Success() throws Exception {
159        checkReadBytesWithOffsetAndLength_WithString1(0, TEST_STRING1.length);
160    }
161
162    @MediumTest
163    public void testReadBytes_NonZeroOffset_FullLength_Success() throws Exception {
164        checkReadBytesWithOffsetAndLength_WithString1(3, TEST_STRING1.length - 3);
165    }
166
167    private void checkSingleByteRead_WithString1(int offset, int length) throws Exception {
168        InputStream is = new LimitedLengthInputStream(mTestStream1, offset, length);
169
170        for (int i = 0; i < length; i++) {
171            assertEquals(TEST_STRING1[offset + i], is.read());
172        }
173
174        assertEquals(-1, is.read());
175    }
176
177    @MediumTest
178    public void testSingleByteRead_ZeroOffset_PartialLength_Success() throws Exception {
179        checkSingleByteRead_WithString1(0, 2);
180    }
181
182    @MediumTest
183    public void testSingleByteRead_NonZeroOffset_PartialLength_Success() throws Exception {
184        checkSingleByteRead_WithString1(3, 2);
185    }
186
187    @MediumTest
188    public void testSingleByteRead_ZeroOffset_FullLength_Success() throws Exception {
189        checkSingleByteRead_WithString1(0, TEST_STRING1.length);
190    }
191
192    @MediumTest
193    public void testSingleByteRead_NonZeroOffset_FullLength_Success() throws Exception {
194        checkSingleByteRead_WithString1(3, TEST_STRING1.length - 3);
195    }
196}
197