package org.opennms.netmgt.provision.detector;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.InetAddress;

import org.apache.mina.core.future.IoFutureListener;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opennms.netmgt.provision.DetectFuture;
import org.opennms.netmgt.provision.ServiceDetector;
import org.opennms.netmgt.provision.detector.simple.TcpDetector;
import org.opennms.netmgt.provision.server.SimpleServer;
import org.opennms.netmgt.provision.support.NullDetectorMonitor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.annotation.Repeat;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/META-INF/opennms/detectors.xml"})
public class AsyncDetectorFileDescriptorLeakTest implements ApplicationContextAware {
    
    private SimpleServer m_server;
    private TcpDetector m_detector;
    private ApplicationContext m_applicationContext;
    
    @Before
    public void setUp() throws Exception {
        m_detector  = getDetector(TcpDetector.class);
        m_detector.setServiceName("TCP");
        m_detector.setTimeout(1000);
        m_detector.init();
    }
    
    @BeforeClass
    public static void beforeTest(){
        System.setProperty("org.opennms.netmgt.provision.maxConcurrentConnectors", "2000");
    }
    
    @After
    public void tearDown() throws IOException {
        if(m_server != null){
            m_server.stopServer();
        }
        
    }
    
    @Test
    @Repeat(10000)
    public void testSucessServer() throws Exception {
        m_server = new SimpleServer() {
            
            public void onInit() {
               setBanner("Winner");
            }
            
        };
        m_server.init();
        m_server.startServer();
        
        m_detector.setPort(m_server.getLocalPort());
        
        DetectFuture future = m_detector.isServiceDetected(m_server.getInetAddress(), new NullDetectorMonitor());
        future.addListener(new IoFutureListener<DetectFuture>() {

            public void operationComplete(DetectFuture future) {
                TcpDetector detector = m_detector;
                m_detector = null;
                detector.dispose();
            }
            
        });
        
        future.awaitUninterruptibly();
        assertNotNull(future);
        assertTrue(future.isServiceDetected());
       
    }
    
    @Test
    @Repeat(10000)
    public void testNoServerPresent() throws Exception {
        
        m_detector.setPort(1999);
        
        DetectFuture future = m_detector.isServiceDetected(InetAddress.getLocalHost(), new NullDetectorMonitor());
        future.addListener(new IoFutureListener<DetectFuture>() {

            public void operationComplete(DetectFuture future) {
                TcpDetector detector = m_detector;
                m_detector = null;
                detector.dispose();
            }
            
        });
        assertNotNull(future);
        future.awaitUninterruptibly();
        assertFalse(future.isServiceDetected());
        
        
        
        System.err.println("Finish test");
    }
    
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        m_applicationContext = applicationContext;
    }
    
    private TcpDetector getDetector(Class<? extends ServiceDetector> detectorClass) {
        Object bean = m_applicationContext.getBean(detectorClass.getName());
        assertNotNull(bean);
        assertTrue(detectorClass.isInstance(bean));
        return (TcpDetector)bean;
    }
}

@@ -1474,17 +1474,16 @@
 etector 
- 
 = getDet
@@ -1946,35 +1946,16 @@
   @Test%0A
-    @Repeat(10000)%0A
     publ
@@ -1992,32 +1992,153 @@
 ows Exception %7B%0A
+        for (int i = 0; i %3C 10000; i++) %7B%0A            setUp();%0A            System.err.println(%22current loop: %22 + i);%0A    
         m_server
@@ -2165,33 +2165,41 @@
 ) %7B%0A            
+   
-%0A
+ %0A    
             publ
@@ -2232,16 +2232,20 @@
         
+    
 setBanne
@@ -2253,24 +2253,28 @@
 (%22Winner%22);%0A
+    
             
@@ -2287,25 +2287,31 @@
         
-%0A
+    %0A  
         
 %7D;%0A     
@@ -2306,11 +2306,30 @@
     
+  
 %7D;%0A
+            %0A    
     
@@ -2349,32 +2349,36 @@
 init();%0A        
+    
 m_server.startSe
@@ -2385,29 +2385,120 @@
 rver();%0A    
+%0A            assertNotNull(m_detector);%0A            assertNotNull(m_server.getLocalPort());%0A
     
-%0A
         m_de
@@ -2538,32 +2538,36 @@
 ort());%0A        
+    
 %0A        DetectF
@@ -2551,32 +2551,36 @@
        %0A        
+    
 DetectFuture fut
@@ -2669,32 +2669,36 @@
 tor());%0A        
+    
 future.addListen
@@ -2731,32 +2731,36 @@
 tectFuture%3E() %7B%0A
+    
 %0A            pub
@@ -2748,32 +2748,36 @@
    %0A            
+    
 public void oper
@@ -2821,32 +2821,36 @@
                 
+    
 TcpDetector dete
@@ -2860,32 +2860,36 @@
 r = m_detector;%0A
+    
                 
@@ -2915,32 +2915,36 @@
                 
+    
 detector.dispose
@@ -2951,34 +2951,42 @@
 ();%0A            
-%7D%0A
+    %7D%0A    
             %0A   
@@ -2982,32 +2982,36 @@
        %0A        
+    
 %7D);%0A        %0A   
@@ -2998,33 +2998,41 @@
     %7D);%0A        
+  
-%0A
+  %0A    
         future.a
@@ -3054,32 +3054,36 @@
 ibly();%0A        
+ 
+   
 assertNotNull(fu
@@ -3081,32 +3081,36 @@
 otNull(future);%0A
+    
         assertTr
@@ -3144,24 +3144,103 @@
 ());%0A       
+     
+%0A            m_server.stopServer();%0A            m_server = null;%0A        %7D
 %0A    %7D%0A    %0A

work around a weird test issue