You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by gn...@apache.org on 2017/03/10 17:22:28 UTC
svn commit: r1786394 - in /felix/branches/scr-1.8.x: pom.xml
src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
src/test/java/org/apache/felix/scr/impl/ConfigurationSupportFactoryPidsAndLocationUpdatesTest.java
Author: gnodet
Date: Fri Mar 10 17:22:28 2017
New Revision: 1786394
URL: http://svn.apache.org/viewvc?rev=1786394&view=rev
Log:
FELIX-5576 - added unit test and modified visibility of some elements in ConfigurationSupport
Added:
felix/branches/scr-1.8.x/src/test/java/org/apache/felix/scr/impl/ConfigurationSupportFactoryPidsAndLocationUpdatesTest.java
Modified:
felix/branches/scr-1.8.x/pom.xml
felix/branches/scr-1.8.x/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
Modified: felix/branches/scr-1.8.x/pom.xml
URL: http://svn.apache.org/viewvc/felix/branches/scr-1.8.x/pom.xml?rev=1786394&r1=1786393&r2=1786394&view=diff
==============================================================================
--- felix/branches/scr-1.8.x/pom.xml (original)
+++ felix/branches/scr-1.8.x/pom.xml Fri Mar 10 17:22:28 2017
@@ -220,12 +220,18 @@
<version>1.0.0</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>animal-sniffer-annotations</artifactId>
- <version>1.9</version>
- <scope>compile</scope>
- </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-annotations</artifactId>
+ <version>1.9</version>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
<build>
<directory>${bundle.build.name}</directory>
Modified: felix/branches/scr-1.8.x/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
URL: http://svn.apache.org/viewvc/felix/branches/scr-1.8.x/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java?rev=1786394&r1=1786393&r2=1786394&view=diff
==============================================================================
--- felix/branches/scr-1.8.x/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java (original)
+++ felix/branches/scr-1.8.x/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java Fri Mar 10 17:22:28 2017
@@ -395,7 +395,7 @@ public class ConfigurationSupport implem
}
- private static class ConfigurationInfo
+ protected static class ConfigurationInfo
{
private final Dictionary<String, Object> props;
private final String bundleLocation;
@@ -440,7 +440,7 @@ public class ConfigurationSupport implem
* @param bundleContext BundleContext to get the CA from
* @return ConfigurationInfo object containing the info we need from the configuration.
*/
- private ConfigurationInfo getConfigurationInfo(final TargetedPID pid, ComponentHolder componentHolder,
+ protected ConfigurationInfo getConfigurationInfo(final TargetedPID pid, ComponentHolder componentHolder,
final BundleContext bundleContext)
{
final ServiceReference caRef = bundleContext
Added: felix/branches/scr-1.8.x/src/test/java/org/apache/felix/scr/impl/ConfigurationSupportFactoryPidsAndLocationUpdatesTest.java
URL: http://svn.apache.org/viewvc/felix/branches/scr-1.8.x/src/test/java/org/apache/felix/scr/impl/ConfigurationSupportFactoryPidsAndLocationUpdatesTest.java?rev=1786394&view=auto
==============================================================================
--- felix/branches/scr-1.8.x/src/test/java/org/apache/felix/scr/impl/ConfigurationSupportFactoryPidsAndLocationUpdatesTest.java (added)
+++ felix/branches/scr-1.8.x/src/test/java/org/apache/felix/scr/impl/ConfigurationSupportFactoryPidsAndLocationUpdatesTest.java Fri Mar 10 17:22:28 2017
@@ -0,0 +1,152 @@
+/*
+ * 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.scr.impl;
+
+import junit.framework.TestCase;
+import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.config.ConfigurableComponentHolder;
+import org.apache.felix.scr.impl.config.ConfigurationSupport;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.mockito.Mockito;
+import org.mockito.exceptions.base.MockitoAssertionError;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.ConfigurationEvent;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import static org.mockito.Mockito.*;
+
+public class ConfigurationSupportFactoryPidsAndLocationUpdatesTest extends TestCase
+{
+
+ public static final String FACTORY_PID_X = "io.fabric8.gateway.http.mapping";
+ public static final String PID = "io.fabric8.gateway.http.mapping.68a728ef-7dab-4381-9e63-9c69e128f79a";
+
+
+ /**
+ * This test represents a race condition depending on events ordering that can happen at runtime.
+ * A CM_LOCATION_CHANGED event can risk to update the component registry with the wrong pid, with the effect that
+ * subsequent CM_UPDATE event will be discarded since not matching the pid.
+ *
+ * This test simulates this interaction:
+ * - verifies that an UPDATE event correctly triggers an update operation
+ * - forges a LOCATION_UPDATE event
+ * - verifies that after that even, a subsequent UPDATE event still triggers the update operation.
+ *
+ * https://issues.apache.org/jira/browse/FELIX-5576
+ */
+ public void testFactoryPids()
+ {
+ BundleContext bundleContext = Mockito.mock(BundleContext.class);
+ Bundle bundle = mock(Bundle.class);
+ when(bundleContext.getBundle()).thenReturn(bundle);
+
+ ComponentRegistry componentRegistry = new ComponentRegistry(bundleContext);
+
+ ComponentMetadata metadata = mock(ComponentMetadata.class);
+ BundleComponentActivator activator = mock(BundleComponentActivator.class);
+ ComponentHolder holder = spy(new ConfigurableComponentHolder(activator, metadata));
+
+ when(metadata.getConfigurationPid()).thenReturn(PID);
+ when(metadata.isConfigurationIgnored()).thenReturn(false);
+
+ when(activator.getBundleContext()).thenReturn(bundleContext);
+
+ componentRegistry.registerComponentHolder(key(1, "bundle1"), holder);
+
+ when(bundleContext.registerService(any(String[].class), any(), any(Dictionary.class))).thenReturn(null);
+ //wrong visibility for ConfigurationSupport::getConfigurationInfo, I have to subclass to re-expose
+ ConfigurationSupport support = spy(new ConfigurationSupport(bundleContext, componentRegistry){
+ ConfigurationInfo configurationInfo;
+ @Override
+ public ConfigurationInfo getConfigurationInfo(final TargetedPID pid, ComponentHolder componentHolder,
+ final BundleContext bundleContext){
+ if(this.configurationInfo == null){
+ ConfigurationInfo configurationInfo = mock(ConfigurationInfo.class);
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ when(configurationInfo.getProps()).thenReturn(props);
+ this.configurationInfo = configurationInfo;
+ }
+
+ return configurationInfo;
+ }
+
+ });
+
+
+ ConfigurationEvent event = null;
+
+ event = mockAnEvent(ConfigurationEvent.CM_UPDATED);
+
+ // this represents the race condition
+ doReturn(null).when(holder).getConfigurationTargetedPID(any(TargetedPID.class));
+
+ //emit event
+ support.configurationEvent(event);
+
+ verify(holder, times(1)).configurationUpdated(any(String.class), any(Dictionary.class), anyLong(), any(TargetedPID.class));
+
+ event = mockAnEvent(ConfigurationEvent.CM_LOCATION_CHANGED);
+
+ //emit event
+ support.configurationEvent(event);
+
+ // here we are removing the subbed call for the value seen during race conditions
+ Mockito.reset(holder);
+
+ event = mockAnEvent(ConfigurationEvent.CM_UPDATED);
+
+ //emit event
+ support.configurationEvent(event);
+
+
+ try {
+ verify(holder, times(1)).configurationUpdated(any(String.class), any(Dictionary.class), anyLong(), any(TargetedPID.class));
+ } catch (MockitoAssertionError e) {
+ MockitoAssertionError err = new MockitoAssertionError("Was expecting a call to holder.configurationUpdated().");
+ err.initCause(e);
+ throw err;
+ }
+
+ }
+
+ protected ConfigurationEvent mockAnEvent(int eventType) {
+ ConfigurationEvent event;
+ event = mock(ConfigurationEvent.class);
+ when(event.getPid()).thenReturn(FACTORY_PID_X);
+ when(event.getFactoryPid()).thenReturn(PID);
+ when(event.getType()).thenReturn(eventType);
+ return event;
+ }
+
+ private static ComponentRegistryKey key( final long bundleId, final String name )
+ {
+ return new ComponentRegistryKey( new MockBundle()
+ {
+ // @Override
+ public long getBundleId()
+ {
+ return bundleId;
+ }
+ }, name );
+ }
+
+}
\ No newline at end of file