diff options
Diffstat (limited to 'init/reboot_test.cpp')
-rw-r--r-- | init/reboot_test.cpp | 196 |
1 files changed, 0 insertions, 196 deletions
diff --git a/init/reboot_test.cpp b/init/reboot_test.cpp deleted file mode 100644 index b3d038d14..000000000 --- a/init/reboot_test.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 "reboot.h" - -#include <errno.h> -#include <unistd.h> - -#include <memory> -#include <string_view> - -#include <android-base/file.h> -#include <android-base/properties.h> -#include <android-base/strings.h> -#include <gtest/gtest.h> -#include <selinux/selinux.h> - -#include "builtin_arguments.h" -#include "builtins.h" -#include "parser.h" -#include "service_list.h" -#include "service_parser.h" -#include "subcontext.h" -#include "util.h" - -using namespace std::literals; - -using android::base::GetProperty; -using android::base::Join; -using android::base::SetProperty; -using android::base::Split; -using android::base::StringReplace; -using android::base::WaitForProperty; -using android::base::WriteStringToFd; - -namespace android { -namespace init { - -class RebootTest : public ::testing::Test { - public: - RebootTest() { - std::vector<std::string> names = GetServiceNames(); - if (!names.empty()) { - ADD_FAILURE() << "Expected empty ServiceList but found: [" << Join(names, ',') << "]"; - } - } - - ~RebootTest() { - std::vector<std::string> names = GetServiceNames(); - for (const auto& name : names) { - auto s = ServiceList::GetInstance().FindService(name); - auto pid = s->pid(); - ServiceList::GetInstance().RemoveService(*s); - if (pid > 0) { - kill(pid, SIGTERM); - kill(pid, SIGKILL); - } - } - } - - private: - std::vector<std::string> GetServiceNames() const { - std::vector<std::string> names; - for (const auto& s : ServiceList::GetInstance()) { - names.push_back(s->name()); - } - return names; - } -}; - -std::string GetSecurityContext() { - char* ctx; - if (getcon(&ctx) == -1) { - ADD_FAILURE() << "Failed to call getcon : " << strerror(errno); - } - std::string result = std::string(ctx); - freecon(ctx); - return result; -} - -void AddTestService(const std::string& name) { - static constexpr std::string_view kScriptTemplate = R"init( -service $name /system/bin/yes - user shell - group shell - seclabel $selabel -)init"; - - std::string script = StringReplace(StringReplace(kScriptTemplate, "$name", name, false), - "$selabel", GetSecurityContext(), false); - ServiceList& service_list = ServiceList::GetInstance(); - Parser parser; - parser.AddSectionParser("service", - std::make_unique<ServiceParser>(&service_list, nullptr, std::nullopt)); - - TemporaryFile tf; - ASSERT_TRUE(tf.fd != -1); - ASSERT_TRUE(WriteStringToFd(script, tf.fd)); - ASSERT_TRUE(parser.ParseConfig(tf.path)); -} - -TEST_F(RebootTest, StopServicesSIGTERM) { - if (getuid() != 0) { - GTEST_SKIP() << "Skipping test, must be run as root."; - return; - } - - AddTestService("A"); - AddTestService("B"); - - auto service_a = ServiceList::GetInstance().FindService("A"); - ASSERT_NE(nullptr, service_a); - auto service_b = ServiceList::GetInstance().FindService("B"); - ASSERT_NE(nullptr, service_b); - - ASSERT_RESULT_OK(service_a->Start()); - ASSERT_TRUE(service_a->IsRunning()); - ASSERT_RESULT_OK(service_b->Start()); - ASSERT_TRUE(service_b->IsRunning()); - - std::unique_ptr<Service> oneshot_service; - { - auto result = Service::MakeTemporaryOneshotService( - {"exec", GetSecurityContext(), "--", "/system/bin/yes"}); - ASSERT_RESULT_OK(result); - oneshot_service = std::move(*result); - } - std::string oneshot_service_name = oneshot_service->name(); - oneshot_service->Start(); - ASSERT_TRUE(oneshot_service->IsRunning()); - ServiceList::GetInstance().AddService(std::move(oneshot_service)); - - EXPECT_EQ(0, StopServicesAndLogViolations({"A", "B", oneshot_service_name}, 10s, - /* terminate= */ true)); - EXPECT_FALSE(service_a->IsRunning()); - EXPECT_FALSE(service_b->IsRunning()); - // Oneshot services are deleted from the ServiceList after they are destroyed. - auto oneshot_service_after_stop = ServiceList::GetInstance().FindService(oneshot_service_name); - EXPECT_EQ(nullptr, oneshot_service_after_stop); -} - -TEST_F(RebootTest, StopServicesSIGKILL) { - if (getuid() != 0) { - GTEST_SKIP() << "Skipping test, must be run as root."; - return; - } - - AddTestService("A"); - AddTestService("B"); - - auto service_a = ServiceList::GetInstance().FindService("A"); - ASSERT_NE(nullptr, service_a); - auto service_b = ServiceList::GetInstance().FindService("B"); - ASSERT_NE(nullptr, service_b); - - ASSERT_RESULT_OK(service_a->Start()); - ASSERT_TRUE(service_a->IsRunning()); - ASSERT_RESULT_OK(service_b->Start()); - ASSERT_TRUE(service_b->IsRunning()); - - std::unique_ptr<Service> oneshot_service; - { - auto result = Service::MakeTemporaryOneshotService( - {"exec", GetSecurityContext(), "--", "/system/bin/yes"}); - ASSERT_RESULT_OK(result); - oneshot_service = std::move(*result); - } - std::string oneshot_service_name = oneshot_service->name(); - oneshot_service->Start(); - ASSERT_TRUE(oneshot_service->IsRunning()); - ServiceList::GetInstance().AddService(std::move(oneshot_service)); - - EXPECT_EQ(0, StopServicesAndLogViolations({"A", "B", oneshot_service_name}, 10s, - /* terminate= */ false)); - EXPECT_FALSE(service_a->IsRunning()); - EXPECT_FALSE(service_b->IsRunning()); - // Oneshot services are deleted from the ServiceList after they are destroyed. - auto oneshot_service_after_stop = ServiceList::GetInstance().FindService(oneshot_service_name); - EXPECT_EQ(nullptr, oneshot_service_after_stop); -} - -} // namespace init -} // namespace android |