permission_auditing_service_unittest.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/permissions/permission_auditing_service.h"
  5. #include <memory>
  6. #include <vector>
  7. #include "base/files/file_util.h"
  8. #include "base/files/scoped_temp_dir.h"
  9. #include "base/run_loop.h"
  10. #include "base/task/task_traits.h"
  11. #include "base/task/thread_pool.h"
  12. #include "base/test/bind.h"
  13. #include "base/test/task_environment.h"
  14. #include "base/time/clock.h"
  15. #include "base/time/time.h"
  16. #include "components/permissions/permission_usage_session.h"
  17. #include "testing/gmock/include/gmock/gmock.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "url/gurl.h"
  20. namespace permissions {
  21. using ::testing::ElementsAre;
  22. using ::testing::IsEmpty;
  23. using ::testing::UnorderedElementsAre;
  24. namespace {
  25. constexpr base::Time kTestTimes[] = {base::Time() + base::Days(1),
  26. base::Time() + base::Days(2),
  27. base::Time() + base::Days(3)};
  28. constexpr ContentSettingsType kTestTypes[] = {
  29. ContentSettingsType::MEDIASTREAM_MIC,
  30. ContentSettingsType::MEDIASTREAM_CAMERA};
  31. constexpr const char* kTestOrigins[] = {
  32. "https://foo1.com", "https://foo2.com", "https://foo3.com",
  33. "https://foo4.com", "https://foo5.com",
  34. };
  35. PermissionUsageSession BuildUsageSession(base::Time usage_start_time,
  36. base::Time usage_end_time) {
  37. return {.origin = url::Origin::Create(GURL(kTestOrigins[0])),
  38. .type = kTestTypes[0],
  39. .usage_start = usage_start_time,
  40. .usage_end = usage_end_time,
  41. .had_user_activation = false,
  42. .was_foreground = false,
  43. .had_focus = false};
  44. }
  45. PermissionUsageSession BuildUsageSession(ContentSettingsType type,
  46. const url::Origin& origin) {
  47. return {.origin = origin,
  48. .type = type,
  49. .usage_start = kTestTimes[0],
  50. .usage_end = kTestTimes[1],
  51. .had_user_activation = false,
  52. .was_foreground = false,
  53. .had_focus = false};
  54. }
  55. } // namespace
  56. class PermissionAuditingServiceTest : public testing::Test {
  57. public:
  58. PermissionAuditingServiceTest() = default;
  59. protected:
  60. PermissionAuditingService& service() { return *service_.get(); }
  61. base::test::TaskEnvironment& task_environment() { return task_environment_; }
  62. void SetUp() override {
  63. backend_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
  64. {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
  65. service_ =
  66. std::make_unique<PermissionAuditingService>(backend_task_runner_);
  67. ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
  68. base::FilePath database_path = temp_directory_.GetPath().Append(
  69. FILE_PATH_LITERAL("test_permission_auditing_database"));
  70. service_->Init(database_path);
  71. service_->StartPeriodicCullingOfExpiredSessions();
  72. }
  73. void TearDown() override {
  74. // Ensure the database is destroyed on the |backend_task_runner_|.
  75. service_.reset();
  76. task_environment_.RunUntilIdle();
  77. }
  78. std::vector<PermissionUsageSession> GetPermissionUsageHistory(
  79. ContentSettingsType type,
  80. const url::Origin& origin,
  81. base::Time start_time) {
  82. base::RunLoop run_loop;
  83. std::vector<PermissionUsageSession> history;
  84. service().GetPermissionUsageHistory(
  85. type, origin, start_time,
  86. base::BindLambdaForTesting(
  87. [&](std::vector<PermissionUsageSession> sessions) {
  88. history = std::move(sessions);
  89. run_loop.QuitWhenIdle();
  90. }));
  91. run_loop.Run();
  92. return history;
  93. }
  94. base::Time GetLastPermissionUsageTime(ContentSettingsType type,
  95. const url::Origin& origin) {
  96. base::RunLoop run_loop;
  97. base::Time last_usage_time;
  98. service().GetLastPermissionUsageTime(
  99. type, origin,
  100. base::BindLambdaForTesting([&](absl::optional<base::Time> time) {
  101. last_usage_time = time.value_or(base::Time());
  102. run_loop.QuitWhenIdle();
  103. }));
  104. run_loop.Run();
  105. return last_usage_time;
  106. }
  107. private:
  108. base::ScopedTempDir temp_directory_;
  109. std::unique_ptr<PermissionAuditingService> service_;
  110. base::test::TaskEnvironment task_environment_{
  111. base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  112. scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
  113. };
  114. TEST_F(PermissionAuditingServiceTest, StorePermissionUsage) {
  115. std::vector<url::Origin> origins(std::size(kTestOrigins));
  116. std::vector<PermissionUsageSession> sessions(std::size(kTestOrigins));
  117. for (size_t i = 0; i < std::size(kTestOrigins); ++i) {
  118. origins[i] = url::Origin::Create(GURL(kTestOrigins[i]));
  119. sessions[i] = BuildUsageSession(kTestTypes[i % 2], origins[i]);
  120. service().StorePermissionUsage(sessions[i]);
  121. }
  122. for (size_t i = 0; i < std::size(kTestOrigins); ++i) {
  123. EXPECT_THAT(
  124. GetPermissionUsageHistory(kTestTypes[i % 2], origins[i], base::Time()),
  125. ElementsAre(sessions[i]));
  126. }
  127. }
  128. TEST_F(PermissionAuditingServiceTest, GetLastPermissionUsageTime) {
  129. std::vector<url::Origin> origins(std::size(kTestOrigins));
  130. for (size_t i = 0; i < std::size(kTestOrigins); ++i) {
  131. origins[i] = url::Origin::Create(GURL(kTestOrigins[i]));
  132. service().StorePermissionUsage(
  133. BuildUsageSession(kTestTypes[0], origins[i]));
  134. task_environment().FastForwardBy(base::TimeDelta());
  135. EXPECT_EQ(GetLastPermissionUsageTime(kTestTypes[0], origins[i]),
  136. kTestTimes[1]);
  137. }
  138. }
  139. TEST_F(PermissionAuditingServiceTest, UpdateEndTime) {
  140. std::vector<url::Origin> origins(std::size(kTestOrigins));
  141. for (size_t i = 0; i < std::size(kTestOrigins); ++i) {
  142. origins[i] = url::Origin::Create(GURL(kTestOrigins[i]));
  143. service().StorePermissionUsage(
  144. BuildUsageSession(kTestTypes[1], origins[i]));
  145. }
  146. for (const auto& origin : origins) {
  147. service().UpdateEndTime(kTestTypes[1], origin, kTestTimes[0],
  148. kTestTimes[2]);
  149. EXPECT_EQ(GetLastPermissionUsageTime(kTestTypes[1], origin), kTestTimes[2]);
  150. }
  151. }
  152. TEST_F(PermissionAuditingServiceTest, DeleteSessionsBetween) {
  153. auto session1 = BuildUsageSession(kTestTimes[0], kTestTimes[1]);
  154. auto session2 = BuildUsageSession(kTestTimes[1], kTestTimes[2]);
  155. auto origin = url::Origin::Create(GURL(kTestOrigins[0]));
  156. auto type = session1.type;
  157. session1.origin = origin;
  158. session2.origin = origin;
  159. auto store_sessions = [&]() {
  160. service().StorePermissionUsage(session1);
  161. service().StorePermissionUsage(session2);
  162. task_environment().FastForwardBy(base::TimeDelta());
  163. };
  164. auto history = [&]() -> std::vector<PermissionUsageSession> {
  165. return GetPermissionUsageHistory(type, origin, base::Time());
  166. };
  167. store_sessions();
  168. ASSERT_THAT(history(), UnorderedElementsAre(session1, session2));
  169. service().DeleteSessionsBetween(kTestTimes[0], kTestTimes[1]);
  170. ASSERT_THAT(history(), IsEmpty());
  171. store_sessions();
  172. ASSERT_THAT(history(), UnorderedElementsAre(session1, session2));
  173. service().DeleteSessionsBetween(kTestTimes[1], kTestTimes[2]);
  174. ASSERT_THAT(history(), IsEmpty());
  175. store_sessions();
  176. ASSERT_THAT(history(), UnorderedElementsAre(session1, session2));
  177. service().DeleteSessionsBetween(kTestTimes[0], kTestTimes[2]);
  178. ASSERT_THAT(history(), IsEmpty());
  179. store_sessions();
  180. ASSERT_THAT(history(), UnorderedElementsAre(session1, session2));
  181. service().DeleteSessionsBetween(kTestTimes[0], kTestTimes[0]);
  182. ASSERT_THAT(history(), ElementsAre(session2));
  183. service().DeleteSessionsBetween(kTestTimes[1], kTestTimes[1]);
  184. ASSERT_THAT(history(), IsEmpty());
  185. store_sessions();
  186. ASSERT_THAT(history(), UnorderedElementsAre(session1, session2));
  187. service().DeleteSessionsBetween(kTestTimes[2], kTestTimes[2]);
  188. ASSERT_THAT(history(), ElementsAre(session1));
  189. service().DeleteSessionsBetween(kTestTimes[1], kTestTimes[1]);
  190. ASSERT_THAT(history(), IsEmpty());
  191. }
  192. TEST_F(PermissionAuditingServiceTest, OldSessionsAreExpired) {
  193. auto delay = service().GetUsageSessionCullingInterval();
  194. auto time1 = base::Time::Now() - service().GetUsageSessionMaxAge() + delay;
  195. auto time2 = time1 + 2 * delay;
  196. auto time3 = time2 + 2 * delay;
  197. auto session1 = BuildUsageSession(time1, time1);
  198. auto session2 = BuildUsageSession(time2, time2);
  199. auto session3 = BuildUsageSession(time3, time3);
  200. service().StorePermissionUsage(session1);
  201. service().StorePermissionUsage(session2);
  202. service().StorePermissionUsage(session3);
  203. auto history = [&]() -> std::vector<PermissionUsageSession> {
  204. return GetPermissionUsageHistory(kTestTypes[0],
  205. url::Origin::Create(GURL(kTestOrigins[0])),
  206. base::Time());
  207. };
  208. ASSERT_THAT(history(), UnorderedElementsAre(session1, session2, session3));
  209. task_environment().FastForwardBy(2 * delay);
  210. ASSERT_THAT(history(), UnorderedElementsAre(session2, session3));
  211. task_environment().FastForwardBy(2 * delay);
  212. ASSERT_THAT(history(), ElementsAre(session3));
  213. task_environment().FastForwardBy(2 * delay);
  214. EXPECT_THAT(history(), IsEmpty());
  215. }
  216. } // namespace permissions