1 /*
   2  * Copyright (c) 2003, 2012, 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
  26  * @summary Unit tests for java.util.UUID
  27  */
  28 
  29 import java.util.*;
  30 
  31 public class UUIDTest {
  32 
  33     static Random generator = new Random();
  34 
  35     public static void main(String[] args) throws Exception {
  36         containsTest();
  37         randomUUIDTest();
  38         nameUUIDFromBytesTest();
  39         stringTest();
  40         versionTest();
  41         variantTest();
  42         timestampTest();
  43         clockSequenceTest();
  44         nodeTest();
  45         hashCodeEqualsTest();
  46         compareTo();
  47     }
  48 
  49     // Verify that list.contains detects UUID collisons
  50     private static void containsTest() throws Exception {
  51         List list = new LinkedList();
  52         list.add(new UUID(4,4));
  53         if (!list.contains(new UUID(4,4)))
  54             throw new Exception("contains test did not work as expected");
  55     }
  56 
  57     private static void randomUUIDTest() throws Exception {
  58         List list = new LinkedList();
  59         for (int i=0; i<100; i++) {
  60             UUID u1 = UUID.randomUUID();
  61             if (4 != u1.version()) {
  62                 throw new Exception("bad version");
  63             }
  64             if (2 != u1.variant()) {
  65                 throw new Exception("bad variant");
  66             }
  67             if (list.contains(u1))
  68                 throw new Exception("random UUID collision very unlikely");
  69             list.add(u1);
  70         }
  71     }
  72 
  73     private static void nameUUIDFromBytesTest() throws Exception {
  74         Random byteSource = new Random();
  75         byte[] someBytes = new byte[12];
  76         List list = new LinkedList();
  77         for (int i=0; i<100; i++) {
  78             byteSource.nextBytes(someBytes);
  79             UUID u1 = UUID.nameUUIDFromBytes(someBytes);
  80             if (3 != u1.version()) {
  81                 throw new Exception("bad version");
  82             }
  83             if (2 != u1.variant()) {
  84                 throw new Exception("bad variant");
  85             }
  86             if (list.contains(u1))
  87                 throw new Exception("byte UUID collision very unlikely");
  88             list.add(u1);
  89         }
  90     }
  91 
  92     private static void stringTest() throws Exception {
  93         for (int i=0; i<100; i++) {
  94             UUID u1 = UUID.randomUUID();
  95             UUID u2 = UUID.fromString(u1.toString());
  96             if (!u1.equals(u2))
  97                 throw new Exception("UUID -> string -> UUID failed");
  98         }
  99 
 100         testFromStringError("-0");
 101         testFromStringError("x");
 102         testFromStringError("----");
 103         testFromStringError("-0-0-0-0");
 104         testFromStringError("0-0-0-0-");
 105         testFromStringError("0-0-0-0-0-");
 106         testFromStringError("0-0-0-0-x");
 107     }
 108 
 109     private static void testFromStringError(String str) {
 110         try {
 111             UUID test = UUID.fromString(str);
 112             throw new RuntimeException("Should have thrown IAE");
 113         } catch (IllegalArgumentException iae) {
 114             // pass
 115         }
 116     }
 117 
 118     private static void versionTest() throws Exception {
 119         UUID test = UUID.randomUUID();
 120         if (test.version() != 4)
 121             throw new Exception("randomUUID not type 4");
 122         Random byteSource = new Random();
 123         byte[] someBytes = new byte[12];
 124         byteSource.nextBytes(someBytes);
 125         test = UUID.nameUUIDFromBytes(someBytes);
 126         if (test.version() != 3)
 127             throw new Exception("nameUUIDFromBytes not type 3");
 128         test = UUID.fromString("9835451d-e2e0-1e41-8a5a-be785f17dcda");
 129         if (test.version() != 1)
 130             throw new Exception("wrong version fromString 1");
 131         test = UUID.fromString("9835451d-e2e0-2e41-8a5a-be785f17dcda");
 132         if (test.version() != 2)
 133             throw new Exception("wrong version fromString 2");
 134         test = UUID.fromString("9835451d-e2e0-3e41-8a5a-be785f17dcda");
 135         if (test.version() != 3)
 136             throw new Exception("wrong version fromString 3");
 137         test = UUID.fromString("9835451d-e2e0-4e41-8a5a-be785f17dcda");
 138         if (test.version() != 4)
 139             throw new Exception("wrong version fromString 4");
 140         test = new UUID(0x0000000000001000L, 55L);
 141         if (test.version() != 1)
 142             throw new Exception("wrong version from bit set to 1");
 143         test = new UUID(0x0000000000002000L, 55L);
 144         if (test.version() != 2)
 145             throw new Exception("wrong version from bit set to 2");
 146         test = new UUID(0x0000000000003000L, 55L);
 147         if (test.version() != 3)
 148             throw new Exception("wrong version from bit set to 3");
 149         test = new UUID(0x0000000000004000L, 55L);
 150         if (test.version() != 4)
 151             throw new Exception("wrong version from bit set to 4");
 152     }
 153 
 154     private static void variantTest() throws Exception {
 155         UUID test = UUID.randomUUID();
 156         if (test.variant() != 2)
 157             throw new Exception("randomUUID not variant 2");
 158         Random byteSource = new Random();
 159         byte[] someBytes = new byte[12];
 160         byteSource.nextBytes(someBytes);
 161         test = UUID.nameUUIDFromBytes(someBytes);
 162         if (test.variant() != 2)
 163             throw new Exception("nameUUIDFromBytes not variant 2");
 164         test = new UUID(55L, 0x0000000000001000L);
 165         if (test.variant() != 0)
 166             throw new Exception("wrong variant from bit set to 0");
 167         test = new UUID(55L, 0x8000000000001000L);
 168         if (test.variant() != 2)
 169             throw new Exception("wrong variant from bit set to 2");
 170        test = new UUID(55L, 0xc000000000001000L);
 171         if (test.variant() != 6)
 172             throw new Exception("wrong variant from bit set to 6");
 173        test = new UUID(55L, 0xe000000000001000L);
 174         if (test.variant() != 7)
 175             throw new Exception("wrong variant from bit set to 7");
 176     }
 177 
 178     private static void timestampTest() throws Exception {
 179         UUID test = UUID.randomUUID();
 180         try {
 181             test.timestamp();
 182             throw new Exception("Expected exception not thrown");
 183         } catch (UnsupportedOperationException uoe) {
 184             // Correct result
 185         }
 186         test = UUID.fromString("00000001-0000-1000-8a5a-be785f17dcda");
 187         if (test.timestamp() != 1)
 188             throw new Exception("Incorrect timestamp");
 189         test = UUID.fromString("00000400-0000-1000-8a5a-be785f17dcda");
 190         if (test.timestamp() != 1024)
 191             throw new Exception("Incorrect timestamp");
 192         test = UUID.fromString("FFFFFFFF-FFFF-1FFF-8a5a-be785f17dcda");
 193         if (test.timestamp() != Long.MAX_VALUE>>3)
 194             throw new Exception("Incorrect timestamp");
 195     }
 196 
 197     private static void clockSequenceTest() throws Exception {
 198         UUID test = UUID.randomUUID();
 199         try {
 200             test.clockSequence();
 201             throw new Exception("Expected exception not thrown");
 202         } catch (UnsupportedOperationException uoe) {
 203             // Correct result
 204         }
 205         test = UUID.fromString("00000001-0000-1000-8001-be785f17dcda");
 206         if (test.clockSequence() != 1)
 207             throw new Exception("Incorrect sequence");
 208         test = UUID.fromString("00000001-0000-1000-8002-be785f17dcda");
 209         if (test.clockSequence() != 2)
 210             throw new Exception("Incorrect sequence");
 211         test = UUID.fromString("00000001-0000-1000-8010-be785f17dcda");
 212         if (test.clockSequence() != 16)
 213             throw new Exception("Incorrect sequence");
 214         test = UUID.fromString("00000001-0000-1000-bFFF-be785f17dcda");
 215         if (test.clockSequence() != ((2L<<13)-1)) // 2^14 - 1
 216             throw new Exception("Incorrect sequence");
 217     }
 218 
 219     private static void nodeTest() throws Exception {
 220         UUID test = UUID.randomUUID();
 221         try {
 222             test.node();
 223             throw new Exception("Expected exception not thrown");
 224         } catch (UnsupportedOperationException uoe) {
 225             // Correct result
 226         }
 227         test = UUID.fromString("00000001-0000-1000-8001-000000000001");
 228         if (test.node() != 1)
 229             throw new Exception("Incorrect node");
 230         test = UUID.fromString("00000001-0000-1000-8002-FFFFFFFFFFFF");
 231         if (test.node() != ((2L<<47)-1)) // 2^48 - 1
 232             throw new Exception("Incorrect node");
 233     }
 234 
 235     private static void hashCodeEqualsTest() throws Exception {
 236         // If two UUIDs are equal they must have the same hashCode
 237         for (int i=0; i<100; i++) {
 238             UUID u1 = UUID.randomUUID();
 239             UUID u2 = UUID.fromString(u1.toString());
 240             if (u1.hashCode() != u2.hashCode())
 241                 throw new Exception("Equal UUIDs with different hashcodes");
 242         }
 243         // Test equality of UUIDs with tampered bits
 244         for (int i=0; i<1000; i++) {
 245             long l = generator.nextLong();
 246             long l2 = generator.nextLong();
 247             int position = generator.nextInt(64);
 248             UUID u1 = new UUID(l, l2);
 249             l = l ^ (1L << position);
 250             UUID u2 = new UUID(l, l2);
 251             if (u1.equals(u2))
 252                 throw new Exception("UUIDs with different bits equal");
 253         }
 254     }
 255 
 256     private static void compareTo() throws Exception {
 257         UUID id = new UUID(33L, 63L);
 258         UUID id2 = new UUID(34L, 62L);
 259         UUID id3 = new UUID(34L, 63L);
 260         UUID id4 = new UUID(34L, 64L);
 261         UUID id5 = new UUID(35L, 63L);
 262 
 263         if ((id.compareTo(id2) >= 0) ||
 264             (id2.compareTo(id3) >= 0) ||
 265             (id3.compareTo(id4) >= 0) ||
 266             (id4.compareTo(id5) >= 0))
 267             throw new RuntimeException("compareTo failure");
 268 
 269         if ((id5.compareTo(id4) <= 0) ||
 270             (id4.compareTo(id3) <= 0) ||
 271             (id3.compareTo(id2) <= 0) ||
 272             (id2.compareTo(id) <= 0))
 273             throw new RuntimeException("compareTo failure");
 274 
 275         if (id.compareTo(id) != 0)
 276             throw new RuntimeException("compareTo failure");
 277 
 278     }
 279 
 280 }