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