/*
 * Copyright to the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.rioproject.impl.exec;

import junit.framework.Assert;
import org.junit.Test;
import org.rioproject.impl.fdh.FaultDetectionListener;
import org.rioproject.impl.exec.JVMProcessMonitor;
import org.rioproject.impl.exec.VirtualMachineHelper;

/**
 * Test {@code JVMProcessMonitor} interactions
 *
 * @author Dennis Reedy
 */
public class JVMProcessMonitorTest {

    @Test
    public void testJVMProcessMonitorConstruction() throws InterruptedException {
        Client client1 = new Client();
        Client client2 = new Client();
        Client client3 = new Client();
        new Thread(client1).start();
        new Thread(client2).start();
        new Thread(client3).start();
        while(client1.jvmProcessMonitor==null ||
              client2.jvmProcessMonitor==null ||
              client3.jvmProcessMonitor==null) {
            Thread.sleep(10);
        }
        Assert.assertEquals(client1.jvmProcessMonitor, client2.jvmProcessMonitor);
        Assert.assertEquals(client2.jvmProcessMonitor, client3.jvmProcessMonitor);
    }

    @Test(expected=IllegalArgumentException.class)
    public void testNullArgs1() {
        JVMProcessMonitor.getInstance().monitor(null, new Listener());
    }

    @Test(expected=IllegalArgumentException.class)
    public void testNullArgs2() {
        JVMProcessMonitor.getInstance().monitor("1", null);
    }

    @Test
    public void testNotification() throws InterruptedException {
        Listener l = new Listener();
        JVMProcessMonitor.getInstance().monitor("-1", l);
        while(l.serviceID==null) {
            Thread.sleep(100);
        }
        Assert.assertNotNull(l.serviceID);
        Assert.assertEquals("-1", l.serviceID);
        Assert.assertNull(JVMProcessMonitor.getInstance().getMonitorReaper());
    }

    @Test
    public void testNotification2() throws InterruptedException {
        Listener l1 = new Listener();
        JVMProcessMonitor.getInstance().monitor(VirtualMachineHelper.getID(), l1);
        Listener l2 = new Listener();
        JVMProcessMonitor.getInstance().monitor("-1", l2);
        while(l2.serviceID==null) {
            Thread.sleep(100);
        }
        Assert.assertNotNull(l2.serviceID);
        Assert.assertEquals("-1", l2.serviceID);
        Assert.assertNotNull(JVMProcessMonitor.getInstance().getMonitorReaper());
        JVMProcessMonitor.getInstance().clear();
        while(JVMProcessMonitor.getInstance().getMonitorReaper()!=null) {
            Thread.sleep(1000);
        }
    }

    @Test
    public void testReapInterval() {
        JVMProcessMonitor monitor = JVMProcessMonitor.getInstance();
        monitor.clear();
        System.setProperty(JVMProcessMonitor.REAP_INTERVAL, "3");
        monitor.monitor(VirtualMachineHelper.getID(), new Listener());
        int interval = getReapInterval(monitor);
        Assert.assertEquals(3, interval);
    }

    int getReapInterval(JVMProcessMonitor JVMProcessMonitor) {
        return JVMProcessMonitor.getMonitorReaper()==null?-1: JVMProcessMonitor.getMonitorReaper().getReapInterval();
    }

    class Listener implements FaultDetectionListener<String> {
        String serviceID;

        @Override
        public void serviceFailure(Object service, String serviceID) {
            this.serviceID = serviceID;
        }
    }

    class Client implements Runnable {
        JVMProcessMonitor jvmProcessMonitor;

        @Override
        public void run() {
            jvmProcessMonitor = JVMProcessMonitor.getInstance();
        }
    }
}

@@ -755,111 +755,45 @@
 er;%0A
+%0A
 import 
-org.rioproject.impl.exec.JVMProcessMonitor;%0Aimport org.rioprojec
+java.util.concurren
 t.
+T
 im
-pl.exec.VirtualMachineHelper
+eUnit
 ;%0A%0A/
@@ -2235,32 +2235,238 @@
 , l.serviceID);%0A
+        while(JVMProcessMonitor.getInstance().getMonitorReaper()!=null)%7B%0A            Thread.sleep(TimeUnit.SECONDS.toMillis(JVMProcessMonitor.getInstance().getMonitorReaper().getReapInterval()));%0A        %7D%0A
         Assert.a
@@ -3233,24 +3233,194 @@
 eep(
-1000);%0A        %7D
+TimeUnit.SECONDS.toMillis(JVMProcessMonitor.getInstance().getMonitorReaper().getReapInterval()));%0A        %7D%0A        Assert.assertNull(JVMProcessMonitor.getInstance().getMonitorReaper());
 %0A   
@@ -3467,16 +3467,44 @@
 terval()
+ throws InterruptedException
  %7B%0A     
@@ -3725,24 +3725,49 @@
 istener());%0A
+        monitor.clear();%0A
         int 
@@ -3841,24 +3841,215 @@
  interval);%0A
+        /* Wait for the created MonitorReaper to be null before returning*/%0A        while(JVMProcessMonitor.getInstance().getMonitorReaper()!=null) %7B%0A            Thread.sleep(500);%0A        %7D%0A
     %7D%0A%0A    i

Test case fix