Arquivos
hhvm/hphp/test/ext/test_ext_process.cpp
T
Paul Tarjan f5569e4755 clean up tests dir
I think this dir shouldn't have anything non-necessary in the root.
2013-06-06 16:31:09 -07:00

453 linhas
12 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/test/ext/test_ext_process.h"
#include "hphp/runtime/ext/ext_process.h"
#include "hphp/runtime/ext/ext_file.h"
#include "hphp/runtime/base/file/file.h"
#include "hphp/runtime/base/util/string_buffer.h"
#include "hphp/runtime/base/runtime_option.h"
#include "hphp/util/light_process.h"
///////////////////////////////////////////////////////////////////////////////
bool TestExtProcess::RunTests(const std::string &which) {
bool ret = true;
RUN_TEST(test_pcntl_alarm);
//RUN_TEST(test_pcntl_exec); // this has to run manually
RUN_TEST(test_pcntl_fork);
RUN_TEST(test_pcntl_getpriority);
RUN_TEST(test_pcntl_setpriority);
RUN_TEST(test_pcntl_signal);
RUN_TEST(test_pcntl_wait);
RUN_TEST(test_pcntl_waitpid);
RUN_TEST(test_pcntl_wexitstatus);
RUN_TEST(test_pcntl_wifexited);
RUN_TEST(test_pcntl_wifsignaled);
RUN_TEST(test_pcntl_wifstopped);
RUN_TEST(test_pcntl_wstopsig);
RUN_TEST(test_pcntl_wtermsig);
RUN_TEST(test_pcntl_signal_dispatch);
RUN_TEST(test_shell_exec);
RUN_TEST(test_exec);
RUN_TEST(test_passthru);
RUN_TEST(test_system);
RUN_TEST(test_proc_open);
RUN_TEST(test_proc_terminate);
RUN_TEST(test_proc_close);
RUN_TEST(test_proc_open_env_inh);
RUN_TEST(test_proc_get_status);
RUN_TEST(test_proc_nice);
RUN_TEST(test_escapeshellarg);
RUN_TEST(test_escapeshellcmd);
LightProcess::Initialize(RuntimeOption::LightProcessFilePrefix,
RuntimeOption::LightProcessCount,
std::vector<int>());
RUN_TEST(test_pcntl_alarm);
//RUN_TEST(test_pcntl_exec); // this has to run manually
RUN_TEST(test_pcntl_fork);
RUN_TEST(test_pcntl_getpriority);
RUN_TEST(test_pcntl_setpriority);
RUN_TEST(test_pcntl_signal);
RUN_TEST(test_pcntl_wait);
RUN_TEST(test_pcntl_waitpid);
RUN_TEST(test_pcntl_wexitstatus);
RUN_TEST(test_pcntl_wifexited);
RUN_TEST(test_pcntl_wifsignaled);
RUN_TEST(test_pcntl_wifstopped);
RUN_TEST(test_pcntl_wstopsig);
RUN_TEST(test_pcntl_wtermsig);
RUN_TEST(test_pcntl_signal_dispatch);
RUN_TEST(test_shell_exec);
RUN_TEST(test_exec);
RUN_TEST(test_passthru);
RUN_TEST(test_system);
RUN_TEST(test_proc_open);
RUN_TEST(test_proc_terminate);
RUN_TEST(test_proc_close);
RUN_TEST(test_proc_open_env_inh);
RUN_TEST(test_proc_get_status);
RUN_TEST(test_proc_nice);
LightProcess::Close();
return ret;
}
///////////////////////////////////////////////////////////////////////////////
bool TestExtProcess::test_pcntl_alarm() {
//f_pcntl_alarm(1);
return Count(true);
}
bool TestExtProcess::test_pcntl_exec() {
f_pcntl_exec("/bin/sh",
CREATE_VECTOR1("test/ext/test_pcntl_exec.sh"),
CREATE_MAP1("name", "value"));
return Count(true);
}
bool TestExtProcess::test_pcntl_fork() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(123);
}
Variant status;
f_pcntl_wait(ref(status));
return Count(true);
}
bool TestExtProcess::test_pcntl_getpriority() {
VS(f_pcntl_getpriority(), 0);
return Count(true);
}
bool TestExtProcess::test_pcntl_setpriority() {
VERIFY(f_pcntl_setpriority(0));
return Count(true);
}
bool TestExtProcess::test_pcntl_signal() {
f_pcntl_signal(k_SIGALRM, "test", true);
return Count(true);
}
bool TestExtProcess::test_pcntl_wait() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x12);
}
Variant status;
f_pcntl_wait(ref(status));
VS(status, 0x1200);
return Count(true);
}
bool TestExtProcess::test_pcntl_waitpid() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x12);
}
Variant status;
f_pcntl_waitpid(0, ref(status));
VS(status, 0x1200);
return Count(true);
}
bool TestExtProcess::test_pcntl_wexitstatus() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x80);
}
Variant status;
f_pcntl_waitpid(0, ref(status));
VS(f_pcntl_wexitstatus(status), 0x80);
return Count(true);
}
bool TestExtProcess::test_pcntl_wifexited() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x12);
}
Variant status;
f_pcntl_waitpid(0, ref(status));
VERIFY(f_pcntl_wifexited(status));
return Count(true);
}
bool TestExtProcess::test_pcntl_wifsignaled() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x12);
}
Variant status;
f_pcntl_waitpid(0, ref(status));
VERIFY(!f_pcntl_wifsignaled(status));
return Count(true);
}
bool TestExtProcess::test_pcntl_wifstopped() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x12);
}
Variant status;
f_pcntl_waitpid(0, ref(status));
VERIFY(!f_pcntl_wifstopped(status));
return Count(true);
}
bool TestExtProcess::test_pcntl_wstopsig() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x12);
}
Variant status;
f_pcntl_waitpid(0, ref(status));
VS(f_pcntl_wstopsig(status), 0x12);
return Count(true);
}
bool TestExtProcess::test_pcntl_wtermsig() {
int pid = f_pcntl_fork();
if (pid == 0) {
_exit(0x12);
}
Variant status;
f_pcntl_waitpid(0, ref(status));
VS(f_pcntl_wtermsig(status), 0);
return Count(true);
}
bool TestExtProcess::test_shell_exec() {
Variant output = f_shell_exec("echo hello");
VS(output, "hello\n");
string cur_cwd = Process::GetCurrentDirectory();
f_chdir("/tmp/");
VS(f_shell_exec("/bin/pwd"), "/tmp\n");
f_chdir(String(cur_cwd));
return Count(true);
}
bool TestExtProcess::test_pcntl_signal_dispatch() {
f_pcntl_signal_dispatch();
return Count(true);
}
bool TestExtProcess::test_exec() {
Variant output, ret;
String last_line = f_exec("echo hello; echo world;", ref(output), ref(ret));
VS(output, CREATE_VECTOR2("hello", "world"));
VS(last_line, "world");
VS(ret, 0);
string cur_cwd = Process::GetCurrentDirectory();
f_chdir("/tmp/");
VS(f_exec("/bin/pwd"), "/tmp");
f_chdir(String(cur_cwd));
return Count(true);
}
bool TestExtProcess::test_passthru() {
g_context->obStart();
Variant ret;
f_passthru("echo hello; echo world;", ref(ret));
String output = g_context->obCopyContents();
g_context->obEnd();
VS(output, "hello\nworld\n");
VS(ret, 0);
string cur_cwd = Process::GetCurrentDirectory();
f_chdir("/tmp/");
g_context->obStart();
f_passthru("/bin/pwd");
output = g_context->obCopyContents();
g_context->obEnd();
VS(output, "/tmp\n");
f_chdir(String(cur_cwd));
return Count(true);
}
bool TestExtProcess::test_system() {
g_context->obStart();
Variant ret;
String last_line = f_system("echo hello; echo world;", ref(ret));
String output = g_context->obCopyContents();
g_context->obEnd();
VS(output, "hello\nworld\n");
VS(last_line, "world");
VS(ret, 0);
string cur_cwd = Process::GetCurrentDirectory();
f_chdir("/tmp/");
VS(f_system("/bin/pwd"), "/tmp");
f_chdir(String(cur_cwd));
return Count(true);
}
bool TestExtProcess::test_proc_open_env_inh() {
Array descriptorspec =
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
1, CREATE_VECTOR2("pipe", "w"),
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
Variant pipes;
g_context->setenv("inherit_me", "please");
Variant process = f_proc_open("echo $inherit_me", descriptorspec, ref(pipes));
VERIFY(!same(process, false));
{
File *f = pipes[1].toObject().getTyped<File>();
VERIFY(f->valid());
StringBuffer sbuf;
sbuf.read(f);
f->close();
VS(sbuf.detach(), "please\n");
}
VS(f_proc_close(process.toObject()), 0);
// Ensure that PATH makes it through too
process = f_proc_open("echo $PATH", descriptorspec, ref(pipes));
VERIFY(!same(process, false));
{
File *f = pipes[1].toObject().getTyped<File>();
VERIFY(f->valid());
StringBuffer sbuf;
sbuf.read(f);
f->close();
VERIFY(sbuf.length() != 0);
}
VS(f_proc_close(process.toObject()), 0);
// And check that the libc putenv() takes effect, even though we don't
// want to use that in a threaded environment
putenv("ZOO=animals");
process = f_proc_open("echo $ZOO", descriptorspec, ref(pipes));
VERIFY(!same(process, false));
{
File *f = pipes[1].toObject().getTyped<File>();
VERIFY(f->valid());
StringBuffer sbuf;
sbuf.read(f);
f->close();
VS(sbuf.detach(), "animals\n");
}
VS(f_proc_close(process.toObject()), 0);
return Count(true);
}
bool TestExtProcess::test_proc_open() {
Array descriptorspec =
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
1, CREATE_VECTOR2("pipe", "w"),
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
String cwd = "/tmp";
Array env = CREATE_MAP1("some_option", "aeiou");
Variant pipes;
Variant process = f_proc_open(php_path, descriptorspec, ref(pipes), cwd, env);
VERIFY(!same(process, false));
{
File *f = pipes[0].toObject().getTyped<File>();
VERIFY(f->valid());
String s("<?php print(getenv('some_option')); ?>", AttachLiteral);
f->write(s);
f->close();
}
{
File *f = pipes[1].toObject().getTyped<File>();
VERIFY(f->valid());
StringBuffer sbuf;
sbuf.read(f);
f->close();
VS(sbuf.detach(), "aeiou");
}
VS(f_proc_close(process.toObject()), 0);
return Count(true);
}
bool TestExtProcess::test_proc_terminate() {
Array descriptorspec =
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
1, CREATE_VECTOR2("pipe", "w"),
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
Variant pipes;
Variant process = f_proc_open(php_path, descriptorspec, ref(pipes));
VERIFY(!same(process, false));
VERIFY(f_proc_terminate(process.toObject()));
// still need to close it, not to leave a zombie behind
f_proc_close(process.toObject());
return Count(true);
}
bool TestExtProcess::test_proc_close() {
return test_proc_open();
}
bool TestExtProcess::test_proc_get_status() {
static const StaticString
s_command("command"),
s_pid("pid"),
s_running("running"),
s_signaled("signaled"),
s_exitcode("exitcode"),
s_termsig("termsig"),
s_stopsig("stopsig");
Array descriptorspec =
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
1, CREATE_VECTOR2("pipe", "w"),
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
Variant pipes;
Variant process = f_proc_open(php_path, descriptorspec, ref(pipes));
VERIFY(!same(process, false));
Array ret = f_proc_get_status(process.toObject());
VS(ret[s_command], php_path);
VERIFY(ret[s_pid].toInt32() > 0);
VERIFY(ret[s_running]);
VERIFY(!ret[s_signaled]);
VS(ret[s_exitcode], -1);
VS(ret[s_termsig], 0);
VS(ret[s_stopsig], 0);
{
File *f = pipes[0].toObject().getTyped<File>();
VERIFY(f->valid());
f->close();
}
{
File *f = pipes[1].toObject().getTyped<File>();
VERIFY(f->valid());
f->close();
}
VS(f_proc_close(process.toObject()), 0);
return Count(true);
}
bool TestExtProcess::test_proc_nice() {
VERIFY(f_proc_nice(0));
return Count(true);
}
bool TestExtProcess::test_escapeshellarg() {
VS(f_escapeshellarg("\""), "'\"'");
return Count(true);
}
bool TestExtProcess::test_escapeshellcmd() {
VS(f_escapeshellcmd("perl \""), "perl \\\"");
return Count(true);
}