aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/remotelinux/filesystemaccess_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/remotelinux/filesystemaccess_test.cpp')
-rw-r--r--src/plugins/remotelinux/filesystemaccess_test.cpp360
1 files changed, 355 insertions, 5 deletions
diff --git a/src/plugins/remotelinux/filesystemaccess_test.cpp b/src/plugins/remotelinux/filesystemaccess_test.cpp
index fcc8477974a..2edb78fa7b3 100644
--- a/src/plugins/remotelinux/filesystemaccess_test.cpp
+++ b/src/plugins/remotelinux/filesystemaccess_test.cpp
@@ -9,7 +9,11 @@
#include <projectexplorer/devicesupport/filetransfer.h>
#include <projectexplorer/devicesupport/sshparameters.h>
#include <utils/filepath.h>
+#include <utils/filestreamer.h>
+#include <utils/filestreamermanager.h>
+#include <utils/process.h>
#include <utils/processinterface.h>
+#include <utils/scopedtimer.h>
#include <QDebug>
#include <QFile>
@@ -86,6 +90,45 @@ void FileSystemAccessTest::initTestCase()
QVERIFY(!filePath.exists());
QVERIFY(filePath.createDir());
QVERIFY(filePath.exists());
+
+ const QString streamerLocalDir("streamerLocalDir");
+ const QString streamerRemoteDir("streamerRemoteDir");
+ const QString sourceDir("source");
+ const QString destDir("dest");
+ const QString localDir("local");
+ const QString remoteDir("remote");
+ const FilePath localRoot;
+ const FilePath remoteRoot = m_device->rootPath();
+ const FilePath localTempDir = *localRoot.tmpDir();
+ const FilePath remoteTempDir = *remoteRoot.tmpDir();
+ m_localStreamerDir = localTempDir / streamerLocalDir;
+ m_remoteStreamerDir = remoteTempDir / streamerRemoteDir;
+ m_localSourceDir = m_localStreamerDir / sourceDir;
+ m_remoteSourceDir = m_remoteStreamerDir / sourceDir;
+ m_localDestDir = m_localStreamerDir / destDir;
+ m_remoteDestDir = m_remoteStreamerDir / destDir;
+ m_localLocalDestDir = m_localDestDir / localDir;
+ m_localRemoteDestDir = m_localDestDir / remoteDir;
+ m_remoteLocalDestDir = m_remoteDestDir / localDir;
+ m_remoteRemoteDestDir = m_remoteDestDir / remoteDir;
+
+ QVERIFY(m_localSourceDir.createDir());
+ QVERIFY(m_remoteSourceDir.createDir());
+ QVERIFY(m_localDestDir.createDir());
+ QVERIFY(m_remoteDestDir.createDir());
+ QVERIFY(m_localLocalDestDir.createDir());
+ QVERIFY(m_localRemoteDestDir.createDir());
+ QVERIFY(m_remoteLocalDestDir.createDir());
+ QVERIFY(m_remoteRemoteDestDir.createDir());
+
+ QVERIFY(m_localSourceDir.exists());
+ QVERIFY(m_remoteSourceDir.exists());
+ QVERIFY(m_localDestDir.exists());
+ QVERIFY(m_remoteDestDir.exists());
+ QVERIFY(m_localLocalDestDir.exists());
+ QVERIFY(m_localRemoteDestDir.exists());
+ QVERIFY(m_remoteLocalDestDir.exists());
+ QVERIFY(m_remoteRemoteDestDir.exists());
}
void FileSystemAccessTest::cleanupTestCase()
@@ -94,6 +137,14 @@ void FileSystemAccessTest::cleanupTestCase()
return;
QVERIFY(baseFilePath().exists());
QVERIFY(baseFilePath().removeRecursively());
+
+ QVERIFY(m_localStreamerDir.removeRecursively());
+ QVERIFY(m_remoteStreamerDir.removeRecursively());
+
+ QVERIFY(!m_localStreamerDir.exists());
+ QVERIFY(!m_remoteStreamerDir.exists());
+
+ FileStreamerManager::stopAll();
}
void FileSystemAccessTest::testCreateRemoteFile_data()
@@ -102,13 +153,13 @@ void FileSystemAccessTest::testCreateRemoteFile_data()
QTest::newRow("Spaces") << QByteArray("Line with spaces");
QTest::newRow("Newlines") << QByteArray("Some \n\n newlines \n");
- QTest::newRow("Carriage return") << QByteArray("Line with carriage \r return");
+ QTest::newRow("CarriageReturn") << QByteArray("Line with carriage \r return");
QTest::newRow("Tab") << QByteArray("Line with \t tab");
QTest::newRow("Apostrophe") << QByteArray("Line with apostrophe's character");
- QTest::newRow("Quotation marks") << QByteArray("Line with \"quotation marks\"");
- QTest::newRow("Backslash 1") << QByteArray("Line with \\ backslash");
- QTest::newRow("Backslash 2") << QByteArray("Line with \\\" backslash");
- QTest::newRow("Command output") << QByteArray("The date is: $(date +%D)");
+ QTest::newRow("QuotationMarks") << QByteArray("Line with \"quotation marks\"");
+ QTest::newRow("Backslash1") << QByteArray("Line with \\ backslash");
+ QTest::newRow("Backslash2") << QByteArray("Line with \\\" backslash");
+ QTest::newRow("CommandOutput") << QByteArray("The date is: $(date +%D)");
const int charSize = sizeof(char) * 0x100;
QByteArray charString(charSize, Qt::Uninitialized);
@@ -132,6 +183,21 @@ void FileSystemAccessTest::testCreateRemoteFile()
QVERIFY(!testFilePath.exists());
}
+void FileSystemAccessTest::testWorkingDirectory()
+{
+ const FilePath dir = baseFilePath() / "testdir with space and 'various' \"quotes\" here";
+ QVERIFY(dir.ensureWritableDir());
+ Process proc;
+ proc.setCommand({"pwd", {}});
+ proc.setWorkingDirectory(dir);
+ proc.start();
+ QVERIFY(proc.waitForFinished());
+ const QString out = proc.readAllStandardOutput().trimmed();
+ QCOMPARE(out, dir.path());
+ const QString err = proc.readAllStandardOutput();
+ QVERIFY(err.isEmpty());
+}
+
void FileSystemAccessTest::testDirStatus()
{
FilePath filePath = baseFilePath();
@@ -201,6 +267,8 @@ void FileSystemAccessTest::testFileTransfer_data()
QTest::addColumn<FileTransferMethod>("fileTransferMethod");
QTest::addRow("Sftp") << FileTransferMethod::Sftp;
+ // TODO: By default rsync doesn't support creating target directories,
+ // needs to be done manually - see RsyncDeployService.
// QTest::addRow("Rsync") << FileTransferMethod::Rsync;
}
@@ -282,5 +350,287 @@ void FileSystemAccessTest::testFileTransfer()
QVERIFY2(remoteDir.removeRecursively(&errorString), qPrintable(errorString));
}
+void FileSystemAccessTest::testFileStreamer_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QByteArray>("data");
+
+ const QByteArray spaces("Line with spaces");
+ const QByteArray newlines("Some \n\n newlines \n");
+ const QByteArray carriageReturn("Line with carriage \r return");
+ const QByteArray tab("Line with \t tab");
+ const QByteArray apostrophe("Line with apostrophe's character");
+ const QByteArray quotationMarks("Line with \"quotation marks\"");
+ const QByteArray backslash1("Line with \\ backslash");
+ const QByteArray backslash2("Line with \\\" backslash");
+ const QByteArray commandOutput("The date is: $(date +%D)");
+
+ const int charSize = sizeof(char) * 0x100;
+ QByteArray charString(charSize, Qt::Uninitialized);
+ char *data = charString.data();
+ for (int c = 0; c < charSize; ++c)
+ data[c] = c;
+
+ const int bigSize = 1024 * 1024; // = 256 * 1024 * 1024 = 268.435.456 bytes
+ QByteArray bigString;
+ for (int i = 0; i < bigSize; ++i)
+ bigString += charString;
+
+ QTest::newRow("Spaces") << QString("spaces") << spaces;
+ QTest::newRow("Newlines") << QString("newlines") << newlines;
+ QTest::newRow("CarriageReturn") << QString("carriageReturn") << carriageReturn;
+ QTest::newRow("Tab") << QString("tab") << tab;
+ QTest::newRow("Apostrophe") << QString("apostrophe") << apostrophe;
+ QTest::newRow("QuotationMarks") << QString("quotationMarks") << quotationMarks;
+ QTest::newRow("Backslash1") << QString("backslash1") << backslash1;
+ QTest::newRow("Backslash2") << QString("backslash2") << backslash2;
+ QTest::newRow("CommandOutput") << QString("commandOutput") << commandOutput;
+ QTest::newRow("AllCharacters") << QString("charString") << charString;
+ QTest::newRow("BigString") << QString("bigString") << bigString;
+}
+
+void FileSystemAccessTest::testFileStreamer()
+{
+ QTC_SCOPED_TIMER("testFileStreamer");
+
+ QFETCH(QString, fileName);
+ QFETCH(QByteArray, data);
+
+ const FilePath localSourcePath = m_localSourceDir / fileName;
+ const FilePath remoteSourcePath = m_remoteSourceDir / fileName;
+ const FilePath localLocalDestPath = m_localDestDir / "local" / fileName;
+ const FilePath localRemoteDestPath = m_localDestDir / "remote" / fileName;
+ const FilePath remoteLocalDestPath = m_remoteDestDir / "local" / fileName;
+ const FilePath remoteRemoteDestPath = m_remoteDestDir / "remote" / fileName;
+
+ localSourcePath.removeFile();
+ remoteSourcePath.removeFile();
+ localLocalDestPath.removeFile();
+ localRemoteDestPath.removeFile();
+ remoteLocalDestPath.removeFile();
+ remoteRemoteDestPath.removeFile();
+
+ QVERIFY(!localSourcePath.exists());
+ QVERIFY(!remoteSourcePath.exists());
+ QVERIFY(!localLocalDestPath.exists());
+ QVERIFY(!localRemoteDestPath.exists());
+ QVERIFY(!remoteLocalDestPath.exists());
+ QVERIFY(!remoteRemoteDestPath.exists());
+
+ std::optional<QByteArray> localData;
+ std::optional<QByteArray> remoteData;
+ std::optional<QByteArray> localLocalData;
+ std::optional<QByteArray> localRemoteData;
+ std::optional<QByteArray> remoteLocalData;
+ std::optional<QByteArray> remoteRemoteData;
+
+ using namespace Tasking;
+
+ const auto localWriter = [&] {
+ const auto setup = [&](FileStreamer &streamer) {
+ streamer.setStreamMode(StreamMode::Writer);
+ streamer.setDestination(localSourcePath);
+ streamer.setWriteData(data);
+ };
+ return FileStreamerTask(setup);
+ };
+ const auto remoteWriter = [&] {
+ const auto setup = [&](FileStreamer &streamer) {
+ streamer.setStreamMode(StreamMode::Writer);
+ streamer.setDestination(remoteSourcePath);
+ streamer.setWriteData(data);
+ };
+ return FileStreamerTask(setup);
+ };
+ const auto localReader = [&] {
+ const auto setup = [&](FileStreamer &streamer) {
+ streamer.setStreamMode(StreamMode::Reader);
+ streamer.setSource(localSourcePath);
+ };
+ const auto onDone = [&](const FileStreamer &streamer) {
+ localData = streamer.readData();
+ };
+ return FileStreamerTask(setup, onDone);
+ };
+ const auto remoteReader = [&] {
+ const auto setup = [&](FileStreamer &streamer) {
+ streamer.setStreamMode(StreamMode::Reader);
+ streamer.setSource(remoteSourcePath);
+ };
+ const auto onDone = [&](const FileStreamer &streamer) {
+ remoteData = streamer.readData();
+ };
+ return FileStreamerTask(setup, onDone);
+ };
+ const auto transfer = [](const FilePath &source, const FilePath &dest,
+ std::optional<QByteArray> *result) {
+ const auto setupTransfer = [=](FileStreamer &streamer) {
+ streamer.setSource(source);
+ streamer.setDestination(dest);
+ };
+ const auto setupReader = [=](FileStreamer &streamer) {
+ streamer.setStreamMode(StreamMode::Reader);
+ streamer.setSource(dest);
+ };
+ const auto onReaderDone = [result](const FileStreamer &streamer) {
+ *result = streamer.readData();
+ };
+ const Group root {
+ FileStreamerTask(setupTransfer),
+ FileStreamerTask(setupReader, onReaderDone)
+ };
+ return root;
+ };
+
+ // In total: 5 local reads, 3 local writes, 5 remote reads, 3 remote writes
+ const Group root {
+ Group {
+ parallel,
+ localWriter(),
+ remoteWriter()
+ },
+ Group {
+ parallel,
+ localReader(),
+ remoteReader()
+ },
+ Group {
+ parallel,
+ transfer(localSourcePath, localLocalDestPath, &localLocalData),
+ transfer(remoteSourcePath, localRemoteDestPath, &localRemoteData),
+ transfer(localSourcePath, remoteLocalDestPath, &remoteLocalData),
+ transfer(remoteSourcePath, remoteRemoteDestPath, &remoteRemoteData),
+ }
+ };
+
+ using namespace std::chrono_literals;
+ QVERIFY(TaskTree::runBlocking(root, 10000ms));
+
+ QVERIFY(localData);
+ QCOMPARE(*localData, data);
+ QVERIFY(remoteData);
+ QCOMPARE(*remoteData, data);
+
+ QVERIFY(localLocalData);
+ QCOMPARE(*localLocalData, data);
+ QVERIFY(localRemoteData);
+ QCOMPARE(*localRemoteData, data);
+ QVERIFY(remoteLocalData);
+ QCOMPARE(*remoteLocalData, data);
+ QVERIFY(remoteRemoteData);
+ QCOMPARE(*remoteRemoteData, data);
+}
+
+void FileSystemAccessTest::testFileStreamerManager_data()
+{
+ testFileStreamer_data();
+}
+
+void FileSystemAccessTest::testFileStreamerManager()
+{
+ QTC_SCOPED_TIMER("testFileStreamerManager");
+
+ QFETCH(QString, fileName);
+ QFETCH(QByteArray, data);
+
+ const FilePath localSourcePath = m_localSourceDir / fileName;
+ const FilePath remoteSourcePath = m_remoteSourceDir / fileName;
+ const FilePath localLocalDestPath = m_localDestDir / "local" / fileName;
+ const FilePath localRemoteDestPath = m_localDestDir / "remote" / fileName;
+ const FilePath remoteLocalDestPath = m_remoteDestDir / "local" / fileName;
+ const FilePath remoteRemoteDestPath = m_remoteDestDir / "remote" / fileName;
+
+ localSourcePath.removeFile();
+ remoteSourcePath.removeFile();
+ localLocalDestPath.removeFile();
+ localRemoteDestPath.removeFile();
+ remoteLocalDestPath.removeFile();
+ remoteRemoteDestPath.removeFile();
+
+ QVERIFY(!localSourcePath.exists());
+ QVERIFY(!remoteSourcePath.exists());
+ QVERIFY(!localLocalDestPath.exists());
+ QVERIFY(!localRemoteDestPath.exists());
+ QVERIFY(!remoteLocalDestPath.exists());
+ QVERIFY(!remoteRemoteDestPath.exists());
+
+ std::optional<QByteArray> localData;
+ std::optional<QByteArray> remoteData;
+ std::optional<QByteArray> localLocalData;
+ std::optional<QByteArray> localRemoteData;
+ std::optional<QByteArray> remoteLocalData;
+ std::optional<QByteArray> remoteRemoteData;
+
+ QEventLoop eventLoop1;
+ QEventLoop *loop = &eventLoop1;
+ int counter = 0;
+ int *hitCount = &counter;
+
+ const auto writeAndRead = [hitCount, loop, data](const FilePath &destination,
+ std::optional<QByteArray> *result) {
+ const auto onWrite = [hitCount, loop, destination, result]
+ (const expected_str<qint64> &writeResult) {
+ QVERIFY(writeResult);
+ const auto onRead = [hitCount, loop, result]
+ (const expected_str<QByteArray> &readResult) {
+ QVERIFY(readResult);
+ *result = *readResult;
+ ++(*hitCount);
+ if (*hitCount == 2)
+ loop->quit();
+ };
+ FileStreamerManager::read(destination, onRead);
+ };
+ FileStreamerManager::write(destination, data, onWrite);
+ };
+
+ writeAndRead(localSourcePath, &localData);
+ writeAndRead(remoteSourcePath, &remoteData);
+ loop->exec();
+
+ QVERIFY(localData);
+ QCOMPARE(*localData, data);
+ QVERIFY(remoteData);
+ QCOMPARE(*remoteData, data);
+
+ QEventLoop eventLoop2;
+ loop = &eventLoop2;
+ counter = 0;
+
+ const auto transferAndRead = [hitCount, loop, data](const FilePath &source,
+ const FilePath &destination,
+ std::optional<QByteArray> *result) {
+ const auto onTransfer = [hitCount, loop, destination, result]
+ (const expected_str<void> &transferResult) {
+ QVERIFY(transferResult);
+ const auto onRead = [hitCount, loop, result]
+ (const expected_str<QByteArray> &readResult) {
+ QVERIFY(readResult);
+ *result = *readResult;
+ ++(*hitCount);
+ if (*hitCount == 4)
+ loop->quit();
+ };
+ FileStreamerManager::read(destination, onRead);
+ };
+ FileStreamerManager::copy(source, destination, onTransfer);
+ };
+
+ transferAndRead(localSourcePath, localLocalDestPath, &localLocalData);
+ transferAndRead(remoteSourcePath, localRemoteDestPath, &localRemoteData);
+ transferAndRead(localSourcePath, remoteLocalDestPath, &remoteLocalData);
+ transferAndRead(remoteSourcePath, remoteRemoteDestPath, &remoteRemoteData);
+ loop->exec();
+
+ QVERIFY(localLocalData);
+ QCOMPARE(*localLocalData, data);
+ QVERIFY(localRemoteData);
+ QCOMPARE(*localRemoteData, data);
+ QVERIFY(remoteLocalData);
+ QCOMPARE(*remoteLocalData, data);
+ QVERIFY(remoteRemoteData);
+ QCOMPARE(*remoteRemoteData, data);
+}
+
} // Internal
} // RemoteLinux