aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/remotelinux/linuxdevicetester.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/remotelinux/linuxdevicetester.cpp')
-rw-r--r--src/plugins/remotelinux/linuxdevicetester.cpp98
1 files changed, 57 insertions, 41 deletions
diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp
index 3c34a638202..37aea361123 100644
--- a/src/plugins/remotelinux/linuxdevicetester.cpp
+++ b/src/plugins/remotelinux/linuxdevicetester.cpp
@@ -10,20 +10,21 @@
#include <projectexplorer/devicesupport/filetransfer.h>
#include <utils/algorithm.h>
+#include <utils/process.h>
#include <utils/processinterface.h>
#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
+#include <utils/stringutils.h>
using namespace ProjectExplorer;
+using namespace Tasking;
using namespace Utils;
-using namespace Utils::Tasking;
namespace RemoteLinux {
namespace Internal {
struct TransferStorage
{
- bool sftpWorks = false;
+ bool useGenericCopy = false;
};
class GenericLinuxDeviceTesterPrivate
@@ -33,7 +34,7 @@ public:
QStringList commandsToTest() const;
- TaskItem echoTask() const;
+ TaskItem echoTask(const QString &contents) const;
TaskItem unameTask() const;
TaskItem gathererTask() const;
TaskItem transferTask(FileTransferMethod method,
@@ -49,8 +50,6 @@ public:
QList<TaskItem> m_extraTests;
};
-static const char s_echoContents[] = "Hello Remote World!";
-
QStringList GenericLinuxDeviceTesterPrivate::commandsToTest() const
{
static const QStringList s_commandsToTest = {"base64",
@@ -91,48 +90,49 @@ QStringList GenericLinuxDeviceTesterPrivate::commandsToTest() const
return commands;
}
-TaskItem GenericLinuxDeviceTesterPrivate::echoTask() const
+TaskItem GenericLinuxDeviceTesterPrivate::echoTask(const QString &contents) const
{
- const auto setup = [this](QtcProcess &process) {
+ const auto setup = [this, contents](Process &process) {
emit q->progressMessage(Tr::tr("Sending echo to device..."));
- process.setCommand({m_device->filePath("echo"), {s_echoContents}});
+ process.setCommand({m_device->filePath("echo"), {contents}});
};
- const auto done = [this](const QtcProcess &process) {
- const QString reply = process.cleanedStdOut().chopped(1); // Remove trailing '\n'
- if (reply != s_echoContents)
- emit q->errorMessage(Tr::tr("Device replied to echo with unexpected contents.") + '\n');
+ const auto done = [this, contents](const Process &process) {
+ const QString reply = Utils::chopIfEndsWith(process.cleanedStdOut(), '\n');
+ if (reply != contents)
+ emit q->errorMessage(Tr::tr("Device replied to echo with unexpected contents: \"%1\"")
+ .arg(reply) + '\n');
else
emit q->progressMessage(Tr::tr("Device replied to echo with expected contents.") + '\n');
};
- const auto error = [this](const QtcProcess &process) {
+ const auto error = [this](const Process &process) {
const QString stdErrOutput = process.cleanedStdErr();
if (!stdErrOutput.isEmpty())
emit q->errorMessage(Tr::tr("echo failed: %1").arg(stdErrOutput) + '\n');
else
emit q->errorMessage(Tr::tr("echo failed.") + '\n');
};
- return Process(setup, done, error);
+ return ProcessTask(setup, done, error);
}
TaskItem GenericLinuxDeviceTesterPrivate::unameTask() const
{
- const auto setup = [this](QtcProcess &process) {
+ const auto setup = [this](Process &process) {
emit q->progressMessage(Tr::tr("Checking kernel version..."));
process.setCommand({m_device->filePath("uname"), {"-rsm"}});
};
- const auto done = [this](const QtcProcess &process) {
+ const auto done = [this](const Process &process) {
emit q->progressMessage(process.cleanedStdOut());
};
- const auto error = [this](const QtcProcess &process) {
+ const auto error = [this](const Process &process) {
const QString stdErrOutput = process.cleanedStdErr();
if (!stdErrOutput.isEmpty())
emit q->errorMessage(Tr::tr("uname failed: %1").arg(stdErrOutput) + '\n');
else
emit q->errorMessage(Tr::tr("uname failed.") + '\n');
};
- return Tasking::Group {
- optional,
- Process(setup, done, error)
+ return Group {
+ finishAllAndDone,
+ ProcessTask(setup, done, error)
};
}
@@ -154,9 +154,14 @@ TaskItem GenericLinuxDeviceTesterPrivate::gathererTask() const
}
};
const auto error = [this](const DeviceUsedPortsGatherer &gatherer) {
- emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n');
+ emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n'
+ + Tr::tr("Some tools will not work out of the box.\n"));
+ };
+
+ return Group {
+ finishAllAndDone,
+ DeviceUsedPortsGathererTask(setup, done, error)
};
- return PortGatherer(setup, done, error);
}
TaskItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method,
@@ -173,8 +178,10 @@ TaskItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method
emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName));
if (method == FileTransferMethod::Rsync)
m_device->setExtraData(Constants::SupportsRSync, true);
+ else if (method == FileTransferMethod::Sftp)
+ m_device->setExtraData(Constants::SupportsSftp, true);
else
- storage->sftpWorks = true;
+ storage->useGenericCopy = true;
};
const auto error = [this, method, storage](const FileTransfer &transfer) {
const QString methodName = FileTransfer::transferMethodName(method);
@@ -189,28 +196,36 @@ TaskItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method
.arg(methodName).arg(resultData.m_exitCode).arg(resultData.m_errorString);
}
emit q->errorMessage(error);
- if (method == FileTransferMethod::Rsync) {
+ if (method == FileTransferMethod::Rsync)
m_device->setExtraData(Constants::SupportsRSync, false);
- if (!storage->sftpWorks)
- return;
+ else if (method == FileTransferMethod::Sftp)
+ m_device->setExtraData(Constants::SupportsSftp, false);
+
+ const QVariant supportsRSync = m_device->extraData(Constants::SupportsRSync);
+ const QVariant supportsSftp = m_device->extraData(Constants::SupportsSftp);
+ if (supportsRSync.isValid() && !supportsRSync.toBool()
+ && supportsSftp.isValid() && !supportsSftp.toBool()) {
+ const QString generic = FileTransfer::transferMethodName(FileTransferMethod::GenericCopy);
const QString sftp = FileTransfer::transferMethodName(FileTransferMethod::Sftp);
- const QString rsync = methodName;
+ const QString rsync = FileTransfer::transferMethodName(FileTransferMethod::Rsync);
emit q->progressMessage(Tr::tr("\"%1\" will be used for deployment, because \"%2\" "
- "is not available.\n").arg(sftp, rsync));
+ "and \"%3\" are not available.\n")
+ .arg(generic, sftp, rsync));
}
};
- return TransferTest(setup, done, error);
+ return FileTransferTestTask(setup, done, error);
}
TaskItem GenericLinuxDeviceTesterPrivate::transferTasks() const
{
TreeStorage<TransferStorage> storage;
- return Tasking::Group {
+ return Group {
continueOnDone,
Storage(storage),
+ transferTask(FileTransferMethod::GenericCopy, storage),
transferTask(FileTransferMethod::Sftp, storage),
transferTask(FileTransferMethod::Rsync, storage),
- OnGroupError([this] { emit q->errorMessage(Tr::tr("Deployment to this device will not "
+ onGroupError([this] { emit q->errorMessage(Tr::tr("Deployment to this device will not "
"work out of the box.\n"));
})
};
@@ -218,34 +233,34 @@ TaskItem GenericLinuxDeviceTesterPrivate::transferTasks() const
TaskItem GenericLinuxDeviceTesterPrivate::commandTask(const QString &commandName) const
{
- const auto setup = [this, commandName](QtcProcess &process) {
+ const auto setup = [this, commandName](Process &process) {
emit q->progressMessage(Tr::tr("%1...").arg(commandName));
CommandLine command{m_device->filePath("/bin/sh"), {"-c"}};
command.addArgs(QLatin1String("\"command -v %1\"").arg(commandName), CommandLine::Raw);
process.setCommand(command);
};
- const auto done = [this, commandName](const QtcProcess &) {
+ const auto done = [this, commandName](const Process &) {
emit q->progressMessage(Tr::tr("%1 found.").arg(commandName));
};
- const auto error = [this, commandName](const QtcProcess &process) {
+ const auto error = [this, commandName](const Process &process) {
const QString message = process.result() == ProcessResult::StartFailed
? Tr::tr("An error occurred while checking for %1.").arg(commandName)
+ '\n' + process.errorString()
: Tr::tr("%1 not found.").arg(commandName);
emit q->errorMessage(message);
};
- return Process(setup, done, error);
+ return ProcessTask(setup, done, error);
}
TaskItem GenericLinuxDeviceTesterPrivate::commandTasks() const
{
QList<TaskItem> tasks {continueOnError};
- tasks.append(OnGroupSetup([this] {
+ tasks.append(onGroupSetup([this] {
emit q->progressMessage(Tr::tr("Checking if required commands are available..."));
}));
for (const QString &commandName : commandsToTest())
tasks.append(commandTask(commandName));
- return Tasking::Group {tasks};
+ return Group {tasks};
}
} // namespace Internal
@@ -281,7 +296,8 @@ void GenericLinuxDeviceTester::testDevice(const IDevice::Ptr &deviceConfiguratio
};
QList<TaskItem> taskItems = {
- d->echoTask(),
+ d->echoTask("Hello"), // No quoting necessary
+ d->echoTask("Hello Remote World!"), // Checks quoting, too.
d->unameTask(),
d->gathererTask(),
d->transferTasks()
@@ -289,8 +305,8 @@ void GenericLinuxDeviceTester::testDevice(const IDevice::Ptr &deviceConfiguratio
if (!d->m_extraTests.isEmpty())
taskItems << Group { d->m_extraTests };
taskItems << d->commandTasks()
- << OnGroupDone(std::bind(allFinished, TestSuccess))
- << OnGroupError(std::bind(allFinished, TestFailure));
+ << onGroupDone(std::bind(allFinished, TestSuccess))
+ << onGroupError(std::bind(allFinished, TestFailure));
d->m_taskTree.reset(new TaskTree(taskItems));
d->m_taskTree->start();