blob: 9d1025e92b98bd8f504f4c09110feef406f25a67 [file] [log] [blame]
/*
* 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.cm.integration;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import junit.framework.TestCase;
import org.apache.felix.cm.integration.helper.ManagedServiceFactoryTestActivator;
import org.apache.felix.cm.integration.helper.ManagedServiceTestActivator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
@RunWith(JUnit4TestRunner.class)
public class ConfigurationBaseTest extends ConfigurationTestBase
{
static
{
// uncomment to enable debugging of this test class
// paxRunnerVmOption = DEBUG_VM_OPTION;
}
@Test
public void test_configuration_getFacotryPid_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.getFactoryPid();
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_equals_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.equals( config );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_hashCode_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.hashCode();
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_toString_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.toString();
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
public void test_configuration_getPid_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.getPid();
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_getProperties_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.getProperties();
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_delete_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.delete();
TestCase.fail( "Expected IllegalStateException for config.delete" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for config.delete" );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_getBundleLocation_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.getBundleLocation();
TestCase.fail( "Expected IllegalStateException for config.getBundleLocation" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for config.getBundleLocation" );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_setBundleLocation_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.setBundleLocation( "?*" );
TestCase.fail( "Expected IllegalStateException for config.setBundleLocation" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for config.setBundleLocation" );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_update_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.update();
TestCase.fail( "Expected IllegalStateException for config.update" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for config.update" );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@SuppressWarnings("serial")
@Test
public void test_configuration_update_with_Dictionary_after_config_admin_stop() throws BundleException
{
final String pid = "test_configuration_after_config_admin_stop";
final Configuration config = configure( pid, null, true );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
config.update( new Hashtable<String, Object>()
{
{
put( "sample", "sample" );
}
} );
TestCase.fail( "Expected IllegalStateException for config.update" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for config.update" );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_admin_createFactoryConfiguration_1_after_config_admin_stop() throws BundleException
{
final ConfigurationAdmin ca = getConfigurationAdmin();
TestCase.assertNotNull( "ConfigurationAdmin service is required", ca );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
ca.createFactoryConfiguration( "sample" );
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.createFactoryConfiguration" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.createFactoryConfiguration, got: " + e );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_admin_createFactoryConfiguration_2_after_config_admin_stop() throws BundleException
{
final ConfigurationAdmin ca = getConfigurationAdmin();
TestCase.assertNotNull( "ConfigurationAdmin service is required", ca );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
ca.createFactoryConfiguration( "sample", "location" );
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.createFactoryConfiguration" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.createFactoryConfiguration, got: " + e );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_admin_getConfiguration_1_after_config_admin_stop() throws BundleException
{
final ConfigurationAdmin ca = getConfigurationAdmin();
TestCase.assertNotNull( "ConfigurationAdmin service is required", ca );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
ca.getConfiguration( "sample" );
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.getConfiguration" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.getConfiguration, got: " + e );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_admin_getConfiguration_2_after_config_admin_stop() throws BundleException
{
final ConfigurationAdmin ca = getConfigurationAdmin();
TestCase.assertNotNull( "ConfigurationAdmin service is required", ca );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
ca.getConfiguration( "sample", "location" );
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.getConfiguration" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.getConfiguration, got: " + e );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_admin_listConfigurations_after_config_admin_stop() throws BundleException
{
final ConfigurationAdmin ca = getConfigurationAdmin();
TestCase.assertNotNull( "ConfigurationAdmin service is required", ca );
final Bundle cfgAdminBundle = configAdminTracker.getServiceReference().getBundle();
cfgAdminBundle.stop();
try
{
ca.listConfigurations( "(service.pid=sample)" );
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.listConfigurations" );
}
catch ( IllegalStateException ise )
{
// expected
}
catch ( Exception e )
{
TestCase.fail( "Expected IllegalStateException for ConfigurationAdmin.listConfigurations, got: " + e );
}
finally
{
try
{
cfgAdminBundle.start();
}
catch ( BundleException be )
{
// tooo bad
}
}
}
@Test
public void test_configuration_change_counter() throws IOException
{
// 1. create config with pid and locationA
// 2. update config with properties
final String pid = "test_configuration_change_counter";
final Configuration config = configure( pid, null, false );
TestCase.assertEquals("Expect first version to be 1", 1, config.getChangeCount());
config.update(new Hashtable(){{put("x", "x");}});
TestCase.assertEquals("Expect second version to be 2", 2, config.getChangeCount());
// delete
config.delete();
}
@Test
public void test_basic_configuration_configure_then_start() throws BundleException, IOException
{
// 1. create config with pid and locationA
// 2. update config with properties
final String pid = "test_basic_configuration_configure_then_start";
final Configuration config = configure( pid, null, true );
// 3. register ManagedService ms1 with pid from said locationA
bundle = installBundle( pid, ManagedServiceTestActivator.class );
bundle.start();
delay();
// ==> configuration supplied to the service ms1
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( tester.props );
TestCase.assertEquals( pid, tester.props.get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.props.get( PROP_NAME ) );
TestCase.assertEquals( 1, tester.numManagedServiceUpdatedCalls );
// delete
config.delete();
delay();
// ==> update with null
TestCase.assertNull( tester.props );
TestCase.assertEquals( 2, tester.numManagedServiceUpdatedCalls );
}
@Test
public void test_basic_configuration_strange_pid() throws BundleException, IOException
{
// 1. create config with pid and locationA
// 2. update config with properties
final String pid = "pid with blanks and stuff %\"'";
theConfig.put( pid, pid );
final Configuration config = configure( pid, null, true );
theConfig.remove( pid );
// 3. register ManagedService ms1 with pid from said locationA
bundle = installBundle( pid, ManagedServiceTestActivator.class );
bundle.start();
delay();
// ==> configuration supplied to the service ms1
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( tester.props );
TestCase.assertEquals( pid, tester.props.get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.props.get( PROP_NAME ) );
TestCase.assertEquals( pid, tester.props.get( pid ) );
TestCase.assertEquals( 1, tester.numManagedServiceUpdatedCalls );
// delete
config.delete();
delay();
// ==> update with null
TestCase.assertNull( tester.props );
TestCase.assertEquals( 2, tester.numManagedServiceUpdatedCalls );
}
@Test
public void test_basic_configuration_start_then_configure() throws BundleException, IOException
{
final String pid = "test_basic_configuration_start_then_configure";
// 1. register ManagedService ms1 with pid from said locationA
bundle = installBundle( pid, ManagedServiceTestActivator.class );
bundle.start();
delay();
// 1. create config with pid and locationA
// 2. update config with properties
final Configuration config = configure( pid, null, true );
delay();
// ==> configuration supplied to the service ms1
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( tester.props );
TestCase.assertEquals( pid, tester.props.get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.props.get( PROP_NAME ) );
TestCase.assertEquals( 2, tester.numManagedServiceUpdatedCalls );
// delete
config.delete();
delay();
// ==> update with null
TestCase.assertNull( tester.props );
TestCase.assertEquals( 3, tester.numManagedServiceUpdatedCalls );
}
@Test
public void test_basic_configuration_factory_start_then_configure() throws BundleException, IOException
{
final String factoryPid = "test_basic_configuration_factory_configure_then_start";
bundle = installBundle( factoryPid, ManagedServiceFactoryTestActivator.class );
bundle.start();
delay();
final Configuration config = createFactoryConfiguration( factoryPid, null, true );
final String pid = config.getPid();
delay();
// ==> configuration supplied to the service ms1
final ManagedServiceFactoryTestActivator tester = ManagedServiceFactoryTestActivator.INSTANCE;
Dictionary<?, ?> props = tester.configs.get( pid );
TestCase.assertNotNull( props );
TestCase.assertEquals( pid, props.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid, props.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props.get( PROP_NAME ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 0, tester.numManagedServiceFactoryDeleteCalls );
// delete
config.delete();
delay();
// ==> update with null
TestCase.assertNull( tester.configs.get( pid ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryDeleteCalls );
}
@Test
public void test_basic_configuration_factory_configure_then_start() throws BundleException, IOException
{
// 1. create config with pid and locationA
// 2. update config with properties
final String factoryPid = "test_basic_configuration_factory_start_then_configure";
final Configuration config = createFactoryConfiguration( factoryPid, null, true );
final String pid = config.getPid();
delay();
// 3. register ManagedService ms1 with pid from said locationA
bundle = installBundle( factoryPid, ManagedServiceFactoryTestActivator.class );
bundle.start();
delay();
// ==> configuration supplied to the service ms1
final ManagedServiceFactoryTestActivator tester = ManagedServiceFactoryTestActivator.INSTANCE;
Dictionary<?, ?> props = tester.configs.get( pid );
TestCase.assertNotNull( props );
TestCase.assertEquals( pid, props.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid, props.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props.get( PROP_NAME ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 0, tester.numManagedServiceFactoryDeleteCalls );
// delete
config.delete();
delay();
// ==> update with null
TestCase.assertNull( tester.configs.get( pid ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryDeleteCalls );
}
@Test
public void test_start_bundle_configure_stop_start_bundle() throws BundleException
{
String pid = "test_start_bundle_configure_stop_start_bundle";
// start the bundle and assert this
bundle = installBundle( pid );
bundle.start();
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( "Activator not started !!", tester );
// give cm time for distribution
delay();
// assert activater has no configuration
TestCase.assertNull( "Expect no Properties after Service Registration", tester.props );
TestCase.assertEquals( "Expect update call", 1, tester.numManagedServiceUpdatedCalls );
// configure after ManagedServiceRegistration --> configure via update
configure( pid );
delay();
// assert activater has configuration
TestCase.assertNotNull( "Expect Properties after Service Registration", tester.props );
TestCase.assertEquals( "Expect a second update call", 2, tester.numManagedServiceUpdatedCalls );
// stop the bundle now
bundle.stop();
// assert INSTANCE is null
TestCase.assertNull( ManagedServiceTestActivator.INSTANCE );
delay();
// start the bundle again (and check)
bundle.start();
final ManagedServiceTestActivator tester2 = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( "Activator not started the second time!!", tester2 );
TestCase.assertNotSame( "Instances must not be the same", tester, tester2 );
// give cm time for distribution
delay();
// assert activater has configuration
TestCase.assertNotNull( "Expect Properties after Service Registration", tester2.props );
TestCase.assertEquals( "Expect a second update call", 1, tester2.numManagedServiceUpdatedCalls );
// cleanup
bundle.uninstall();
bundle = null;
// remove the configuration for good
deleteConfig( pid );
}
@Test
public void test_configure_start_bundle_stop_start_bundle() throws BundleException
{
String pid = "test_configure_start_bundle_stop_start_bundle";
configure( pid );
// start the bundle and assert this
bundle = installBundle( pid );
bundle.start();
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( "Activator not started !!", tester );
// give cm time for distribution
delay();
// assert activater has configuration
TestCase.assertNotNull( "Expect Properties after Service Registration", tester.props );
TestCase.assertEquals( "Expect no update call", 1, tester.numManagedServiceUpdatedCalls );
// stop the bundle now
bundle.stop();
// assert INSTANCE is null
TestCase.assertNull( ManagedServiceTestActivator.INSTANCE );
delay();
// start the bundle again (and check)
bundle.start();
final ManagedServiceTestActivator tester2 = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( "Activator not started the second time!!", tester2 );
TestCase.assertNotSame( "Instances must not be the same", tester, tester2 );
// give cm time for distribution
delay();
// assert activater has configuration
TestCase.assertNotNull( "Expect Properties after Service Registration", tester2.props );
TestCase.assertEquals( "Expect a second update call", 1, tester2.numManagedServiceUpdatedCalls );
// cleanup
bundle.uninstall();
bundle = null;
// remove the configuration for good
deleteConfig( pid );
}
@Test
public void test_listConfiguration() throws BundleException, IOException
{
// 1. create a new Conf1 with pid1 and null location.
// 2. Conf1#update(props) is called.
final String pid = "test_listConfiguration";
final Configuration config = configure( pid, null, true );
// 3. bundleA will locationA registers ManagedServiceA with pid1.
bundle = installBundle( pid );
bundle.start();
delay();
// ==> ManagedServiceA is called back.
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( tester );
TestCase.assertNotNull( tester.props );
TestCase.assertEquals( 1, tester.numManagedServiceUpdatedCalls );
// 4. bundleA is stopped but *NOT uninstalled*.
bundle.stop();
delay();
// 5. test bundle calls cm.listConfigurations(null).
final Configuration listed = getConfiguration( pid );
// ==> Conf1 is included in the returned list and
// it has locationA.
// (In debug mode, dynamicBundleLocation==locationA
// and staticBundleLocation==null)
TestCase.assertNotNull( listed );
TestCase.assertEquals( bundle.getLocation(), listed.getBundleLocation() );
// 6. test bundle calls cm.getConfiguration(pid1)
final Configuration get = getConfigurationAdmin().getConfiguration( pid );
TestCase.assertEquals( bundle.getLocation(), get.getBundleLocation() );
final Bundle cmBundle = getCmBundle();
cmBundle.stop();
delay();
cmBundle.start();
delay();
// 5. test bundle calls cm.listConfigurations(null).
final Configuration listed2 = getConfiguration( pid );
// ==> Conf1 is included in the returned list and
// it has locationA.
// (In debug mode, dynamicBundleLocation==locationA
// and staticBundleLocation==null)
TestCase.assertNotNull( listed2 );
TestCase.assertEquals( bundle.getLocation(), listed2.getBundleLocation() );
// 6. test bundle calls cm.getConfiguration(pid1)
final Configuration get2 = getConfigurationAdmin().getConfiguration( pid );
TestCase.assertEquals( bundle.getLocation(), get2.getBundleLocation() );
}
@Test
public void test_ManagedService_change_pid() throws BundleException, IOException
{
final String pid0 = "test_ManagedService_change_pid_0";
final String pid1 = "test_ManagedService_change_pid_1";
final Configuration config0 = configure( pid0, null, true );
final Configuration config1 = configure( pid1, null, true );
delay();
// register ManagedService ms1 with pid from said locationA
bundle = installBundle( pid0, ManagedServiceTestActivator.class );
bundle.start();
delay();
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( tester.props );
TestCase.assertEquals( pid0, tester.props.get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.props.get( PROP_NAME ) );
TestCase.assertEquals( 1, tester.numManagedServiceUpdatedCalls );
// change ManagedService PID
tester.changePid( pid1 );
delay();
TestCase.assertNotNull( tester.props );
TestCase.assertEquals( pid1, tester.props.get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.props.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.props.get( PROP_NAME ) );
TestCase.assertEquals( 2, tester.numManagedServiceUpdatedCalls );
// delete
config0.delete();
config1.delete();
delay();
// ==> update with null
TestCase.assertNull( tester.props );
TestCase.assertEquals( 3, tester.numManagedServiceUpdatedCalls );
}
@Test
public void test_ManagedService_change_pid_overlap() throws BundleException, IOException
{
final String pid0 = "test_ManagedService_change_pid_0";
final String pid1 = "test_ManagedService_change_pid_1";
final String pid2 = "test_ManagedService_change_pid_2";
final Configuration config0 = configure( pid0, null, true );
final Configuration config1 = configure( pid1, null, true );
final Configuration config2 = configure( pid2, null, true );
delay();
// register ManagedService ms1 with pid from said locationA
bundle = installBundle( pid0 + "," + pid1, ManagedServiceTestActivator.class );
bundle.start();
delay();
final ManagedServiceTestActivator tester = ManagedServiceTestActivator.INSTANCE;
TestCase.assertNotNull( tester.props );
TestCase.assertEquals( pid0, tester.configs.get( pid0 ).get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.configs.get( pid0 ).get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.configs.get( pid0 ).get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.configs.get( pid0 ).get( PROP_NAME ) );
TestCase.assertEquals( pid1, tester.configs.get( pid1 ).get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.configs.get( pid1 ).get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.configs.get( pid1 ).get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.configs.get( pid1 ).get( PROP_NAME ) );
// two pids, two calls
TestCase.assertEquals( 2, tester.numManagedServiceUpdatedCalls );
// change ManagedService PID
tester.changePid( pid1 + "," + pid2 );
delay();
TestCase.assertNotNull( tester.props );
// config pid0 is not "removed"
TestCase.assertEquals( pid0, tester.configs.get( pid0 ).get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.configs.get( pid0 ).get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.configs.get( pid0 ).get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.configs.get( pid0 ).get( PROP_NAME ) );
// config pid1 is retained
TestCase.assertEquals( pid1, tester.configs.get( pid1 ).get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.configs.get( pid1 ).get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.configs.get( pid1 ).get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.configs.get( pid1 ).get( PROP_NAME ) );
// config pid2 is added
TestCase.assertEquals( pid2, tester.configs.get( pid2 ).get( Constants.SERVICE_PID ) );
TestCase.assertNull( tester.configs.get( pid2 ).get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( tester.configs.get( pid2 ).get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, tester.configs.get( pid2 ).get( PROP_NAME ) );
// one "additional" pid, one additional call
TestCase.assertEquals( 3, tester.numManagedServiceUpdatedCalls );
// delete
config0.delete(); // ignored by MS
config1.delete();
config2.delete();
delay();
// ==> update with null
TestCase.assertNull( tester.props );
// two pids removed, two calls
TestCase.assertEquals( 5, tester.numManagedServiceUpdatedCalls );
}
@Test
public void test_ManagedServiceFactory_change_pid() throws BundleException, IOException
{
final String factoryPid0 = "test_ManagedServiceFactory_change_pid_0";
final String factoryPid1 = "test_ManagedServiceFactory_change_pid_1";
final Configuration config0 = createFactoryConfiguration( factoryPid0, null, true );
final String pid0 = config0.getPid();
final Configuration config1 = createFactoryConfiguration( factoryPid1, null, true );
final String pid1 = config1.getPid();
delay();
bundle = installBundle( factoryPid0, ManagedServiceFactoryTestActivator.class );
bundle.start();
delay();
// pid0 properties provided on registration
final ManagedServiceFactoryTestActivator tester = ManagedServiceFactoryTestActivator.INSTANCE;
Dictionary<?, ?> props0 = tester.configs.get( pid0 );
TestCase.assertNotNull( props0 );
TestCase.assertEquals( pid0, props0.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid0, props0.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props0.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props0.get( PROP_NAME ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 0, tester.numManagedServiceFactoryDeleteCalls );
// change ManagedService PID
tester.changePid( factoryPid1 );
delay();
// pid1 properties must have been added
Dictionary<?, ?> props1 = tester.configs.get( pid1 );
TestCase.assertNotNull( props1 );
TestCase.assertEquals( pid1, props1.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid1, props1.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props1.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props1.get( PROP_NAME ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 2, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 0, tester.numManagedServiceFactoryDeleteCalls );
// pid0 properties must still exist !
Dictionary<?, ?> props01 = tester.configs.get( pid0 );
TestCase.assertNotNull( props01 );
TestCase.assertEquals( pid0, props01.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid0, props01.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props01.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props01.get( PROP_NAME ) );
// delete
config0.delete();
config1.delete();
delay();
// only pid1 properties removed because pid0 is not registered any longer
TestCase.assertNotNull( tester.configs.get( pid0 ) );
TestCase.assertNull( tester.configs.get( pid1 ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 2, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 1, tester.numManagedServiceFactoryDeleteCalls );
}
@Test
public void test_ManagedServiceFactory_change_pid_overlap() throws BundleException, IOException
{
final String factoryPid0 = "test_ManagedServiceFactory_change_pid_0";
final String factoryPid1 = "test_ManagedServiceFactory_change_pid_1";
final String factoryPid2 = "test_ManagedServiceFactory_change_pid_2";
final Configuration config0 = createFactoryConfiguration( factoryPid0, null, true );
final String pid0 = config0.getPid();
final Configuration config1 = createFactoryConfiguration( factoryPid1, null, true );
final String pid1 = config1.getPid();
final Configuration config2 = createFactoryConfiguration( factoryPid2, null, true );
final String pid2 = config2.getPid();
delay();
bundle = installBundle( factoryPid0 + "," + factoryPid1, ManagedServiceFactoryTestActivator.class );
bundle.start();
delay();
// pid0 properties provided on registration
final ManagedServiceFactoryTestActivator tester = ManagedServiceFactoryTestActivator.INSTANCE;
Dictionary<?, ?> props0 = tester.configs.get( pid0 );
TestCase.assertNotNull( props0 );
TestCase.assertEquals( pid0, props0.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid0, props0.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props0.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props0.get( PROP_NAME ) );
Dictionary<?, ?> props1 = tester.configs.get( pid1 );
TestCase.assertNotNull( props1 );
TestCase.assertEquals( pid1, props1.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid1, props1.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props1.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props1.get( PROP_NAME ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 2, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 0, tester.numManagedServiceFactoryDeleteCalls );
// change ManagedService PID
tester.changePid( factoryPid1 + "," + factoryPid2 );
delay();
// pid2 properties must have been added
Dictionary<?, ?> props2 = tester.configs.get( pid2 );
TestCase.assertNotNull( props2 );
TestCase.assertEquals( pid2, props2.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid2, props2.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props2.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props2.get( PROP_NAME ) );
// pid0 properties must still exist !
Dictionary<?, ?> props01 = tester.configs.get( pid0 );
TestCase.assertNotNull( props01 );
TestCase.assertEquals( pid0, props01.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid0, props01.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props01.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props01.get( PROP_NAME ) );
// pid1 properties must still exist !
Dictionary<?, ?> props11 = tester.configs.get( pid1 );
TestCase.assertNotNull( props11 );
TestCase.assertEquals( pid1, props11.get( Constants.SERVICE_PID ) );
TestCase.assertEquals( factoryPid1, props11.get( ConfigurationAdmin.SERVICE_FACTORYPID ) );
TestCase.assertNull( props11.get( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) );
TestCase.assertEquals( PROP_NAME, props11.get( PROP_NAME ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 3, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 0, tester.numManagedServiceFactoryDeleteCalls );
// delete
config0.delete();
config1.delete();
config2.delete();
delay();
// only pid1 and pid2 properties removed because pid0 is not registered any longer
TestCase.assertNotNull( tester.configs.get( pid0 ) );
TestCase.assertNull( tester.configs.get( pid1 ) );
TestCase.assertNull( tester.configs.get( pid2 ) );
TestCase.assertEquals( 0, tester.numManagedServiceUpdatedCalls );
TestCase.assertEquals( 3, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( 2, tester.numManagedServiceFactoryDeleteCalls );
}
@Test
public void test_factory_configuration_collision() throws IOException, InvalidSyntaxException, BundleException {
final String factoryPid = "test_factory_configuration_collision";
final Configuration cf = getConfigurationAdmin().createFactoryConfiguration( factoryPid, null );
TestCase.assertNotNull( cf );
final String pid = cf.getPid();
// check factory configuration setup
TestCase.assertNotNull( "Configuration must have PID", pid );
TestCase.assertEquals( "Factory configuration must have requested factory PID", factoryPid, cf.getFactoryPid() );
try
{
bundle = installBundle( factoryPid, ManagedServiceFactoryTestActivator.class );
bundle.start();
delay();
final ManagedServiceFactoryTestActivator tester = ManagedServiceFactoryTestActivator.INSTANCE;
TestCase.assertEquals( "MSF must not be updated with new configuration", 0, tester.numManagedServiceFactoryUpdatedCalls );
// assert getConfiguration returns the same configurtion
final Configuration c1 = getConfigurationAdmin().getConfiguration( pid, null );
TestCase.assertEquals( "getConfiguration must retrieve required PID", pid, c1.getPid() );
TestCase.assertEquals( "getConfiguration must retrieve new factory configuration", factoryPid, c1.getFactoryPid() );
TestCase.assertNull( "Configuration must not have properties", c1.getProperties() );
TestCase.assertEquals( "MSF must not be updated with new configuration", 0, tester.numManagedServiceFactoryUpdatedCalls );
// restart config admin and verify getConfiguration persisted
// the new factory configuration as such
final Bundle cmBundle = getCmBundle();
TestCase.assertNotNull( "Config Admin Bundle missing", cmBundle );
cmBundle.stop();
delay();
cmBundle.start();
delay();
TestCase.assertEquals( "MSF must not be updated with new configuration even after CM restart", 0, tester.numManagedServiceFactoryUpdatedCalls );
final Configuration c2 = getConfigurationAdmin().getConfiguration( pid, null );
TestCase.assertEquals( "getConfiguration must retrieve required PID", pid, c2.getPid() );
TestCase.assertEquals( "getConfiguration must retrieve new factory configuration from persistence", factoryPid, c2.getFactoryPid() );
TestCase.assertNull( "Configuration must not have properties", c2.getProperties() );
c2.update( theConfig );
delay();
TestCase.assertEquals( 1, tester.numManagedServiceFactoryUpdatedCalls );
TestCase.assertEquals( theConfig.get( PROP_NAME ), tester.configs.get( cf.getPid() ).get( PROP_NAME ) );
final Configuration[] cfs = getConfigurationAdmin().listConfigurations( "(" + ConfigurationAdmin.SERVICE_FACTORYPID + "="
+ factoryPid + ")" );
TestCase.assertNotNull( "Expect at least one configuration", cfs );
TestCase.assertEquals( "Expect exactly one configuration", 1, cfs.length );
TestCase.assertEquals( cf.getPid(), cfs[0].getPid() );
TestCase.assertEquals( cf.getFactoryPid(), cfs[0].getFactoryPid() );
}
finally
{
// make sure no configuration survives ...
getConfigurationAdmin().getConfiguration( pid, null ).delete();
}
}
@Test
public void test_collection_property_order() throws IOException, BundleException
{
final String pid = "test_collection_property_order";
final String[] value = new String[]
{ "a", "b", "c" };
final Bundle cmBundle = getCmBundle();
try
{
final Vector v = new Vector( Arrays.asList( value ) );
getConfigurationAdmin().getConfiguration( pid ).update( new Hashtable()
{
{
put( "v", v );
}
} );
assertOrder( value, getConfigurationAdmin().getConfiguration( pid ).getProperties().get( "v" ) );
cmBundle.stop();
cmBundle.start();
assertOrder( value, getConfigurationAdmin().getConfiguration( pid ).getProperties().get( "v" ) );
getConfigurationAdmin().getConfiguration( pid, null ).delete();
final List l = Arrays.asList( value );
getConfigurationAdmin().getConfiguration( pid ).update( new Hashtable()
{
{
put( "v", l );
}
} );
assertOrder( value, getConfigurationAdmin().getConfiguration( pid ).getProperties().get( "v" ) );
cmBundle.stop();
cmBundle.start();
assertOrder( value, getConfigurationAdmin().getConfiguration( pid ).getProperties().get( "v" ) );
getConfigurationAdmin().getConfiguration( pid, null ).delete();
}
finally
{
// make sure no configuration survives ...
getConfigurationAdmin().getConfiguration( pid, null ).delete();
}
}
private void assertOrder( final String[] expected, final Object actual )
{
TestCase.assertTrue( "Actual value must be a collection", actual instanceof Collection );
TestCase.assertEquals( "Collection must have " + expected.length + " entries", expected.length,
( ( Collection ) actual ).size() );
final Iterator actualI = ( ( Collection ) actual ).iterator();
for ( int i = 0; i < expected.length; i++ )
{
String string = expected[i];
TestCase.assertEquals( i + "th element must be " + string, string, actualI.next() );
}
}
}