Make subprocess_test platform independent.
PiperOrigin-RevId: 292186297 Change-Id: I18e7a03c2038e9024da4ec5f36438fb965df6b79
This commit is contained in:
parent
a7f8058daf
commit
cfe8b42b91
tensorflow/core/platform
@ -890,10 +890,17 @@ tf_cc_test(
|
||||
name = "subprocess_test",
|
||||
size = "small",
|
||||
srcs = ["subprocess_test.cc"],
|
||||
data = [
|
||||
"//tensorflow/core/platform/testdata:test_echo",
|
||||
"//tensorflow/core/platform/testdata:test_echo_argv_1",
|
||||
"//tensorflow/core/platform/testdata:test_noop",
|
||||
"//tensorflow/core/platform/testdata:test_stderr",
|
||||
],
|
||||
tags = [
|
||||
"no_windows",
|
||||
],
|
||||
deps = [
|
||||
":strcat",
|
||||
":subprocess",
|
||||
"//tensorflow/core:test",
|
||||
"//tensorflow/core:test_main",
|
||||
|
@ -13,26 +13,48 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==============================================================================*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include "tensorflow/core/platform/subprocess.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "tensorflow/core/lib/core/status_test_util.h"
|
||||
#include "tensorflow/core/platform/subprocess.h"
|
||||
#include "tensorflow/core/platform/strcat.h"
|
||||
#include "tensorflow/core/platform/test.h"
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
#define WIFEXITED(code) ((code) != 3)
|
||||
#define WEXITSTATUS(code) (code)
|
||||
#define SIGKILL 9
|
||||
#else
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
const char kEchoProgram[] = "core/platform/testdata/test_echo";
|
||||
const char kEchoArgv1Program[] = "core/platform/testdata/test_echo_argv_1";
|
||||
const char kNoopProgram[] = "core/platform/testdata/test_noop";
|
||||
const char kStdErrProgram[] = "core/platform/testdata/test_stderr";
|
||||
|
||||
namespace tensorflow {
|
||||
|
||||
class SubProcessTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(SubProcessTest, NoOutputNoComm) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/cat", {"cat", "/dev/null"});
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kNoopProgram).c_str(),
|
||||
{kNoopProgram});
|
||||
EXPECT_TRUE(proc.Start());
|
||||
EXPECT_TRUE(proc.Wait());
|
||||
}
|
||||
|
||||
TEST_F(SubProcessTest, NoOutput) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/cat", {"cat", "/dev/null"});
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kNoopProgram).c_str(),
|
||||
{kNoopProgram});
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDERR, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
@ -47,7 +69,11 @@ TEST_F(SubProcessTest, NoOutput) {
|
||||
|
||||
TEST_F(SubProcessTest, Stdout) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/echo", {"echo", "-n", "hello world"});
|
||||
const char test_string[] = "hello_world";
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kEchoArgv1Program)
|
||||
.c_str(),
|
||||
{kEchoArgv1Program, test_string});
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDERR, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
@ -56,13 +82,17 @@ TEST_F(SubProcessTest, Stdout) {
|
||||
int status = proc.Communicate(nullptr, &out, &err);
|
||||
EXPECT_TRUE(WIFEXITED(status));
|
||||
EXPECT_EQ(0, WEXITSTATUS(status));
|
||||
EXPECT_EQ("hello world", out);
|
||||
EXPECT_EQ(test_string, out);
|
||||
EXPECT_EQ("", err);
|
||||
}
|
||||
|
||||
TEST_F(SubProcessTest, StdoutIgnored) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/echo", {"echo", "-n", "hello world"});
|
||||
const char test_string[] = "hello_world";
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kEchoArgv1Program)
|
||||
.c_str(),
|
||||
{kEchoArgv1Program, test_string});
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDERR, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
@ -74,7 +104,11 @@ TEST_F(SubProcessTest, StdoutIgnored) {
|
||||
|
||||
TEST_F(SubProcessTest, Stderr) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/cat", {"cat", "/file_does_not_exist"});
|
||||
const char test_string[] = "muh_failure!";
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kStdErrProgram)
|
||||
.c_str(),
|
||||
{kStdErrProgram, test_string});
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDERR, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
@ -84,12 +118,16 @@ TEST_F(SubProcessTest, Stderr) {
|
||||
EXPECT_TRUE(WIFEXITED(status));
|
||||
EXPECT_EQ(1, WEXITSTATUS(status));
|
||||
EXPECT_EQ("", out);
|
||||
EXPECT_NE(string::npos, err.find("/file_does_not_exist"));
|
||||
EXPECT_EQ(test_string, err);
|
||||
}
|
||||
|
||||
TEST_F(SubProcessTest, StderrIgnored) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/cat", {"cat", "/file_does_not_exist"});
|
||||
const char test_string[] = "muh_failure!";
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kStdErrProgram)
|
||||
.c_str(),
|
||||
{kStdErrProgram, test_string});
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDERR, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
@ -101,7 +139,9 @@ TEST_F(SubProcessTest, StderrIgnored) {
|
||||
|
||||
TEST_F(SubProcessTest, Stdin) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/usr/bin/wc", {"wc", "-l"});
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kEchoProgram).c_str(),
|
||||
{kEchoProgram});
|
||||
proc.SetChannelAction(CHAN_STDIN, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
|
||||
@ -113,7 +153,9 @@ TEST_F(SubProcessTest, Stdin) {
|
||||
|
||||
TEST_F(SubProcessTest, StdinStdout) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/usr/bin/wc", {"wc", "-l"});
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kEchoProgram).c_str(),
|
||||
{kEchoProgram});
|
||||
proc.SetChannelAction(CHAN_STDIN, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
@ -123,13 +165,16 @@ TEST_F(SubProcessTest, StdinStdout) {
|
||||
int status = proc.Communicate(&in, &out, nullptr);
|
||||
EXPECT_TRUE(WIFEXITED(status));
|
||||
EXPECT_EQ(0, WEXITSTATUS(status));
|
||||
int count = stoi(out);
|
||||
EXPECT_EQ(3, count);
|
||||
// Sanitize out of carriage returns, because windows...
|
||||
out.erase(std::remove(out.begin(), out.end(), '\r'), out.end());
|
||||
EXPECT_EQ(in, out);
|
||||
}
|
||||
|
||||
TEST_F(SubProcessTest, StdinChildExit) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/sleep", {"sleep", "0"});
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kNoopProgram).c_str(),
|
||||
{kNoopProgram});
|
||||
proc.SetChannelAction(CHAN_STDIN, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
|
||||
@ -148,7 +193,9 @@ TEST_F(SubProcessTest, StdinChildExit) {
|
||||
|
||||
TEST_F(SubProcessTest, StdinStdoutOverlap) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/cat", {"cat"});
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kEchoProgram).c_str(),
|
||||
{kEchoProgram});
|
||||
proc.SetChannelAction(CHAN_STDIN, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
@ -165,12 +212,16 @@ TEST_F(SubProcessTest, StdinStdoutOverlap) {
|
||||
int status = proc.Communicate(&in, &out, nullptr);
|
||||
EXPECT_TRUE(WIFEXITED(status));
|
||||
EXPECT_EQ(0, WEXITSTATUS(status));
|
||||
// Sanitize out of carriage returns, because windows...
|
||||
out.erase(std::remove(out.begin(), out.end(), '\r'), out.end());
|
||||
EXPECT_EQ(in, out);
|
||||
}
|
||||
|
||||
TEST_F(SubProcessTest, KillProc) {
|
||||
tensorflow::SubProcess proc;
|
||||
proc.SetProgram("/bin/cat", {"cat"});
|
||||
proc.SetProgram(
|
||||
strings::StrCat(testing::TensorFlowSrcRoot(), "/", kEchoProgram).c_str(),
|
||||
{kEchoProgram});
|
||||
proc.SetChannelAction(CHAN_STDIN, ACTION_PIPE);
|
||||
proc.SetChannelAction(CHAN_STDOUT, ACTION_PIPE);
|
||||
EXPECT_TRUE(proc.Start());
|
||||
|
30
tensorflow/core/platform/testdata/BUILD
vendored
Normal file
30
tensorflow/core/platform/testdata/BUILD
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# Test helper binaries to use in tests.
|
||||
# These are provided to avoid linux-only binaries in tests.
|
||||
# Thus helping write cross platform tests.
|
||||
|
||||
package(
|
||||
default_visibility = [
|
||||
"//tensorflow/core/platform:__pkg__",
|
||||
],
|
||||
licenses = ["notice"], # Apache 2.0
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "test_echo",
|
||||
srcs = ["test_echo.cc"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "test_noop",
|
||||
srcs = ["test_noop.cc"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "test_echo_argv_1",
|
||||
srcs = ["test_echo_argv_1.cc"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "test_stderr",
|
||||
srcs = ["test_stderr.cc"],
|
||||
)
|
27
tensorflow/core/platform/testdata/test_echo.cc
vendored
Normal file
27
tensorflow/core/platform/testdata/test_echo.cc
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
int main() {
|
||||
while (true) {
|
||||
int c = fgetc(stdin);
|
||||
if (c <= 0) {
|
||||
break;
|
||||
}
|
||||
fputc(static_cast<char>(c), stdout);
|
||||
}
|
||||
return 0;
|
||||
}
|
22
tensorflow/core/platform/testdata/test_echo_argv_1.cc
vendored
Normal file
22
tensorflow/core/platform/testdata/test_echo_argv_1.cc
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
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 <iostream>
|
||||
#include <string>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::cout << argv[1];
|
||||
return 0;
|
||||
}
|
16
tensorflow/core/platform/testdata/test_noop.cc
vendored
Normal file
16
tensorflow/core/platform/testdata/test_noop.cc
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
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.
|
||||
==============================================================================*/
|
||||
|
||||
int main() { return 0; }
|
21
tensorflow/core/platform/testdata/test_stderr.cc
vendored
Normal file
21
tensorflow/core/platform/testdata/test_stderr.cc
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
|
||||
|
||||
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 <iostream>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::cerr << argv[1];
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user