| // Copyright 2018 The Fuchsia 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 "src/sys/appmgr/util.h" |
| |
| #include "gtest/gtest.h" |
| |
| namespace component { |
| namespace { |
| |
| TEST(UtilTests, GetLabelFromURL) { |
| std::string values[][2] = {{"", ""}, {"foo/bar", "bar"}, {"foo/bar/", "foo/bar/"}, |
| {"/foo", "foo"}, {"/foo/bar", "bar"}, {"foo", "foo"}, |
| {"foo/", "foo/"}}; |
| for (auto value : values) { |
| auto& url = value[0]; |
| auto& expected = value[1]; |
| EXPECT_EQ(Util::GetLabelFromURL(url), expected) << "for url: " << url; |
| } |
| } |
| |
| TEST(UtilTests, GetArgsString) { |
| ::fidl::VectorPtr<::std::string> null_vec; |
| EXPECT_EQ(Util::GetArgsString(null_vec), ""); |
| |
| ::fidl::VectorPtr<::std::string> empty_vec(3); |
| EXPECT_EQ(Util::GetArgsString(empty_vec), " "); |
| |
| std::vector<::std::string> vec; |
| vec.push_back("foo"); |
| EXPECT_EQ(Util::GetArgsString(vec), "foo"); |
| vec.push_back("bar"); |
| EXPECT_EQ(Util::GetArgsString(vec), "foo bar"); |
| vec.push_back("blah"); |
| EXPECT_EQ(Util::GetArgsString(vec), "foo bar blah"); |
| } |
| |
| TEST(UtilTests, BindDirectory) { |
| zx::channel dir, dir_req; |
| ASSERT_EQ(zx::channel::create(0, &dir, &dir_req), ZX_OK); |
| fuchsia::sys::LaunchInfo launchInfo; |
| launchInfo.directory_request = std::move(dir_req); |
| auto channels = Util::BindDirectory(&launchInfo); |
| ASSERT_TRUE(channels.exported_dir.is_valid()); |
| ASSERT_TRUE(channels.client_request.is_valid()); |
| |
| const char* msg1 = "message1"; |
| dir.write(0, msg1, strlen(msg1) + 1, nullptr, 0); |
| |
| const char* msg2 = "message2"; |
| channels.exported_dir.write(0, msg2, strlen(msg2) + 1, nullptr, 0); |
| |
| char got1[strlen(msg1) + 1]; |
| char got2[strlen(msg2) + 1]; |
| |
| channels.client_request.read(0, got1, nullptr, sizeof(got1), 0, nullptr, nullptr); |
| launchInfo.directory_request.read(0, got2, nullptr, sizeof(got2), 0, nullptr, nullptr); |
| |
| EXPECT_STREQ(got1, msg1); |
| EXPECT_STREQ(got2, msg2); |
| } |
| |
| class RestartBackOffTester : public RestartBackOff { |
| public: |
| RestartBackOffTester(zx::duration min_backoff, zx::duration max_backoff, |
| zx::duration alive_reset_limit) |
| : RestartBackOff(min_backoff, max_backoff, alive_reset_limit) {} |
| void SetCurrentTime(zx::time time) { current_time_ = time; } |
| |
| protected: |
| zx::time GetCurrentTime() const override { return current_time_; } |
| |
| private: |
| zx::time current_time_; |
| }; |
| |
| TEST(RestartBackOffTest, WaitIncreasesAndResets) { |
| auto start_time = zx::time() + zx::hour(10); |
| auto within_limit = start_time + zx::msec(100); |
| auto after_limit = start_time + zx::msec(1100); |
| RestartBackOffTester util(zx::sec(1), zx::sec(10), zx::sec(1)); |
| util.SetCurrentTime(start_time); |
| util.Start(); |
| util.SetCurrentTime(within_limit); |
| EXPECT_GE(util.GetNext(), zx::sec(1)); |
| for (int i = 0; i < 10; i++) { |
| util.GetNext(); |
| } |
| // Ensure we don't go over the limit. |
| EXPECT_EQ(util.GetNext(), zx::sec(10)); |
| |
| // If the task succeeded for long enough, ensure backoff is reset. |
| util.SetCurrentTime(after_limit); |
| EXPECT_LT(util.GetNext(), zx::sec(10)); |
| } |
| |
| } // namespace |
| } // namespace component |