/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed 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 net.java.sip.communicator.slick.protocol.icq;
import junit.framework.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import org.osgi.framework.*;
/**
* Tests whether accaounts are uninstalled properly. It is important that
* tests from this class be called last since they will install the accounts
* that have been used to test the implementations.
*
* @author Emil Ivov
* @author Damian Minkov
*/
public class TestAccountUninstallation
extends TestCase
{
private static final Logger logger =
Logger.getLogger(TestAccountUninstallation.class);
IcqSlickFixture fixture = new IcqSlickFixture();
/**
* An event adapter that would collec registation state change events
*/
public RegistrationEventCollector regEvtCollector
= new RegistrationEventCollector();
/**
* The lock that we wait on until registration is finalized.
*/
private Object registrationLock = new Object();
/**
* Constructs a test instance
* @param name The name of the test.
*/
public TestAccountUninstallation(String name)
{
super(name);
}
/**
* JUnit setup method.
* @throws Exception in case anything goes wrong.
*/
@Override
protected void setUp() throws Exception
{
super.setUp();
fixture.setUp();
}
/**
* JUnit teardown method.
* @throws Exception in case anything goes wrong.
*/
@Override
protected void tearDown() throws Exception
{
fixture.tearDown();
super.tearDown();
}
/**
* Returns a suite containing tests in this class in the order that we'd
* like them executed.
* @return a Test suite containing tests in this class in the order that
* we'd like them executed.
*/
public static Test suite()
{
TestSuite suite = new TestSuite();
if(! IcqSlickFixture.onlineTestingDisabled)
suite.addTest(
new TestAccountUninstallation("testMultipleLogins"));
suite.addTest(
new TestAccountUninstallation("testInstallationPersistency"));
suite.addTest(
new TestAccountUninstallation("testUninstallAccount"));
return suite;
}
/**
* Before we uninstall the current account which is registered to the server
* we add a registration change listener and wait for unregistered event
* to be fired.
* Then we use the tester agent to register to the servers with
* the account info of the currently logged in account so we must
* receive multiple logins event.
*/
public void testMultipleLogins()
{
fixture.provider.addRegistrationStateChangeListener(regEvtCollector);
String passwd = System.getProperty( IcqProtocolProviderSlick
.TESTED_IMPL_PWD_PROP_NAME, null );
String uin = System.getProperty( IcqProtocolProviderSlick
.TESTED_IMPL_USER_ID_PROP_NAME, null);
IcqTesterAgent testerAgent = new IcqTesterAgent(uin);
testerAgent.register(passwd);
// give time to the register process
Object lock = new Object();
synchronized(lock)
{
try
{
logger.debug("Giving the aim server time to notify for our arrival!");
lock.wait(5000);
}
catch (Exception ex)
{}
}
testerAgent.unregister();
assertNotNull(
"No event was dispatched"
,regEvtCollector.stateRecieved);
assertEquals(
"Event is not UNREGISTERED event"
, regEvtCollector.stateRecieved
, RegistrationState.UNREGISTERED);
assertEquals(
"No registration event notifying of Multiple logins dispatched "
, regEvtCollector.eventReason
, RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS);
}
/**
* Stops and removes the tested bundle, verifies that it has unregistered
* its provider, then reloads and restarts the bundle and verifies that
* the protocol provider is reRegistered in the bundle context.
*
* @throws java.lang.Exception if an exception occurs during testing.
*/
public void testInstallationPersistency()
throws Exception
{
Bundle providerBundle
= IcqSlickFixture.findProtocolProviderBundle(fixture.provider);
//set the global providerBundle reference that we will be using
//in the last series of tests (Account uninstallation persistency)
IcqSlickFixture.providerBundle = providerBundle;
assertNotNull("Couldn't find a bundle for the tested provider"
, providerBundle);
providerBundle.stop();
assertTrue("Couldn't stop the protocol provider bundle. State was "
+ providerBundle.getState()
, Bundle.ACTIVE != providerBundle.getState()
&& Bundle.STOPPING != providerBundle.getState());
providerBundle.uninstall();
assertEquals("Couldn't stop the protocol provider bundle."
, Bundle.UNINSTALLED, providerBundle.getState());
//verify that the provider is no longer available
ServiceReference[] icqProviderRefs = null;
try
{
icqProviderRefs = IcqSlickFixture.bc.getServiceReferences(
ProtocolProviderService.class.getName(),
"(&"
+ "(" + ProtocolProviderFactory.PROTOCOL
+ "=" +ProtocolNames.ICQ + ")"
+ "(" + ProtocolProviderFactory.USER_ID
+ "="+ IcqSlickFixture.icqAccountID.getUserID() + ")"
+ ")");
}
catch (InvalidSyntaxException ex)
{
fail("We apparently got our filter wrong: " + ex.getMessage());
}
//make sure we didn't see a service
assertTrue("A Protocol Provider Service was still regged as an osgi service "
+"for ICQ UIN:" + IcqSlickFixture.icqAccountID
+ "After it was explicitly uninstalled"
,icqProviderRefs == null || icqProviderRefs.length == 0);
//verify that the provider factory knows that we have uninstalled the
//provider.
assertTrue(
"The ICQ provider factory kept a reference to the provider we just "
+"uninstalled (accID="+IcqSlickFixture.icqAccountID+")",
fixture.providerFactory.getRegisteredAccounts().isEmpty()
&& fixture.providerFactory.getProviderForAccount(IcqSlickFixture.icqAccountID)
== null);
//Now reinstall the bundle
providerBundle = IcqSlickFixture.bc.installBundle(providerBundle.getLocation());
//set the global providerBundle reference that we will be using
//in the last series of tests (Account uninstallation persistency)
IcqSlickFixture.providerBundle = providerBundle;
assertEquals("Couldn't re-install protocol provider bundle."
, Bundle.INSTALLED, providerBundle.getState());
AccountManagerUtils.startBundleAndWaitStoredAccountsLoaded(
IcqSlickFixture.bc, providerBundle, ProtocolNames.ICQ);
assertEquals("Couldn't re-start protocol provider bundle."
, Bundle.ACTIVE, providerBundle.getState());
//Make sure that the provider is there again.
//verify that the provider is no longer available
try
{
icqProviderRefs = IcqSlickFixture.bc.getServiceReferences(
ProtocolProviderService.class.getName(),
"(&"
+ "(" + ProtocolProviderFactory.PROTOCOL
+ "=" +ProtocolNames.ICQ + ")"
+ "(" + ProtocolProviderFactory.USER_ID
+ "="+ IcqSlickFixture.icqAccountID.getUserID() + ")"
+ ")");
}
catch (InvalidSyntaxException ex)
{
fail("We apparently got our filter wrong: " + ex.getMessage());
}
//make sure we didn't see a service
assertTrue("A Protocol Provider Service was not restored after being"
+"reinstalled. ICQ UIN:" + IcqSlickFixture.icqAccountID
,icqProviderRefs != null && icqProviderRefs.length > 0);
ServiceReference[] icqFactoryRefs = null;
try
{
icqFactoryRefs = IcqSlickFixture.bc.getServiceReferences(
ProtocolProviderFactory.class.getName(),
"(" + ProtocolProviderFactory.PROTOCOL
+ "=" +ProtocolNames.ICQ + ")");
}
catch (InvalidSyntaxException ex)
{
fail("We apparently got our filter wrong: " + ex.getMessage());
}
//we're the ones who've reinstalled the factory so it's our
//responsibility to update the fixture.
fixture.providerFactory
= (ProtocolProviderFactory)IcqSlickFixture.bc.getService(icqFactoryRefs[0]);
fixture.provider
= (ProtocolProviderService)IcqSlickFixture.bc.getService(icqProviderRefs[0]);
IcqSlickFixture.icqAccountID
= fixture.provider.getAccountID();
//verify that the provider is also restored in the provider factory
//itself
assertTrue(
"The ICQ provider did not restore its own reference to the provider "
+"that we just reinstalled (accID="+IcqSlickFixture.icqAccountID+")",
!fixture.providerFactory.getRegisteredAccounts().isEmpty()
&& fixture.providerFactory.getProviderForAccount(IcqSlickFixture.icqAccountID)
!= null);
}
/**
* Uinstalls our test account and makes sure it really has been removed.
*/
public void testUninstallAccount()
{
assertFalse("No installed accounts found"
,fixture.providerFactory.getRegisteredAccounts().isEmpty());
assertNotNull(
"Found no provider corresponding to account ID "
+ IcqSlickFixture.icqAccountID
,fixture.providerFactory.getProviderForAccount(IcqSlickFixture.icqAccountID));
assertTrue(
"Failed to remove a provider corresponding to acc id "
+ IcqSlickFixture.icqAccountID
, fixture.providerFactory.uninstallAccount(IcqSlickFixture.icqAccountID));
ServiceReference[] icqProviderRefs = null;
try
{
icqProviderRefs = IcqSlickFixture.bc.getServiceReferences(
ProtocolProviderService.class.getName(),
"(&"
+ "(" + ProtocolProviderFactory.PROTOCOL
+ "=" +ProtocolNames.ICQ + ")"
+ "(" + ProtocolProviderFactory.USER_ID
+ "="+ IcqSlickFixture.icqAccountID.getUserID() + ")"
+ ")");
}
catch (InvalidSyntaxException ex)
{
fail("We apparently got our filter wrong: " + ex.getMessage());
}
//make sure we didn't see a service
assertTrue("A Protocol Provider Service was still regged as an osgi service "
+"for ICQ UIN:" + IcqSlickFixture.icqAccountID
+ "After it was explicitly uninstalled"
,icqProviderRefs == null || icqProviderRefs.length == 0);
//verify that the provider factory knows that we have uninstalled the
//provider.
assertTrue(
"The ICQ provider factory kept a reference to the provider we just "
+"uninstalled (accID="+IcqSlickFixture.icqAccountID+")"
, fixture.providerFactory.getRegisteredAccounts().isEmpty()
&& fixture.providerFactory.getProviderForAccount(IcqSlickFixture.icqAccountID)
== null);
}
/**
* A class that would plugin as a registration listener to a protocol
* provider and simply record all events that it sees and notify the
* registrationLock if it sees an event that notifies us of a completed
* registration.
*/
public class RegistrationEventCollector implements RegistrationStateChangeListener
{
RegistrationState stateRecieved = null;
int eventReason = -1;
/**
* The method would simply register all received events so that they
* could be available for later inspection by the unit tests. In the
* case where a registraiton event notifying us of a completed
* registration is seen, the method would call notifyAll() on the
* registrationLock.
*
* @param evt ProviderStatusChangeEvent the event describing the status
* change.
*/
public void registrationStateChanged(RegistrationStateChangeEvent evt)
{
logger.debug("Received a RegistrationStateChangeEvent: " + evt);
if(evt.getNewState().equals( RegistrationState.UNREGISTERED))
{
logger.debug("Connection FAILED!");
stateRecieved = evt.getNewState();
eventReason = evt.getReasonCode();
synchronized(registrationLock)
{
logger.debug(".");
registrationLock.notifyAll();
logger.debug(".");
}
}
}
}
}