PinningIndex.cpp (5985B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "TestCommon.h" 5 #include <Microsoft/PinningIndex.h> 6 #include <Microsoft/Schema/IPinningIndex.h> 7 #include <Microsoft/Schema/Pinning_1_0/PinTable.h> 8 #include <winget/Pin.h> 9 10 using namespace std::string_literals; 11 using namespace TestCommon; 12 using namespace AppInstaller::Pinning; 13 using namespace AppInstaller::Repository::Microsoft; 14 using namespace AppInstaller::SQLite; 15 using namespace AppInstaller::Repository::Microsoft::Schema; 16 17 TEST_CASE("PinningIndexCreateLatestAndReopen", "[pinningIndex]") 18 { 19 TempFile tempFile{ "repolibtest_tempdb"s, ".db"s }; 20 INFO("Using temporary file named: " << tempFile.GetPath()); 21 22 Version versionCreated; 23 24 // Create the index 25 { 26 PinningIndex index = PinningIndex::CreateNew(tempFile, Version::Latest()); 27 versionCreated = index.GetVersion(); 28 } 29 30 // Reopen the index for read only 31 { 32 INFO("Trying with Read"); 33 PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Read); 34 Version versionRead = index.GetVersion(); 35 REQUIRE(versionRead == versionCreated); 36 } 37 38 // Reopen the index for read/write 39 { 40 INFO("Trying with ReadWrite"); 41 PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite); 42 Version versionRead = index.GetVersion(); 43 REQUIRE(versionRead == versionCreated); 44 } 45 46 // Reopen the index for immutable read 47 { 48 INFO("Trying with Immutable"); 49 PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Immutable); 50 Version versionRead = index.GetVersion(); 51 REQUIRE(versionRead == versionCreated); 52 } 53 } 54 55 TEST_CASE("PinningIndexAddEntryToTable", "[pinningIndex]") 56 { 57 TempFile tempFile{ "repolibtest_tempdb"s, ".db"s }; 58 INFO("Using temporary file named: " << tempFile.GetPath()); 59 60 Pin pin = Pin::CreateBlockingPin({ "pkgId", "sourceId" }); 61 62 { 63 PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 }); 64 index.AddPin(pin); 65 } 66 67 { 68 // Open it directly to directly test table state 69 Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite); 70 71 auto pins = Pinning_V1_0::PinTable::GetAllPins(connection); 72 REQUIRE(pins.size() == 1); 73 REQUIRE(pins[0] == pin); 74 75 auto pinFromIndex = Pinning_V1_0::PinTable::GetPinById(connection, 1); 76 REQUIRE(pinFromIndex.has_value()); 77 REQUIRE(pinFromIndex.value() == pin); 78 79 REQUIRE(pinFromIndex->GetType() == pin.GetType()); 80 REQUIRE(pinFromIndex->GetKey() == pin.GetKey()); 81 } 82 83 { 84 PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite); 85 index.RemovePin(pin.GetKey()); 86 } 87 88 { 89 // Open it directly to directly test table state 90 Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite); 91 REQUIRE(Pinning_V1_0::PinTable::GetAllPins(connection).empty()); 92 REQUIRE(!Pinning_V1_0::PinTable::GetPinById(connection, 1)); 93 } 94 } 95 96 TEST_CASE("PinningIndex_AddUpdateRemove", "[pinningIndex]") 97 { 98 TempFile tempFile{ "repolibtest_tempdb"s, ".db"s }; 99 INFO("Using temporary file named: " << tempFile.GetPath()); 100 101 Pin pin = Pin::CreateGatingPin({ "pkgId", "srcId" }, { "1.0.*"sv }); 102 Pin updatedPin = Pin::CreatePinningPin({ "pkgId", "srcId" }); 103 104 { 105 PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 }); 106 index.AddPin(pin); 107 REQUIRE(index.UpdatePin(updatedPin)); 108 } 109 110 { 111 Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly); 112 auto pinFromIndex = Pinning_V1_0::PinTable::GetPinById(connection, 1); 113 REQUIRE(pinFromIndex.has_value()); 114 REQUIRE(pinFromIndex.value() == updatedPin); 115 } 116 117 { 118 PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite); 119 index.RemovePin(updatedPin.GetKey()); 120 } 121 122 { 123 // Open it directly to directly test table state 124 Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite); 125 REQUIRE(Pinning_V1_0::PinTable::GetAllPins(connection).empty()); 126 REQUIRE(!Pinning_V1_0::PinTable::GetPinById(connection, 1)); 127 } 128 } 129 130 TEST_CASE("PinningIndex_ResetAll", "[pinningIndex]") 131 { 132 TempFile tempFile{ "repolibtest_tempdb"s, ".db"s }; 133 INFO("Using temporary file named: " << tempFile.GetPath()); 134 135 Pin pin1 = Pin::CreateBlockingPin({ "pkg1", "src1" }); 136 Pin pin2 = Pin::CreatePinningPin({ "pkg2", "src2" }); 137 138 // Add two pins to the index, then check that they show up when queried 139 PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 }); 140 index.AddPin(pin1); 141 index.AddPin(pin2); 142 143 REQUIRE(index.GetAllPins().size() == 2); 144 REQUIRE(index.GetPin(pin1.GetKey()).has_value()); 145 REQUIRE(index.GetPin(pin2.GetKey()).has_value()); 146 REQUIRE(!index.GetPin({ "pkg", "src" }).has_value()); 147 148 // Reset the index, then check that there are no pins 149 index.ResetAllPins(); 150 REQUIRE(index.GetAllPins().empty()); 151 REQUIRE(!index.GetPin(pin1.GetKey()).has_value()); 152 REQUIRE(!index.GetPin(pin2.GetKey()).has_value()); 153 } 154 155 TEST_CASE("PinningIndex_AddDuplicatePin", "[pinningIndex]") 156 { 157 TempFile tempFile{ "repolibtest_tempdb"s, ".db"s }; 158 INFO("Using temporary file named: " << tempFile.GetPath()); 159 160 Pin pin = Pin::CreateGatingPin({ "pkg", "src" }, { "1.*"sv }); 161 162 PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 }); 163 index.AddPin(pin); 164 165 REQUIRE_THROWS(index.AddPin(pin), ERROR_ALREADY_EXISTS); 166 }