From e7fc725c370336d95752dc446631812053a21dc7 Mon Sep 17 00:00:00 2001 From: slan Date: Fri, 29 May 2015 16:05:43 -0700 Subject: [PATCH] Add process and path utilities to chromecast/base. These are useful utilities to internal code which will be added to chromecast/ subdirectories. BUG=internal b/20121400 Change-Id: Ida8430c3dd1602488d9bee6c7c3abbdbd2dd7c48 Review URL: https://codereview.chromium.org/1163683002 Cr-Commit-Position: refs/heads/master@{#332072} --- chromecast/base/path_utils.cc | 55 ++++++++++++++++++++++++++++++ chromecast/base/path_utils.h | 31 +++++++++++++++++ chromecast/base/path_utils_unittest.cc | 56 +++++++++++++++++++++++++++++++ chromecast/base/process_utils.cc | 44 ++++++++++++++++++++++++ chromecast/base/process_utils.h | 22 ++++++++++++ chromecast/base/process_utils_unittest.cc | 52 ++++++++++++++++++++++++++++ chromecast/chromecast.gyp | 4 +++ chromecast/chromecast_tests.gypi | 2 ++ 8 files changed, 266 insertions(+) create mode 100644 chromecast/base/path_utils.cc create mode 100644 chromecast/base/path_utils.h create mode 100644 chromecast/base/path_utils_unittest.cc create mode 100644 chromecast/base/process_utils.cc create mode 100644 chromecast/base/process_utils.h create mode 100644 chromecast/base/process_utils_unittest.cc diff --git a/chromecast/base/path_utils.cc b/chromecast/base/path_utils.cc new file mode 100644 index 000000000000..4f5b27b7e02f --- /dev/null +++ b/chromecast/base/path_utils.cc @@ -0,0 +1,55 @@ +// Copyright 2015 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 "chromecast/base/path_utils.h" + +#include "base/logging.h" +#include "base/path_service.h" + +namespace chromecast { + +namespace { + +base::FilePath GetPath(base::BasePathKey default_dir_key, + const base::FilePath& path) { + if (path.IsAbsolute()) + return path; + + base::FilePath default_dir; + if (!PathService::Get(default_dir_key, &default_dir)) + LOG(DFATAL) << "Cannot get default dir: " << default_dir_key; + + base::FilePath adjusted_path(default_dir.Append(path)); + VLOG(1) << "Path adjusted from " << path.value() << " to " + << adjusted_path.value(); + return adjusted_path; +} + +} // namespace + +base::FilePath GetHomePath(const base::FilePath& path) { + return GetPath(base::DIR_HOME, path); +} + +base::FilePath GetHomePathASCII(const std::string& path) { + return GetHomePath(base::FilePath(path)); +} + +base::FilePath GetBinPath(const base::FilePath& path) { + return GetPath(base::DIR_EXE, path); +} + +base::FilePath GetBinPathASCII(const std::string& path) { + return GetBinPath(base::FilePath(path)); +} + +base::FilePath GetTmpPath(const base::FilePath& path) { + return GetPath(base::DIR_TEMP, path); +} + +base::FilePath GetTmpPathASCII(const std::string& path) { + return GetTmpPath(base::FilePath(path)); +} + +} // namespace chromecast diff --git a/chromecast/base/path_utils.h b/chromecast/base/path_utils.h new file mode 100644 index 000000000000..5c1e205c2c38 --- /dev/null +++ b/chromecast/base/path_utils.h @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#ifndef CHROMECAST_BASE_PATH_UTILS_H_ +#define CHROMECAST_BASE_PATH_UTILS_H_ + +#include + +#include "base/files/file_path.h" + +namespace chromecast { + +// If |path| is relative, returns the path created by prepending HOME directory +// to |path| (e.g. {HOME}/|path|). If |path| is absolute, returns |path|. +base::FilePath GetHomePath(const base::FilePath& path); +base::FilePath GetHomePathASCII(const std::string& path); + +// If |path| is relative, returns the path created by prepending BIN directory +// to |path| (e.g. {BIN}/|path|). If |path| is absolute, returns |path|. +base::FilePath GetBinPath(const base::FilePath& path); +base::FilePath GetBinPathASCII(const std::string& path); + +// If |path| is relative, returns the path created by prepending TMP directory +// to |path| (e.g. {TMP}/|path|). If |path| is absolute, returns |path|. +base::FilePath GetTmpPath(const base::FilePath& path); +base::FilePath GetTmpPathASCII(const std::string& path); + +} // namespace chromecast + +#endif // CHROMECAST_BASE_PATH_UTILS_H_ diff --git a/chromecast/base/path_utils_unittest.cc b/chromecast/base/path_utils_unittest.cc new file mode 100644 index 000000000000..618bb0f3e4b2 --- /dev/null +++ b/chromecast/base/path_utils_unittest.cc @@ -0,0 +1,56 @@ +// Copyright 2015 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 "base/files/file_path.h" +#include "base/path_service.h" +#include "chromecast/base/path_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromecast { +namespace { +const char kTestRelPath[] = "rel/path"; +const char kTestAbsPath[] = "/abs/path/to/dir"; + +std::string GetTestString(int base_dir_key) { + base::FilePath basedir; + EXPECT_TRUE(PathService::Get(base_dir_key, &basedir)); + return basedir.value() + "/" + kTestRelPath; +} + +} // namespace + +TEST(PathUtilsTest, GetHomePath) { + // Test with relative path. + std::string expected = GetTestString(base::DIR_HOME); + base::FilePath actual = GetHomePath(base::FilePath(kTestRelPath)); + EXPECT_EQ(expected, actual.value()); + + // Test with absolute path. + actual = GetHomePath(base::FilePath(kTestAbsPath)); + EXPECT_EQ(kTestAbsPath, actual.value()); +} + +TEST(PathUtilsTest, GetBinPath) { + // Test with relative path. + std::string expected = GetTestString(base::DIR_EXE); + base::FilePath actual = GetBinPath(base::FilePath(kTestRelPath)); + EXPECT_EQ(expected, actual.value()); + + // Test with absolute path. + actual = GetBinPath(base::FilePath(kTestAbsPath)); + EXPECT_EQ(kTestAbsPath, actual.value()); +} + +TEST(PathUtilsTest, GetTmpPath) { + // Test with relative path. + std::string expected = GetTestString(base::DIR_TEMP); + base::FilePath actual = GetTmpPath(base::FilePath(kTestRelPath)); + EXPECT_EQ(expected, actual.value()); + + // Test with absolute path. + actual = GetTmpPath(base::FilePath(kTestAbsPath)); + EXPECT_EQ(kTestAbsPath, actual.value()); +} + +} // chromecast \ No newline at end of file diff --git a/chromecast/base/process_utils.cc b/chromecast/base/process_utils.cc new file mode 100644 index 000000000000..901d53d764d9 --- /dev/null +++ b/chromecast/base/process_utils.cc @@ -0,0 +1,44 @@ +// Copyright 2015 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 "chromecast/base/process_utils.h" + +#include +#include + +#include "base/logging.h" +#include "base/safe_strerror_posix.h" +#include "base/strings/string_util.h" + +namespace chromecast { + +bool GetAppOutput(const std::vector& argv, std::string* output) { + DCHECK(output); + + // Join the args into one string, creating the command. + std::string command = JoinString(argv, ' '); + + // Open the process. + FILE* fp = popen(command.c_str(), "r"); + if (!fp) { + LOG(ERROR) << "popen (" << command << ") failed: " << safe_strerror(errno); + return false; + } + + // Fill |output| with the stdout from the process. + output->clear(); + while (!feof(fp)) { + char buffer[256]; + size_t bytes_read = fread(buffer, 1, sizeof(buffer), fp); + if (bytes_read <= 0) + break; + output->append(buffer, bytes_read); + } + + // pclose() function waits for the associated process to terminate and returns + // the exit status. + return (pclose(fp) == 0); +} + +} // namespace chromecast diff --git a/chromecast/base/process_utils.h b/chromecast/base/process_utils.h new file mode 100644 index 000000000000..c79da17c037b --- /dev/null +++ b/chromecast/base/process_utils.h @@ -0,0 +1,22 @@ +// Copyright 2015 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. + +#ifndef CHROMECAST_BASE_PROCESS_UTILS_H_ +#define CHROMECAST_BASE_PROCESS_UTILS_H_ + +#include +#include + +namespace chromecast { + +// Executes application, for which arguments are specified by |argv| and wait +// for it to exit. Stores the output (stdout) in |output|. Returns true on +// success. +// TODO(slan): Replace uses of this with base::GetAppOutput when crbug/493711 is +// resolved. +bool GetAppOutput(const std::vector& argv, std::string* output); + +} // namespace chromecast + +#endif // CHROMECAST_BASE_PROCESS_UTILS_H_ diff --git a/chromecast/base/process_utils_unittest.cc b/chromecast/base/process_utils_unittest.cc new file mode 100644 index 000000000000..42e56a295ef7 --- /dev/null +++ b/chromecast/base/process_utils_unittest.cc @@ -0,0 +1,52 @@ +// Copyright 2015 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 "chromecast/base/process_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromecast { + +// Verify that a simple process works as expected. +TEST(ProcessUtilsTest, SimpleProcess) { + // Create a simple command. + std::vector args; + args.push_back("echo"); + args.push_back("Hello World"); + + // Execute the command and collect the output. + std::string stdout; + ASSERT_TRUE(GetAppOutput(args, &stdout)); + + // Echo will append a newline to the stdout. + EXPECT_EQ("Hello World\n", stdout); +} + +// Verify that false is returned for an invalid command. +TEST(ProcessUtilsTest, InvalidCommand) { + // Create a command which is not valid. + std::vector args; + args.push_back("invalid_command"); + + // The command should not run. + std::string stdout; + ASSERT_FALSE(GetAppOutput(args, &stdout)); + ASSERT_TRUE(stdout.empty()); +} + +// Verify that false is returned when a command an error code. +TEST(ProcessUtilsTest, ProcessReturnsError) { + // Create a simple command. + std::vector args; + args.push_back("cd"); + args.push_back("path/to/invalid/directory"); + args.push_back("2>&1"); // Pipe the stderr into stdout. + + // Execute the command and collect the output. Verify that the output of the + // process is collected, even when the process returns an error code. + std::string stderr; + ASSERT_FALSE(GetAppOutput(args, &stderr)); + ASSERT_FALSE(stderr.empty()); +} + +} // namespace chromecast \ No newline at end of file diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp index ee769fa63a12..b70b310eb737 100644 --- a/chromecast/chromecast.gyp +++ b/chromecast/chromecast.gyp @@ -70,6 +70,10 @@ 'base/metrics/cast_metrics_helper.h', 'base/metrics/grouped_histogram.cc', 'base/metrics/grouped_histogram.h', + 'base/path_utils.cc', + 'base/path_utils.h', + 'base/process_utils.cc', + 'base/process_utils.h', 'base/serializers.cc', 'base/serializers.h' ], diff --git a/chromecast/chromecast_tests.gypi b/chromecast/chromecast_tests.gypi index 06a89e723516..5f9aa93921bd 100644 --- a/chromecast/chromecast_tests.gypi +++ b/chromecast/chromecast_tests.gypi @@ -16,6 +16,8 @@ '../testing/gtest.gyp:gtest', ], 'sources': [ + 'base/path_utils_unittest.cc', + 'base/process_utils_unittest.cc', 'base/serializers_unittest.cc', ], }, -- 2.11.4.GIT