mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2025-12-06 05:01:12 +01:00
SmackReactor/NIO, Java8/Android19, Pretty print XML, FSM connections
This commit adds - SmackReactor / NIO - a framework for finite state machine connections - support for Java 8 - pretty printed XML debug output It also - reworks the integration test framework - raises the minimum Android API level to 19 - introduces XmppNioTcpConnection Furthermore fixes SMACK-801 (at least partly). Java 8 language features are available, but not all runtime library methods. For that we would need to raise the Android API level to 24 or higher.
This commit is contained in:
parent
dba12919d0
commit
e98d42790a
144 changed files with 8692 additions and 1455 deletions
|
|
@ -55,7 +55,7 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
|
||||
private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>();
|
||||
|
||||
public static ConnectionConfiguration.Builder<?,?> getDummyConfigurationBuilder() {
|
||||
public static DummyConnectionConfiguration.Builder getDummyConfigurationBuilder() {
|
||||
return DummyConnectionConfiguration.builder().setXmppDomain(JidTestUtil.EXAMPLE_ORG).setUsernameAndPassword("dummy",
|
||||
"dummypass");
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
}
|
||||
}
|
||||
|
||||
public DummyConnection(ConnectionConfiguration configuration) {
|
||||
public DummyConnection(DummyConnectionConfiguration configuration) {
|
||||
super(configuration);
|
||||
|
||||
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package org.jivesoftware.smack;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
|
||||
|
|
@ -55,34 +57,42 @@ public class StanzaCollectorTest {
|
|||
assertEquals("14", collector.pollResult().getStanzaId());
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
assertNull(collector.nextResult(1000));
|
||||
assertNull(collector.nextResult(10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Although this doesn't guarentee anything due to the nature of threading, it can potentially
|
||||
* Although this doesn't guarantee anything due to the nature of threading, it can potentially
|
||||
* catch problems.
|
||||
*
|
||||
* @throws InterruptedException if interrupted.
|
||||
*/
|
||||
@SuppressWarnings("ThreadPriorityCheck")
|
||||
@Test
|
||||
public void verifyThreadSafety() {
|
||||
int insertCount = 500;
|
||||
public void verifyThreadSafety() throws InterruptedException {
|
||||
final int insertCount = 500;
|
||||
final TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), insertCount);
|
||||
|
||||
final AtomicInteger consumer1Dequeued = new AtomicInteger();
|
||||
final AtomicInteger consumer2Dequeued = new AtomicInteger();
|
||||
final AtomicInteger consumer3Dequeued = new AtomicInteger();
|
||||
|
||||
Thread consumer1 = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int dequeueCount = 0;
|
||||
try {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(3);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
Thread.yield();
|
||||
Stanza packet = collector.nextResultBlockForever();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + packet);
|
||||
if (packet != null) {
|
||||
dequeueCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
// Ignore as it is expected.
|
||||
} finally {
|
||||
consumer1Dequeued.set(dequeueCount);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -92,20 +102,20 @@ public class StanzaCollectorTest {
|
|||
@Override
|
||||
public void run() {
|
||||
Stanza p;
|
||||
|
||||
int dequeueCount = 0;
|
||||
do {
|
||||
Thread.yield();
|
||||
try {
|
||||
Thread.sleep(3);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
try {
|
||||
p = collector.nextResult(1);
|
||||
p = collector.nextResult(1000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
if (p != null) {
|
||||
dequeueCount++;
|
||||
}
|
||||
}
|
||||
while (p != null);
|
||||
consumer2Dequeued.set(dequeueCount);
|
||||
}
|
||||
});
|
||||
consumer2.setName("consumer 2");
|
||||
|
|
@ -114,37 +124,42 @@ public class StanzaCollectorTest {
|
|||
@Override
|
||||
public void run() {
|
||||
Stanza p;
|
||||
|
||||
int dequeueCount = 0;
|
||||
do {
|
||||
try {
|
||||
Thread.sleep(3);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
Thread.yield();
|
||||
p = collector.pollResult();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
if (p != null) {
|
||||
dequeueCount++;
|
||||
}
|
||||
} while (p != null);
|
||||
consumer3Dequeued.set(dequeueCount);
|
||||
}
|
||||
});
|
||||
consumer3.setName("consumer 3");
|
||||
|
||||
consumer1.start();
|
||||
consumer2.start();
|
||||
consumer3.start();
|
||||
|
||||
for (int i = 0; i < insertCount; i++) {
|
||||
collector.processStanza(new TestPacket(i));
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
consumer3.join();
|
||||
consumer2.join();
|
||||
consumer1.interrupt();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
consumer1.start();
|
||||
consumer2.start();
|
||||
consumer3.start();
|
||||
|
||||
consumer3.join();
|
||||
consumer2.join();
|
||||
consumer1.interrupt();
|
||||
consumer1.join();
|
||||
|
||||
// We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
|
||||
// and main, but the probability is extremely remote.
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
int consumer1DequeuedLocal = consumer1Dequeued.get();
|
||||
int consumer2DequeuedLocal = consumer2Dequeued.get();
|
||||
int consumer3DequeuedLocal = consumer3Dequeued.get();
|
||||
final int totalDequeued = consumer1DequeuedLocal + consumer2DequeuedLocal + consumer3DequeuedLocal;
|
||||
assertEquals("Inserted " + insertCount + " but only " + totalDequeued + " c1: " + consumer1DequeuedLocal + " c2: " + consumer2DequeuedLocal + " c3: "
|
||||
+ consumer3DequeuedLocal, insertCount, totalDequeued);
|
||||
}
|
||||
|
||||
static class OKEverything implements StanzaFilter {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 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.smack.compress.packet;
|
||||
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jivesoftware.smack.packet.StanzaError;
|
||||
import org.jivesoftware.smack.packet.StanzaError.Condition;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public class FailureTest {
|
||||
|
||||
@Test
|
||||
public void simpleFailureTest() throws SAXException, IOException {
|
||||
Failure failure = new Failure(Failure.CompressFailureError.processing_failed);
|
||||
CharSequence xml = failure.toXML(null);
|
||||
|
||||
final String expectedXml = "<failure xmlns='http://jabber.org/protocol/compress'><processing-failed/></failure>";
|
||||
|
||||
assertXMLEqual(expectedXml, xml.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withStanzaErrrorFailureTest() throws SAXException, IOException {
|
||||
StanzaError stanzaError = StanzaError.getBuilder()
|
||||
.setCondition(Condition.bad_request)
|
||||
.build();
|
||||
Failure failure = new Failure(Failure.CompressFailureError.setup_failed, stanzaError);
|
||||
CharSequence xml = failure.toXML(null);
|
||||
|
||||
final String expectedXml = "<failure xmlns='http://jabber.org/protocol/compress'>"
|
||||
+ "<setup-failed/>"
|
||||
+ "<error xmlns='jabber:client' type='modify'>"
|
||||
+ "<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
|
||||
+ "</error>"
|
||||
+ "</failure>";
|
||||
|
||||
assertXMLEqual(expectedXml, xml.toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 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.smack.compress.provider;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.jivesoftware.smack.compress.packet.Failure;
|
||||
import org.jivesoftware.smack.packet.StanzaError;
|
||||
import org.jivesoftware.smack.packet.StanzaError.Condition;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class FailureProviderTest {
|
||||
|
||||
@Test
|
||||
public void simpleFailureTest() throws Exception {
|
||||
final String xml = "<failure xmlns='http://jabber.org/protocol/compress'><processing-failed/></failure>";
|
||||
final XmlPullParser parser = PacketParserUtils.getParserFor(xml);
|
||||
final Failure failure = FailureProvider.INSTANCE.parse(parser);
|
||||
|
||||
assertEquals(Failure.CompressFailureError.processing_failed, failure.getCompressFailureError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withStanzaErrrorFailureTest() throws Exception {
|
||||
final String xml = "<failure xmlns='http://jabber.org/protocol/compress'>"
|
||||
+ "<setup-failed/>"
|
||||
+ "<error xmlns='jabber:client' type='modify'>"
|
||||
+ "<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
|
||||
+ "</error>"
|
||||
+ "</failure>";
|
||||
final XmlPullParser parser = PacketParserUtils.getParserFor(xml);
|
||||
final Failure failure = FailureProvider.INSTANCE.parse(parser);
|
||||
|
||||
assertEquals(Failure.CompressFailureError.setup_failed, failure.getCompressFailureError());
|
||||
|
||||
final StanzaError error = failure.getStanzaError();
|
||||
assertEquals(Condition.bad_request, error.getCondition());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue