1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-09 17:19:39 +02:00

Re-activate EntityCaps integration test

This commit is contained in:
Florian Schmaus 2016-12-19 14:35:09 +01:00
parent 1f7770b831
commit 7655ac17f2
16 changed files with 358 additions and 181 deletions

View file

@ -1,6 +1,6 @@
/**
*
* Copyright 2015 Florian Schmaus
* Copyright 2015-2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,12 +17,58 @@
package org.igniterealtime.smack.inttest;
import java.util.Random;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.StanzaFilter;
public abstract class AbstractSmackIntTest {
protected static final Logger LOGGER = Logger.getLogger(AbstractSmackIntTest.class.getName());
protected static final Random INSECURE_RANDOM = new Random();
protected final String testRunId;
protected final long timeout;
protected AbstractSmackIntTest(String testRunId, long timeout) {
this.testRunId = testRunId;
this.timeout = timeout;
}
protected void performActionAndWaitUntilStanzaReceived(Runnable action, XMPPConnection connection, StanzaFilter filter)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
PacketCollector.Configuration configuration = PacketCollector.newConfiguration().setStanzaFilter(
filter).setSize(1);
PacketCollector collector = connection.createPacketCollector(configuration);
try {
action.run();
collector.nextResultOrThrow(timeout);
}
finally {
collector.cancel();
}
}
protected void waitUntilTrue(Condition condition) throws TimeoutException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
final long deadline = System.currentTimeMillis() + timeout;
do {
if (condition.evaluate()) {
return;
}
Thread.yield();
} while (System.currentTimeMillis() <= deadline);
throw new TimeoutException("Timeout waiting for condition to become true. Timeout was " + timeout + " ms.");
}
protected interface Condition {
boolean evaluate() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException;
}
}

View file

@ -40,19 +40,10 @@ public abstract class AbstractSmackIntegrationTest extends AbstractSmackIntTest
*/
protected final XMPPConnection connection;
protected final String testRunId;
protected final long defaultTimeout;
public AbstractSmackIntegrationTest(SmackIntegrationTestEnvironment environment) {
super(environment.testRunId, environment.configuration.replyTimeout);
this.connection = this.conOne = environment.conOne;
this.conTwo = environment.conTwo;
this.conThree = environment.conThree;
if (environment.configuration.replyTimeout > 0) {
this.defaultTimeout = environment.configuration.replyTimeout;
} else {
this.defaultTimeout = 2 * 60 * 1000;
}
this.testRunId = environment.testRunId;
}
}

View file

@ -36,14 +36,12 @@ public abstract class AbstractSmackLowLevelIntegrationTest extends AbstractSmack
*/
protected final Configuration configuration;
protected final String testRunId;
protected final DomainBareJid service;
public AbstractSmackLowLevelIntegrationTest(SmackIntegrationTestEnvironment environment) {
super(environment.testRunId, environment.configuration.replyTimeout);
this.environment = environment;
this.configuration = environment.configuration;
this.testRunId = environment.testRunId;
this.service = configuration.service;
}

View file

