1 /*
2  * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /* @test
25  * @bug 4173528 5068772 8148936 8196334
26  * @summary Unit tests for java.util.UUID
27  * @key randomness
28  * @run main/othervm -XX:+CompactStrings UUIDTest
29  * @run main/othervm -XX:-CompactStrings UUIDTest
30  */
31 
32 package test.java.util.UUID;
33 
34 import java.util.*;
35 
36 public class UUIDTest {
37 
38     static Random generator = new Random();
39 
main(String[] args)40     public static void main(String[] args) throws Exception {
41         containsTest();
42         randomUUIDTest();
43         nameUUIDFromBytesTest();
44         stringTest();
45         versionTest();
46         variantTest();
47         timestampTest();
48         clockSequenceTest();
49         nodeTest();
50         hashCodeEqualsTest();
51         compareTo();
52     }
53 
54     // Verify that list.contains detects UUID collisons
containsTest()55     private static void containsTest() throws Exception {
56         List list = new LinkedList();
57         list.add(new UUID(4,4));
58         if (!list.contains(new UUID(4,4)))
59             throw new Exception("contains test did not work as expected");
60     }
61 
randomUUIDTest()62     private static void randomUUIDTest() throws Exception {
63         List list = new LinkedList();
64         for (int i=0; i<100; i++) {
65             UUID u1 = UUID.randomUUID();
66             if (4 != u1.version()) {
67                 throw new Exception("bad version");
68             }
69             if (2 != u1.variant()) {
70                 throw new Exception("bad variant");
71             }
72             if (list.contains(u1))
73                 throw new Exception("random UUID collision very unlikely");
74             list.add(u1);
75         }
76     }
77 
nameUUIDFromBytesTest()78     private static void nameUUIDFromBytesTest() throws Exception {
79         Random byteSource = new Random();
80         byte[] someBytes = new byte[12];
81         List list = new LinkedList();
82         for (int i=0; i<100; i++) {
83             byteSource.nextBytes(someBytes);
84             UUID u1 = UUID.nameUUIDFromBytes(someBytes);
85             if (3 != u1.version()) {
86                 throw new Exception("bad version");
87             }
88             if (2 != u1.variant()) {
89                 throw new Exception("bad variant");
90             }
91             if (list.contains(u1))
92                 throw new Exception("byte UUID collision very unlikely");
93             list.add(u1);
94         }
95     }
96 
stringTest()97     private static void stringTest() throws Exception {
98         for (int i=0; i<100; i++) {
99             UUID u1 = UUID.randomUUID();
100             UUID u2 = UUID.fromString(u1.toString().toLowerCase());
101             UUID u3 = UUID.fromString(u1.toString().toUpperCase());
102             if (!u1.equals(u2) || !u1.equals(u3))
103                 throw new Exception("UUID -> string -> UUID failed");
104         }
105 
106         testFromStringError("-0");
107         testFromStringError("x");
108         testFromStringError("----");
109         testFromStringError("-0-0-0-0");
110         testFromStringError("0-0-0-0-");
111         // Android-changed: due to targetSdkVersion this test checks old
112         // implementation, which is not that strict.
113         // testFromStringError("0-0-0-0-0-");
114         testFromStringError("0-0-0-0-x");
115     }
116 
testFromStringError(String str)117     private static void testFromStringError(String str) {
118         try {
119             UUID test = UUID.fromString(str);
120             throw new RuntimeException("Should have thrown IAE");
121         } catch (IllegalArgumentException iae) {
122             // pass
123         }
124     }
125 
versionTest()126     private static void versionTest() throws Exception {
127         UUID test = UUID.randomUUID();
128         if (test.version() != 4)
129             throw new Exception("randomUUID not type 4");
130         Random byteSource = new Random();
131         byte[] someBytes = new byte[12];
132         byteSource.nextBytes(someBytes);
133         test = UUID.nameUUIDFromBytes(someBytes);
134         if (test.version() != 3)
135             throw new Exception("nameUUIDFromBytes not type 3");
136         test = UUID.fromString("9835451d-e2e0-1e41-8a5a-be785f17dcda");
137         if (test.version() != 1)
138             throw new Exception("wrong version fromString 1");
139         test = UUID.fromString("9835451d-e2e0-2e41-8a5a-be785f17dcda");
140         if (test.version() != 2)
141             throw new Exception("wrong version fromString 2");
142         test = UUID.fromString("9835451d-e2e0-3e41-8a5a-be785f17dcda");
143         if (test.version() != 3)
144             throw new Exception("wrong version fromString 3");
145         test = UUID.fromString("9835451d-e2e0-4e41-8a5a-be785f17dcda");
146         if (test.version() != 4)
147             throw new Exception("wrong version fromString 4");
148         test = new UUID(0x0000000000001000L, 55L);
149         if (test.version() != 1)
150             throw new Exception("wrong version from bit set to 1");
151         test = new UUID(0x0000000000002000L, 55L);
152         if (test.version() != 2)
153             throw new Exception("wrong version from bit set to 2");
154         test = new UUID(0x0000000000003000L, 55L);
155         if (test.version() != 3)
156             throw new Exception("wrong version from bit set to 3");
157         test = new UUID(0x0000000000004000L, 55L);
158         if (test.version() != 4)
159             throw new Exception("wrong version from bit set to 4");
160     }
161 
variantTest()162     private static void variantTest() throws Exception {
163         UUID test = UUID.randomUUID();
164         if (test.variant() != 2)
165             throw new Exception("randomUUID not variant 2");
166         Random byteSource = new Random();
167         byte[] someBytes = new byte[12];
168         byteSource.nextBytes(someBytes);
169         test = UUID.nameUUIDFromBytes(someBytes);
170         if (test.variant() != 2)
171             throw new Exception("nameUUIDFromBytes not variant 2");
172         test = new UUID(55L, 0x0000000000001000L);
173         if (test.variant() != 0)
174             throw new Exception("wrong variant from bit set to 0");
175         test = new UUID(55L, 0x8000000000001000L);
176         if (test.variant() != 2)
177             throw new Exception("wrong variant from bit set to 2");
178        test = new UUID(55L, 0xc000000000001000L);
179         if (test.variant() != 6)
180             throw new Exception("wrong variant from bit set to 6");
181        test = new UUID(55L, 0xe000000000001000L);
182         if (test.variant() != 7)
183             throw new Exception("wrong variant from bit set to 7");
184     }
185 
timestampTest()186     private static void timestampTest() throws Exception {
187         UUID test = UUID.randomUUID();
188         try {
189             test.timestamp();
190             throw new Exception("Expected exception not thrown");
191         } catch (UnsupportedOperationException uoe) {
192             // Correct result
193         }
194         test = UUID.fromString("00000001-0000-1000-8a5a-be785f17dcda");
195         if (test.timestamp() != 1)
196             throw new Exception("Incorrect timestamp");
197         test = UUID.fromString("00000400-0000-1000-8a5a-be785f17dcda");
198         if (test.timestamp() != 1024)
199             throw new Exception("Incorrect timestamp");
200         test = UUID.fromString("FFFFFFFF-FFFF-1FFF-8a5a-be785f17dcda");
201         if (test.timestamp() != Long.MAX_VALUE>>3)
202             throw new Exception("Incorrect timestamp");
203     }
204 
clockSequenceTest()205     private static void clockSequenceTest() throws Exception {
206         UUID test = UUID.randomUUID();
207         try {
208             test.clockSequence();
209             throw new Exception("Expected exception not thrown");
210         } catch (UnsupportedOperationException uoe) {
211             // Correct result
212         }
213         test = UUID.fromString("00000001-0000-1000-8001-be785f17dcda");
214         if (test.clockSequence() != 1)
215             throw new Exception("Incorrect sequence");
216         test = UUID.fromString("00000001-0000-1000-8002-be785f17dcda");
217         if (test.clockSequence() != 2)
218             throw new Exception("Incorrect sequence");
219         test = UUID.fromString("00000001-0000-1000-8010-be785f17dcda");
220         if (test.clockSequence() != 16)
221             throw new Exception("Incorrect sequence");
222         test = UUID.fromString("00000001-0000-1000-bFFF-be785f17dcda");
223         if (test.clockSequence() != ((2L<<13)-1)) // 2^14 - 1
224             throw new Exception("Incorrect sequence");
225     }
226 
nodeTest()227     private static void nodeTest() throws Exception {
228         UUID test = UUID.randomUUID();
229         try {
230             test.node();
231             throw new Exception("Expected exception not thrown");
232         } catch (UnsupportedOperationException uoe) {
233             // Correct result
234         }
235         test = UUID.fromString("00000001-0000-1000-8001-000000000001");
236         if (test.node() != 1)
237             throw new Exception("Incorrect node");
238         test = UUID.fromString("00000001-0000-1000-8002-FFFFFFFFFFFF");
239         if (test.node() != ((2L<<47)-1)) // 2^48 - 1
240             throw new Exception("Incorrect node");
241     }
242 
hashCodeEqualsTest()243     private static void hashCodeEqualsTest() throws Exception {
244         // If two UUIDs are equal they must have the same hashCode
245         for (int i=0; i<100; i++) {
246             UUID u1 = UUID.randomUUID();
247             UUID u2 = UUID.fromString(u1.toString());
248             if (u1.hashCode() != u2.hashCode())
249                 throw new Exception("Equal UUIDs with different hashcodes");
250         }
251         // Test equality of UUIDs with tampered bits
252         for (int i=0; i<1000; i++) {
253             long l = generator.nextLong();
254             long l2 = generator.nextLong();
255             int position = generator.nextInt(64);
256             UUID u1 = new UUID(l, l2);
257             l = l ^ (1L << position);
258             UUID u2 = new UUID(l, l2);
259             if (u1.equals(u2))
260                 throw new Exception("UUIDs with different bits equal");
261         }
262     }
263 
compareTo()264     private static void compareTo() throws Exception {
265         UUID id = new UUID(33L, 63L);
266         UUID id2 = new UUID(34L, 62L);
267         UUID id3 = new UUID(34L, 63L);
268         UUID id4 = new UUID(34L, 64L);
269         UUID id5 = new UUID(35L, 63L);
270 
271         if ((id.compareTo(id2) >= 0) ||
272             (id2.compareTo(id3) >= 0) ||
273             (id3.compareTo(id4) >= 0) ||
274             (id4.compareTo(id5) >= 0))
275             throw new RuntimeException("compareTo failure");
276 
277         if ((id5.compareTo(id4) <= 0) ||
278             (id4.compareTo(id3) <= 0) ||
279             (id3.compareTo(id2) <= 0) ||
280             (id2.compareTo(id) <= 0))
281             throw new RuntimeException("compareTo failure");
282 
283         if (id.compareTo(id) != 0)
284             throw new RuntimeException("compareTo failure");
285 
286     }
287 
288 }
289