PageRenderTime 46ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp

https://gitlab.com/admin-github-cloud/cynara
C++ | 544 lines | 333 code | 100 blank | 111 comment | 11 complexity | 0e13f3eb47091b5fd7890cc2af1cc455 MD5 | raw file
  1. /*
  2. * Copyright (c) 2014-2016 Samsung Electronics Co., Ltd All Rights Reserved
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /**
  17. * @file test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp
  18. * @author Aleksander Zdyb <a.zdyb@samsung.com>
  19. * @version 1.0
  20. * @brief Tests of InMemoryStorageBackend
  21. */
  22. #include <gmock/gmock.h>
  23. #include <gtest/gtest.h>
  24. #include "exceptions/BucketNotExistsException.h"
  25. #include "exceptions/BucketDeserializationException.h"
  26. #include "exceptions/DatabaseCorruptedException.h"
  27. #include "exceptions/DefaultBucketDeletionException.h"
  28. #include "exceptions/FileNotFoundException.h"
  29. #include "storage/InMemoryStorageBackend.h"
  30. #include "storage/StorageBackend.h"
  31. #include "types/PolicyCollection.h"
  32. #include "types/PolicyKey.h"
  33. #include "types/PolicyResult.h"
  34. #include "types/PolicyType.h"
  35. #include "config/PathConfig.h"
  36. #include "../../helpers.h"
  37. #include "fakeinmemorystoragebackend.h"
  38. #include "inmemorystoragebackendfixture.h"
  39. using namespace Cynara;
  40. const std::string InMemoryStorageBackendFixture::m_indexFileName("buckets");
  41. const std::string InMemoryStorageBackendFixture::m_backupFileNameSuffix("~");
  42. const std::string InMemoryStorageBackendFixture::m_fakeDbPath("/fake/database/path");
  43. TEST_F(InMemoryStorageBackendFixture, defaultPolicyIsDeny) {
  44. using ::testing::ReturnRef;
  45. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  46. EXPECT_CALL(backend, buckets())
  47. .WillOnce(ReturnRef(m_buckets));
  48. createBucket(defaultPolicyBucketId);
  49. // Policy key will not be found -- should fall back to default policy for bucket
  50. auto filteredBucket = backend.searchDefaultBucket(Helpers::generatePolicyKey());
  51. auto defaultPolicy = filteredBucket.defaultPolicy();
  52. ASSERT_EQ(PredefinedPolicyType::DENY, defaultPolicy.policyType());
  53. }
  54. // TODO: Refactorize this test to be shorter and clearer
  55. TEST_F(InMemoryStorageBackendFixture, deleteLinking) {
  56. using ::testing::ReturnRef;
  57. using ::testing::IsEmpty;
  58. using ::testing::UnorderedElementsAre;
  59. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  60. EXPECT_CALL(backend, buckets())
  61. .Times(4)
  62. .WillRepeatedly(ReturnRef(m_buckets));
  63. const PolicyBucketId testBucket1 = "test-bucket-1";
  64. const PolicyBucketId testBucket2 = "test-bucket-2";
  65. const PolicyBucketId testBucket3 = "test-bucket-3";
  66. // Create 2 buckets
  67. for (const auto &bucketId : { testBucket1, testBucket2, testBucket3 }) {
  68. PolicyResult defaultPolicy(PredefinedPolicyType::DENY);
  69. backend.createBucket(bucketId, defaultPolicy);
  70. }
  71. // These policies do not link to buckets, so should stay untouched
  72. PolicyCollection policiesToStay = {
  73. Policy::simpleWithKey(Helpers::generatePolicyKey("1"), PredefinedPolicyType::DENY),
  74. Policy::simpleWithKey(Helpers::generatePolicyKey("1"), PredefinedPolicyType::DENY),
  75. Policy::simpleWithKey(Helpers::generatePolicyKey("2"), PredefinedPolicyType::ALLOW),
  76. };
  77. // Add some policies to 1st bucket, which link to 2nd bucket
  78. addToBucket(testBucket1, {
  79. Policy::bucketWithKey(Helpers::generatePolicyKey("1"), testBucket2), /* 1st */
  80. Policy::bucketWithKey(Helpers::generatePolicyKey("2"), testBucket2), /* 2nd */
  81. policiesToStay.at(0)
  82. });
  83. // Add some policies to 2nd bucket
  84. addToBucket(testBucket2, {
  85. policiesToStay.at(1), policiesToStay.at(2)
  86. });
  87. // Add some policies to 3rd bucket, which link to 2nd bucket
  88. addToBucket(testBucket3, {
  89. Policy::bucketWithKey(Helpers::generatePolicyKey("X"), testBucket2),
  90. Policy::bucketWithKey(Helpers::generatePolicyKey("Y"), testBucket2),
  91. });
  92. // Should delete 1st and 2nd policy from 1st bucket
  93. backend.deleteLinking(testBucket2);
  94. ASSERT_THAT(m_buckets.at(testBucket1),
  95. UnorderedElementsAre(policiesToStay.at(0)));
  96. ASSERT_THAT(m_buckets.at(testBucket2),
  97. UnorderedElementsAre(policiesToStay.at(1), policiesToStay.at(2)));
  98. ASSERT_THAT(m_buckets.at(testBucket3), IsEmpty());
  99. }
  100. TEST_F(InMemoryStorageBackendFixture, insertPolicy) {
  101. using ::testing::ReturnRef;
  102. using ::testing::UnorderedElementsAre;
  103. using PredefinedPolicyType::ALLOW;
  104. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  105. EXPECT_CALL(backend, buckets())
  106. .WillOnce(ReturnRef(m_buckets));
  107. PolicyBucketId bucketId = "test-bucket";
  108. createBucket(bucketId);
  109. auto policyToAdd = Policy::simpleWithKey(Helpers::generatePolicyKey(), ALLOW);
  110. backend.insertPolicy(bucketId, policyToAdd);
  111. ASSERT_THAT(m_buckets.at(bucketId), UnorderedElementsAre(policyToAdd));
  112. }
  113. TEST_F(InMemoryStorageBackendFixture, insertPolicyToNonexistentBucket) {
  114. using ::testing::ReturnRef;
  115. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  116. EXPECT_CALL(backend, buckets())
  117. .WillOnce(ReturnRef(m_buckets));
  118. EXPECT_THROW(backend.insertPolicy("non-existent", nullptr), BucketNotExistsException);
  119. }
  120. TEST_F(InMemoryStorageBackendFixture, deletePolicy) {
  121. using ::testing::ReturnRef;
  122. using ::testing::IsEmpty;
  123. using ::testing::UnorderedElementsAre;
  124. using ::testing::UnorderedElementsAreArray;
  125. using ::testing::ContainerEq;
  126. using PredefinedPolicyType::ALLOW;
  127. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  128. EXPECT_CALL(backend, buckets())
  129. .WillOnce(ReturnRef(m_buckets));
  130. PolicyBucketId bucketId = "test-bucket";
  131. createBucket(bucketId);
  132. auto policyToDelete = Policy::simpleWithKey(Helpers::generatePolicyKey(), ALLOW);
  133. PolicyCollection otherPolicies = {
  134. Policy::simpleWithKey(Helpers::generatePolicyKey("other-policy-1"), ALLOW),
  135. Policy::simpleWithKey(Helpers::generatePolicyKey("other-policy-2"), ALLOW),
  136. Policy::simpleWithKey(Helpers::generatePolicyKey("other-policy-3"), ALLOW),
  137. };
  138. addToBucket(bucketId, {
  139. otherPolicies.at(0),
  140. otherPolicies.at(1),
  141. policyToDelete,
  142. otherPolicies.at(2),
  143. });
  144. backend.deletePolicy(bucketId, policyToDelete->key());
  145. // Check if only policyToDelete has been deleted
  146. EXPECT_THAT(m_buckets.at(bucketId), UnorderedElementsAreArray(otherPolicies));
  147. }
  148. TEST_F(InMemoryStorageBackendFixture, deletePolicyFromNonexistentBucket) {
  149. using ::testing::ReturnRef;
  150. using ::testing::IsEmpty;
  151. using ::testing::UnorderedElementsAre;
  152. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  153. EXPECT_CALL(backend, buckets())
  154. .WillOnce(ReturnRef(m_buckets));
  155. EXPECT_THROW(backend.deletePolicy("non-existent", Helpers::generatePolicyKey()),
  156. BucketNotExistsException);
  157. }
  158. // Database dir is empty
  159. TEST_F(InMemoryStorageBackendFixture, load_no_db) {
  160. using ::testing::ReturnRef;
  161. auto testDbPath = Cynara::PathConfig::testsPath + "/empty_db/";
  162. FakeInMemoryStorageBackend backend(testDbPath);
  163. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  164. EXPECT_THROW(backend.load(), DatabaseCorruptedException);
  165. ASSERT_DB_EMPTY(m_buckets);
  166. }
  167. // Database dir contains index with default bucket, but no file for this bucket
  168. TEST_F(InMemoryStorageBackendFixture, load_no_default) {
  169. using ::testing::ReturnRef;
  170. auto testDbPath = Cynara::PathConfig::testsPath + "/db2/";
  171. FakeInMemoryStorageBackend backend(testDbPath);
  172. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  173. EXPECT_THROW(backend.load(), DatabaseCorruptedException);
  174. ASSERT_DB_EMPTY(m_buckets);
  175. }
  176. // Database contains index with default bucket and an empty bucket file
  177. TEST_F(InMemoryStorageBackendFixture, load_default_only) {
  178. using ::testing::ReturnRef;
  179. using ::testing::Return;
  180. auto testDbPath = Cynara::PathConfig::testsPath + "/db11_md5/";
  181. FakeInMemoryStorageBackend backend(testDbPath);
  182. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  183. EXPECT_CALL(backend, postLoadCleanup(false)).WillOnce(Return());
  184. backend.load();
  185. ASSERT_DB_VIRGIN(m_buckets);
  186. }
  187. // Database contains index with default bucket and an additional bucket
  188. // There are files for both buckets present
  189. TEST_F(InMemoryStorageBackendFixture, load_2_buckets) {
  190. using ::testing::ReturnRef;
  191. using ::testing::Return;
  192. using ::testing::IsEmpty;
  193. auto testDbPath = Cynara::PathConfig::testsPath + "/db12/";
  194. FakeInMemoryStorageBackend backend(testDbPath);
  195. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  196. EXPECT_CALL(backend, postLoadCleanup(false)).WillOnce(Return());
  197. backend.load();
  198. std::vector<std::string> bucketIds = { "", "additional" };
  199. for(const auto &bucketId : bucketIds) {
  200. SCOPED_TRACE(bucketId);
  201. const auto bucketIter = m_buckets.find(bucketId);
  202. ASSERT_NE(m_buckets.end(), bucketIter);
  203. const auto &bucketPolicies = bucketIter->second;
  204. ASSERT_THAT(bucketPolicies, IsEmpty());
  205. }
  206. }
  207. // Database contains index with 2 buckets; 1st bucket is valid, but second is corrupted
  208. TEST_F(InMemoryStorageBackendFixture, second_bucket_corrupted) {
  209. using ::testing::ReturnRef;
  210. auto testDbPath = Cynara::PathConfig::testsPath + "/db5/";
  211. FakeInMemoryStorageBackend backend(testDbPath);
  212. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  213. EXPECT_THROW(backend.load(), DatabaseCorruptedException);
  214. ASSERT_DB_EMPTY(m_buckets);
  215. }
  216. /**
  217. * @brief Database was corrupted, restore from backup (which is present)
  218. * @test Scenario:
  219. * - There still is guard file in earlier prepared Cynara's policy database directory (db6)
  220. * - Execution of load() should use backup files (present, with different contents than primaries)
  221. * - Loaded database is checked - backup files were empty, so should recently loaded policies
  222. */
  223. TEST_F(InMemoryStorageBackendFixture, load_from_backup) {
  224. using ::testing::ReturnRef;
  225. using ::testing::Return;
  226. using ::testing::IsEmpty;
  227. using ::testing::InSequence;
  228. auto testDbPath = Cynara::PathConfig::testsPath + "/db13/";
  229. FakeInMemoryStorageBackend backend(testDbPath);
  230. {
  231. // Calls are expected in a specific order
  232. InSequence s;
  233. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  234. EXPECT_CALL(backend, postLoadCleanup(true)).WillOnce(Return());
  235. backend.load();
  236. }
  237. std::vector<std::string> bucketIds = { "", "additional" };
  238. for(const auto &bucketId : bucketIds) {
  239. SCOPED_TRACE(bucketId);
  240. const auto bucketIter = m_buckets.find(bucketId);
  241. ASSERT_NE(m_buckets.end(), bucketIter);
  242. const auto &bucketPolicies = bucketIter->second;
  243. ASSERT_THAT(bucketPolicies, IsEmpty());
  244. }
  245. }
  246. /**
  247. * @brief Erase from non-exiting bucket should throw BucketNotExistsException
  248. * @test Scenario:
  249. * - For different filter keys:
  250. * - try erase policies from "non-existing-bucket"
  251. * - expect BucketNotExistsException is thrown
  252. */
  253. TEST_F(InMemoryStorageBackendFixture, erasePoliciesEmptyBase) {
  254. using ::testing::ReturnRef;
  255. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  256. EXPECT_CALL(backend, buckets())
  257. .WillRepeatedly(ReturnRef(m_buckets));
  258. PolicyBucketId bucketId = "non-existing-bucket";
  259. const bool NON_RECURSIVE = false;
  260. for (const auto &filter : filters()) {
  261. SCOPED_TRACE(filter.name());
  262. EXPECT_THROW(backend.erasePolicies(bucketId, NON_RECURSIVE, filter.key()),
  263. BucketNotExistsException);
  264. }
  265. }
  266. /**
  267. * @brief Erase from single bucket
  268. * @test Scenario:
  269. * - For different filter keys:
  270. * - create "test-bucket"
  271. * - add all types of policies (fullPoliciesCollection) into "test-bucket"
  272. * - erase policies from "test-bucket"
  273. * - check if received results match expected
  274. */
  275. TEST_F(InMemoryStorageBackendFixture, erasePoliciesSingleBucket) {
  276. using ::testing::ReturnRef;
  277. using ::testing::UnorderedElementsAreArray;
  278. PolicyBucketId bucketId = "test-bucket";
  279. const bool NON_RECURSIVE = false;
  280. for (const auto &filter : filters()) {
  281. SCOPED_TRACE(filter.name());
  282. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  283. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  284. createBucket(bucketId);
  285. addToBucket(bucketId, fullPoliciesCollection());
  286. backend.erasePolicies(bucketId, NON_RECURSIVE, filter.key());
  287. ASSERT_THAT(m_buckets.at(bucketId),
  288. UnorderedElementsAreArray(expectedEraseResult(filter.name())));
  289. }
  290. }
  291. /**
  292. * @brief Verify if recursive erase doesn't propagate to not linked bucket
  293. * @test Scenario:
  294. * - For different filter keys:
  295. * - create "test-bucket"
  296. * - add all types of policies (fullPoliciesCollection) into "test-bucket"
  297. * - create "test-bucket2"
  298. * - add all types of policies (fullPoliciesCollection) into "test-bucket2"
  299. * - erase policies from "test-bucket"
  300. * - check if received results match expected in case of "test-bucket"
  301. * - check if policies in "test-bucket2" remain unaffected
  302. */
  303. TEST_F(InMemoryStorageBackendFixture, erasePoliciesRecursiveNotLinkedBuckets) {
  304. using ::testing::ReturnRef;
  305. using ::testing::UnorderedElementsAreArray;
  306. PolicyBucketId bucketId = "test-bucket";
  307. PolicyBucketId bucketId2 = "test-bucket2";
  308. const bool RECURSIVE = true;
  309. for (const auto &filter : filters()) {
  310. SCOPED_TRACE(filter.name());
  311. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  312. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  313. createBucket(bucketId);
  314. addToBucket(bucketId, fullPoliciesCollection());
  315. createBucket(bucketId2);
  316. addToBucket(bucketId2, fullPoliciesCollection());
  317. backend.erasePolicies(bucketId, RECURSIVE, filter.key());
  318. ASSERT_THAT(m_buckets.at(bucketId),
  319. UnorderedElementsAreArray(expectedEraseResult(filter.name())));
  320. ASSERT_THAT(m_buckets.at(bucketId2),
  321. UnorderedElementsAreArray(fullPoliciesCollection()));
  322. }
  323. }
  324. /**
  325. * @brief Verify if recursive erase does propagate to linked bucket
  326. * @test Scenario:
  327. * - For different filter keys:
  328. * - create "test-bucket"
  329. * - add all types of policies (fullPoliciesCollection) into "test-bucket"
  330. * - create "test-bucket2"
  331. * - add all types of policies (fullPoliciesCollection) into "test-bucket2"
  332. * - add policy linking test buckets
  333. * - erase policies from "test-bucket"
  334. * - check if received results match expected in case of "test-bucket"
  335. * - check if received results match expected in case of "test-bucket2"
  336. */
  337. TEST_F(InMemoryStorageBackendFixture, erasePoliciesRecursiveLinkedBuckets) {
  338. using ::testing::ReturnRef;
  339. using ::testing::UnorderedElementsAreArray;
  340. PolicyBucketId bucketId = "test-bucket";
  341. PolicyBucketId bucketId2 = "test-bucket2";
  342. PolicyKey linkKey = Helpers::generatePolicyKey("link");
  343. PolicyCollection linkPolicy = {Policy::bucketWithKey(linkKey, bucketId2)};
  344. const bool RECURSIVE = true;
  345. for (const auto &filter : filters()) {
  346. SCOPED_TRACE(filter.name());
  347. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  348. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  349. createBucket(bucketId);
  350. addToBucket(bucketId, fullPoliciesCollection());
  351. createBucket(bucketId2);
  352. addToBucket(bucketId2, fullPoliciesCollection());
  353. addToBucket(bucketId, linkPolicy);
  354. backend.erasePolicies(bucketId, RECURSIVE, filter.key());
  355. PolicyCollection expectedResult = expectedEraseResult(filter.name());
  356. if (!isLinkPolicyErased(filter.name())) {
  357. expectedResult.insert(expectedResult.end(), linkPolicy.begin(), linkPolicy.end());
  358. }
  359. ASSERT_THAT(m_buckets.at(bucketId),
  360. UnorderedElementsAreArray(expectedResult));
  361. ASSERT_THAT(m_buckets.at(bucketId2),
  362. UnorderedElementsAreArray(expectedEraseResult(filter.name())));
  363. }
  364. }
  365. /**
  366. * @brief Verify if recursive erase doesn't propagate backwards to linked bucket
  367. * @test Scenario:
  368. * - For different filter keys:
  369. * - create "test-bucket"
  370. * - add all types of policies (fullPoliciesCollection) into "test-bucket"
  371. * - create "test-bucket2"
  372. * - add all types of policies (fullPoliciesCollection) into "test-bucket2"
  373. * - add policy linking test buckets
  374. * - erase policies from "test-bucket2"
  375. * - check if policies in "test-bucket" remain unaffected
  376. * - check if received results match expected in case of "test-bucket2"
  377. */
  378. TEST_F(InMemoryStorageBackendFixture, erasePoliciesRecursiveLinkedBucketsNoBackwardPropagation) {
  379. using ::testing::ReturnRef;
  380. using ::testing::UnorderedElementsAreArray;
  381. PolicyBucketId bucketId = "test-bucket";
  382. PolicyBucketId bucketId2 = "test-bucket2";
  383. PolicyKey linkKey = Helpers::generatePolicyKey("link");
  384. PolicyCollection linkPolicy = {Policy::bucketWithKey(linkKey, bucketId2)};
  385. const bool RECURSIVE = true;
  386. for (const auto &filter : filters()) {
  387. SCOPED_TRACE(filter.name());
  388. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  389. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  390. createBucket(bucketId);
  391. addToBucket(bucketId, fullPoliciesCollection());
  392. createBucket(bucketId2);
  393. addToBucket(bucketId2, fullPoliciesCollection());
  394. addToBucket(bucketId, linkPolicy);
  395. backend.erasePolicies(bucketId2, RECURSIVE, filter.key());
  396. PolicyCollection expectedResult = fullPoliciesCollection();
  397. expectedResult.insert(expectedResult.end(), linkPolicy.begin(), linkPolicy.end());
  398. ASSERT_THAT(m_buckets.at(bucketId),
  399. UnorderedElementsAreArray(expectedResult));
  400. ASSERT_THAT(m_buckets.at(bucketId2),
  401. UnorderedElementsAreArray(expectedEraseResult(filter.name())));
  402. }
  403. }
  404. /**
  405. * @brief Verify if non-recursive erase doesn't propagate to linked bucket
  406. * @test Scenario:
  407. * - For different filter keys:
  408. * - create "test-bucket"
  409. * - add all types of policies (fullPoliciesCollection) into "test-bucket"
  410. * - create "test-bucket2"
  411. * - add all types of policies (fullPoliciesCollection) into "test-bucket2"
  412. * - add policy linking test buckets
  413. * - erase policies from "test-bucket"
  414. * - check if received results match expected in case of "test-bucket"
  415. * - check if policies in "test-bucket2" remain unaffected
  416. */
  417. TEST_F(InMemoryStorageBackendFixture, erasePoliciesNonRecursiveLinkedBuckets) {
  418. using ::testing::ReturnRef;
  419. using ::testing::UnorderedElementsAreArray;
  420. PolicyBucketId bucketId = "test-bucket";
  421. PolicyBucketId bucketId2 = "test-bucket2";
  422. PolicyKey linkKey = Helpers::generatePolicyKey("link");
  423. PolicyCollection linkPolicy = {Policy::bucketWithKey(linkKey, bucketId2)};
  424. const bool NON_RECURSIVE = false;
  425. for (const auto &filter : filters()) {
  426. SCOPED_TRACE(filter.name());
  427. FakeInMemoryStorageBackend backend(m_fakeDbPath);
  428. EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
  429. createBucket(bucketId);
  430. addToBucket(bucketId, fullPoliciesCollection());
  431. createBucket(bucketId2);
  432. addToBucket(bucketId2, fullPoliciesCollection());
  433. addToBucket(bucketId, linkPolicy);
  434. backend.erasePolicies(bucketId, NON_RECURSIVE, filter.key());
  435. PolicyCollection expectedResult = expectedEraseResult(filter.name());
  436. if (!isLinkPolicyErased(filter.name())) {
  437. expectedResult.insert(expectedResult.end(), linkPolicy.begin(), linkPolicy.end());
  438. }
  439. ASSERT_THAT(m_buckets.at(bucketId),
  440. UnorderedElementsAreArray(expectedResult));
  441. ASSERT_THAT(m_buckets.at(bucketId2),
  442. UnorderedElementsAreArray(fullPoliciesCollection()));
  443. }
  444. }