1 /* 2 * Copyright (c) 2016, 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 package java.lang.reflect; 25 26 import java.lang.ref.Reference; 27 import java.util.Objects; 28 29 /** 30 * Functional test for WeakPairMap 31 * 32 * @author Peter Levart 33 */ 34 public class WeakPairMapTest { 35 public static void main(String[] args) { 36 WeakPairMap<Object, Object, String> pm = new WeakPairMap<>(); 37 Object key1 = new Object(); 38 Object key2 = new Object(); 39 40 // check for emptiness 41 assertEquals(pm.constainsKeyPair(key1, key2), false); 42 assertEquals(pm.get(key1, key2), null); 43 44 // check for NPE(s) 45 for (Object k1 : new Object[]{null, key1}) { 46 for (Object k2 : new Object[]{null, key2}) { 47 for (String v : new String[]{null, "abc"}) { 48 49 if (k1 != null && k2 != null && v != null) { 50 // skip non-null args 51 continue; 52 } 53 54 try { 55 pm.put(k1, k2, v); 56 throw new AssertionError("Unexpected code path, k1=" + 57 k1 + ", k2=" + k2 + ", v=" + v); 58 } catch (NullPointerException e) { 59 // expected 60 } 61 62 try { 63 pm.putIfAbsent(k1, k2, v); 64 throw new AssertionError("Unexpected code path, k1=" + 65 k1 + ", k2=" + k2 + ", v=" + v); 66 } catch (NullPointerException e) { 67 // expected 68 } 69 70 if (k1 != null && k2 != null) { 71 // skip non-null args 72 continue; 73 } 74 75 try { 76 pm.computeIfAbsent(k1, k2, (_k1, _k2) -> v); 77 throw new AssertionError("Unexpected code path, k1=" + 78 k1 + ", k2=" + k2 + ", v=" + v); 79 } catch (NullPointerException e) { 80 // expected 81 } 82 83 try { 84 pm.constainsKeyPair(k1, k2); 85 throw new AssertionError("Unexpected code path, k1=" + 86 k1 + ", k2=" + k2); 87 } catch (NullPointerException e) { 88 // expected 89 } 90 91 try { 92 pm.get(k1, k2); 93 throw new AssertionError("Unexpected code path, k1=" + 94 k1 + ", k2=" + k2); 95 } catch (NullPointerException e) { 96 // expected 97 } 98 } 99 } 100 } 101 102 // check insertion 103 assertEquals(pm.putIfAbsent(key1, key2, "abc"), null); 104 assertEquals(pm.get(key1, key2), "abc"); 105 106 // check retention while both keys are still reachable 107 gc(); 108 assertEquals(pm.values().contains("abc"), true); 109 assertEquals(pm.get(key1, key2), "abc"); 110 111 // check cleanup when both keys are unreachable 112 key1 = null; 113 key2 = null; 114 gc(); 115 assertEquals(pm.values().contains("abc"), false); 116 117 // new insertion 118 key1 = new Object(); 119 key2 = new Object(); 120 assertEquals(pm.putIfAbsent(key1, key2, "abc"), null); 121 assertEquals(pm.get(key1, key2), "abc"); 122 123 // check retention while both keys are still reachable 124 gc(); 125 assertEquals(pm.values().contains("abc"), true); 126 assertEquals(pm.get(key1, key2), "abc"); 127 128 // check cleanup when 1st key is unreachable 129 key1 = null; 130 gc(); 131 assertEquals(pm.values().contains("abc"), false); 132 Reference.reachabilityFence(key2); 133 134 // new insertion 135 key1 = new Object(); 136 key2 = new Object(); 137 assertEquals(pm.putIfAbsent(key1, key2, "abc"), null); 138 assertEquals(pm.get(key1, key2), "abc"); 139 140 // check retention while both keys are still reachable 141 gc(); 142 assertEquals(pm.values().contains("abc"), true); 143 assertEquals(pm.get(key1, key2), "abc"); 144 145 // check cleanup when 2nd key is unreachable 146 key2 = null; 147 gc(); 148 assertEquals(pm.values().contains("abc"), false); 149 Reference.reachabilityFence(key1); 150 } 151 152 static void gc() { 153 System.gc(); 154 try { 155 Thread.sleep(500L); 156 } catch (InterruptedException e) { 157 throw new AssertionError("Interrupted"); 158 } 159 } 160 161 static void assertEquals(Object actual, Object expected) { 162 if (!Objects.equals(actual, expected)) { 163 throw new AssertionError("Expected: " + expected + ", actual: " + actual); 164 } 165 } 166 }