system_session_analyzer_win_unittest.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright 2017 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/metrics/system_session_analyzer/system_session_analyzer_win.h"
  5. #include <algorithm>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/logging.h"
  9. #include "base/time/time.h"
  10. #include "testing/gmock/include/gmock/gmock.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace metrics {
  13. namespace {
  14. const uint16_t kIdSessionStart = 6005U;
  15. const uint16_t kIdSessionEnd = 6006U;
  16. const uint16_t kIdSessionEndUnclean = 6008U;
  17. } // namespace
  18. // Ensure the fetcher retrieves events.
  19. // Due to https://crbug.com/1053451 which is caused by a Windows "bug" tracked
  20. // by https://crbug.com/1053451 this cannot be made reliable. Running
  21. // browser_tests can and does generate so much event logging (DCOM events) that
  22. // none of the looked for events remain.
  23. TEST(SystemSessionAnalyzerTest, DISABLED_FetchEvents) {
  24. SystemSessionAnalyzer analyzer(0);
  25. std::vector<SystemSessionAnalyzer::EventInfo> events;
  26. ASSERT_TRUE(analyzer.FetchEvents(1U, &events));
  27. EXPECT_EQ(1U, events.size());
  28. }
  29. // Ensure the fetcher's retrieved events conform to our expectations.
  30. // Note: this test fails if the host system doesn't have at least 1 prior
  31. // session.
  32. TEST(SystemSessionAnalyzerTest, ValidateEvents) {
  33. SystemSessionAnalyzer analyzer(1U);
  34. auto is_session_unclean = analyzer.IsSessionUnclean(base::Time::Now());
  35. // If the system event log rate is high enough then there may not be enough
  36. // events to make a clean/unclean determination. Check for this situation and
  37. // don't treat it as a failure. See https://crbug.com/968440 and
  38. // https://crbug.com/1053451 for details.
  39. if (is_session_unclean == SystemSessionAnalyzer::INSUFFICIENT_DATA) {
  40. // This warning can be ignored, but it does mean that our clean/unclean
  41. // check did not give an answer.
  42. LOG(WARNING) << "Insufficient events found in ValidateEvents.";
  43. } else {
  44. EXPECT_EQ(SystemSessionAnalyzer::CLEAN, is_session_unclean)
  45. << "Extended error code is: "
  46. << static_cast<int>(analyzer.GetExtendedFailureStatus());
  47. }
  48. }
  49. // Stubs FetchEvents.
  50. class StubSystemSessionAnalyzer : public SystemSessionAnalyzer {
  51. public:
  52. StubSystemSessionAnalyzer(uint32_t max_session_cnt)
  53. : SystemSessionAnalyzer(max_session_cnt) {}
  54. bool FetchEvents(size_t requested_events,
  55. std::vector<EventInfo>* event_infos) override {
  56. DCHECK(event_infos);
  57. size_t num_to_copy = std::min(requested_events, events_.size());
  58. if (num_to_copy) {
  59. event_infos->clear();
  60. event_infos->insert(event_infos->begin(), events_.begin(),
  61. events_.begin() + num_to_copy);
  62. events_.erase(events_.begin(), events_.begin() + num_to_copy);
  63. }
  64. return true;
  65. }
  66. void AddEvent(const EventInfo& info) { events_.push_back(info); }
  67. private:
  68. std::vector<EventInfo> events_;
  69. };
  70. TEST(SystemSessionAnalyzerTest, StandardCase) {
  71. StubSystemSessionAnalyzer analyzer(2U);
  72. base::Time time = base::Time::Now();
  73. analyzer.AddEvent({kIdSessionStart, time});
  74. analyzer.AddEvent({kIdSessionEndUnclean, time - base::Seconds(10)});
  75. analyzer.AddEvent({kIdSessionStart, time - base::Seconds(20)});
  76. analyzer.AddEvent({kIdSessionEnd, time - base::Seconds(22)});
  77. analyzer.AddEvent({kIdSessionStart, time - base::Seconds(28)});
  78. EXPECT_EQ(SystemSessionAnalyzer::OUTSIDE_RANGE,
  79. analyzer.IsSessionUnclean(time - base::Seconds(30)));
  80. EXPECT_EQ(SystemSessionAnalyzer::CLEAN,
  81. analyzer.IsSessionUnclean(time - base::Seconds(25)));
  82. EXPECT_EQ(SystemSessionAnalyzer::UNCLEAN,
  83. analyzer.IsSessionUnclean(time - base::Seconds(20)));
  84. EXPECT_EQ(SystemSessionAnalyzer::UNCLEAN,
  85. analyzer.IsSessionUnclean(time - base::Seconds(15)));
  86. EXPECT_EQ(SystemSessionAnalyzer::UNCLEAN,
  87. analyzer.IsSessionUnclean(time - base::Seconds(10)));
  88. EXPECT_EQ(SystemSessionAnalyzer::CLEAN,
  89. analyzer.IsSessionUnclean(time - base::Seconds(5)));
  90. EXPECT_EQ(SystemSessionAnalyzer::CLEAN,
  91. analyzer.IsSessionUnclean(time + base::Seconds(5)));
  92. }
  93. TEST(SystemSessionAnalyzerTest, NoEvent) {
  94. StubSystemSessionAnalyzer analyzer(0U);
  95. EXPECT_EQ(SystemSessionAnalyzer::INSUFFICIENT_DATA,
  96. analyzer.IsSessionUnclean(base::Time::Now()));
  97. }
  98. TEST(SystemSessionAnalyzerTest, TimeInversion) {
  99. StubSystemSessionAnalyzer analyzer(1U);
  100. base::Time time = base::Time::Now();
  101. analyzer.AddEvent({kIdSessionStart, time});
  102. analyzer.AddEvent({kIdSessionEnd, time + base::Seconds(1)});
  103. analyzer.AddEvent({kIdSessionStart, time - base::Seconds(1)});
  104. EXPECT_EQ(SystemSessionAnalyzer::INITIALIZE_FAILED,
  105. analyzer.IsSessionUnclean(base::Time::Now()));
  106. }
  107. TEST(SystemSessionAnalyzerTest, IdInversion) {
  108. StubSystemSessionAnalyzer analyzer(1U);
  109. base::Time time = base::Time::Now();
  110. analyzer.AddEvent({kIdSessionStart, time});
  111. analyzer.AddEvent({kIdSessionStart, time - base::Seconds(1)});
  112. analyzer.AddEvent({kIdSessionEnd, time - base::Seconds(2)});
  113. EXPECT_EQ(SystemSessionAnalyzer::INITIALIZE_FAILED,
  114. analyzer.IsSessionUnclean(base::Time::Now()));
  115. }
  116. } // namespace metrics