1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-06-23 20:14:51 +02:00
Smack/smack-tcp/src/test/java/org/jivesoftware/smack/tcp/PacketWriterTest.java
Florian Schmaus 701aa7d9c4 Merge branch '4.1'
Conflicts:
	smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java
	smack-core/src/main/java/org/jivesoftware/smack/PacketCollector.java
	smack-core/src/main/java/org/jivesoftware/smack/PacketListener.java
	smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java
	smack-core/src/main/java/org/jivesoftware/smack/debugger/SmackDebugger.java
	smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java
	smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java
	smack-core/src/test/java/org/jivesoftware/smack/ThreadedDummyConnection.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/address/provider/MultipleAddressesProvider.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/DataListener.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java
	smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java
	smack-extensions/src/test/java/org/jivesoftware/smackx/receipts/DeliveryReceiptTest.java
	smack-im/src/main/java/org/jivesoftware/smack/chat/ChatManager.java
	smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java
	smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleProvider.java
	smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/UserID.java
	smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/provider/RosterExchangeProvider.java
	smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java
	version.gradle
2015-03-04 22:42:36 +01:00

125 lines
4.2 KiB
Java

/**
*
* Copyright 2014 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.tcp;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection.PacketWriter;
import org.junit.Test;
import org.jxmpp.stringprep.XmppStringprepException;
import static org.junit.Assert.fail;
public class PacketWriterTest {
volatile boolean shutdown;
volatile boolean prematureUnblocked;
/**
* Make sure that packet writer does block once the queue reaches
* {@link PacketWriter#QUEUE_SIZE} and that
* {@link PacketWriter#sendStanza(org.jivesoftware.smack.tcp.packet.Packet)} does unblock after the
* interrupt.
*
* @throws InterruptedException
* @throws BrokenBarrierException
* @throws NotConnectedException
* @throws XmppStringprepException
*/
@SuppressWarnings("javadoc")
@Test
public void shouldBlockAndUnblockTest() throws InterruptedException, BrokenBarrierException, NotConnectedException, XmppStringprepException {
XMPPTCPConnection connection = new XMPPTCPConnection("user", "pass", "example.org");
final PacketWriter pw = connection.new PacketWriter();
connection.packetWriter = pw;
connection.packetReader = connection.new PacketReader();
connection.setWriter(new BlockingStringWriter());
pw.init();
for (int i = 0; i < XMPPTCPConnection.PacketWriter.QUEUE_SIZE; i++) {
pw.sendStreamElement(new Message());
}
final CyclicBarrier barrier = new CyclicBarrier(2);
shutdown = false;
prematureUnblocked = false;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
barrier.await();
pw.sendStreamElement(new Message());
// should only return after the pw was interrupted
if (!shutdown) {
prematureUnblocked = true;
}
}
catch (Exception e) {
}
try {
barrier.await();
}
catch (InterruptedException | BrokenBarrierException e) {
}
}
});
t.start();
// This barrier is not strictly necessary, but may increases the chances that the threat
// will block before we call shutdown. Otherwise we may get false positives (which is still
// better then false negatives).
barrier.await();
// Not really cool, but may increases the chances for 't' to block in sendStanza.
Thread.sleep(250);
// Set to true for testing purposes, so that shutdown() won't wait packet writer
pw.shutdownDone.reportSuccess();
// Shutdown the packetwriter
pw.shutdown(false);
shutdown = true;
barrier.await();
if (prematureUnblocked) {
fail("Should not unblock before the thread got shutdown");
}
synchronized (t) {
t.notify();
}
}
public class BlockingStringWriter extends Writer {
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
try {
wait();
}
catch (InterruptedException e) {
}
}
@Override
public void flush() throws IOException {
}
@Override
public void close() throws IOException {
}
}
}