1 /*
   2  * Copyright (c) 2003, 2004, 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 /*
  25  * @test
  26  * @bug     4904135 4923181
  27  * @summary Unit test for EnumSet
  28  * @author  Josh Bloch
  29  * @author  Neal Gafter
  30  * @author  Yo Ma Ma
  31  * @key randomness
  32  */
  33 
  34 import java.util.*;
  35 import java.io.*;
  36 
  37 public class EnumSetBash {
  38     static Random rnd = new Random();
  39 
  40     public static void main(String[] args) {
  41         bash(Silly0.class);
  42         bash(Silly1.class);
  43         bash(Silly31.class);
  44         bash(Silly32.class);
  45         bash(Silly33.class);
  46         bash(Silly63.class);
  47         bash(Silly64.class);
  48         bash(Silly65.class);
  49         bash(Silly127.class);
  50         bash(Silly128.class);
  51         bash(Silly129.class);
  52         bash(Silly500.class);
  53     }
  54 
  55     static <T extends Enum<T>> void bash(Class<T> enumClass) {
  56         Enum[] universe = EnumSet.allOf(enumClass).toArray(new Enum[0]);
  57         int numItr = 1000;
  58 
  59         for (int i=0; i<numItr; i++) {
  60             EnumSet<T> s1 = EnumSet.noneOf(enumClass);
  61             EnumSet<T> s2 = clone(s1, enumClass);
  62             AddRandoms(s1, universe);
  63             AddRandoms(s2, universe);
  64 
  65             EnumSet<T> intersection = clone(s1, enumClass);
  66             intersection.retainAll(s2);
  67             EnumSet<T> diff1 = clone(s1, enumClass); diff1.removeAll(s2);
  68             EnumSet<T> diff2 = clone(s2, enumClass); diff2.removeAll(s1);
  69             EnumSet<T> union = clone(s1, enumClass); union.addAll(s2);
  70 
  71             if (diff1.removeAll(diff2))
  72                 fail("Set algebra identity 2 failed");
  73             if (diff1.removeAll(intersection))
  74                 fail("Set algebra identity 3 failed");
  75             if (diff2.removeAll(diff1))
  76                 fail("Set algebra identity 4 failed");
  77             if (diff2.removeAll(intersection))
  78                 fail("Set algebra identity 5 failed");
  79             if (intersection.removeAll(diff1))
  80                 fail("Set algebra identity 6 failed");
  81             if (intersection.removeAll(diff1))
  82                 fail("Set algebra identity 7 failed");
  83 
  84             intersection.addAll(diff1); intersection.addAll(diff2);
  85             if (!intersection.equals(union))
  86                 fail("Set algebra identity 1 failed");
  87 
  88             if (new HashSet<T>(union).hashCode() != union.hashCode())
  89                 fail("Incorrect hashCode computation.");
  90 
  91             Iterator e = union.iterator();
  92             while (e.hasNext())
  93                 if (!intersection.remove(e.next()))
  94                     fail("Couldn't remove element from copy.");
  95             if (!intersection.isEmpty())
  96                 fail("Copy nonempty after deleting all elements.");
  97 
  98             e = union.iterator();
  99             while (e.hasNext()) {
 100                 Object o = e.next();
 101                 if (!union.contains(o))
 102                     fail("Set doesn't contain one of its elements.");
 103                 e.remove();
 104                 if (union.contains(o))
 105                     fail("Set contains element after deletion.");
 106             }
 107             if (!union.isEmpty())
 108                 fail("Set nonempty after deleting all elements.");
 109 
 110             s1.clear();
 111             if (!s1.isEmpty())
 112                 fail("Set nonempty after clear.");
 113         }
 114     }
 115 
 116     // Done inefficiently so as to exercise various functions
 117     static <E extends Enum<E>> EnumSet<E> clone(EnumSet<E> s, Class<E> cl) {
 118         EnumSet<E> clone = null;
 119         int method = rnd.nextInt(6);
 120         switch(method) {
 121             case 0:
 122                 clone = s.clone();
 123                 break;
 124             case 1:
 125                 clone = EnumSet.noneOf(cl);
 126                 Collection arrayList = (Collection)Arrays.asList(s.toArray());
 127                 clone.addAll((Collection<E>)arrayList);
 128                 break;
 129             case 2:
 130                 clone = EnumSet.copyOf(s);
 131                 break;
 132             case 3:
 133                 clone = EnumSet.copyOf((Collection<E>)s);
 134                 break;
 135             case 4:
 136                 if (s.isEmpty())
 137                     clone = EnumSet.copyOf((Collection<E>)s);
 138                 else
 139                     clone = EnumSet.copyOf((Collection<E>)(Collection)
 140                                            Arrays.asList(s.toArray()));
 141                 break;
 142             case 5:
 143                 clone = (EnumSet<E>) deepCopy(s);
 144         }
 145         if (!s.equals(clone))
 146             fail("Set not equal to copy. " + method);
 147         if (!s.containsAll(clone))
 148             fail("Set does not contain copy. " + method);
 149         if (!clone.containsAll(s))
 150             fail("Copy does not contain set. " + method);
 151         return clone;
 152     }
 153 
 154     // Utility method to do a deep copy of an object *very slowly* using
 155     // serialization/deserialization
 156     static <T> T deepCopy(T oldObj) {
 157         try {
 158             ByteArrayOutputStream bos = new ByteArrayOutputStream();
 159             ObjectOutputStream oos = new ObjectOutputStream(bos);
 160             oos.writeObject(oldObj);
 161             oos.flush();
 162             ByteArrayInputStream bin = new ByteArrayInputStream(
 163                 bos.toByteArray());
 164             ObjectInputStream ois = new ObjectInputStream(bin);
 165             return (T) ois.readObject();
 166         } catch(Exception e) {
 167             throw new IllegalArgumentException(e.toString());
 168         }
 169     }
 170 
 171     static <T extends Enum<T>> void AddRandoms(EnumSet<T> s, Enum[] universe) {
 172         for (int i=0; i < universe.length * 2 / 3; i++) {
 173             T e = (T) universe[rnd.nextInt(universe.length)];
 174 
 175             boolean prePresent = s.contains(e);
 176             int preSize = s.size();
 177             boolean added = s.add(e);
 178             if (!s.contains(e))
 179                 fail ("Element not present after addition.");
 180             if (added == prePresent)
 181                 fail ("added == alreadyPresent");
 182             int postSize = s.size();
 183             if (added && preSize == postSize)
 184                 fail ("Add returned true, but size didn't change.");
 185             if (!added && preSize != postSize)
 186                 fail ("Add returned false, but size changed.");
 187         }
 188     }
 189 
 190     static void fail(String s) {
 191         throw new RuntimeException(s);
 192     }
 193 
 194     public enum Silly0 { };
 195 
 196     public enum Silly1 { e1 }
 197 
 198     public enum Silly31 {
 199         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 200         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30
 201     }
 202 
 203     public enum Silly32 {
 204         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 205         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31
 206     }
 207 
 208     public enum Silly33 {
 209         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 210         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 211         e32
 212     }
 213 
 214     public enum Silly63 {
 215         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 216         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 217         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 218         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 219         e62
 220     }
 221 
 222     public enum Silly64 {
 223         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 224         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 225         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 226         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 227         e62, e63
 228     }
 229 
 230     public enum Silly65 {
 231         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 232         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 233         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 234         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 235         e62, e63, e64
 236     }
 237 
 238     public enum Silly127 {
 239         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 240         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 241         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 242         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 243         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 244         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 245         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 246         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 247         e118, e119, e120, e121, e122, e123, e124, e125, e126
 248     }
 249 
 250     public enum Silly128 {
 251         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 252         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 253         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 254         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 255         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 256         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 257         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 258         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 259         e118, e119, e120, e121, e122, e123, e124, e125, e126, e127
 260     }
 261 
 262     public enum Silly129 {
 263         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 264         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 265         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 266         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 267         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 268         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 269         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 270         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 271         e118, e119, e120, e121, e122, e123, e124, e125, e126, e127, e128
 272     }
 273 
 274     public enum Silly500 {
 275         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16,
 276         e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31,
 277         e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46,
 278         e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61,
 279         e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76,
 280         e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91,
 281         e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105,
 282         e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117,
 283         e118, e119, e120, e121, e122, e123, e124, e125, e126, e127, e128, e129,
 284         e130, e131, e132, e133, e134, e135, e136, e137, e138, e139, e140, e141,
 285         e142, e143, e144, e145, e146, e147, e148, e149, e150, e151, e152, e153,
 286         e154, e155, e156, e157, e158, e159, e160, e161, e162, e163, e164, e165,
 287         e166, e167, e168, e169, e170, e171, e172, e173, e174, e175, e176, e177,
 288         e178, e179, e180, e181, e182, e183, e184, e185, e186, e187, e188, e189,
 289         e190, e191, e192, e193, e194, e195, e196, e197, e198, e199, e200, e201,
 290         e202, e203, e204, e205, e206, e207, e208, e209, e210, e211, e212, e213,
 291         e214, e215, e216, e217, e218, e219, e220, e221, e222, e223, e224, e225,
 292         e226, e227, e228, e229, e230, e231, e232, e233, e234, e235, e236, e237,
 293         e238, e239, e240, e241, e242, e243, e244, e245, e246, e247, e248, e249,
 294         e250, e251, e252, e253, e254, e255, e256, e257, e258, e259, e260, e261,
 295         e262, e263, e264, e265, e266, e267, e268, e269, e270, e271, e272, e273,
 296         e274, e275, e276, e277, e278, e279, e280, e281, e282, e283, e284, e285,
 297         e286, e287, e288, e289, e290, e291, e292, e293, e294, e295, e296, e297,
 298         e298, e299, e300, e301, e302, e303, e304, e305, e306, e307, e308, e309,
 299         e310, e311, e312, e313, e314, e315, e316, e317, e318, e319, e320, e321,
 300         e322, e323, e324, e325, e326, e327, e328, e329, e330, e331, e332, e333,
 301         e334, e335, e336, e337, e338, e339, e340, e341, e342, e343, e344, e345,
 302         e346, e347, e348, e349, e350, e351, e352, e353, e354, e355, e356, e357,
 303         e358, e359, e360, e361, e362, e363, e364, e365, e366, e367, e368, e369,
 304         e370, e371, e372, e373, e374, e375, e376, e377, e378, e379, e380, e381,
 305         e382, e383, e384, e385, e386, e387, e388, e389, e390, e391, e392, e393,
 306         e394, e395, e396, e397, e398, e399, e400, e401, e402, e403, e404, e405,
 307         e406, e407, e408, e409, e410, e411, e412, e413, e414, e415, e416, e417,
 308         e418, e419, e420, e421, e422, e423, e424, e425, e426, e427, e428, e429,
 309         e430, e431, e432, e433, e434, e435, e436, e437, e438, e439, e440, e441,
 310         e442, e443, e444, e445, e446, e447, e448, e449, e450, e451, e452, e453,
 311         e454, e455, e456, e457, e458, e459, e460, e461, e462, e463, e464, e465,
 312         e466, e467, e468, e469, e470, e471, e472, e473, e474, e475, e476, e477,
 313         e478, e479, e480, e481, e482, e483, e484, e485, e486, e487, e488, e489,
 314         e490, e491, e492, e493, e494, e495, e496, e497, e498, e499
 315     }
 316 
 317 }