1/*
2 * Copyright (C) 2011 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.os.Parcel;
20import android.support.test.filters.LargeTest;
21
22import java.util.Random;
23
24@LargeTest
25public class VerifierDeviceIdentityTest extends android.test.AndroidTestCase {
26    private static final long TEST_1 = 0x7A5F00FF5A55AAA5L;
27
28    private static final String TEST_1_ENCODED = "HUXY-A75N-FLKV-F";
29
30    private static final String TEST_1_ENCODED_LOWERCASE = "huxy-a75n-flkv-f";
31
32    private static final long TEST_2 = 0x5A05FF5A05F0A555L;
33
34    private static final long TEST_MAXVALUE = Long.MAX_VALUE;
35
36    private static final String TEST_MAXVALUE_ENCODED = "H777-7777-7777-7";
37
38    private static final long TEST_MINVALUE = Long.MIN_VALUE;
39
40    private static final String TEST_MINVALUE_ENCODED = "IAAA-AAAA-AAAA-A";
41
42    private static final long TEST_ZERO = 0L;
43
44    private static final String TEST_ZERO_ENCODED = "AAAA-AAAA-AAAA-A";
45
46    private static final long TEST_NEGONE = -1L;
47
48    private static final String TEST_NEGONE_ENCODED = "P777-7777-7777-7";
49
50    private static final String TEST_OVERFLOW_ENCODED = "QAAA-AAAA-AAAA-A";
51
52    private static final String TEST_SUBSTITUTION_CORRECTED = "OIIO-IIOO-IOOI-I";
53
54    private static final String TEST_SUBSTITUTION_UNCORRECTED = "0110-1100-1001-1";
55
56    public void testVerifierDeviceIdentity_Equals_Success() {
57        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
58        VerifierDeviceIdentity id2 = new VerifierDeviceIdentity(TEST_1);
59
60        assertTrue("The two VerifierDeviceIdentity instances should be equal", id1.equals(id2));
61    }
62
63    public void testVerifierDeviceIdentity_Equals_Failure() {
64        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
65        VerifierDeviceIdentity id2 = new VerifierDeviceIdentity(TEST_2);
66
67        assertFalse("The two VerifierDeviceIdentity instances should be unique", id1.equals(id2));
68    }
69
70    public void testVerifierDeviceIdentity_HashCode() {
71        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
72
73        assertEquals("The VerifierDeviceIdentity should have the same hashcode as its identity",
74                (int) TEST_1, id1.hashCode());
75    }
76
77    public void testVerifierDeviceIdentity_ToString_Success() {
78        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
79
80        assertEquals("The identity should encode correctly to the expected Base 32 string",
81                TEST_1_ENCODED, id1.toString());
82    }
83
84    public void testVerifierDeviceIdentity_ToString_Largest() {
85        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_MAXVALUE);
86
87        assertEquals("The identity should encode correctly to the expected Base 32 string",
88                TEST_MAXVALUE_ENCODED, id1.toString());
89    }
90
91    public void testVerifierDeviceIdentity_ToString_Zero() {
92        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_ZERO);
93
94        assertEquals("The identity should encode correctly to the expected Base 32 string",
95                TEST_ZERO_ENCODED, id1.toString());
96    }
97
98    public void testVerifierDeviceIdentity_ToString_NegOne() {
99        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_NEGONE);
100
101        assertEquals("The identity should encode correctly to the expected Base 32 string",
102                TEST_NEGONE_ENCODED, id1.toString());
103    }
104
105    public void testVerifierDeviceIdentity_ToString_MinValue() {
106        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_MINVALUE);
107
108        assertEquals("The identity should encode correctly to the expected Base 32 string",
109                TEST_MINVALUE_ENCODED, id1.toString());
110    }
111
112    public void testVerifierDeviceIdentity_Parcel_ReadNegative() {
113        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_MINVALUE);
114
115        Parcel parcel = Parcel.obtain();
116        parcel.writeLong(TEST_MINVALUE);
117        parcel.setDataPosition(0);
118
119        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.CREATOR.createFromParcel(parcel);
120
121        assertEquals("Parcel created should match expected value", id1, id2);
122    }
123
124    public void testVerifierDeviceIdentity_Parcel_Read_Pass() {
125        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
126
127        Parcel parcel = Parcel.obtain();
128        id1.writeToParcel(parcel, 0);
129        parcel.setDataPosition(0);
130
131        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.CREATOR.createFromParcel(parcel);
132
133        assertEquals("Original identity and parceled identity should be the same", id1, id2);
134    }
135
136    @SuppressWarnings("serial")
137    private static class MockRandom extends Random {
138        private long mNextLong;
139
140        public MockRandom() {
141        }
142
143        public void setNextLong(long nextLong) {
144            mNextLong = nextLong;
145        }
146
147        @Override
148        public long nextLong() {
149            return mNextLong;
150        }
151    }
152
153    public void testVerifierDeviceIdentity_Generate_MinValue() {
154        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_MINVALUE);
155
156        MockRandom random = new MockRandom();
157        random.setNextLong(Long.MIN_VALUE);
158        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.generate(random);
159
160        assertEquals("Identity created from Long.MIN_VALUE and one created from return from RNG"
161                + " should be the same", id1, id2);
162    }
163
164    public void testVerifierDeviceIdentity_Generate_Random() {
165        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
166
167        MockRandom random = new MockRandom();
168        random.setNextLong(TEST_1);
169        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.generate(random);
170
171        assertEquals("Identity should end up being same when coming from RNG", id1, id2);
172    }
173
174    public void testVerifierDeviceIdentity_Parse_Normal() {
175        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
176
177        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.parse(TEST_1_ENCODED);
178
179        assertEquals("Parsed device identity should have the same value as original identity",
180                id1, id2);
181    }
182
183    public void testVerifierDeviceIdentity_Parse_MaxValue() {
184        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_MAXVALUE);
185
186        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.parse(TEST_MAXVALUE_ENCODED);
187
188        assertEquals("Original max value and parsed max value should be equal", id1, id2);
189    }
190
191    public void testVerifierDeviceIdentity_Parse_TooShort() {
192        try {
193            VerifierDeviceIdentity.parse("AAAA-AAAA-AAAA-");
194            fail("Parsing should fail when device identifier is too short");
195        } catch (IllegalArgumentException e) {
196            // success
197        }
198    }
199
200    public void testVerifierDeviceIdentity_Parse_WayTooShort() {
201        try {
202            VerifierDeviceIdentity.parse("----------------");
203            fail("Parsing should fail when device identifier is too short");
204        } catch (IllegalArgumentException e) {
205            // success
206        }
207    }
208
209    public void testVerifierDeviceIdentity_Parse_TooLong() {
210        try {
211            VerifierDeviceIdentity.parse("AAAA-AAAA-AAAA-AA");
212            fail("Parsing should fail when device identifier is too long");
213        } catch (IllegalArgumentException e) {
214            // success
215        }
216    }
217
218    public void testVerifierDeviceIdentity_Parse_Overflow() {
219        try {
220            VerifierDeviceIdentity.parse(TEST_OVERFLOW_ENCODED);
221            fail("Parsing should fail when the value will overflow");
222        } catch (IllegalArgumentException e) {
223            // success
224        }
225    }
226
227    public void testVerifierDeviceIdentity_Parse_SquashToUppercase() {
228        VerifierDeviceIdentity id1 = new VerifierDeviceIdentity(TEST_1);
229
230        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.parse(TEST_1_ENCODED_LOWERCASE);
231
232        assertEquals("Lowercase should parse to be the same as uppercase", id1, id2);
233
234        assertEquals("Substituted identity should render to the same string",
235                id1.toString(), id2.toString());
236    }
237
238    public void testVerifierDeviceIdentity_Parse_1I_And_0O_Substitution() {
239        VerifierDeviceIdentity id1 = VerifierDeviceIdentity.parse(TEST_SUBSTITUTION_CORRECTED);
240
241        VerifierDeviceIdentity id2 = VerifierDeviceIdentity.parse(TEST_SUBSTITUTION_UNCORRECTED);
242
243        assertEquals("Substitution should replace 0 with O and 1 with I", id1, id2);
244
245        assertEquals("Substituted identity should render to the same string",
246                id1.toString(), id2.toString());
247    }
248}
249