You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ma...@apache.org on 2010/08/20 14:23:05 UTC

svn commit: r987474 - in /felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test: AspectBaseTest.java AspectDynamicsTest.java AspectTest.java ResourceAdapterTest.java

Author: marrs
Date: Fri Aug 20 12:23:05 2010
New Revision: 987474

URL: http://svn.apache.org/viewvc?rev=987474&view=rev
Log:
Extended the test suite for aspects, added a resource adapter test.

Added:
    felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectBaseTest.java   (with props)
    felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectDynamicsTest.java
      - copied, changed from r986634, felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectTest.java
    felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/ResourceAdapterTest.java
Removed:
    felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectTest.java

Added: felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectBaseTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectBaseTest.java?rev=987474&view=auto
==============================================================================
--- felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectBaseTest.java (added)
+++ felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectBaseTest.java Fri Aug 20 12:23:05 2010
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.dm.test;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.Service;
+import org.apache.felix.dm.ServiceUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+@RunWith(JUnit4TestRunner.class)
+public class AspectBaseTest extends Base {
+    @Configuration
+    public static Option[] configuration() {
+        return options(
+//            vmOption( "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005" ),
+//            waitForFrameworkStartupFor(Long.MAX_VALUE),
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject()
+            )
+        );
+    }
+    
+    @Test
+    public void testSingleAspect(BundleContext context) {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create a service provider and consumer
+        ServiceProvider p = new ServiceProvider(e, "a");
+        ServiceConsumer c = new ServiceConsumer(e);
+        Service sp = m.createService().setImplementation(p).setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "a"); }});
+        Service sc = m.createService().setImplementation(c).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true).setCallbacks("add", "remove").setAutoConfig(true));
+        Service sa = m.createAspectService(ServiceInterface.class, null, 20, null).setImplementation(ServiceAspect.class);
+        m.add(sc);
+        m.add(sp);
+        // after the provider was added, the consumer's add should have been invoked once
+        e.waitForStep(1, 2000);
+        Assert.assertEquals("a", c.invoke());
+        m.add(sa);
+        // after the aspect was added, the consumer should get and add for the aspect and a remove
+        // for the original service
+        e.waitForStep(3, 2000);
+        Assert.assertEquals("aa", c.invoke());
+        m.remove(sa);
+        // removing the aspect again should give a remove and add
+        e.waitForStep(5, 2000);
+        Assert.assertEquals("a", c.invoke());
+        m.remove(sp);
+        // finally removing the original service should give a remove
+        e.waitForStep(6, 2000);
+        m.remove(sc);
+        e.step(7);
+    }
+    
+    @Test
+    public void testSingleAspectThatAlreadyExisted(BundleContext context) {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create a service provider and consumer
+        ServiceProvider p = new ServiceProvider(e, "a");
+        ServiceConsumer c = new ServiceConsumer(e);
+        Service sp = m.createService().setImplementation(p).setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "a"); }});
+        Service sc = m.createService().setImplementation(c).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true).setCallbacks("add", "remove").setAutoConfig(true));
+        Service sa = m.createAspectService(ServiceInterface.class, null, 20, null).setImplementation(ServiceAspect.class);
+        // we first add the aspect
+        m.add(sa);
+        // then the service provider
+        m.add(sp);
+        // finally the consumer
+        m.add(sc);
+
+        Assert.assertEquals("aa", c.invoke());
+        
+        // now the consumer's added should be invoked once, as the aspect is already available and should
+        // directly hide the original service
+        e.waitForStep(1, 2000);
+        e.step(2);
+
+        m.remove(sa);
+        // after removing the aspect, the consumer should get the original service back, so
+        // remove and add will be invoked
+        e.waitForStep(4, 2000);
+        
+        m.remove(sp);
+        // after removing the original service, the consumer's remove should be called once
+        e.waitForStep(5, 2000);
+        
+        m.remove(sc);
+        e.step(6);
+    }
+
+    @Test
+    public void testMultipleAspects(BundleContext context) {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        
+        // create service providers and consumers
+        ServiceConsumer c = new ServiceConsumer(e);
+        Service sp = m.createService().setImplementation(new ServiceProvider(e, "a")).setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "a"); }});
+        Service sp2 = m.createService().setImplementation(new ServiceProvider(e, "b")).setInterface(ServiceInterface.class.getName(), new Properties() {{ put("name", "b"); }});
+        Service sc = m.createService().setImplementation(c).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true).setCallbacks("add", "remove"));
+        Service sa = m.createAspectService(ServiceInterface.class, null, 20, null).setImplementation(ServiceAspect.class);
+        Service sa2 = m.createAspectService(ServiceInterface.class, null, 10, null).setImplementation(ServiceAspect.class);
+        m.add(sp);
+        m.add(sp2);
+        m.add(sa);
+        m.add(sa2);
+        m.add(sc);
+        // the consumer will monitor progress, it should get it's add invoked twice, once for every
+        // (highest) aspect
+        e.waitForStep(2, 2000);
+        e.step(3);
+        
+        // now invoke all services the consumer collected
+        List<String> list = c.invokeAll();
+        // and make sure both of them are correctly invoked
+        Assert.assertTrue(list.size() == 2);
+        Assert.assertTrue(list.contains("aaa"));
+        Assert.assertTrue(list.contains("bbb"));
+        
+        m.remove(sc);
+        // removing the consumer now should get its removed method invoked twice
+        e.waitForStep(5, 2000);
+        e.step(6);
+        m.remove(sa2);
+        m.remove(sa);
+        m.remove(sp2);
+        m.remove(sp);
+        e.step(7);
+    }
+    
+    public static interface ServiceInterface {
+        public String invoke(String input);
+    }
+    
+    public static class ServiceProvider implements ServiceInterface {
+        private final Ensure m_ensure;
+        private final String m_name;
+        public ServiceProvider(Ensure e, String name) {
+            m_ensure = e;
+            m_name = name;
+        }
+        public String invoke(String input) {
+            return input + m_name;
+        }
+    }
+    
+    public static class ServiceAspect implements ServiceInterface {
+        private volatile ServiceInterface m_originalService;
+        private volatile ServiceRegistration m_registration;
+        
+        public String invoke(String input) {
+            String result = m_originalService.invoke(input);
+            String property = (String) m_registration.getReference().getProperty("name");
+            return result + property;
+        }
+    }
+
+    public static class ServiceConsumer {
+        private final Ensure m_ensure;
+        private volatile ServiceInterface m_service;
+        private List<ServiceInterface> m_services = new ArrayList<ServiceInterface>();
+
+        public ServiceConsumer(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void add(ServiceReference ref, ServiceInterface si) {
+            System.out.println("add: " + ServiceUtil.toString(ref));
+            m_services.add(si);
+            m_ensure.step();
+        }
+        
+        public void remove(ServiceReference ref, ServiceInterface si) {
+            System.out.println("rem: " + ServiceUtil.toString(ref));
+            m_services.remove(si);
+            m_ensure.step();
+        }
+        
+        public String invoke() {
+            return m_service.invoke("");
+        }
+        
+        public List<String> invokeAll() {
+            List<String> results = new ArrayList<String>();
+            for (ServiceInterface si : m_services) {
+                results.add(si.invoke(""));
+            }
+            return results;
+        }
+    }
+}

