blob: 4027e41f2d9ed86b6848cf195bd15f2ba36a5876 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/arc/process/arc_process.h"
#include <assert.h>
#include <list>
#include <sstream>
#include "testing/gtest/include/gtest/gtest.h"
namespace arc {
namespace {
// Tests that ArcProcess objects can be sorted by their priority (higher to
// lower). This is critical for the OOM handler to work correctly.
TEST(ArcProcess, TestSorting) {
constexpr int64_t kNow = 1234567890;
std::list<ArcProcess> processes; // use list<> for emplace_front.
processes.emplace_back(0, 0, "process 0", mojom::ProcessState::PERSISTENT,
false /* is_focused */, kNow + 1);
processes.emplace_front(1, 1, "process 1", mojom::ProcessState::PERSISTENT,
false, kNow);
processes.emplace_back(2, 2, "process 2", mojom::ProcessState::LAST_ACTIVITY,
false, kNow);
processes.emplace_front(3, 3, "process 3", mojom::ProcessState::LAST_ACTIVITY,
false, kNow + 1);
processes.emplace_back(4, 4, "process 4", mojom::ProcessState::CACHED_EMPTY,
false, kNow + 1);
processes.emplace_front(5, 5, "process 5", mojom::ProcessState::CACHED_EMPTY,
false, kNow);
processes.sort();
static_assert(
mojom::ProcessState::PERSISTENT < mojom::ProcessState::LAST_ACTIVITY,
"unexpected enum values");
static_assert(
mojom::ProcessState::LAST_ACTIVITY < mojom::ProcessState::CACHED_EMPTY,
"unexpected enum values");
std::list<ArcProcess>::const_iterator it = processes.begin();
// 0 should have higher priority since its last_activity_time is more recent.
EXPECT_EQ(0, it->pid());
++it;
EXPECT_EQ(1, it->pid());
++it;
// Same, 3 should have higher priority.
EXPECT_EQ(3, it->pid());
++it;
EXPECT_EQ(2, it->pid());
++it;
// Same, 4 should have higher priority.
EXPECT_EQ(4, it->pid());
++it;
EXPECT_EQ(5, it->pid());
}
TEST(ArcProcess, TestIsImportant) {
constexpr bool kIsNotFocused = false;
// Processes up to IMPORTANT_FOREGROUND are considered important.
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::PERSISTENT,
kIsNotFocused, 0)
.IsImportant());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::PERSISTENT_UI,
kIsNotFocused, 0)
.IsImportant());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::TOP, true, 0)
.IsImportant());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::TOP, false, 0)
.IsImportant());
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::BOUND_FOREGROUND_SERVICE,
kIsNotFocused, 0)
.IsImportant());
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::FOREGROUND_SERVICE, kIsNotFocused,
0)
.IsImportant());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::TOP_SLEEPING,
kIsNotFocused, 0)
.IsImportant());
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::IMPORTANT_FOREGROUND,
kIsNotFocused, 0)
.IsImportant());
// Others are not important.
EXPECT_FALSE(ArcProcess(0, 0, "process",
mojom::ProcessState::IMPORTANT_BACKGROUND,
kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(
ArcProcess(0, 0, "process", mojom::ProcessState::BACKUP, kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::HEAVY_WEIGHT,
kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::SERVICE,
kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::RECEIVER,
kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(
ArcProcess(0, 0, "process", mojom::ProcessState::HOME, kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::LAST_ACTIVITY,
kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::CACHED_ACTIVITY,
kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(ArcProcess(0, 0, "process",
mojom::ProcessState::CACHED_ACTIVITY_CLIENT,
kIsNotFocused, 0)
.IsImportant());
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::CACHED_EMPTY,
kIsNotFocused, 0)
.IsImportant());
}
TEST(ArcProcess, TestIsKernelKillable) {
constexpr bool kIsNotFocused = false;
// Only PERSISITENT* processes are protected from the kernel OOM killer.
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::PERSISTENT,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_FALSE(ArcProcess(0, 0, "process", mojom::ProcessState::PERSISTENT_UI,
kIsNotFocused, 0)
.IsKernelKillable());
// Both TOP+focused and TOP apps are still kernel-killable.
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::TOP, true, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::TOP, false, 0)
.IsKernelKillable());
// Others are kernel-killable.
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::BOUND_FOREGROUND_SERVICE,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::FOREGROUND_SERVICE, kIsNotFocused,
0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::TOP_SLEEPING,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::IMPORTANT_FOREGROUND,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::IMPORTANT_BACKGROUND,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(
ArcProcess(0, 0, "process", mojom::ProcessState::BACKUP, kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::HEAVY_WEIGHT,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::SERVICE,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::RECEIVER,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(
ArcProcess(0, 0, "process", mojom::ProcessState::HOME, kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::LAST_ACTIVITY,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::CACHED_ACTIVITY,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process",
mojom::ProcessState::CACHED_ACTIVITY_CLIENT,
kIsNotFocused, 0)
.IsKernelKillable());
EXPECT_TRUE(ArcProcess(0, 0, "process", mojom::ProcessState::CACHED_EMPTY,
kIsNotFocused, 0)
.IsKernelKillable());
}
// Tests operator<<() does not crash and returns non-empty result, at least.
TEST(ArcProcess, TestStringification) {
std::stringstream s;
s << ArcProcess(0, 0, "p", mojom::ProcessState::PERSISTENT, false, 0);
EXPECT_FALSE(s.str().empty());
}
} // namespace
} // namespace arc