Add test for profiler CPU guardrail.

Change-Id: Ic71014e148bbc7f4b56ba97d18141527feba9ee2
diff --git a/Android.bp b/Android.bp
index f174c13..80358ff 100644
--- a/Android.bp
+++ b/Android.bp
@@ -6537,6 +6537,7 @@
   srcs: [
     "src/profiling/common/interner_unittest.cc",
     "src/profiling/common/proc_utils_unittest.cc",
+    "src/profiling/common/profiler_guardrails_unittest.cc",
   ],
 }
 
diff --git a/src/profiling/common/BUILD.gn b/src/profiling/common/BUILD.gn
index 5a35838..a8b948f 100644
--- a/src/profiling/common/BUILD.gn
+++ b/src/profiling/common/BUILD.gn
@@ -94,6 +94,7 @@
   deps = [
     ":interner",
     ":proc_utils",
+    ":profiler_guardrails",
     "../../../gn:default_deps",
     "../../../gn:gtest_and_gmock",
     "../../../include/perfetto/profiling:normalize",
@@ -103,5 +104,6 @@
   sources = [
     "interner_unittest.cc",
     "proc_utils_unittest.cc",
+    "profiler_guardrails_unittest.cc",
   ]
 }
diff --git a/src/profiling/common/profiler_guardrails_unittest.cc b/src/profiling/common/profiler_guardrails_unittest.cc
new file mode 100644
index 0000000..79bf7be
--- /dev/null
+++ b/src/profiling/common/profiler_guardrails_unittest.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/common/profiler_guardrails.h"
+
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <map>
+
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace profiling {
+namespace {
+
+class StubDataSource {
+ public:
+  StubDataSource(uint64_t cpu_guardrails_secs,
+                 uint64_t cpu_start_secs,
+                 uint64_t memory_guardrail_kb)
+      : cpu_guardrails_secs_(cpu_guardrails_secs),
+        cpu_start_secs_(cpu_start_secs),
+        memory_guardrail_kb_(memory_guardrail_kb) {}
+
+  uint64_t GetCpuGuardrailSecs() const { return cpu_guardrails_secs_; }
+
+  base::Optional<uint64_t> GetCpuStartSecs() const { return cpu_start_secs_; }
+
+  uint64_t GetMemoryGuardrailKb() const { return memory_guardrail_kb_; }
+
+  void Delete() { deleted_ = true; }
+  bool deleted() { return deleted_; }
+
+ private:
+  uint64_t cpu_guardrails_secs_;
+  uint64_t cpu_start_secs_;
+  uint64_t memory_guardrail_kb_;
+  bool deleted_ = false;
+};
+
+TEST(ProfilerCpuGuardrailsTest, Exceeded) {
+  const auto clk = static_cast<unsigned long>(sysconf(_SC_CLK_TCK));
+  StubDataSource ds(5000000 / clk, 1000000 / clk, 0);
+  std::map<int, StubDataSource> ds_map = {{1, std::move(ds)}};
+  base::TempFile f = base::TempFile::CreateUnlinked();
+  constexpr const char stat[] =
+      "2965981 (zsh) S 2965977 2965981 2965981 34822 2966607 4194304 6632 6697 "
+      "0 0 1000000 6000000 4 1 20 0 1 0 227163466 15839232 2311 "
+      "18446744073709551615 "
+      "94823961161728 94823961762781 140722993535472 0 0 0 2 3686400 134295555 "
+      "0 0 0 17 2 0 0 0 0 0 94823961905904 94823961935208 94823993954304 "
+      "140722993543678 140722993543691 140722993543691 140722993545195 0";
+  base::WriteAll(f.fd(), stat, sizeof(stat));
+  ProfilerCpuGuardrails gr(f.ReleaseFD());
+  gr.CheckDataSourceCpu(ds_map.begin(), ds_map.end(),
+                        [](StubDataSource* d) { d->Delete(); });
+  auto it = ds_map.find(1);
+  ASSERT_NE(it, ds_map.end());
+  EXPECT_TRUE(it->second.deleted());
+}
+
+TEST(ProfilerCpuGuardrailsTest, NotExceeded) {
+  const auto clk = static_cast<unsigned long>(sysconf(_SC_CLK_TCK));
+  StubDataSource ds(7000000 / clk, 1000000 / clk, 0);
+  std::map<int, StubDataSource> ds_map = {{1, std::move(ds)}};
+  base::TempFile f = base::TempFile::CreateUnlinked();
+  constexpr const char stat[] =
+      "2965981 (zsh) S 2965977 2965981 2965981 34822 2966607 4194304 6632 6697 "
+      "0 0 1000000 6000000 4 1 20 0 1 0 227163466 15839232 2311 "
+      "18446744073709551615 "
+      "94823961161728 94823961762781 140722993535472 0 0 0 2 3686400 134295555 "
+      "0 0 0 17 2 0 0 0 0 0 94823961905904 94823961935208 94823993954304 "
+      "140722993543678 140722993543691 140722993543691 140722993545195 0";
+  base::WriteAll(f.fd(), stat, sizeof(stat));
+  ProfilerCpuGuardrails gr(f.ReleaseFD());
+  gr.CheckDataSourceCpu(ds_map.begin(), ds_map.end(),
+                        [](StubDataSource* d) { d->Delete(); });
+  auto it = ds_map.find(1);
+  ASSERT_NE(it, ds_map.end());
+  EXPECT_FALSE(it->second.deleted());
+}
+
+}  // namespace
+}  // namespace profiling
+}  // namespace perfetto