1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.harmony.tests.java.lang; 18 19 import java.util.ArrayList; 20 import java.util.List; 21 22 public class ObjectTest extends junit.framework.TestCase { 23 24 final Object lock = new Object(); 25 26 // Helpers for test_notify() and test_notifyAll(). Access is guarded by {@code lock}'s monitor. 27 int ready = 0; 28 int finished = 0; 29 int outstandingNotifications = 0; 30 int spuriousNotifications = 0; 31 Throwable backgroundException; 32 33 @Override setUp()34 protected void setUp() throws Exception { 35 super.setUp(); 36 synchronized (lock) { 37 backgroundException = null; 38 } 39 } 40 41 @Override tearDown()42 protected void tearDown() throws Exception { 43 synchronized (lock) { 44 if (backgroundException != null) { 45 fail("Encountered " + backgroundException); 46 } 47 } 48 super.tearDown(); 49 } 50 51 /** 52 * java.lang.Object#Object() 53 */ test_constructor()54 public void test_constructor() { 55 // Test for method java.lang.Object() 56 assertNotNull("Constructor failed", new Object()); 57 } 58 59 /** 60 * java.lang.Object#equals(java.lang.Object) 61 */ test_equalsLjava_lang_Object()62 public void test_equalsLjava_lang_Object() { 63 Object obj1 = new Object(); 64 Object obj2 = new Object(); 65 // Test for method boolean java.lang.Object.equals(java.lang.Object) 66 assertTrue("Same object should be equal", obj1.equals(obj1)); 67 assertTrue("Different objects should not be equal", !obj1.equals(obj2)); 68 } 69 70 /** 71 * java.lang.Object#getClass() 72 */ test_getClass()73 public void test_getClass() throws Exception { 74 // Test for method java.lang.Class java.lang.Object.getClass() 75 String[] classNames = { "java.lang.Object", "java.lang.Throwable", 76 "java.lang.StringBuffer" }; 77 for (String className : classNames) { 78 final Class<?> classToTest = Class.forName(className); 79 final Object instanceToTest = classToTest.newInstance(); 80 assertSame("Instance didn't match creator class.", instanceToTest.getClass(), 81 classToTest); 82 assertSame("Instance didn't match class with matching name.", instanceToTest.getClass(), 83 Class.forName(className)); 84 } 85 } 86 87 /** 88 * java.lang.Object#hashCode() 89 */ test_hashCode()90 public void test_hashCode() { 91 // Test for method int java.lang.Object.hashCode() 92 Object obj1 = new Object(); 93 Object obj2; 94 int origHashCodeForObj1 = obj1.hashCode(); 95 // Force obj1 lock inflation. 96 synchronized (obj1) { 97 obj2 = new Object(); 98 } 99 assertEquals("Same object should have same hash.", obj1.hashCode(), obj1.hashCode()); 100 assertEquals("Lock inflation shouldn't change hash code.", 101 obj1.hashCode(), origHashCodeForObj1); 102 assertEquals("Same object should have same hash.", obj2.hashCode(), obj2.hashCode()); 103 Runtime.getRuntime().gc(); 104 assertEquals("Gc shouldn't change hash code.", obj1.hashCode(), origHashCodeForObj1); 105 } 106 107 /** 108 * java.lang.Object#notify() 109 */ test_notify()110 public void test_notify() { 111 // Test for method void java.lang.Object.notify() 112 class TestThread extends Thread { 113 public TestThread(String name) { 114 super(name); 115 } 116 117 @Override 118 public void run() { 119 synchronized (lock) { 120 try { 121 ready++; 122 lock.wait(); // Wait to be notified. 123 while (outstandingNotifications <= 0) { 124 spuriousNotifications++; 125 lock.wait(); 126 } 127 outstandingNotifications--; 128 } catch (InterruptedException ex) { 129 backgroundException = ex; 130 } 131 } 132 } 133 } 134 135 // Warning: 136 // This code relies on each thread getting serviced within 137 // 400 msec of when it is notified. Although this 138 // seems reasonable, it could lead to false-failures. 139 140 ready = 0; 141 outstandingNotifications = 0; 142 spuriousNotifications = 0; 143 final int readyWaitSecs = 3; 144 145 final int threadCount = 20; 146 List<TestThread> threads = new ArrayList<>(); 147 for (int i = 0; i < threadCount; ++i) { 148 TestThread thread = new TestThread("TestThread " + i); 149 threads.add(thread); 150 thread.start(); 151 } 152 synchronized (lock) { 153 try { 154 // Wait up to readyWaitSeconds for all threads to be waiting on 155 // monitor 156 for (int i = 0; i < 10 * readyWaitSecs; i++) { 157 lock.wait(100, 0); 158 if (ready == threadCount) { 159 break; 160 } 161 } 162 assertEquals("Not all launched threads are waiting. (ready=" + ready + ")", 163 ready, threadCount); 164 for (int i = 1; i <= threadCount; ++i) { 165 outstandingNotifications++; 166 lock.notify(); 167 for (int j = 0; j < 10 && outstandingNotifications > 0; ++j) { 168 lock.wait(100); // Sleep for 100 msecs, releasing lock. 169 } 170 assertEquals("Notification #" + i + " took too long to wake a thread.", 171 0, outstandingNotifications); 172 // Spurious notifications are allowed, but should be very rare. 173 assertTrue("Too many spurious notifications: " + spuriousNotifications, 174 spuriousNotifications <= 1); 175 } 176 } catch (InterruptedException ex) { 177 fail("Unexpectedly got an InterruptedException."); 178 } 179 } 180 } 181 182 /** 183 * java.lang.Object#notifyAll() 184 */ test_notifyAll()185 public void test_notifyAll() { 186 // Test for method void java.lang.Object.notifyAll() 187 188 // Inner class to run test thread. 189 class TestThread implements Runnable { 190 public void run() { 191 synchronized (lock) { 192 try { 193 ready += 1; 194 lock.wait();// Wait forever. 195 finished += 1; 196 } catch (InterruptedException ex) { 197 backgroundException = ex; 198 } 199 } 200 } 201 } 202 ; 203 204 // Start of test code. 205 206 // Warning: 207 // This code relies on all threads getting serviced within 208 // 5 seconds of when they are notified. Although this 209 // seems reasonable, it could lead to false-failures. 210 211 ready = 0; 212 finished = 0; 213 final int readyWaitSecs = 3; 214 final int finishedWaitSecs = 5; 215 final int threadCount = 20; 216 for (int i = 0; i < threadCount; ++i) { 217 new Thread(new TestThread()).start(); 218 } 219 220 synchronized (lock) { 221 222 try { 223 // Wait up to readyWaitSeconds for all threads to be waiting on 224 // monitor 225 for (int i = 0; i < readyWaitSecs; i++) { 226 lock.wait(1000, 0); 227 if (ready == threadCount) { 228 break; 229 } 230 } 231 232 // Check pre-conditions of testing notifyAll 233 assertEquals("Not all launched threads are waiting.", threadCount, ready); 234 // This assumes no spurious wakeups. If we ever see any, we might check for at 235 // most one finished thread instead. 236 assertEquals("At least one thread woke too early.", 0, finished); 237 238 lock.notifyAll(); 239 240 for (int i = 0; finished < threadCount && i < finishedWaitSecs; ++i) { 241 lock.wait(1000, 0); 242 } 243 244 assertEquals("At least one thread did not get notified.", threadCount, finished); 245 246 } catch (InterruptedException ex) { 247 fail("Unexpectedly got an InterruptedException. (finished = " + finished + ")"); 248 } 249 250 } 251 } 252 253 /** 254 * java.lang.Object#toString() 255 */ test_toString()256 public void test_toString() { 257 // Test for method java.lang.String java.lang.Object.toString() 258 assertNotNull("Object toString returned null.", lock.toString()); 259 } 260 261 /** 262 * java.lang.Object#wait() 263 */ test_wait()264 public void test_wait() { 265 // Test for method void java.lang.Object.wait() 266 267 // Inner class to run test thread. 268 class TestThread extends Thread { 269 int status; 270 271 public void run() { 272 synchronized (lock) { 273 try { 274 do { 275 lock.wait(); // Wait to be notified. 276 } while (outstandingNotifications <= 0); 277 outstandingNotifications--; 278 status = 1; 279 } catch (InterruptedException ex) { 280 backgroundException = ex; 281 } 282 } 283 } 284 } 285 286 // Start of test code. 287 288 // Warning: 289 // This code relies on threads getting serviced within 290 // 1 second of when they are notified. Although this 291 // seems reasonable, it could lead to false-failures. 292 293 TestThread thread = new TestThread(); 294 synchronized (lock) { 295 thread.status = 0; 296 } 297 thread.start(); 298 synchronized (lock) { 299 try { 300 lock.wait(1000, 0); 301 assertEquals("Thread woke too early. (status=" + thread.status + ")", 302 0, thread.status); 303 outstandingNotifications = 1; 304 lock.notifyAll(); 305 lock.wait(1000, 0); 306 assertEquals("Thread did not get notified. (status=" + thread.status + ")", 307 1, thread.status); 308 } catch (InterruptedException ex) { 309 fail("Unexpectedly got an InterruptedException. (status=" + thread.status + ")"); 310 } 311 } 312 } 313 314 /** 315 * java.lang.Object#wait(long) 316 */ test_waitJ()317 public void test_waitJ() { 318 // Test for method void java.lang.Object.wait(long) 319 320 // Start of test code. 321 322 final int loopCount = 20; 323 final int allowableError = 100; // milliseconds 324 final int delay = 200; // milliseconds 325 synchronized (lock) { 326 try { 327 int count = 0; 328 long[][] toLong = new long[3][3]; 329 for (int i = 0; i < loopCount; ++i) { 330 long before = System.currentTimeMillis(); 331 lock.wait(delay, 0); 332 long after = System.currentTimeMillis(); 333 long error = (after - before - delay); 334 if (error < 0) 335 error = -error; 336 if (i > 0 && error > allowableError) { 337 // Allow jit to warm up before testing 338 if (count < toLong.length) { 339 toLong[count][0] = i; 340 toLong[count][1] = before; 341 toLong[count][2] = after; 342 count++; 343 } 344 if (error > (1000 + delay) || count == toLong.length) { 345 StringBuilder sb = new StringBuilder(); 346 for (int j = 0; j < count; j++) { 347 sb.append("wakeup time too inaccurate, iteration "); 348 sb.append(toLong[j][0]); 349 sb.append(", before: "); 350 sb.append(toLong[j][1]); 351 sb.append(" after: "); 352 sb.append(toLong[j][2]); 353 sb.append(" diff: "); 354 sb.append(toLong[j][2] - toLong[j][1]); 355 sb.append("\n"); 356 } 357 fail(sb.toString()); 358 } 359 } 360 } 361 } catch (InterruptedException ex) { 362 fail("Unexpectedly got an InterruptedException."); 363 } 364 } 365 } 366 367 /** 368 * java.lang.Object#wait(long, int) 369 */ test_waitJI()370 public void test_waitJI() { 371 // Test for method void java.lang.Object.wait(long, int) 372 373 // Inner class to run test thread. 374 class TestThread extends Thread { 375 int status; 376 377 @Override 378 public void run() { 379 synchronized (lock) { 380 try { 381 lock.wait(0, 1); // Don't wait very long. 382 status = 1; 383 do { 384 lock.wait(0, 0); // Wait to be notified. 385 } while (outstandingNotifications <= 0); 386 outstandingNotifications--; 387 status = 2; 388 } catch (InterruptedException ex) { 389 backgroundException = ex; 390 } 391 } 392 } 393 } 394 395 // Start of test code. 396 397 // Warning: 398 // This code relies on threads getting serviced within 399 // 1 second of when they are notified. Although this 400 // seems reasonable, it could lead to false-failures. 401 402 TestThread thread = new TestThread(); 403 synchronized (lock) { 404 thread.status = 0; 405 } 406 thread.start(); 407 synchronized (lock) { 408 try { 409 lock.wait(1000, 0); 410 assertEquals("Thread did not wake after 1sec. (status=" + thread.status + ")", 411 1, thread.status); 412 outstandingNotifications++; 413 lock.notifyAll(); 414 lock.wait(1000, 0); 415 assertEquals("Thread did not get notified. (status=" + 416 thread.status + ")", 2, thread.status); 417 } catch (InterruptedException ex) { 418 fail("Unexpectedly got an InterruptedException. (status = " + 419 thread.status + ")"); 420 } 421 } 422 } 423 } 424