/*
 * 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.ArrayList;
import java.util.Dictionary;

import junit.framework.TestCase;

import org.apache.felix.cm.integration.helper.ConfigureThread;
import org.apache.felix.cm.integration.helper.ManagedServiceFactoryThread;
import org.apache.felix.cm.integration.helper.ManagedServiceThread;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;


/**
 * The <code>ConfigUpdateStressTest</code> class tests the issues related to
 * concurrency between configuration update (Configuration.update(Dictionary))
 * and ManagedService[Factory] registration.
 * <p>
 * @see <a href="https://issues.apache.org/jira/browse/FELIX-1545">FELIX-1545</a>
 */
@RunWith(JUnit4TestRunner.class)
public class ConfigUpdateStressTest extends ConfigurationTestBase
{

    @Test
    public void test_ManagedService_race_condition_test()
    {
        int counterMax = 30;
        int failures = 0;

        for ( int counter = 0; counter < counterMax; counter++ )
        {
            try
            {
                single_test_ManagedService_race_condition_test( counter );
            }
            catch ( Throwable ae )
            {
                System.out.println( "single_test_ManagedService_race_condition_test#" + counter + " failed: " + ae );
                ae.printStackTrace( System.out );
                failures++;
            }
        }

        // fail the test if there is at least one failure
        if ( failures != 0 )
        {
            TestCase.fail( failures + "/" + counterMax + " iterations failed" );
        }
    }


    @Test
    public void test_ManagedServiceFactory_race_condition_test()
    {
        int counterMax = 30;
        int failures = 0;

        for ( int counter = 0; counter < counterMax; counter++ )
        {
            try
            {
                single_test_ManagedServiceFactory_race_condition_test( counter );
            }
            catch ( Throwable ae )
            {
                System.out.println( "single_test_ManagedServiceFactory_race_condition_test#" + counter + " failed: "
                    + ae );
                ae.printStackTrace( System.out );
                failures++;
            }
        }

        // fail the test if there is at least one failure
        if ( failures != 0 )
        {
            TestCase.fail( failures + "/" + counterMax + " iterations failed" );
        }
    }


    // runs a single test to encounter the race condition between ManagedService
    // registration and Configuration.update(Dictionary)
    // This test creates/updates configuration and registers a ManagedService
    // almost at the same time. The ManagedService must receive the
    // configuration
    // properties exactly once.
    private void single_test_ManagedService_race_condition_test( final int counter ) throws IOException,
        InterruptedException
    {

        final String pid = "single_test_ManagedService_race_condition_test." + counter;

        final ConfigureThread ct = new ConfigureThread( getConfigurationAdmin(), pid, false );
        final ManagedServiceThread mt = new ManagedServiceThread( bundleContext, pid );

        try
        {
            // start threads -- both are waiting to be triggered
            ct.start();
            mt.start();

            // trigger for action
            ct.trigger();
            mt.trigger();

            // wait for threads to terminate
            ct.join();
            mt.join();

            // wait for all tasks to terminate
            delay();

            final boolean isConfigured = mt.isConfigured();
            final ArrayList<Dictionary> configs = mt.getConfigs();

            // terminate mt to ensure no further config updates
            mt.cleanup();

            TestCase.assertTrue( "Last update call must have been with configuration",  isConfigured);

            if ( configs.size() == 0 )
            {
                TestCase.fail( "No configuration provided to ManagedService at all" );
            }
            else if ( configs.size() == 2 )
            {
                final Dictionary props0 = configs.get( 0 );
                final Dictionary props1 = configs.get( 1 );

                TestCase.assertNull( "Expected first (of two) updates without configuration", props0 );
                TestCase.assertNotNull( "Expected second (of two) updates with configuration", props1 );
            }
            else if ( configs.size() == 1 )
            {
                final Dictionary props = configs.get( 0 );
                TestCase.assertNotNull( "Expected non-null configuration: " + props, props );
            }
            else
            {
                TestCase.fail( "Unexpectedly got " + configs.size() + " updated" );
            }
        }
        finally
        {
            mt.cleanup();
            ct.cleanup();
        }
    }


    // runs a single test to encounter the race condition between
    // ManagedServiceFactory registration and Configuration.update(Dictionary)
    // This test creates/updates configuration and registers a
    // ManagedServiceFactory almost at the same time. The ManagedServiceFactory
    // must receive the configuration properties exactly once.
    private void single_test_ManagedServiceFactory_race_condition_test( final int counter ) throws IOException,
        InterruptedException
    {

        final String factoryPid = "single_test_ManagedServiceFactory_race_condition_test." + counter;

        final ConfigureThread ct = new ConfigureThread( getConfigurationAdmin(), factoryPid, true );
        final ManagedServiceFactoryThread mt = new ManagedServiceFactoryThread( bundleContext, factoryPid );

        try
        {
            // start threads -- both are waiting to be triggered
            ct.start();
            mt.start();

            // trigger for action
            ct.trigger();
            mt.trigger();

            // wait for threads to terminate
            ct.join();
            mt.join();

            // wait for all tasks to terminate
            delay();

            final boolean isConfigured = mt.isConfigured();
            final ArrayList<Dictionary> configs = mt.getConfigs();

            // terminate mt to ensure no further config updates
            mt.cleanup();

            TestCase.assertTrue( "Last update call must have been with configuration",  isConfigured);

            if ( configs.size() == 0 )
            {
                TestCase.fail( "No configuration provided to ManagedServiceFactory at all" );
            }
            else if ( configs.size() == 1 )
            {
                final Dictionary props = configs.get( 0 );
                TestCase.assertNotNull( "Expected non-null configuration: " + props, props );
            }
            else
            {
                TestCase.fail( "Unexpectedly got " + configs.size() + " updated" );
            }
        }
        finally
        {
            mt.cleanup();
            ct.cleanup();
        }
    }
}
