From 08138f5a41e5df36f269f196ffd2fc4f1028fcdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Mon, 5 Oct 2020 11:39:04 +0200 Subject: [PATCH 1/2] [partition] Reduce direct dependency of PartUtils on PartitionCoreModule --- src/modules/partition/core/PartUtils.cpp | 9 +++------ src/modules/partition/core/PartUtils.h | 10 +++++----- src/modules/partition/core/PartitionCoreModule.cpp | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index 099cdf299..36b5cefe2 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -11,8 +11,6 @@ #include "PartUtils.h" -#include "PartitionCoreModule.h" - #include "core/DeviceModel.h" #include "core/KPMHelpers.h" #include "core/PartitionInfo.h" @@ -198,13 +196,12 @@ canBeResized( Partition* candidate ) bool -canBeResized( PartitionCoreModule* core, const QString& partitionPath ) +canBeResized( DeviceModel* dm, const QString& partitionPath ) { cDebug() << "Checking if" << partitionPath << "can be resized."; QString partitionWithOs = partitionPath; if ( partitionWithOs.startsWith( "/dev/" ) ) { - DeviceModel* dm = core->deviceModel(); for ( int i = 0; i < dm->rowCount(); ++i ) { Device* dev = dm->deviceForIndex( dm->index( i ) ); @@ -358,7 +355,7 @@ findPartitionPathForMountPoint( const FstabEntryList& fstab, const QString& moun OsproberEntryList -runOsprober( PartitionCoreModule* core ) +runOsprober( DeviceModel* dm ) { QString osproberOutput; QProcess osprober; @@ -406,7 +403,7 @@ runOsprober( PartitionCoreModule* core ) QString homePath = findPartitionPathForMountPoint( fstabEntries, "/home" ); osproberEntries.append( - { prettyName, path, QString(), canBeResized( core, path ), lineColumns, fstabEntries, homePath } ); + { prettyName, path, QString(), canBeResized( dm, path ), lineColumns, fstabEntries, homePath } ); osproberCleanLines.append( line ); } } diff --git a/src/modules/partition/core/PartUtils.h b/src/modules/partition/core/PartUtils.h index f5ca0ddaa..f210cc3ab 100644 --- a/src/modules/partition/core/PartUtils.h +++ b/src/modules/partition/core/PartUtils.h @@ -22,7 +22,7 @@ // Qt #include -class PartitionCoreModule; +class DeviceModel; class Partition; namespace PartUtils @@ -56,19 +56,19 @@ bool canBeResized( Partition* candidate ); /** * @brief canBeReplaced checks whether the given Partition satisfies the criteria * for resizing (shrinking) it to make room for a new OS. - * @param core the PartitionCoreModule instance. + * @param dm the DeviceModel instance. * @param partitionPath the device path of the candidate partition to resize. * @return true if the criteria are met, otherwise false. */ -bool canBeResized( PartitionCoreModule* core, const QString& partitionPath ); +bool canBeResized( DeviceModel* dm, const QString& partitionPath ); /** * @brief runOsprober executes os-prober, parses the output and writes relevant * data to GlobalStorage. - * @param core the PartitionCoreModule instance. + * @param dm the DeviceModel instance. * @return a list of os-prober entries, parsed. */ -OsproberEntryList runOsprober( PartitionCoreModule* core ); +OsproberEntryList runOsprober( DeviceModel* dm ); /** * @brief Is this system EFI-enabled? Decides based on /sys/firmware/efi diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index d78ef70c7..dc2324061 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -180,7 +180,7 @@ PartitionCoreModule::doInit() // The following PartUtils::runOsprober call in turn calls PartUtils::canBeResized, // which relies on a working DeviceModel. - m_osproberLines = PartUtils::runOsprober( this ); + m_osproberLines = PartUtils::runOsprober( this->deviceModel() ); // We perform a best effort of filling out filesystem UUIDs in m_osproberLines // because we will need them later on in PartitionModel if partition paths From a7bd1040c5d64ab134bbd58e8296a16ebddbdedb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Mon, 5 Oct 2020 11:40:04 +0200 Subject: [PATCH 2/2] [partition] Add tests for Layout-constrained partionning --- src/modules/partition/tests/CMakeLists.txt | 18 +++ .../partition/tests/CreateLayoutsTests.cpp | 145 ++++++++++++++++++ .../partition/tests/CreateLayoutsTests.h | 36 +++++ 3 files changed, 199 insertions(+) create mode 100644 src/modules/partition/tests/CreateLayoutsTests.cpp create mode 100644 src/modules/partition/tests/CreateLayoutsTests.h diff --git a/src/modules/partition/tests/CMakeLists.txt b/src/modules/partition/tests/CMakeLists.txt index dd4e41068..f16435230 100644 --- a/src/modules/partition/tests/CMakeLists.txt +++ b/src/modules/partition/tests/CMakeLists.txt @@ -40,3 +40,21 @@ calamares_add_test( DEFINITIONS ${_partition_defs} ) + +calamares_add_test( + createlayoutstests + SOURCES + ${PartitionModule_SOURCE_DIR}/core/KPMHelpers.cpp + ${PartitionModule_SOURCE_DIR}/core/PartitionInfo.cpp + ${PartitionModule_SOURCE_DIR}/core/PartitionLayout.cpp + ${PartitionModule_SOURCE_DIR}/core/PartUtils.cpp + ${PartitionModule_SOURCE_DIR}/core/DeviceModel.cpp + CreateLayoutsTests.cpp + LIBRARIES + kpmcore + calamares + calamaresui + Qt5::Gui + DEFINITIONS ${_partition_defs} +) + diff --git a/src/modules/partition/tests/CreateLayoutsTests.cpp b/src/modules/partition/tests/CreateLayoutsTests.cpp new file mode 100644 index 000000000..dab49c2b0 --- /dev/null +++ b/src/modules/partition/tests/CreateLayoutsTests.cpp @@ -0,0 +1,145 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Corentin Noël + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#include "CreateLayoutsTests.h" + +#include "core/PartitionLayout.h" + +#include "utils/Logger.h" +#include "partition/KPMManager.h" +#include "JobQueue.h" + +#include +#include +#include + +#include + +#include + +class PartitionTable; +class SmartStatus; + +QTEST_GUILESS_MAIN( CreateLayoutsTests ) + +CalamaresUtils::Partition::KPMManager* kpmcore = nullptr; + +using CalamaresUtils::operator""_MiB; +using CalamaresUtils::operator""_GiB; + +#define LOGICAL_SIZE 512 + +CreateLayoutsTests::CreateLayoutsTests() +{ + Logger::setupLogLevel( Logger::LOGDEBUG ); +} + +void +CreateLayoutsTests::init() +{ + std::unique_ptr< Calamares::JobQueue > jobqueue_p( new Calamares::JobQueue( nullptr ) ); + kpmcore = new CalamaresUtils::Partition::KPMManager(); +} + +void +CreateLayoutsTests::cleanup() +{ + delete kpmcore; +} + +void +CreateLayoutsTests::testFixedSizePartition() +{ + PartitionLayout layout = PartitionLayout(); + TestDevice dev( QString( "test" ), LOGICAL_SIZE, 5_GiB/LOGICAL_SIZE ); + PartitionRole role( PartitionRole::Role::Any ); + QList< Partition* > partitions; + + if (!layout.addEntry( QString( "/" ), QString( "5MiB" ) )) + { + QFAIL( qPrintable( "Unable to create / partition" ) ); + } + + partitions = layout.execute( static_cast(&dev), 0, dev.totalLogical(), nullptr, nullptr, role ); + + QCOMPARE( partitions.count(), 1 ); + + QCOMPARE( partitions[0]->length(), 5_MiB/LOGICAL_SIZE ); +} + +void +CreateLayoutsTests::testPercentSizePartition() +{ + PartitionLayout layout = PartitionLayout(); + TestDevice dev( QString( "test" ), LOGICAL_SIZE, 5_GiB/LOGICAL_SIZE ); + PartitionRole role( PartitionRole::Role::Any ); + QList< Partition* > partitions; + + if (!layout.addEntry( QString( "/" ), QString( "50%" ) )) + { + QFAIL( qPrintable( "Unable to create / partition" ) ); + } + + partitions = layout.execute( static_cast(&dev), 0, dev.totalLogical(), nullptr, nullptr, role ); + + QCOMPARE( partitions.count(), 1 ); + + QCOMPARE( partitions[0]->length(), (5_GiB/2)/LOGICAL_SIZE ); +} + +void +CreateLayoutsTests::testMixedSizePartition() +{ + PartitionLayout layout = PartitionLayout(); + TestDevice dev( QString( "test" ), LOGICAL_SIZE, 5_GiB/LOGICAL_SIZE ); + PartitionRole role( PartitionRole::Role::Any ); + QList< Partition* > partitions; + + if (!layout.addEntry( QString( "/" ), QString( "5MiB" ) )) + { + QFAIL( qPrintable( "Unable to create / partition" ) ); + } + + if (!layout.addEntry( QString( "/home" ), QString( "50%" ) )) + { + QFAIL( qPrintable( "Unable to create /home partition" ) ); + } + + if (!layout.addEntry( QString( "/bkup" ), QString( "50%" ) )) + { + QFAIL( qPrintable( "Unable to create /bkup partition" ) ); + } + + partitions = layout.execute( static_cast(&dev), 0, dev.totalLogical(), nullptr, nullptr, role ); + + QCOMPARE( partitions.count(), 3 ); + + QCOMPARE( partitions[0]->length(), 5_MiB/LOGICAL_SIZE ); + QCOMPARE( partitions[1]->length(), ((5_GiB - 5_MiB)/2)/LOGICAL_SIZE ); + QCOMPARE( partitions[2]->length(), ((5_GiB - 5_MiB)/2)/LOGICAL_SIZE ); +} + +// TODO: Get a clean way to instanciate a test Device from KPMCore +class DevicePrivate +{ +public: + QString m_Name; + QString m_DeviceNode; + qint64 m_LogicalSectorSize; + qint64 m_TotalLogical; + PartitionTable* m_PartitionTable; + QString m_IconName; + std::shared_ptr m_SmartStatus; + Device::Type m_Type; +}; + +TestDevice::TestDevice(const QString& name, const qint64 logicalSectorSize, const qint64 totalLogicalSectors) + : Device (std::make_shared(), name, QString( "node" ), logicalSectorSize, totalLogicalSectors, QString(), Device::Type::Unknown_Device) +{ +} diff --git a/src/modules/partition/tests/CreateLayoutsTests.h b/src/modules/partition/tests/CreateLayoutsTests.h new file mode 100644 index 000000000..9d37d7067 --- /dev/null +++ b/src/modules/partition/tests/CreateLayoutsTests.h @@ -0,0 +1,36 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Corentin Noël + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#ifndef CLEARMOUNTSJOBTESTS_H +#define CLEARMOUNTSJOBTESTS_H + +#include +#include + +class CreateLayoutsTests : public QObject +{ + Q_OBJECT +public: + CreateLayoutsTests(); + +private Q_SLOTS: + void testFixedSizePartition(); + void testPercentSizePartition(); + void testMixedSizePartition(); + void init(); + void cleanup(); +}; + +class TestDevice : public Device +{ +public: + TestDevice(const QString& name, const qint64 logicalSectorSize, const qint64 totalLogicalSectors); +}; + +#endif