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