Fix PipeClosedWhenNotRedirectedTest.
When checking for a file descriptor open on the child, we now execute a
simple test program that just runs fstat on that file descriptor. This
is more reliable than calling sh on different platforms.
Bug: 26955860
TEST=Ran unittests on edison-eng and Chromium OS.
Change-Id: I5d5d87095564159df1a75e78b0aed29c16bc7eb8
diff --git a/Android.mk b/Android.mk
index 8084b71..26ed6e6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -808,6 +808,26 @@
$(bsdiff_static_libs)
include $(BUILD_EXECUTABLE)
+# test_subprocess (type: executable)
+# ========================================================
+# Test helper subprocess program.
+include $(CLEAR_VARS)
+LOCAL_MODULE := test_subprocess
+ifdef BRILLO
+ LOCAL_MODULE_TAGS := eng
+endif
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_NATIVE_TESTS)/update_engine_unittests
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CLANG := true
+LOCAL_CFLAGS := $(ue_common_cflags)
+LOCAL_CPPFLAGS := $(ue_common_cppflags)
+LOCAL_LDFLAGS := $(ue_common_ldflags)
+LOCAL_C_INCLUDES := $(ue_common_c_includes)
+LOCAL_SHARED_LIBRARIES := $(ue_common_shared_libraries)
+LOCAL_SRC_FILES := test_subprocess.cc
+include $(BUILD_EXECUTABLE)
+
# update_engine_unittests (type: executable)
# ========================================================
# Main unittest file.
@@ -817,6 +837,8 @@
LOCAL_MODULE_TAGS := eng
endif
LOCAL_REQUIRED_MODULES := \
+ test_http_server \
+ test_subprocess \
ue_unittest_bsdiff \
ue_unittest_delta_generator \
ue_unittest_disk_ext2_1k.img \
diff --git a/common/subprocess_unittest.cc b/common/subprocess_unittest.cc
index 5ca44e8..cc1f353 100644
--- a/common/subprocess_unittest.cc
+++ b/common/subprocess_unittest.cc
@@ -171,13 +171,15 @@
// Test that a pipe file descriptor open in the parent is not open in the child.
TEST_F(SubprocessTest, PipeClosedWhenNotRedirectedTest) {
brillo::ScopedPipe pipe;
- const vector<string> cmd = {kBinPath "/sh", "-c",
- base::StringPrintf("echo on pipe >/proc/self/fd/%d", pipe.writer)};
+
+ // test_subprocess will return with the errno of fstat, which should be EBADF
+ // if the passed file descriptor is closed in the child.
+ const vector<string> cmd = {
+ test_utils::GetBuildArtifactsPath("test_subprocess"),
+ "fstat",
+ std::to_string(pipe.writer)};
EXPECT_TRUE(subprocess_.ExecFlags(
- cmd,
- 0,
- {},
- base::Bind(&ExpectedResults, 1, "")));
+ cmd, 0, {}, base::Bind(&ExpectedResults, EBADF, "")));
loop_.Run();
}
diff --git a/test_subprocess.cc b/test_subprocess.cc
new file mode 100644
index 0000000..c7f4a37
--- /dev/null
+++ b/test_subprocess.cc
@@ -0,0 +1,59 @@
+//
+// Copyright (C) 2012 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.
+//
+
+// This is a simple program used to test interaction with update_engine when
+// executing other programs. This program receives pre-programmed actions in the
+// command line and executes them in order.
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+
+#define EX_USAGE_ERROR 100
+
+void usage(const char* program, const char* error) {
+ if (error)
+ fprintf(stderr, "ERROR: %s\n", error);
+ fprintf(stderr, "Usage: %s <cmd> [args..]\n", program);
+ exit(EX_USAGE_ERROR);
+}
+
+int main(int argc, char** argv, char** envp) {
+ if (argc < 2)
+ usage(argv[0], "No command passed");
+
+ std::string cmd(argv[1]);
+ if (cmd == "fstat") {
+ // Call fstat on the passed file descriptor number
+ if (argc < 3)
+ usage(argv[0], "No fd passed to fstat");
+ int fd = atoi(argv[2]);
+ struct stat buf;
+ int rc = fstat(fd, &buf);
+ if (rc < 0) {
+ int ret = errno;
+ perror("fstat");
+ return ret;
+ }
+ return 0;
+ }
+
+ usage(argv[0], "Unknown command");
+}
diff --git a/update_engine.gyp b/update_engine.gyp
index a0fc447..40d6314 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -457,6 +457,14 @@
'test_http_server.cc',
],
},
+ # Test subprocess helper.
+ {
+ 'target_name': 'test_subprocess',
+ 'type': 'executable',
+ 'sources': [
+ 'test_subprocess.cc',
+ ],
+ },
# Main unittest file.
{
'target_name': 'update_engine_unittests',