mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22:05 +01:00
Re-activate EntityCaps integration test
This commit is contained in:
parent
1f7770b831
commit
7655ac17f2
16 changed files with 358 additions and 181 deletions
|
@ -45,7 +45,6 @@ import org.jivesoftware.smack.packet.Presence;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
import org.jivesoftware.smack.roster.AbstractPresenceEventListener;
|
import org.jivesoftware.smack.roster.AbstractPresenceEventListener;
|
||||||
import org.jivesoftware.smack.roster.Roster;
|
import org.jivesoftware.smack.roster.Roster;
|
||||||
import org.jivesoftware.smack.roster.RosterEntry;
|
|
||||||
import org.jivesoftware.smack.roster.SubscribeListener;
|
import org.jivesoftware.smack.roster.SubscribeListener;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
||||||
|
@ -353,10 +352,7 @@ public final class IoTProvisioningManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean iAmFriendOf(BareJid otherJid) {
|
public boolean iAmFriendOf(BareJid otherJid) {
|
||||||
RosterEntry entry = roster.getEntry(otherJid);
|
return roster.iAmSubscribedTo(otherJid);
|
||||||
if (entry == null) return false;
|
|
||||||
|
|
||||||
return entry.canSeeHisPresence();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendFriendshipRequest(BareJid bareJid) throws NotConnectedException, InterruptedException {
|
public void sendFriendshipRequest(BareJid bareJid) throws NotConnectedException, InterruptedException {
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
package org.jivesoftware.smackx.entitycaps;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.PacketListener;
|
|
||||||
import org.jivesoftware.smack.SmackConfiguration;
|
|
||||||
import org.jivesoftware.smack.TCPConnection;
|
|
||||||
import org.jivesoftware.smack.XMPPException;
|
|
||||||
import org.jivesoftware.smack.filter.AndFilter;
|
|
||||||
import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
|
||||||
import org.jivesoftware.smack.filter.IQTypeFilter;
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
|
||||||
import org.jivesoftware.smack.test.SmackTestCase;
|
|
||||||
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
|
||||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
|
||||||
|
|
||||||
public class EntityCapsTest extends SmackTestCase {
|
|
||||||
|
|
||||||
private static final String DISCOVER_TEST_FEATURE = "entityCapsTest";
|
|
||||||
|
|
||||||
XMPPTCPConnection con0;
|
|
||||||
XMPPTCPConnection con1;
|
|
||||||
EntityCapsManager ecm0;
|
|
||||||
EntityCapsManager ecm1;
|
|
||||||
ServiceDiscoveryManager sdm0;
|
|
||||||
ServiceDiscoveryManager sdm1;
|
|
||||||
|
|
||||||
private boolean discoInfoSend = false;
|
|
||||||
|
|
||||||
public EntityCapsTest(String arg0) {
|
|
||||||
super(arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getMaxConnections() {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
SmackConfiguration.setAutoEnableEntityCaps(true);
|
|
||||||
con0 = getConnection(0);
|
|
||||||
con1 = getConnection(1);
|
|
||||||
ecm0 = EntityCapsManager.getInstanceFor(getConnection(0));
|
|
||||||
ecm1 = EntityCapsManager.getInstanceFor(getConnection(1));
|
|
||||||
sdm0 = ServiceDiscoveryManager.getInstanceFor(con0);
|
|
||||||
sdm1 = ServiceDiscoveryManager.getInstanceFor(con1);
|
|
||||||
letsAllBeFriends();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testLocalEntityCaps() throws InterruptedException {
|
|
||||||
DiscoverInfo info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecm1.getLocalNodeVer());
|
|
||||||
assertFalse(info.containsFeature(DISCOVER_TEST_FEATURE));
|
|
||||||
|
|
||||||
dropWholeEntityCapsCache();
|
|
||||||
|
|
||||||
// This should cause a new presence stanza from con1 with and updated
|
|
||||||
// 'ver' String
|
|
||||||
sdm1.addFeature(DISCOVER_TEST_FEATURE);
|
|
||||||
|
|
||||||
// Give the server some time to handle the stanza and send it to con0
|
|
||||||
Thread.sleep(2000);
|
|
||||||
|
|
||||||
// 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(ecm1.getLocalNodeVer());
|
|
||||||
assertNotNull(info);
|
|
||||||
assertTrue(info.containsFeature(DISCOVER_TEST_FEATURE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test if entity caps actually prevent a disco info request and reply
|
|
||||||
*
|
|
||||||
* @throws XMPPException
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void testPreventDiscoInfo() throws XMPPException {
|
|
||||||
con0.addPacketSendingListener(new PacketListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processPacket(Packet packet) {
|
|
||||||
discoInfoSend = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, new AndFilter(new StanzaTypeFilter(DiscoverInfo.class), new IQTypeFilter(IQ.Type.get)));
|
|
||||||
|
|
||||||
// add a bogus feature so that con1 ver won't match con0's
|
|
||||||
sdm1.addFeature(DISCOVER_TEST_FEATURE);
|
|
||||||
|
|
||||||
dropCapsCache();
|
|
||||||
// discover that
|
|
||||||
DiscoverInfo info = sdm0.discoverInfo(con1.getUser());
|
|
||||||
// that discovery should cause a disco#info
|
|
||||||
assertTrue(discoInfoSend);
|
|
||||||
assertTrue(info.containsFeature(DISCOVER_TEST_FEATURE));
|
|
||||||
discoInfoSend = false;
|
|
||||||
|
|
||||||
// discover that
|
|
||||||
info = sdm0.discoverInfo(con1.getUser());
|
|
||||||
// that discovery shouldn't cause a disco#info
|
|
||||||
assertFalse(discoInfoSend);
|
|
||||||
assertTrue(info.containsFeature(DISCOVER_TEST_FEATURE));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCapsChanged() {
|
|
||||||
String nodeVerBefore = EntityCapsManager.getNodeVersionByJid(con1.getUser());
|
|
||||||
sdm1.addFeature(DISCOVER_TEST_FEATURE);
|
|
||||||
String nodeVerAfter = EntityCapsManager.getNodeVersionByJid(con1.getUser());
|
|
||||||
|
|
||||||
assertFalse(nodeVerBefore.equals(nodeVerAfter));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testEntityCaps() throws XMPPException, InterruptedException {
|
|
||||||
dropWholeEntityCapsCache();
|
|
||||||
sdm1.addFeature(DISCOVER_TEST_FEATURE);
|
|
||||||
|
|
||||||
Thread.sleep(3000);
|
|
||||||
|
|
||||||
DiscoverInfo info = sdm0.discoverInfo(con1.getUser());
|
|
||||||
assertTrue(info.containsFeature(DISCOVER_TEST_FEATURE));
|
|
||||||
|
|
||||||
String u1ver = EntityCapsManager.getNodeVersionByJid(con1.getUser());
|
|
||||||
assertNotNull(u1ver);
|
|
||||||
|
|
||||||
DiscoverInfo entityInfo = EntityCapsManager.caps.get(u1ver);
|
|
||||||
assertNotNull(entityInfo);
|
|
||||||
|
|
||||||
assertEquals(info.toXML(), entityInfo.toXML());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void dropWholeEntityCapsCache() {
|
|
||||||
EntityCapsManager.caps.clear();
|
|
||||||
EntityCapsManager.jidCaps.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void dropCapsCache() {
|
|
||||||
EntityCapsManager.caps.clear();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -101,7 +101,7 @@ public final class EntityCapsManager extends Manager {
|
||||||
/**
|
/**
|
||||||
* Map of "node + '#' + hash" to DiscoverInfo data
|
* Map of "node + '#' + hash" to DiscoverInfo data
|
||||||
*/
|
*/
|
||||||
private static final LruCache<String, DiscoverInfo> CAPS_CACHE = new LruCache<String, DiscoverInfo>(1000);
|
static final LruCache<String, DiscoverInfo> CAPS_CACHE = new LruCache<String, DiscoverInfo>(1000);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of Full JID -> DiscoverInfo/null. In case of c2s connection the
|
* Map of Full JID -> DiscoverInfo/null. In case of c2s connection the
|
||||||
|
@ -109,7 +109,7 @@ public final class EntityCapsManager extends Manager {
|
||||||
* link-local connection the key is formed as user@host (no resource) In
|
* link-local connection the key is formed as user@host (no resource) In
|
||||||
* case of a server or component the key is formed as domain
|
* case of a server or component the key is formed as domain
|
||||||
*/
|
*/
|
||||||
private static final LruCache<Jid, NodeVerHash> JID_TO_NODEVER_CACHE = new LruCache<>(10000);
|
static final LruCache<Jid, NodeVerHash> JID_TO_NODEVER_CACHE = new LruCache<>(10000);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@ -159,7 +159,7 @@ public final class EntityCapsManager extends Manager {
|
||||||
* the user (Full JID)
|
* the user (Full JID)
|
||||||
* @return the node version (node#ver) or null
|
* @return the node version (node#ver) or null
|
||||||
*/
|
*/
|
||||||
public static String getNodeVersionByJid(String jid) {
|
public static String getNodeVersionByJid(Jid jid) {
|
||||||
NodeVerHash nvh = JID_TO_NODEVER_CACHE.get(jid);
|
NodeVerHash nvh = JID_TO_NODEVER_CACHE.get(jid);
|
||||||
if (nvh != null) {
|
if (nvh != null) {
|
||||||
return nvh.nodeVer;
|
return nvh.nodeVer;
|
||||||
|
|
|
@ -1099,6 +1099,25 @@ public final class Roster extends Manager {
|
||||||
return entry.canSeeMyPresence();
|
return entry.canSeeMyPresence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the XMPP entity this roster belongs to is subscribed to the presence of the given JID.
|
||||||
|
*
|
||||||
|
* @param jid the jid to check.
|
||||||
|
* @return <code>true</code> if we are subscribed to the presence of the given jid.
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public boolean iAmSubscribedTo(Jid jid) {
|
||||||
|
if (jid == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BareJid bareJid = jid.asBareJid();
|
||||||
|
RosterEntry entry = getEntry(bareJid);
|
||||||
|
if (entry == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return entry.canSeeHisPresence();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets if the roster will be loaded from the server when logging in for newly created instances
|
* Sets if the roster will be loaded from the server when logging in for newly created instances
|
||||||
* of {@link Roster}.
|
* of {@link Roster}.
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
import org.jivesoftware.smack.SmackException.NotLoggedInException;
|
import org.jivesoftware.smack.SmackException.NotLoggedInException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
import org.jxmpp.jid.BareJid;
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
@ -111,4 +112,46 @@ public class RosterUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ensureSubscribed(XMPPConnection connectionOne, XMPPConnection connectionTwo, long timeout)
|
||||||
|
throws NotLoggedInException, NotConnectedException, InterruptedException, TimeoutException {
|
||||||
|
ensureSubscribedTo(connectionOne, connectionTwo, timeout);
|
||||||
|
ensureSubscribedTo(connectionTwo, connectionOne, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ensureSubscribedTo(XMPPConnection connectionOne, XMPPConnection connectionTwo, long timeout)
|
||||||
|
throws NotLoggedInException, NotConnectedException, InterruptedException, TimeoutException {
|
||||||
|
Date deadline = new Date(System.currentTimeMillis() + timeout);
|
||||||
|
ensureSubscribedTo(connectionOne, connectionTwo, deadline);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ensureSubscribedTo(final XMPPConnection connectionOne, final XMPPConnection connectionTwo,
|
||||||
|
final Date deadline)
|
||||||
|
throws NotLoggedInException, NotConnectedException, InterruptedException, TimeoutException {
|
||||||
|
final Roster rosterOne = Roster.getInstanceFor(connectionOne);
|
||||||
|
final BareJid jidTwo = connectionTwo.getUser().asBareJid();
|
||||||
|
|
||||||
|
if (rosterOne.iAmSubscribedTo(jidTwo))
|
||||||
|
return;
|
||||||
|
|
||||||
|
final BareJid jidOne = connectionOne.getUser().asBareJid();
|
||||||
|
final SubscribeListener subscribeListener = new SubscribeListener() {
|
||||||
|
@Override
|
||||||
|
public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) {
|
||||||
|
if (from.equals(jidOne)) {
|
||||||
|
return SubscribeAnswer.Approve;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final Roster rosterTwo = Roster.getInstanceFor(connectionTwo);
|
||||||
|
|
||||||
|
rosterTwo.addSubscribeListener(subscribeListener);
|
||||||
|
try {
|
||||||
|
rosterOne.sendSubscriptionRequest(jidTwo);
|
||||||
|
waitUntilOtherEntityIsSubscribed(rosterTwo, jidOne, deadline);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
rosterTwo.removeSubscribeListener(subscribeListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2015 Florian Schmaus
|
* Copyright 2015-2016 Florian Schmaus
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,12 +17,58 @@
|
||||||
package org.igniterealtime.smack.inttest;
|
package org.igniterealtime.smack.inttest;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.logging.Logger;
|
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 {
|
public abstract class AbstractSmackIntTest {
|
||||||
|
|
||||||
protected static final Logger LOGGER = Logger.getLogger(AbstractSmackIntTest.class.getName());
|
protected static final Logger LOGGER = Logger.getLogger(AbstractSmackIntTest.class.getName());
|
||||||
|
|
||||||
protected static final Random INSECURE_RANDOM = new Random();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,19 +40,10 @@ public abstract class AbstractSmackIntegrationTest extends AbstractSmackIntTest
|
||||||
*/
|
*/
|
||||||
protected final XMPPConnection connection;
|
protected final XMPPConnection connection;
|
||||||
|
|
||||||
protected final String testRunId;
|
|
||||||
|
|
||||||
protected final long defaultTimeout;
|
|
||||||
|
|
||||||
public AbstractSmackIntegrationTest(SmackIntegrationTestEnvironment environment) {
|
public AbstractSmackIntegrationTest(SmackIntegrationTestEnvironment environment) {
|
||||||
|
super(environment.testRunId, environment.configuration.replyTimeout);
|
||||||
this.connection = this.conOne = environment.conOne;
|
this.connection = this.conOne = environment.conOne;
|
||||||
this.conTwo = environment.conTwo;
|
this.conTwo = environment.conTwo;
|
||||||
this.conThree = environment.conThree;
|
this.conThree = environment.conThree;
|
||||||
if (environment.configuration.replyTimeout > 0) {
|
|
||||||
this.defaultTimeout = environment.configuration.replyTimeout;
|
|
||||||
} else {
|
|
||||||
this.defaultTimeout = 2 * 60 * 1000;
|
|
||||||
}
|
|
||||||
this.testRunId = environment.testRunId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,14 +36,12 @@ public abstract class AbstractSmackLowLevelIntegrationTest extends AbstractSmack
|
||||||
*/
|
*/
|
||||||
protected final Configuration configuration;
|
protected final Configuration configuration;
|
||||||
|
|
||||||
protected final String testRunId;
|
|
||||||
|
|
||||||
protected final DomainBareJid service;
|
protected final DomainBareJid service;
|
||||||
|
|
||||||
public AbstractSmackLowLevelIntegrationTest(SmackIntegrationTestEnvironment environment) {
|
public AbstractSmackLowLevelIntegrationTest(SmackIntegrationTestEnvironment environment) {
|
||||||
|
super(environment.testRunId, environment.configuration.replyTimeout);
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.configuration = environment.configuration;
|
this.configuration = environment.configuration;
|
||||||
this.testRunId = environment.testRunId;
|
|
||||||
this.service = configuration.service;
|
this.service = configuration.service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,11 @@ public final class Configuration {
|
||||||
"'service' must be set. Either via 'properties' files or via system property 'sinttest.service'.");
|
"'service' must be set. Either via 'properties' files or via system property 'sinttest.service'.");
|
||||||
this.serviceTlsPin = serviceTlsPin;
|
this.serviceTlsPin = serviceTlsPin;
|
||||||
this.securityMode = securityMode;
|
this.securityMode = securityMode;
|
||||||
this.replyTimeout = replyTimeout;
|
if (replyTimeout > 0) {
|
||||||
|
this.replyTimeout = replyTimeout;
|
||||||
|
} else {
|
||||||
|
this.replyTimeout = 60000;
|
||||||
|
}
|
||||||
this.debug = debug;
|
this.debug = debug;
|
||||||
if (StringUtils.isNotEmpty(adminAccountUsername, adminAccountPassword)) {
|
if (StringUtils.isNotEmpty(adminAccountUsername, adminAccountPassword)) {
|
||||||
accountRegistration = AccountRegistration.serviceAdministration;
|
accountRegistration = AccountRegistration.serviceAdministration;
|
||||||
|
|
|
@ -95,9 +95,14 @@ public class SmackIntegrationTestFramework {
|
||||||
LOGGER.info("Could not run " + testNotPossible.testMethod.getName() + " because: "
|
LOGGER.info("Could not run " + testNotPossible.testMethod.getName() + " because: "
|
||||||
+ testNotPossible.testNotPossibleException.getMessage());
|
+ 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 ["
|
LOGGER.info("SmackIntegrationTestFramework[" + testRunResult.testRunId + ']' + ": Finished ["
|
||||||
+ testRunResult.successfulTests.size() + '/' + testRunResult.numberOfTests + ']');
|
+ successfulTests + '/' + possibleTests + "] (of " + availableTests + " available tests)");
|
||||||
if (!testRunResult.failedIntegrationTests.isEmpty()) {
|
if (!testRunResult.failedIntegrationTests.isEmpty()) {
|
||||||
|
final int failedTests = testRunResult.failedIntegrationTests.size();
|
||||||
|
LOGGER.warning("The following " + failedTests + " tests failed!");
|
||||||
for (FailedTest failedTest : testRunResult.failedIntegrationTests) {
|
for (FailedTest failedTest : testRunResult.failedIntegrationTests) {
|
||||||
final Method method = failedTest.testMethod;
|
final Method method = failedTest.testMethod;
|
||||||
final String className = method.getDeclaringClass().getName();
|
final String className = method.getDeclaringClass().getName();
|
||||||
|
@ -106,6 +111,8 @@ public class SmackIntegrationTestFramework {
|
||||||
LOGGER.severe(className + CLASS_METHOD_SEP + methodName + " failed: " + cause);
|
LOGGER.severe(className + CLASS_METHOD_SEP + methodName + " failed: " + cause);
|
||||||
}
|
}
|
||||||
System.exit(2);
|
System.exit(2);
|
||||||
|
} else {
|
||||||
|
LOGGER.info("All possible Smack Integration Tests completed successfully. \\o/");
|
||||||
}
|
}
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
@ -251,7 +258,9 @@ public class SmackIntegrationTestFramework {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
testRunResult.numberOfTests.addAndGet(smackIntegrationTestMethods.size());
|
final int detectedTestMethodsCount = smackIntegrationTestMethods.size();
|
||||||
|
testRunResult.numberOfAvailableTests.addAndGet(detectedTestMethodsCount);
|
||||||
|
testRunResult.numberOfPossibleTests.addAndGet(detectedTestMethodsCount);
|
||||||
|
|
||||||
AbstractSmackIntTest test;
|
AbstractSmackIntTest test;
|
||||||
switch (testType) {
|
switch (testType) {
|
||||||
|
@ -274,6 +283,7 @@ public class SmackIntegrationTestFramework {
|
||||||
Throwable cause = e.getCause();
|
Throwable cause = e.getCause();
|
||||||
if (cause instanceof TestNotPossibleException) {
|
if (cause instanceof TestNotPossibleException) {
|
||||||
testRunResult.impossibleTestClasses.put(testClass, cause.getMessage());
|
testRunResult.impossibleTestClasses.put(testClass, cause.getMessage());
|
||||||
|
testRunResult.numberOfPossibleTests.addAndGet(-detectedTestMethodsCount);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throwFatalException(cause);
|
throwFatalException(cause);
|
||||||
|
@ -306,6 +316,7 @@ public class SmackIntegrationTestFramework {
|
||||||
Throwable cause = e.getCause();
|
Throwable cause = e.getCause();
|
||||||
if (cause instanceof TestNotPossibleException) {
|
if (cause instanceof TestNotPossibleException) {
|
||||||
testRunResult.impossibleTestClasses.put(testClass, cause.getMessage());
|
testRunResult.impossibleTestClasses.put(testClass, cause.getMessage());
|
||||||
|
testRunResult.numberOfPossibleTests.addAndGet(-detectedTestMethodsCount);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throwFatalException(cause);
|
throwFatalException(cause);
|
||||||
|
@ -622,7 +633,8 @@ public class SmackIntegrationTestFramework {
|
||||||
private final List<FailedTest> failedIntegrationTests = Collections.synchronizedList(new LinkedList<FailedTest>());
|
private final List<FailedTest> failedIntegrationTests = Collections.synchronizedList(new LinkedList<FailedTest>());
|
||||||
private final List<TestNotPossible> impossibleTestMethods = Collections.synchronizedList(new LinkedList<TestNotPossible>());
|
private final List<TestNotPossible> impossibleTestMethods = Collections.synchronizedList(new LinkedList<TestNotPossible>());
|
||||||
private final Map<Class<? extends AbstractSmackIntTest>, String> impossibleTestClasses = new HashMap<>();
|
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() {
|
private TestRunResult() {
|
||||||
}
|
}
|
||||||
|
@ -631,8 +643,12 @@ public class SmackIntegrationTestFramework {
|
||||||
return testRunId;
|
return testRunId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumberOfTests() {
|
public int getNumberOfAvailableTests() {
|
||||||
return numberOfTests.get();
|
return numberOfAvailableTests.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumberOfPossibleTests() {
|
||||||
|
return numberOfPossibleTests.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SuccessfulTest> getSuccessfulTests() {
|
public List<SuccessfulTest> getSuccessfulTests() {
|
||||||
|
|
|
@ -55,12 +55,12 @@ public class ChatTest extends AbstractSmackIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() {
|
public void setUp() {
|
||||||
JivePropertiesManager.setJavaObjectEnabled(true);
|
JivePropertiesManager.setJavaObjectEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void tearDown() {
|
public void tearDown() {
|
||||||
JivePropertiesManager.setJavaObjectEnabled(false);
|
JivePropertiesManager.setJavaObjectEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../../smack-extensions/src/main/java/org/jivesoftware/smackx/caps/package-info.java
|
|
@ -81,7 +81,7 @@ public class IoTControlIntegrationTest extends AbstractSmackIntegrationTest {
|
||||||
IoTControlManagerOne.installThing(controlThing);
|
IoTControlManagerOne.installThing(controlThing);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, defaultTimeout);
|
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout);
|
||||||
|
|
||||||
SetData data = new SetBoolData(testRunId, true);
|
SetData data = new SetBoolData(testRunId, true);
|
||||||
IoTSetResponse response = IoTControlManagerTwo.setUsingIq(conOne.getUser(), data);
|
IoTSetResponse response = IoTControlManagerTwo.setUsingIq(conOne.getUser(), data);
|
||||||
|
@ -92,6 +92,6 @@ public class IoTControlIntegrationTest extends AbstractSmackIntegrationTest {
|
||||||
RosterIntegrationTest.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo);
|
RosterIntegrationTest.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncPoint.waitForResult(defaultTimeout);
|
syncPoint.waitForResult(timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class IoTDataIntegrationTest extends AbstractSmackIntegrationTest {
|
||||||
|
|
||||||
List<IoTFieldsExtension> values;
|
List<IoTFieldsExtension> values;
|
||||||
try {
|
try {
|
||||||
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, defaultTimeout);
|
RosterIntegrationTest.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout);
|
||||||
|
|
||||||
values = iotDataManagerTwo.requestMomentaryValuesReadOut(conOne.getUser());
|
values = iotDataManagerTwo.requestMomentaryValuesReadOut(conOne.getUser());
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class MultiUserChatIntegrationTest extends AbstractSmackIntegrationTest {
|
||||||
mucAsSeenByTwo.join(Resourcepart.from("two-" + randomString));
|
mucAsSeenByTwo.join(Resourcepart.from("two-" + randomString));
|
||||||
|
|
||||||
mucAsSeenByOne.sendMessage(mucMessage);
|
mucAsSeenByOne.sendMessage(mucMessage);
|
||||||
resultSyncPoint.waitForResult(defaultTimeout);
|
resultSyncPoint.waitForResult(timeout);
|
||||||
|
|
||||||
mucAsSeenByOne.leave();
|
mucAsSeenByOne.leave();
|
||||||
mucAsSeenByTwo.leave();
|
mucAsSeenByTwo.leave();
|
||||||
|
|
Loading…
Reference in a new issue