From 7ea773056433c467dbd321a0a063f4789552ef89 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Mon, 22 Jul 2024 16:40:34 +0000 Subject: [PATCH] 8332551: Test vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java timed out Reviewed-by: sspitsyn, lmesnik --- .../MemoryNotificationInfo/from/from001.java | 85 ++++++++++++------- .../from/from001/TestDescription.java | 11 ++- 2 files changed, 64 insertions(+), 32 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java index b6ca1c84e9c..6e50e6998cd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import javax.management.openmbean.*; import java.util.List; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; import nsk.share.*; import nsk.share.gc.Algorithms; import nsk.share.gc.Memory; @@ -39,6 +40,7 @@ import nsk.share.test.Stresser; public class from001 { private static boolean testFailed = false; + private static final int MAX_TRIES = 6; // limit attempts to receive Notification data public static void main(String[] args) { @@ -62,8 +64,8 @@ public class from001 { log.display("null CompositeData check passed."); - // 2. Check CompositeData that doest not represnt - // MemoryNotificationInfo - IllegalArgumentException must be thrown + // 2. Check CompositeData that does not represent MemoryNotificationInfo + // throws IllegalArgumentException ObjectName mbeanObjectName = null; CompositeData cdata = null; @@ -85,12 +87,13 @@ public class from001 { testFailed = true; } catch (IllegalArgumentException e) { - // Expected: CompositeData doest not represnt MemoryNotificationInfo + // Expected: CompositeData does not represent MemoryNotificationInfo } - log.display("check for CompositeData doest not represnt MemoryNotificationInfo passed."); + log.display("check that CompositeData does not represent MemoryNotificationInfo passed."); - // 3. Check correct CompositeData + // 3. Check correct CompositeData usage: + // First try to provoke a Notification on a MemoryPool. Object poolObject = null; try { mbeanObjectName = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME); @@ -123,7 +126,11 @@ public class from001 { throw new TestFailure("TEST FAILED. See log."); } - // eat memory just to emmit notification + if (poolObject == null) { + throw new TestFailure("No memory pool found to test."); + } + + // eat memory just to emit notification Stresser stresser = new Stresser(args) { @Override @@ -133,41 +140,57 @@ public class from001 { } }; stresser.start(0);// we use timeout, not iterations - GarbageUtils.eatMemory(stresser); + int oomCount = GarbageUtils.eatMemory(stresser); + log.display("eatMemory returns OOM count: " + oomCount); - boolean messageNotRecieved = true; - while(messageNotRecieved) { + // Check for the message. Poll on queue to avoid waiting forver on failure. + // Notification is known to fail, very rarely, with -Xcomp where the allocations + // do not affect the monitored pool. Possibly a timing issue, where the "eatMemory" + // is done before Notification/threshold processing happens. + // The Notification is quite immediate, other than that problem. + boolean messageReceived = false; + int tries = 0; + while (!messageReceived && ++tries < MAX_TRIES) { try { - from001Listener.queue.take(); - messageNotRecieved = false; + Object r = from001Listener.queue.poll(10000, TimeUnit.MILLISECONDS); + if (r == null) { + log.display("poll for Notification data returns null..."); + continue; + } else { + messageReceived = true; + break; + } } catch (InterruptedException e) { - messageNotRecieved = true; + // ignored, continue } } + // If we got a Notification, test that the CompositeData can create a MemoryNotificationInfo + if (!messageReceived) { + throw new TestFailure("No Notification received."); + } result = MemoryNotificationInfo.from(from001Listener.data.get()); try { - ObjectName poolObjectName = new ObjectName(monitor.getName(poolObject)); - ObjectName resultObjectName = new ObjectName( - ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + - ",name=" + result.getPoolName()); + ObjectName poolObjectName = new ObjectName(monitor.getName(poolObject)); + ObjectName resultObjectName = new ObjectName( + ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + + ",name=" + result.getPoolName()); - log.display("poolObjectName : " + poolObjectName + - " resultObjectName : " + resultObjectName); + log.display("poolObjectName : " + poolObjectName + + " resultObjectName : " + resultObjectName); - if (!poolObjectName.equals(resultObjectName)) { - log.complain("FAILURE 3."); - log.complain("Wrong pool name : " + resultObjectName + - ", expected : " + poolObjectName); - testFailed = true; - } + if (!poolObjectName.equals(resultObjectName)) { + log.complain("FAILURE 3."); + log.complain("Wrong pool name : " + resultObjectName + + ", expected : " + poolObjectName); + testFailed = true; + } } catch (Exception e) { log.complain("Unexpected exception " + e); e.printStackTrace(log.getOutStream()); testFailed = true; } - if (testFailed) { throw new TestFailure("TEST FAILED. See log."); } @@ -183,9 +206,13 @@ class from001Listener implements NotificationListener { static SynchronousQueue queue = new SynchronousQueue(); public void handleNotification(Notification notification, Object handback) { - if (data.get() != null) + if (data.get() != null) { + System.out.println("handleNotification: ignoring"); return; - data.set((CompositeData) notification.getUserData()); + } + System.out.println("handleNotification: getting data"); + CompositeData d = (CompositeData) notification.getUserData(); + data.set(d); boolean messageNotSent = true; while(messageNotSent){ @@ -193,7 +220,7 @@ class from001Listener implements NotificationListener { queue.put(new Object()); messageNotSent = false; } catch(InterruptedException e) { - messageNotSent = true; + // ignore, retry } } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java index 3630a3dd36d..629672b2e91 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/MemoryNotificationInfo/from/from001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,15 +34,20 @@ * MemoryNotificationInfo.from(CompositeData) * returns correct results: * 1. null, if CompositeData is null; - * 2. trows IllegalArgumentException, if CompositeData doest not represnt + * 2. throws IllegalArgumentException, if CompositeData does not represent * MemoryNotificationInfo; - * 3. correct MemoryNotificationInfo object, if CompositeData is correst (i.e + * 3. correct MemoryNotificationInfo object, if CompositeData is correct, i.e * all attributes of the CompositeData must have correct values: pool name, * count; init, used, committed, max (from MemoryUsage). * COMMENT * Updated according to: * 5024531 Fix MBeans design flaw that restricts to use JMX CompositeData * + * Avoid running with -Xcomp due to rare failure where the MemoryPool does not + * increase in usage and send Notification. Likely the timing changes so "eatMemory" + * completes before Notification/threshold processing. + * + * @requires vm.compMode != "Xcomp" * @library /vmTestbase * /test/lib * @run main/othervm