Propchange: felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectBaseTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectDynamicsTest.java (from r986634, felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectTest.java)
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectDynamicsTest.java?p2=felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectDynamicsTest.java&p1=felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectTest.java&r1=986634&r2=987474&rev=987474&view=diff
==============================================================================
--- felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectTest.java (original)
+++ felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/AspectDynamicsTest.java Fri Aug 20 12:23:05 2010
@@ -32,7 +32,7 @@ import org.ops4j.pax.exam.junit.JUnit4Te
 import org.osgi.framework.BundleContext;
 
 @RunWith(JUnit4TestRunner.class)
-public class AspectTest extends Base {
+public class AspectDynamicsTest extends Base {
     @Configuration
     public static Option[] configuration() {
         return options(

Added: felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/ResourceAdapterTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/ResourceAdapterTest.java?rev=987474&view=auto
==============================================================================
--- felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/ResourceAdapterTest.java (added)
+++ felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/ResourceAdapterTest.java Fri Aug 20 12:23:05 2010
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.dm.test;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ResourceHandler;
+import org.apache.felix.dm.ResourceUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+@RunWith(JUnit4TestRunner.class)
+public class ResourceAdapterTest extends Base {
+    @Configuration
+    public static Option[] configuration() {
+        return options(
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject()
+            )
+        );
+    }    
+
+    @Test
+    public void testBasicResourceAdapter(BundleContext context) throws Exception {
+        DependencyManager m = new DependencyManager(context);
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a resource provider
+        ResourceProvider provider = new ResourceProvider(e);
+        // activate it
+        m.add(m.createService().setImplementation(provider).add(m.createServiceDependency().setService(ResourceHandler.class).setCallbacks("add", "remove")));
+        // create a resource adapter for our single resource
+        // note that we can provide an actual implementation instance here because there will be only one
+        // adapter, normally you'd want to specify a Class here
+        m.add(m.createResourceAdapterService("(&(path=/path/to/*.txt)(host=localhost))", false, null, "changed")
+              .setImplementation(new ResourceAdapter(e)));
+        // wait until the single resource is available
+        e.waitForStep(3, 5000);
+        // trigger a 'change' in our resource
+        provider.change();
+        // wait until the changed callback is invoked
+        e.waitForStep(4, 5000);
+     }
+    
+    static class ResourceAdapter {
+        protected URL m_resource; // injected by reflection.
+        private Ensure m_ensure;
+        
+        ResourceAdapter(Ensure e) {
+            m_ensure = e;
+        }
+        
+        public void start() {
+            m_ensure.step(1);
+            Assert.assertNotNull("resource not injected", m_resource);
+            m_ensure.step(2);
+            try {
+                InputStream in = m_resource.openStream();
+            } 
+            catch (FileNotFoundException e) {
+                m_ensure.step(3);
+            }
+            catch (IOException e) {
+                Assert.fail("We should not have gotten this exception.");
+            }
+        }
+        
+        public void changed() {
+            m_ensure.step(4);
+        }
+    }
+    
+    static class ResourceProvider {
+        private volatile BundleContext m_context;
+        private final Ensure m_ensure;
+        private final Map m_handlers = new HashMap();
+        private URL[] m_resources;
+
+        public ResourceProvider(Ensure ensure) throws MalformedURLException {
+            m_ensure = ensure;
+            m_resources = new URL[] {
+                new URL("file://localhost/path/to/file1.txt")
+            };
+        }
+        
+        public void change() {
+            ResourceHandler[] handlers;
+            synchronized (m_handlers) {
+                handlers = (ResourceHandler[]) m_handlers.keySet().toArray(new ResourceHandler[m_handlers.size()]);
+            }
+            for (int i = 0; i < m_resources.length; i++) {
+                for (int j = 0; j < handlers.length; j++) {
+                    ResourceHandler handler = handlers[j];
+                    handler.changed(m_resources[i]);
+                }
+            }
+        }
+
+        public void add(ServiceReference ref, ResourceHandler handler) {
+            String filterString = (String) ref.getProperty("filter");
+            Filter filter = null;
+            if (filterString != null) {
+                try {
+                    filter = m_context.createFilter(filterString);
+                }
+                catch (InvalidSyntaxException e) {
+                    Assert.fail("Could not create filter for resource handler: " + e);
+                    return;
+                }
+            }
+            synchronized (m_handlers) {
+                m_handlers.put(handler, filter);
+            }
+            for (int i = 0; i < m_resources.length; i++) {
+                if (filter == null || filter.match(ResourceUtil.createProperties(m_resources[i]))) {
+                    handler.added(m_resources[i]);
+                }
+            }
+        }
+
+        public void remove(ServiceReference ref, ResourceHandler handler) {
+            Filter filter;
+            synchronized (m_handlers) {
+                filter = (Filter) m_handlers.remove(handler);
+            }
+            removeResources(handler, filter);
+        }
+
+        private void removeResources(ResourceHandler handler, Filter filter) {
+                for (int i = 0; i < m_resources.length; i++) {
+                    if (filter == null || filter.match(ResourceUtil.createProperties(m_resources[i]))) {
+                        handler.removed(m_resources[i]);
+                    }
+                }
+            }
+
+        public void destroy() {
+            Entry[] handlers;
+            synchronized (m_handlers) {
+                handlers = (Entry[]) m_handlers.entrySet().toArray(new Entry[m_handlers.size()]);
+            }
+            for (int i = 0; i < handlers.length; i++) {
+                removeResources((ResourceHandler) handlers[i].getKey(), (Filter) handlers[i].getValue());
+            }
+            
+            System.out.println("DESTROY..." + m_handlers.size());
+        }
+    }
+}