@ -83,7 +83,11 @@ public final class Configuration {
"'service' must be set. Either via 'properties' files or via system property 'sinttest.service'.");
this.serviceTlsPin = serviceTlsPin;
this.securityMode = securityMode;
this.replyTimeout = replyTimeout;
if (replyTimeout > 0) {
this.replyTimeout = replyTimeout;
} else {
this.replyTimeout = 60000;
}
this.debug = debug;
if (StringUtils.isNotEmpty(adminAccountUsername, adminAccountPassword)) {
accountRegistration = AccountRegistration.serviceAdministration;

View file

@ -95,9 +95,14 @@ public class SmackIntegrationTestFramework {
LOGGER.info("Could not run " + testNotPossible.testMethod.getName() + " because: "
+ testNotPossible.testNotPossibleException.getMessage());
}
final int successfulTests = testRunResult.successfulTests.size();
final int availableTests = testRunResult.getNumberOfAvailableTests();
final int possibleTests = testRunResult.getNumberOfPossibleTests();
LOGGER.info("SmackIntegrationTestFramework[" + testRunResult.testRunId + ']' + ": Finished ["
+ testRunResult.successfulTests.size() + '/' + testRunResult.numberOfTests + ']');
+ successfulTests + '/' + possibleTests + "] (of " + availableTests + " available tests)");
if (!testRunResult.failedIntegrationTests.isEmpty()) {
final int failedTests = testRunResult.failedIntegrationTests.size();
LOGGER.warning("The following " + failedTests + " tests failed!");
for (FailedTest failedTest : testRunResult.failedIntegrationTests) {
final Method method = failedTest.testMethod;
final String className = method.getDeclaringClass().getName();
@ -106,6 +111,8 @@ public class SmackIntegrationTestFramework {
LOGGER.severe(className + CLASS_METHOD_SEP + methodName + " failed: " + cause);
}
System.exit(2);
} else {
LOGGER.info("All possible Smack Integration Tests completed successfully. \\o/");
}
System.exit(0);
}
@ -251,7 +258,9 @@ public class SmackIntegrationTestFramework {
continue;
}
testRunResult.numberOfTests.addAndGet(smackIntegrationTestMethods.size());
final int detectedTestMethodsCount = smackIntegrationTestMethods.size();
testRunResult.numberOfAvailableTests.addAndGet(detectedTestMethodsCount);
testRunResult.numberOfPossibleTests.addAndGet(detectedTestMethodsCount);
AbstractSmackIntTest test;
switch (testType) {
@ -274,6 +283,7 @@ public class SmackIntegrationTestFramework {
Throwable cause = e.getCause();
if (cause instanceof TestNotPossibleException) {
testRunResult.impossibleTestClasses.put(testClass, cause.getMessage());
testRunResult.numberOfPossibleTests.addAndGet(-detectedTestMethodsCount);
}
else {
throwFatalException(cause);
@ -306,6 +316,7 @@ public class SmackIntegrationTestFramework {
Throwable cause = e.getCause();
if (cause instanceof TestNotPossibleException) {
testRunResult.impossibleTestClasses.put(testClass, cause.getMessage());
testRunResult.numberOfPossibleTests.addAndGet(-detectedTestMethodsCount);
}
else {
throwFatalException(cause);
@ -622,7 +633,8 @@ public class SmackIntegrationTestFramework {
private final List<FailedTest> failedIntegrationTests = Collections.synchronizedList(new LinkedList<FailedTest>());
private final List<TestNotPossible> impossibleTestMethods = Collections.synchronizedList(new LinkedList<TestNotPossible>());
private final Map<Class<? extends AbstractSmackIntTest>, String> impossibleTestClasses = new HashMap<>();
private final AtomicInteger numberOfTests = new AtomicInteger();
private final AtomicInteger numberOfAvailableTests = new AtomicInteger();
private final AtomicInteger numberOfPossibleTests = new AtomicInteger();
private TestRunResult() {
}
@ -631,8 +643,12 @@ public class SmackIntegrationTestFramework {
return testRunId;
}
public int getNumberOfTests() {
return numberOfTests.get();
public int getNumberOfAvailableTests() {
return numberOfAvailableTests.get();
}
public int getNumberOfPossibleTests() {
return numberOfPossibleTests.get();
}
public List<SuccessfulTest> getSuccessfulTests() {

View file

@ -55,12 +55,12 @@ public class ChatTest extends AbstractSmackIntegrationTest {
}
@BeforeClass
public static void setUp() {
public void setUp() {
JivePropertiesManager.setJavaObjectEnabled(true);
}
@AfterClass
public static void tearDown() {
public void tearDown() {
JivePropertiesManager.setJavaObjectEnabled(false);
}

View file

@ -0,0 +1,210 @@
/**
*
* Copyright 2013-2016 Florian Schmaus
*
* 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 org.jivesoftware.smackx.caps;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromMatchesFilter;
import org.jivesoftware.smack.filter.IQTypeFilter;
import org.jivesoftware.smack.filter.PresenceTypeFilter;
import org.jivesoftware.smack.filter.StanzaTypeFilter;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.roster.RosterUtil;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class EntityCapsTest extends AbstractSmackIntegrationTest {
private final EntityCapsManager ecmTwo;
private final ServiceDiscoveryManager sdmOne;
private final ServiceDiscoveryManager sdmTwo;
private boolean discoInfoSend = false;
public EntityCapsTest(SmackIntegrationTestEnvironment environment) {
super(environment);
ecmTwo = EntityCapsManager.getInstanceFor(environment.conTwo);
sdmOne = ServiceDiscoveryManager.getInstanceFor(environment.conOne);
sdmTwo = ServiceDiscoveryManager.getInstanceFor(environment.conTwo);
}
private final AtomicInteger dummyFeatureId = new AtomicInteger();
private final Set<String> dummyFeatures = new HashSet<>();
private String getNewDummyFeature() {
String dummyFeature = "entityCapsTest" + dummyFeatureId.incrementAndGet();
dummyFeatures.add(dummyFeature);
return dummyFeature;
}
@BeforeClass
public void setUp() throws NotLoggedInException, NotConnectedException, InterruptedException, TimeoutException {
RosterUtil.ensureSubscribed(conOne, conTwo, timeout);
}
@AfterClass
public void tearDown() throws NotConnectedException, InterruptedException {
RosterUtil.ensureNotSubscribedToEachOther(conOne, conTwo);
ServiceDiscoveryManager[] sdms = new ServiceDiscoveryManager[] { sdmOne, sdmTwo };
for (ServiceDiscoveryManager sdm : sdms) {
for (String dummyFeature : dummyFeatures) {
sdm.removeFeature(dummyFeature);
}
}
}
@SmackIntegrationTest
public void testLocalEntityCaps() throws InterruptedException, NoResponseException, XMPPErrorException, NotConnectedException {
final String dummyFeature = getNewDummyFeature();
DiscoverInfo info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer());
assertFalse(info.containsFeature(dummyFeature));
dropWholeEntityCapsCache();
performActionAndWaitUntilStanzaReceived(new Runnable() {
@Override
public void run() {
// This should cause a new presence stanza from con1 with and updated
// 'ver' String
sdmTwo.addFeature(dummyFeature);
}
}, conOne, new AndFilter(PresenceTypeFilter.AVAILABLE, FromMatchesFilter.create(conTwo.getUser())));
// The presence stanza should get received by con0 and the data should
// be recorded in the map
// Note that while both connections use the same static Entity Caps
// cache,
// it's assured that *not* con1 added the data to the Entity Caps cache.
// Every time the entities features
// and identities change only a new caps 'ver' is calculated and send
// with the presence stanza
// The other connection has to receive this stanza and record the
// information in order for this test to succeed.
info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer());
assertNotNull(info);
assertTrue(info.containsFeature(dummyFeature));
}
/**
* Test if entity caps actually prevent a disco info request and reply.
*
* @throws XMPPException
* @throws InterruptedException
* @throws NotConnectedException
* @throws NoResponseException
*
*/
@SmackIntegrationTest
public void testPreventDiscoInfo() throws XMPPException, NoResponseException, NotConnectedException, InterruptedException {
final String dummyFeature = getNewDummyFeature();
conOne.addPacketSendingListener(new StanzaListener() {
@Override
public void processPacket(Stanza stanza) {
discoInfoSend = true;
}
}, new AndFilter(new StanzaTypeFilter(DiscoverInfo.class), IQTypeFilter.GET));
// add a bogus feature so that con1 ver won't match con0's
sdmTwo.addFeature(dummyFeature);
dropCapsCache();
// discover that
DiscoverInfo info = sdmOne.discoverInfo(conTwo.getUser());
// that discovery should cause a disco#info
assertTrue(discoInfoSend);
assertTrue(info.containsFeature(dummyFeature));
discoInfoSend = false;
// discover that
info = sdmOne.discoverInfo(conTwo.getUser());
// that discovery shouldn't cause a disco#info
assertFalse(discoInfoSend);
assertTrue(info.containsFeature(dummyFeature));
}
@SmackIntegrationTest
public void testCapsChanged() {
final String dummyFeature = getNewDummyFeature();
String nodeVerBefore = EntityCapsManager.getNodeVersionByJid(conTwo.getUser());
sdmTwo.addFeature(dummyFeature);
String nodeVerAfter = EntityCapsManager.getNodeVersionByJid(conTwo.getUser());
assertFalse(nodeVerBefore.equals(nodeVerAfter));
}
@SmackIntegrationTest
public void testEntityCaps() throws XMPPException, InterruptedException, NoResponseException, NotConnectedException, TimeoutException {
final String dummyFeature = getNewDummyFeature();
dropWholeEntityCapsCache();
performActionAndWaitUntilStanzaReceived(new Runnable() {
@Override
public void run() {
sdmTwo.addFeature(dummyFeature);
}
}, connection, new AndFilter(PresenceTypeFilter.AVAILABLE, FromMatchesFilter.create(conTwo.getUser())));
waitUntilTrue(new Condition() {
@Override
public boolean evaluate() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
DiscoverInfo info = sdmOne.discoverInfo(conTwo.getUser());
return info.containsFeature(dummyFeature);
}
});
DiscoverInfo info = sdmOne.discoverInfo(conTwo.getUser());
String u1ver = EntityCapsManager.getNodeVersionByJid(conTwo.getUser());
assertNotNull(u1ver);
DiscoverInfo entityInfo = EntityCapsManager.CAPS_CACHE.get(u1ver);
assertNotNull(entityInfo);
assertEquals(info.toXML(), entityInfo.toXML());
}
private static void dropWholeEntityCapsCache() {
EntityCapsManager.CAPS_CACHE.clear();
EntityCapsManager.JID_TO_NODEVER_CACHE.clear();
}
private static void dropCapsCache() {
EntityCapsManager.CAPS_CACHE.clear();
}
}

View file

@ -0,0 +1 @@
../../../../../../../../smack-extensions/src/main/java/org/jivesoftware/smackx/caps/package-info.java

View file

@ -81,7 +81,7 @@ public class IoTControlIntegrationTest extends AbstractSmackIntegrationTest {
IoTControlManagerOne.installThing(controlThing);
try {
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, defaultTimeout);
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout);
SetData data = new SetBoolData(testRunId, true);
IoTSetResponse response = IoTControlManagerTwo.setUsingIq(conOne.getUser(), data);
@ -92,6 +92,6 @@ public class IoTControlIntegrationTest extends AbstractSmackIntegrationTest {
RosterIntegrationTest.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo);
}
syncPoint.waitForResult(defaultTimeout);
syncPoint.waitForResult(timeout);
}
}

View file

@ -73,7 +73,7 @@ public class IoTDataIntegrationTest extends AbstractSmackIntegrationTest {
List<IoTFieldsExtension> values;
try {
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, defaultTimeout);
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout);
values = iotDataManagerTwo.requestMomentaryValuesReadOut(conOne.getUser());
}

View file

@ -88,7 +88,7 @@ public class MultiUserChatIntegrationTest extends AbstractSmackIntegrationTest {
mucAsSeenByTwo.join(Resourcepart.from("two-" + randomString));
mucAsSeenByOne.sendMessage(mucMessage);
resultSyncPoint.waitForResult(defaultTimeout);
resultSyncPoint.waitForResult(timeout);
mucAsSeenByOne.leave();
mucAsSeenByTwo.leave();