linuxdevice: Fix ::bytesAvailable

DeviceShell does not support piping commands at the moment.

To continue to support ::bytesAvailable the parsing of the
output from "df" is moved to FileUtils::bytesAvailableFromDFOutput.

Change-Id: Ia229208748aa6c572b99899e6ae042bdd5654f4a
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Marcus Tillmanns
2022-09-14 14:19:59 +02:00
parent 704fb9c0e6
commit ed46f1f002
4 changed files with 55 additions and 6 deletions

View File

@@ -531,4 +531,26 @@ void FileUtils::iterateLsOutput(const FilePath &base,
#endif // QT_WIDGETS_LIB
qint64 FileUtils::bytesAvailableFromDFOutput(const QByteArray &dfOutput)
{
const auto lines = filtered(dfOutput.split('\n'),
[](const QByteArray &line) { return line.size() > 0; });
QTC_ASSERT(lines.size() == 2, return -1);
const auto headers = filtered(lines[0].split(' '),
[](const QByteArray &field) { return field.size() > 0; });
QTC_ASSERT(headers.size() >= 4, return -1);
QTC_ASSERT(headers[3] == QByteArray("Available"), return -1);
const auto fields = filtered(lines[1].split(' '),
[](const QByteArray &field) { return field.size() > 0; });
QTC_ASSERT(fields.size() >= 4, return -1);
bool ok = false;
const quint64 result = QString::fromUtf8(fields[3]).toULongLong(&ok);
if (ok)
return result;
return -1;
}
} // namespace Utils

View File

@@ -144,6 +144,8 @@ public:
const FileFilter &filter,
const std::function<bool(const FilePath &)> &callBack);
static qint64 bytesAvailableFromDFOutput(const QByteArray &dfOutput);
#ifdef QT_WIDGETS_LIB
static void setDialogParentGetter(const std::function<QWidget *()> &getter);

View File

@@ -1273,13 +1273,9 @@ qint64 LinuxDevice::bytesAvailable(const FilePath &filePath) const
QTC_ASSERT(handlesFile(filePath), return -1);
CommandLine cmd("df", {"-k"});
cmd.addArg(filePath.path());
cmd.addArgs("|tail -n 1 |sed 's/ */ /g'|cut -d ' ' -f 4", CommandLine::Raw);
const QByteArray output = d->outputForRunInShell(cmd);
bool ok = false;
const qint64 size = output.toLongLong(&ok);
if (ok)
return size * 1024;
return -1;
return FileUtils::bytesAvailableFromDFOutput(output);
}
QFileDevice::Permissions LinuxDevice::permissions(const FilePath &filePath) const

View File

@@ -62,6 +62,8 @@ private slots:
void linkFromString();
void pathAppended_data();
void pathAppended();
void bytesAvailableFromDF_data();
void bytesAvailableFromDF();
void asyncLocalCopy();
@@ -527,5 +529,32 @@ void tst_fileutils::asyncLocalCopy()
QVERIFY(spy.count() == 1 || spy.wait(3000));
}
void tst_fileutils::bytesAvailableFromDF_data()
{
QTest::addColumn<QByteArray>("dfOutput");
QTest::addColumn<qint64>("expected");
QTest::newRow("empty") << QByteArray("") << qint64(-1);
QTest::newRow("mac") << QByteArray("Filesystem 1024-blocks Used Available Capacity iused ifree %iused Mounted on\n/dev/disk3s5 971350180 610014564 342672532 65% 4246780 3426725320 0% /System/Volumes/Data\n") << qint64(342672532);
QTest::newRow("alpine") << QByteArray("Filesystem 1K-blocks Used Available Use% Mounted on\noverlay 569466448 163526072 376983360 30% /\n") << qint64(376983360);
QTest::newRow("alpine-no-trailing-br") << QByteArray("Filesystem 1K-blocks Used Available Use% Mounted on\noverlay 569466448 163526072 376983360 30% /") << qint64(376983360);
QTest::newRow("alpine-missing-line") << QByteArray("Filesystem 1K-blocks Used Available Use% Mounted on\n") << qint64(-1);
QTest::newRow("wrong-header") << QByteArray("Filesystem 1K-blocks Used avail Use% Mounted on\noverlay 569466448 163526072 376983360 30% /\n") << qint64(-1);
QTest::newRow("not-enough-fields") << QByteArray("Filesystem 1K-blocks Used avail Use% Mounted on\noverlay 569466448\n") << qint64(-1);
QTest::newRow("not-enough-header-fields") << QByteArray("Filesystem 1K-blocks Used \noverlay 569466448 163526072 376983360 30% /\n") << qint64(-1);
}
void tst_fileutils::bytesAvailableFromDF()
{
if (HostOsInfo::isWindowsHost())
QSKIP("Test only valid on unix-ish systems");
QFETCH(QByteArray, dfOutput);
QFETCH(qint64, expected);
const auto result = FileUtils::bytesAvailableFromDFOutput(dfOutput);
QCOMPARE(result, expected);
}
QTEST_GUILESS_MAIN(tst_fileutils)
#include "tst_fileutils.moc"