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