You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2012/10/17 13:29:10 UTC

svn commit: r1399183 - in /felix/trunk/scr/src/test/java/org/apache/felix/scr/integration: ComponentConcurrencyTest.java ComponentTestBase.java Felix3680Test.java components/felix3680/Main.java

Author: pderop
Date: Wed Oct 17 11:29:09 2012
New Revision: 1399183

URL: http://svn.apache.org/viewvc?rev=1399183&view=rev
Log:
FELIX-3680: Don't use anymore a LogReaderService because the LogReaderService is handled in
a dedicate LogService thread, and because of this, we can't log the actual thread of the 
logged message. The ComponentTestBase is now implemeting a light LogService, which logs
messages asynchronously, but the thread of the log is preserved.



Modified:
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConcurrencyTest.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680Test.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680/Main.java

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConcurrencyTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConcurrencyTest.java?rev=1399183&r1=1399182&r2=1399183&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConcurrencyTest.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConcurrencyTest.java Wed Oct 17 11:29:09 2012
@@ -10,22 +10,6 @@
  */
 package org.apache.felix.scr.integration;
 
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Date;
-import java.util.Hashtable;
 import java.util.Iterator;
 
 import javax.inject.Inject;
@@ -37,13 +21,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogListener;
-import org.osgi.service.log.LogReaderService;
-import org.osgi.service.log.LogService;
 
 @RunWith(JUnit4TestRunner.class)
 public class ComponentConcurrencyTest extends ComponentTestBase
