FileTransferIntegrationTest.java

  1. /**
  2.  *
  3.  * Copyright 2015-2021 Florian Schmaus
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.filetransfer;

  18. import java.io.ByteArrayInputStream;
  19. import java.io.ByteArrayOutputStream;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.nio.charset.StandardCharsets;
  23. import java.util.Arrays;

  24. import org.jivesoftware.smack.SmackException;
  25. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  26. import org.jivesoftware.smack.util.StringUtils;
  27. import org.jivesoftware.smackx.filetransfer.FileTransfer.Status;

  28. import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
  29. import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
  30. import org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest;
  31. import org.igniterealtime.smack.inttest.util.ResultSyncPoint;

  32. public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest {

  33.     private static final int MAX_FT_DURATION = 360;

  34.     private final FileTransferManager ftManagerOne;
  35.     private final FileTransferManager ftManagerTwo;

  36.     public FileTransferIntegrationTest(SmackIntegrationTestEnvironment environment) {
  37.         super(environment);
  38.         ftManagerOne = FileTransferManager.getInstanceFor(conOne);
  39.         ftManagerTwo = FileTransferManager.getInstanceFor(conTwo);
  40.     }

  41.     private static final byte[] dataToSend;

  42.     static {
  43.         dataToSend = StringUtils.insecureRandomString(1024 * 4 * 5).getBytes(StandardCharsets.UTF_8);
  44.     }

  45.     @SmackIntegrationTest
  46.     public void fileTransferTest() throws Exception {
  47.         genericfileTransferTest();
  48.     }

  49.     @SmackIntegrationTest
  50.     public void ibbFileTransferTest() throws Exception {
  51.         FileTransferNegotiator.IBB_ONLY = true;
  52.         genericfileTransferTest();
  53.         FileTransferNegotiator.IBB_ONLY = false;
  54.     }

  55.     private void genericfileTransferTest() throws Exception {
  56.         final ResultSyncPoint<String, Exception> resultSyncPoint = new ResultSyncPoint<>();
  57.         final FileTransferListener receiveListener = new FileTransferListener() {
  58.             @Override
  59.             public void fileTransferRequest(FileTransferRequest request) {
  60.                 byte[] dataReceived;
  61.                 IncomingFileTransfer ift = request.accept();
  62.                 try {
  63.                     InputStream is = ift.receiveFile();
  64.                     ByteArrayOutputStream os = new ByteArrayOutputStream();
  65.                     int nRead;
  66.                     byte[] buf = new byte[1024];
  67.                     while ((nRead = is.read(buf, 0, buf.length)) != -1) {
  68.                         os.write(buf, 0, nRead);
  69.                     }
  70.                     os.flush();
  71.                     dataReceived = os.toByteArray();
  72.                     if (Arrays.equals(dataToSend, dataReceived)) {
  73.                         resultSyncPoint.signal("Received data matches send data. \\o/");
  74.                     }
  75.                     else {
  76.                         resultSyncPoint.signal(new Exception("Received data does not match"));
  77.                     }
  78.                 }
  79.                 catch (SmackException | IOException | XMPPErrorException | InterruptedException e) {
  80.                     resultSyncPoint.signal(e);
  81.                 }
  82.             }
  83.         };
  84.         ftManagerTwo.addFileTransferListener(receiveListener);

  85.         OutgoingFileTransfer oft = ftManagerOne.createOutgoingFileTransfer(conTwo.getUser());
  86.         oft.sendStream(new ByteArrayInputStream(dataToSend), "hello.txt", dataToSend.length, "A greeting");
  87.         int duration = 0;
  88.         while (!oft.isDone()) {
  89.             Status status = oft.getStatus();
  90.             switch (status) {
  91.             case error:
  92.                 FileTransfer.Error error = oft.getError();
  93.                 Exception exception = oft.getException();
  94.                 throw new Exception("FileTransfer error: " + error, exception);
  95.             default:
  96.                 LOGGER.info("FileTransfer status: " + oft.getStatus() + ". Progress: " + oft.getProgress());
  97.                 break;
  98.             }
  99.             Thread.sleep(1000);
  100.             if (++duration > MAX_FT_DURATION) {
  101.                 throw new Exception("Max duration reached");
  102.             }
  103.         }

  104.         resultSyncPoint.waitForResult(MAX_FT_DURATION * 1000);

  105.         ftManagerTwo.removeFileTransferListener(receiveListener);
  106.     }
  107. }