File indexing completed on 2024-04-21 05:33:26

0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0002 // SPDX-FileCopyrightText: 2020-2021 Harald Sitter <sitter@kde.org>
0003 
0004 #include <QDebug>
0005 #include <QDir>
0006 #include <QFile>
0007 #include <QJsonDocument>
0008 #include <QObject>
0009 #include <QStandardPaths>
0010 #include <QTest>
0011 
0012 #include <KSycoca>
0013 #include <smartdata.h>
0014 
0015 class SMARTDataTest : public QObject
0016 {
0017     Q_OBJECT
0018 private Q_SLOTS:
0019     void testPass()
0020     {
0021         QFile file(QFINDTESTDATA("fixtures/pass.json"));
0022         QVERIFY(file.open(QFile::ReadOnly));
0023         auto doc = QJsonDocument::fromJson(file.readAll());
0024         SMARTData data(doc);
0025         QCOMPARE(data.m_device, "/dev/testfoobarpass");
0026         QCOMPARE(data.m_status.m_passed, true);
0027         QVERIFY(!data.m_smartctl.failure());
0028         QVERIFY(data.m_valid);
0029     }
0030 
0031     void testFail()
0032     {
0033         // NB: fixture isn't actually of a failure, so fields need tweaking as necessary
0034         QFile file(QFINDTESTDATA("fixtures/fail.json"));
0035         QVERIFY(file.open(QFile::ReadOnly));
0036         auto doc = QJsonDocument::fromJson(file.readAll());
0037         SMARTData data(doc);
0038         QCOMPARE(data.m_device, "/dev/testfoobarfail");
0039         QCOMPARE(data.m_status.m_passed, false);
0040         QVERIFY(!data.m_smartctl.failure());
0041         QVERIFY(data.m_valid);
0042     }
0043 
0044     void testBroken()
0045     {
0046         // Actual broken device provided by ahiemstra@heimr.nl
0047         QFile file(QFINDTESTDATA("fixtures/broken.json"));
0048         QVERIFY(file.open(QFile::ReadOnly));
0049         auto doc = QJsonDocument::fromJson(file.readAll());
0050         SMARTData data(doc);
0051         QCOMPARE(data.m_device, "/dev/sdc");
0052         QCOMPARE(data.m_status.m_passed, false);
0053         QCOMPARE(data.m_smartctl.failure(),
0054                  SMART::Failures({SMART::Failure::Disk, SMART::Failure::Prefail, SMART::Failure::ErrorsRecorded, SMART::Failure::SelfTestErrors}));
0055         QVERIFY(data.m_smartctl.failure());
0056         QVERIFY(!!data.m_smartctl.failure());
0057         QVERIFY(data.m_valid);
0058     }
0059 
0060     void testTimeout()
0061     {
0062         // Query timed out but overall status is available and success.
0063         // From https://bugs.kde.org/show_bug.cgi?id=428844
0064         QFile file(QFINDTESTDATA("fixtures/error-info-log-failed.json"));
0065         QVERIFY(file.open(QFile::ReadOnly));
0066         auto doc = QJsonDocument::fromJson(file.readAll());
0067         SMARTData data(doc);
0068         QCOMPARE(data.m_device, "/dev/nvme0n1");
0069         QCOMPARE(data.m_status.m_passed, true);
0070         QCOMPARE(data.m_smartctl.failure(), SMART::Failures({SMART::Failure::InternalCommand}));
0071         QVERIFY(data.m_smartctl.failure());
0072         QVERIFY(!!data.m_smartctl.failure());
0073         QVERIFY(data.m_valid);
0074     }
0075 
0076     void testFailingSectorsButPassingStatus()
0077     {
0078         // SMART status is a pass but there are problems.
0079         QFile file(QFINDTESTDATA("fixtures/failing-sectors-passing-status.json"));
0080         QVERIFY(file.open(QFile::ReadOnly));
0081         auto doc = QJsonDocument::fromJson(file.readAll());
0082         SMARTData data(doc);
0083         QCOMPARE(data.m_device, "/dev/sdb");
0084         QCOMPARE(data.m_status.m_passed, true);
0085         QCOMPARE(data.m_smartctl.failure(), SMART::Failures({SMART::Failure::ErrorsRecorded | SMART::Failure::SelfTestErrors}));
0086         QVERIFY(data.m_valid);
0087     }
0088 
0089     void testVBoxDrive()
0090     {
0091         // VBox virtual drives fail with bit2 and have no status
0092         QFile file(QFINDTESTDATA("fixtures/invalid-vbox.json"));
0093         QVERIFY(file.open(QFile::ReadOnly));
0094         auto doc = QJsonDocument::fromJson(file.readAll());
0095         SMARTData data(doc);
0096         QCOMPARE(data.m_device, "/dev/sda");
0097         QCOMPARE(data.m_status.m_passed, false);
0098         QCOMPARE(data.m_smartctl.failure(), SMART::Failures({SMART::Failure::InternalCommand}));
0099         QVERIFY(!data.m_valid);
0100     }
0101 
0102     void testNoSmartStatusNoError()
0103     {
0104         // When SMART is disabled we get no smart_status but also no error. Ought to be invalid all the same and
0105         // ignored.
0106         // https://bugs.kde.org/show_bug.cgi?id=435699
0107         QFile file(QFINDTESTDATA("fixtures/pass-without-status.json"));
0108         QVERIFY(file.open(QFile::ReadOnly));
0109         auto doc = QJsonDocument::fromJson(file.readAll());
0110         SMARTData data(doc);
0111         QCOMPARE(data.m_device, "/dev/sdb");
0112         QCOMPARE(data.m_status.m_passed, false);
0113         QCOMPARE(data.m_smartctl.failure(), SMART::Failures());
0114         QVERIFY(!data.m_valid);
0115     }
0116 };
0117 
0118 QTEST_MAIN(SMARTDataTest)
0119 
0120 #include "smartdatatest.moc"