package org.weakref.jmx;

import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;

import static java.lang.String.format;

public class TestUnexporter
{
    private MBeanServer server = null;
    private MBeanExporter exporter = null;

    private List<ObjectName> objectNames;

    @BeforeMethod
    public void setUp()
    {
        server = ManagementFactory.getPlatformMBeanServer();
        exporter = new MBeanExporter(server);

        objectNames = new ArrayList<ObjectName>();
        for (int i = 0; i < 10; ++i) {
            ObjectName name = Util.getUniqueObjectName();
            objectNames.add(name);
            exporter.export(name.getCanonicalName(), new TestBean());
        }

        Assert.assertNotNull(server);
        Assert.assertNotNull(exporter);
    }

    @AfterMethod
    public void tearDown()
    {
        Assert.assertNotNull(server);
        Assert.assertNotNull(exporter);

        for (ObjectName name : objectNames) {
            try {
                exporter.unexport(name.getCanonicalName());
            }
            catch (JmxException e) {
                // ignore
            }
        }
    }

    @Test(expectedExceptions = InstanceNotFoundException.class)
    public void testUnexportOk() throws Exception
    {
        ObjectName name = objectNames.get(0);

        Assert.assertEquals("Hello!", server.getAttribute(name, "Hello"));
        exporter.unexport(name.getCanonicalName());
        server.getAttribute(name, "Hello");
    }

    @Test
    public void testUnexportDouble() throws Throwable
    {
        ObjectName name = objectNames.get(0);

        Assert.assertEquals("Hello!", server.getAttribute(name, "Hello"));
        exporter.unexport(name.getCanonicalName());

        try {
            exporter.unexport(name.getCanonicalName());
        }
        catch (JmxException e) {
            Assert.assertEquals(e.getReason(), JmxException.Reason.INSTANCE_NOT_FOUND);
        }
    }

    @Test
    public void testUnexportAll()
            throws IntrospectionException, ReflectionException
    {
        exporter.unexportAll();

        for (ObjectName name : objectNames) {
            try {
                server.getMBeanInfo(name);
                Assert.fail(format("failed to unexport %s", name.getCanonicalName()));
            }
            catch (InstanceNotFoundException e) {
                // success
            }
        }
    }

    public static class TestBean
    {
        @Managed
        public String getHello()
        {
            return "Hello!";
        }
    }
}

@@ -260,32 +260,84 @@
 ctionException;%0A
+import javax.management.MBeanRegistrationException;%0A
 import javax.man
@@ -535,16 +535,38 @@
 il.List;
+%0Aimport java.util.Map;
 %0A%0Aimport
@@ -2887,24 +2887,1266 @@
    %7D%0A    %7D%0A%0A
+    @Test%0A    public void testUnexportAllIdempotent()%0A            throws IntrospectionException, ReflectionException%0A    %7B%0A        exporter.unexportAll();%0A%0A        for (ObjectName name : objectNames) %7B%0A            try %7B%0A                server.getMBeanInfo(name);%0A                Assert.fail(format(%22failed to unexport %25s%22, name.getCanonicalName()));%0A            %7D%0A            catch (InstanceNotFoundException e) %7B%0A                // success%0A            %7D%0A        %7D%0A%0A        Map%3CString,Exception%3E errors = exporter.unexportAll();%0A        Assert.assertTrue(errors.isEmpty());%0A    %7D%0A%0A    @Test%0A    public void testUnexportAllIgnoresMissing()%0A            throws IntrospectionException, ReflectionException, InstanceNotFoundException, MBeanRegistrationException%0A    %7B%0A        server.unregisterMBean(objectNames.get(0));%0A%0A        Map%3CString,Exception%3E errors = exporter.unexportAll();%0A        Assert.assertTrue(errors.isEmpty());%0A%0A        for (ObjectName name : objectNames) %7B%0A            try %7B%0A                server.getMBeanInfo(name);%0A                Assert.fail(format(%22failed to unexport %25s%22, name.getCanonicalName()));%0A            %7D%0A            catch (InstanceNotFoundException e) %7B%0A                // success%0A            %7D%0A        %7D%0A    %7D%0A%0A%0A
     public s

add unit tests for error cases