@@ -87,8 +64,7 @@ public class ComponentConcurrencyTest ex
         delay( 30 );
         for ( Iterator it = log.foundWarnings().iterator(); it.hasNext();)
         {
-            LogEntry entry = ( LogEntry ) it.next();
-            String message = entry.getMessage();
+            String message = ( String ) it.next();
             if ( message.contains( "FrameworkEvent ERROR" ) ||
                     message.contains( "Could not get service from ref" ) ||
                     message.contains( "Failed creating the component instance; see log for reason" ) ||

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java?rev=1399183&r1=1399182&r2=1399183&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java Wed Oct 17 11:29:09 2012
@@ -48,6 +48,7 @@ import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeSet;
+import java.util.concurrent.LinkedBlockingQueue;
 
 import javax.inject.Inject;
 
@@ -68,12 +69,11 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogListener;
-import org.osgi.service.log.LogReaderService;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.ServiceTracker;
 
@@ -113,9 +113,7 @@ public abstract class ComponentTestBase
     protected static String descriptorFile = "/integration_test_simple_components.xml";
 
     protected static boolean NONSTANDARD_COMPONENT_FACTORY_BEHAVIOR = false;
-    private PrintStream out;
-    private PrintStream err;
-    protected Log log;
+    protected volatile Log log;
 
     static
     {
@@ -125,7 +123,11 @@ public abstract class ComponentTestBase
 
     @ProbeBuilder
     public TestProbeBuilder extendProbe(TestProbeBuilder builder) {
-        builder.setHeader("Export-Package", "org.apache.felix.scr.integration.components,org.apache.felix.scr.integration.components.activatesignature,org.apache.felix.scr.integration.components.circular,org.apache.felix.scr.integration.components.concurrency,org.apache.felix.scr.integration.components.felix3680");
+        builder.setHeader("Export-Package", "org.apache.felix.scr.integration.components," +
+                                            "org.apache.felix.scr.integration.components.activatesignature," +
+                                            "org.apache.felix.scr.integration.components.circular," +
+                                            "org.apache.felix.scr.integration.components.concurrency," +
+                                            "org.apache.felix.scr.integration.components.felix3680");
         builder.setHeader("Import-Package", "org.apache.felix.scr,org.apache.felix.scr.component;mandatory:=\"status\"; status=\"provisional\"");
         builder.setHeader("Bundle-ManifestVersion", "2");
         return builder;
@@ -145,7 +147,6 @@ public abstract class ComponentTestBase
         final Option[] base = options(
             provision(
                 CoreOptions.bundle( bundleFile.toURI().toString() ),
-                    mavenBundle( "org.apache.felix", "org.apache.felix.log", "1.0.1" ),
                 mavenBundle( "org.ops4j.pax.tinybundles", "tinybundles", "1.0.0" ),
                 mavenBundle( "org.apache.felix", "org.apache.felix.configadmin", "1.0.10" )
              ),
@@ -162,18 +163,11 @@ public abstract class ComponentTestBase
     @Before
     public void setUp() throws BundleException
     {
-        out = System.out;
-        err = System.err;
-        System.setOut(new NullStdout());
-        System.setErr( new NullStdout() );
-
         log = new Log();
-            ServiceReference sr = bundleContext.getServiceReference(LogReaderService.class.getName());
-            TestCase.assertNotNull(sr);
-            LogReaderService logReader = (LogReaderService) bundleContext.getService(sr);
-            TestCase.assertNotNull(logReader);
-            logReader.addLogListener( log );
-
+        log.start();
+        bundleContext.addFrameworkListener( log );
+        bundleContext.registerService( LogService.class.getName(), log, null );
+        
         scrTracker = new ServiceTracker( bundleContext, "org.apache.felix.scr.ScrService", null );
         scrTracker.open();
         configAdminTracker = new ServiceTracker( bundleContext, "org.osgi.service.cm.ConfigurationAdmin", null );
@@ -187,18 +181,23 @@ public abstract class ComponentTestBase
     @After
     public void tearDown() throws BundleException
     {
-        if ( bundle != null && bundle.getState() != Bundle.UNINSTALLED )
+        try
         {
-            bundle.uninstall();
-            bundle = null;
-        }
+            if ( bundle != null && bundle.getState() != Bundle.UNINSTALLED )
+            {
+                bundle.uninstall();
+                bundle = null;
+            }
 
-        configAdminTracker.close();
-        configAdminTracker = null;
-        scrTracker.close();
-        scrTracker = null;
-        System.setOut(out);
-        System.setErr(err);
+            configAdminTracker.close();
+            configAdminTracker = null;
+            scrTracker.close();
+            scrTracker = null;
+        }
+        finally
+        {
+            log.stop();
+        }
     }
 
 
@@ -395,7 +394,11 @@ public abstract class ComponentTestBase
                 .set(Constants.BUNDLE_SYMBOLICNAME, "simplecomponent")
                 .set(Constants.BUNDLE_VERSION, "0.0.11")
                 .set(Constants.IMPORT_PACKAGE,
-                        "org.apache.felix.scr.integration.components,org.apache.felix.scr.integration.components.activatesignature,org.apache.felix.scr.integration.components.circular,org.apache.felix.scr.integration.components.concurrency,org.apache.felix.scr.integration.components.felix3680")
+                        "org.apache.felix.scr.integration.components," +
+                        "org.apache.felix.scr.integration.components.activatesignature," +
+                        "org.apache.felix.scr.integration.components.circular," +
+                        "org.apache.felix.scr.integration.components.concurrency," +
+                        "org.apache.felix.scr.integration.components.felix3680")
                 .set("Service-Component", "OSGI-INF/components.xml")
             .build(withBnd());
 
@@ -599,47 +602,208 @@ public abstract class ComponentTestBase
         }
     }
 
-    public static class Log implements LogListener
+    public static class LogEntry
+    {
+        private final String m_msg;
+        private final int m_level;
+        private final Throwable m_err;
+        private final long m_time;
+        private final Thread m_thread;
+
+
+        LogEntry( int level, String msg, Throwable t )
+        {
+            m_level = level;
+            m_msg = msg;
+            m_err = t;
+            m_time = System.currentTimeMillis();
+            m_thread = Thread.currentThread();
+        }
+
+
+        public String toString()
+        {
+            return m_msg;
+        }
+
+
+        public int getLevel()
+        {
+            return m_level;
+        }
+
+
+        public String getMessage()
+        {
+            return m_msg;
+        }
+
+
+        public Throwable getError()
+        {
+            return m_err;
+        }
+
+
+        public long getTime()
+        {
+            return m_time;
+        }
+
+
+        public Thread getThread()
+        {
+            return m_thread;
+        }
+    }
+    
+    public static class Log implements LogService, FrameworkListener, Runnable
     {
-        private final SimpleDateFormat _sdf = new SimpleDateFormat("HH:mm:ss,S");
-        private final List m_warnings = Collections.synchronizedList( new ArrayList() );//<LogEntry>
-        private final static PrintStream _out =
-                new PrintStream(new BufferedOutputStream(new FileOutputStream( FileDescriptor.err), 128));
+        private final SimpleDateFormat m_sdf = new SimpleDateFormat( "HH:mm:ss,S" );
+        private final static PrintStream m_out = new PrintStream( new BufferedOutputStream( new FileOutputStream(
+            FileDescriptor.err ), 128 ) );
+        private final List<String> m_warnings = Collections.synchronizedList( new ArrayList<String>() );//<String>
+        private LinkedBlockingQueue<LogEntry> m_logQueue = new LinkedBlockingQueue<LogEntry>();
+        private volatile Thread m_logThread;
+        private volatile PrintStream m_realOut;
+        private volatile PrintStream m_realErr;
 
-        public void logged(LogEntry entry)
+        public void start()
         {
-            if ( entry.getLevel() > getEnabledLogLevel() )
+            m_realOut = System.out;
+            m_realErr = System.err;
+            System.setOut( new NullStdout() );
+            System.setErr( new NullStdout() );
+            m_logThread = new Thread( this );
+            m_logThread.start();
+        }
+
+        
+        public void stop()
+        {
+            System.setOut(m_realOut);
+            System.setErr(m_realErr);
+            m_out.flush();
+            m_warnings.clear();
+            m_logThread.interrupt();
+            try
             {
-                return;
+                m_logThread.join();
             }
+            catch ( InterruptedException e )
+            {
+            }
+        }
+
 
-            if (entry.getLevel() <= 2)
+        List<String> foundWarnings()
+        {
+            return m_warnings;
+        }
+
+
+        public void run()
+        {
+            try
             {
-                m_warnings.add( entry );
+                LogEntry entry = null;
+                while ( true )
+                {
+                    entry = m_logQueue.take();
+                    if ( entry.getLevel() <= 2 )
+                    {
+                        if ( m_warnings.size() < 1024 )
+                        {
+                            m_warnings.add( entry.getMessage() );
+                        }
+                        else
+                        {
+                            // Avoid out of memory ...
+                            m_warnings.add( 1024, "Unexpected errors logged. Please look at previous logs" );
+                        }
+                    }
+
+                    StringWriter sw = new StringWriter();
+                    sw.append( "log level: " + entry.getLevel() );
+                    sw.append( " D=" );
+                    sw.append( m_sdf.format( new Date( entry.getTime() ) ) );
+                    sw.append( " T=" + entry.getThread() );
+                    sw.append( ": " );
+                    sw.append( entry.getMessage() );
+                    if ( entry.getError() != null )
+                    {
+                        sw.append( System.getProperty( "line.separator" ) );
+                        PrintWriter pw = new PrintWriter( sw );
+                        entry.getError().printStackTrace( pw );
+                    }
+                    m_out.println( sw.toString() );
+
+                }
             }
-            StringWriter sw = new StringWriter();
-            sw.append( "log level: " + entry.getLevel() );
-            sw.append(" D=");
-            sw.append(_sdf.format( new Date(entry.getTime())));
-            sw.append(", T=" + Thread.currentThread().getName());
-            sw.append(": ");
-            sw.append(entry.getMessage());
-            if (entry.getException() != null)
+            catch ( InterruptedException e )
             {
-                sw.append(System.getProperty("line.separator"));
-                PrintWriter pw = new PrintWriter(sw);
-                entry.getException().printStackTrace(pw);
+                return;
             }
-            _out.println(sw.toString());
-            _out.flush();
         }
 
-        List foundWarnings()
+
+        // ------------- FrameworkListener -----------------------------------------------------------
+
+        public void frameworkEvent( final FrameworkEvent event )
         {
-            return m_warnings;
+            int eventType = event.getType();
+            String msg = getFrameworkEventMessage( eventType );
+            int level = ( eventType == FrameworkEvent.ERROR ) ? LogService.LOG_ERROR : LogService.LOG_WARNING;
+            log( level, msg, event.getThrowable() );
         }
-        
-        public int getEnabledLogLevel() {
+
+
+        // ------------ LogService ----------------------------------------------------------------
+
+        public void log( int level, String message )
+        {
+            log( level, message, null );
+        }
+
+
+        public void log( int level, String message, Throwable exception )
+        {
+            if ( level > getEnabledLogLevel() )
+            {
+                return;
+            }
+            m_logQueue.offer( new LogEntry( level, message, exception ) );
+        }
+
+
+        public void log( ServiceReference sr, int osgiLevel, String message )
+        {
+            log( sr, osgiLevel, message, null );
+        }
+
+
+        public void log( ServiceReference sr, int level, String msg, Throwable exception )
+        {
+            if ( sr != null )
+            {
+                StringBuilder sb = new StringBuilder();
+                Object serviceId = sr.getProperty( Constants.SERVICE_ID );
+                if ( serviceId != null )
+                {
+                    sb.append( "[" + serviceId.toString() + "] " );
+                }
+                sb.append( msg );
+                log( level, sb.toString(), exception );
+            }
+            else
+            {
+                log( level, msg, exception );
+            }
+        }
+
+
+        private int getEnabledLogLevel()
+        {
             if ( DS_LOGLEVEL.regionMatches( true, 0, "err", 0, "err".length() ) )
             {
                 return LogService.LOG_ERROR;
@@ -657,7 +821,27 @@ public abstract class ComponentTestBase
                 return LogService.LOG_DEBUG;
             }
         }
-    }
 
 
+        private String getFrameworkEventMessage( int event )
+        {
+            switch ( event )
+            {
+                case FrameworkEvent.ERROR:
+                    return "FrameworkEvent: ERROR";
+                case FrameworkEvent.INFO:
+                    return "FrameworkEvent INFO";
+                case FrameworkEvent.PACKAGES_REFRESHED:
+                    return "FrameworkEvent: PACKAGE REFRESHED";
+                case FrameworkEvent.STARTED:
+                    return "FrameworkEvent: STARTED";
+                case FrameworkEvent.STARTLEVEL_CHANGED:
+                    return "FrameworkEvent: STARTLEVEL CHANGED";
+                case FrameworkEvent.WARNING:
+                    return "FrameworkEvent: WARNING";
+                default:
+                    return null;
+            }
+        }
+    }
 }

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680Test.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680Test.java?rev=1399183&r1=1399182&r2=1399183&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680Test.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680Test.java Wed Oct 17 11:29:09 2012
@@ -18,22 +18,6 @@
  */
 package org.apache.felix.scr.integration;
 
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Date;
-import java.util.Hashtable;
 import java.util.Iterator;
 
 import javax.inject.Inject;
@@ -45,13 +29,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogListener;
-import org.osgi.service.log.LogReaderService;
-import org.osgi.service.log.LogService;
 
 /**
  * This test validates the FELIX-3680 issue.
@@ -95,8 +72,7 @@ public class Felix3680Test extends Compo
         delay( ); //async deactivate
         for (Iterator it = log.foundWarnings().iterator(); it.hasNext();)
         {
-            LogEntry entry = (LogEntry) it.next();
-            String message = entry.getMessage();
+            String message = (String) it.next();
             if (message.startsWith("Performed ") && message.endsWith(" tests."))
             {
                 continue;

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680/Main.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680/Main.java?rev=1399183&r1=1399182&r2=1399183&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680/Main.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680/Main.java Wed Oct 17 11:29:09 2012
@@ -28,6 +28,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.felix.scr.Component;
 import org.apache.felix.scr.ScrService;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
@@ -241,8 +242,17 @@ public class Main implements Runnable
 
     private void dumpState(StringWriter sw, String name)
     {
-        org.apache.felix.scr.Component a = _scr.getComponents(name)[0];
-        sw.append(name).append("[").append(getState(a)).append("] ");
+        org.apache.felix.scr.Component[] comps = _scr.getComponents(name);
+        if (comps == null || comps.length == 0) 
+        {
+            _logService.log(LogService.LOG_ERROR, "could not find component state " + name, null);
+            return;
+        }
+        org.apache.felix.scr.Component c = comps[0];
+        if ( c != null )
+        {
+            sw.append( name ).append( "[" ).append( getState( c ) ).append( "] " );
+        }
     }
 
     private CharSequence getState(org.apache.felix.scr.Component c)