// The goal of this is to test a real web request, rather than simply evaling // snippets of code like the other tests. A single web request is issued and // debugged by multiple other requests. bool TestDebugger::TestWebRequest() { bool ret = false; // If we can't get sandbox host format right, fail early string sandboxHost = getSandboxHostFormat(); if (sandboxHost.empty()) { return CountSkip(); } // A quick sanity check to ensure the server is still up and accepting // requests. string result; if (!getResponse("hello.php", result, -1, sandboxHost) || result != "Hello, World!") { printf("Sanity check didn't pass on sandbox host %s, skip test\n", sandboxHost.c_str()); return CountSkip(); } // We need to wait at various times during the test for a request to progress // to a certian point, at which time we can take further action. This is done // via this pipe. m_fname = "/tmp/hphpd_test_fifo." + boost::lexical_cast<string>(Process::GetProcessId()); if (mkfifo(m_fname.c_str(), 0666)) { printf("Can not make fifo %s, skip test\n", m_fname.c_str()); return CountSkip(); } m_tempResult = false; // Kick off a thread to make requests for the debugger portions of this test. AsyncFunc<TestDebugger> func(this, &TestDebugger::testWebRequestHelperPhase1); func.start(); char flag; // Wait for web_request_phase_1.php, the first debugger portion of the test, // to connect and get ready to debug. if (!recvFromTests(flag) || flag != '1') { printf("failed to receive from test\n"); } else { // Now get web_request_t.php running so that web_requests.php // can debug it. Wait here for the entire request to finish. if (!getResponse("web_request_t.php", result, -1, sandboxHost) || result != "request done") { printf("failed on web_request_t.php\n"); } else { ret = true; } } func.waitForEnd(); unlink(m_fname.c_str()); // testWebRequestHelperPhase1() should flag m_tempResult to true if succeed ret = ret && m_tempResult; return Count(ret); }
void TestDebugger::testWebRequestHelper() { string result; if (getResponse("web_request.php", result)) { m_tempResult = result == "pass"; } else { printf("failed to get response for web_request.php\n"); } if (!m_tempResult) { return; } m_tempResult = false; // test interrupt: again starting a new thread first wait on interrupts AsyncFunc<TestDebugger> func(this, &TestDebugger::testWebRequestHelperSignal); func.start(); char flag; // wait for "web_request_signal.php" to connect and wait if (!recvFromTests(flag) || flag != '2') { printf("failed to receive from test\n"); return; } if (!getResponse("web_request_interrupt.php", result) || result != "interrupt done") { printf("failed on web_request_interrupt.php\n"); return; } // wait for "web_request_t.php" to finish if (!recvFromTests(flag) || flag != '3') { printf("failed to receive from test\n"); return; } if (!getResponse("web_request_interrupt.php", result) || result != "interrupt done") { printf("failed on web_request_interrupt.php\n"); return; } func.waitForEnd(); }
bool TestDebugger::TestWebRequest() { bool ret = false; // If we can't get sandbox host format right, fail early string sandboxHost = getSandboxHostFormat(); if (sandboxHost.empty()) { return CountSkip(); } string result; if (!getResponse("hello.php", result, -1, sandboxHost) || result != "Hello, World!") { printf("Sanity check didn't pass on sandbox host %s, skip test\n", sandboxHost.c_str()); return CountSkip(); } m_fname = "/tmp/hphpd_test_fifo." + boost::lexical_cast<string>(Process::GetProcessId()); if (mkfifo(m_fname.c_str(), 0666)) { printf("Can not make fifo %s, skip test\n", m_fname.c_str()); return CountSkip(); } m_tempResult = false; AsyncFunc<TestDebugger> func(this, &TestDebugger::testWebRequestHelper); func.start(); char flag; // wait for "web_request.php" to connect and wait if (!recvFromTests(flag) || flag != '1') { printf("failed to receive from test\n"); } else if (!getResponse("web_request_t.php", result, -1, sandboxHost) || result != "request done") { printf("failed on web_request_t.php\n"); } else { ret = true; } func.waitForEnd(); unlink(m_fname.c_str()); // testWebRequestHelper() should flag m_tempResult to true if succeed ret = ret && m_tempResult; return Count(ret); }
// First phase of debugging for TestWebRequest. // This thread will issue requests to debug the the request for // web_request_t.php. This is done with multiple requests to allow us to test // breaking with ctrl-c. void TestDebugger::testWebRequestHelperPhase1() { string result; // Start with the first phase of debugging. This will test request start, // breakpoints and inspection, and a hard breakpoint. web_request_t.php will // be left stopped at a hard breakpoint near the end of test_break(). if (getResponse("web_request_phase_1.php", result)) { m_tempResult = result == "pass"; } else { printf("failed to get response for web_request_phase_1.php\n"); } if (!m_tempResult) { return; } m_tempResult = false; // Test interrupt: again starting a new thread to continue the next phase of // debugging logic. This will issue a request for web_request_phase_2.php. AsyncFunc<TestDebugger> func(this, &TestDebugger::testWebRequestHelperPhase2); func.start(); char flag; // Wait for web_request_phase_2.php to connect and get ready to debug. if (!recvFromTests(flag) || flag != '2') { printf("failed to receive from test\n"); return; } // Issue a reqeust for web_request_interrupt.php. Web_request_phase_2.php has // let the original request for web_request_t.php run, and it should now be // spinning in an infinite loop in test_sleep(). This will issue a ctrl-c // which will break within that loop. // // NB: sleep a bit first to give the request thread time to settle // into the infinite loop. sleep(2); if (!getResponse("web_request_interrupt.php", result) || result != "interrupt done") { printf("failed on web_request_interrupt.php\n"); return; } // Wait for web_request_phase_2.php to finish debugging the original request // for web_request_t.php, which will be left running after the end of PSP. if (!recvFromTests(flag) || flag != '3') { printf("failed to receive from test\n"); return; } // Issue another request for web_request_interrupt.php. The original request // for web_request_t.php should be done by now, so this should interrupt in // the dummy sandbox. This will finally let web_request_phase_2.php complete, // thus completing the debugging portion of this test. if (!getResponse("web_request_interrupt.php", result) || result != "interrupt done") { printf("failed on web_request_interrupt.php\n"); return; } func.waitForEnd(); }