BApplication tests:
* Added constructor tests. * Added Run() tests. * AppRunner -> PipedAppRunner + some improvements * New AppRunner using ports for data transfer. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@562 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
28cdc245d3
commit
c9640d94a3
@ -13,7 +13,9 @@ CommonTestLib libapptest.so
|
||||
# BApplication
|
||||
ApplicationTest.cpp
|
||||
AppRunner.cpp
|
||||
AppRunTester.cpp
|
||||
BApplicationTester.cpp
|
||||
PipedAppRunner.cpp
|
||||
|
||||
# BHandler
|
||||
HandlerTest.cpp
|
||||
|
819
src/tests/kits/app/bapplication/AppRunTester.cpp
Normal file
819
src/tests/kits/app/bapplication/AppRunTester.cpp
Normal file
@ -0,0 +1,819 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// AppRunTester.cpp
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Standard Includes -----------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
|
||||
// System Includes -------------------------------------------------------------
|
||||
#include <be/app/Message.h>
|
||||
#include <be/kernel/OS.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Handler.h>
|
||||
#include <Looper.h>
|
||||
#include <String.h>
|
||||
|
||||
// Project Includes ------------------------------------------------------------
|
||||
#include <TestShell.h>
|
||||
#include <TestUtils.h>
|
||||
#include <cppunit/TestAssert.h>
|
||||
|
||||
// Local Includes --------------------------------------------------------------
|
||||
#include "AppRunner.h"
|
||||
#include "AppRunTester.h"
|
||||
|
||||
// Local Defines ---------------------------------------------------------------
|
||||
|
||||
// Globals ---------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// check_output
|
||||
static
|
||||
void
|
||||
check_output(AppRunner &runner, const char *expectedOutput)
|
||||
{
|
||||
BString buffer;
|
||||
CHK(runner.GetOutput(&buffer) == B_OK);
|
||||
if (buffer != expectedOutput)
|
||||
printf("result is `%s', but should be `%s'\n", buffer.String(),
|
||||
expectedOutput);
|
||||
CHK(buffer == expectedOutput);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 1 launch the app two times: B_MULTIPLE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of
|
||||
them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest1()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 = output1;
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp1") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp1") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 2 launch the app two times: B_MULTIPLE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of
|
||||
them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest2()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp1", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp1", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 3 launch the app two times: B_MULTIPLE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest3()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 = output1;
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp2") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp2") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 4 launch the app two times: B_MULTIPLE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest4()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp2", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp2", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 5 launch the app two times: B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest5()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp3") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp3") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 6 launch the app two times: B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest6()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp3", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp3", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 7 launch the app two times: B_SINGLE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest7()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp4") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp4") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 8 launch the app two times: B_SINGLE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest8()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp4", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp4", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 9 launch two apps with the same signature:
|
||||
B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest9()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 = output1;
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp3") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp3a") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 10 launch two apps with the same signature:
|
||||
B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest10()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp3", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp3a", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 11 launch two apps with the same signature:
|
||||
B_SINGLE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest11()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 = output1;
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp4") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp4a") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 12 launch two apps with the same signature:
|
||||
B_SINGLE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
*/
|
||||
void AppRunTester::RunTest12()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp4", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp4a", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 13 launch the app two times: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest13()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp5") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp5") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 14 launch the app two times: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest14()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp5", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp5", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 15 launch the app two times: B_EXCLUSIVE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest15()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp6") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp6") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 16 launch the app two times: B_EXCLUSIVE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest16()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp6", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp6", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 17 launch two apps with the same signature:
|
||||
B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest17()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp5") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp5a") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 18 launch two apps with the same signature:
|
||||
B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest18()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp5", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp5a", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 19 launch two apps with the same signature: B_EXCLUSIVE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest19()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp6") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp6a") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 20 launch two apps with the same signature: B_EXCLUSIVE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest20()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp6", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp6a", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 21 launch the app two times: first: B_EXCLUSIVE_LAUNCH,
|
||||
second: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest21()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: c d e\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp6", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp5", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
/*
|
||||
thread_id Run()
|
||||
@case 22 launch the app two times:
|
||||
first: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
second: B_EXCLUSIVE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them
|
||||
@results first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
*/
|
||||
void AppRunTester::RunTest22()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-app-run-test");
|
||||
const char *output1 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n"
|
||||
"BApplication::ArgvReceived()\n"
|
||||
"args: a b\n"
|
||||
"BApplication::ReadyToRun()\n"
|
||||
"BApplication::QuitRequested()\n"
|
||||
"BApplication::Run() done: 1\n";
|
||||
const char *output2 =
|
||||
"error: 80002004\n"
|
||||
"InitCheck(): 80002004\n";
|
||||
// run the apps
|
||||
AppRunner runner1, runner2;
|
||||
CHK(runner1.Run("AppRunTestApp5", "a b") == B_OK);
|
||||
runner1.Team();
|
||||
CHK(runner2.Run("AppRunTestApp6", "c d e") == B_OK);
|
||||
runner1.WaitFor(true);
|
||||
runner2.WaitFor(true);
|
||||
// get the outputs and compare the results
|
||||
check_output(runner1, output1);
|
||||
check_output(runner2, output2);
|
||||
}
|
||||
|
||||
|
||||
Test* AppRunTester::Suite()
|
||||
{
|
||||
TestSuite* SuiteOfTests = new TestSuite;
|
||||
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest1);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest2);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest3);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest4);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest5);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest6);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest7);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest8);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest9);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest10);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest11);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest12);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest13);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest14);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest15);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest16);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest17);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest18);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest19);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest20);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest21);
|
||||
ADD_TEST4(BApplication, SuiteOfTests, AppRunTester, RunTest22);
|
||||
|
||||
return SuiteOfTests;
|
||||
}
|
||||
|
||||
|
||||
|
55
src/tests/kits/app/bapplication/AppRunTester.h
Normal file
55
src/tests/kits/app/bapplication/AppRunTester.h
Normal file
@ -0,0 +1,55 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// AppRunTester.h
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef APP_RUN_TESTER_H
|
||||
#define APP_RUN_TESTER_H
|
||||
|
||||
// Standard Includes -----------------------------------------------------------
|
||||
|
||||
// System Includes -------------------------------------------------------------
|
||||
|
||||
// Project Includes ------------------------------------------------------------
|
||||
|
||||
// Local Includes --------------------------------------------------------------
|
||||
#include "../common.h"
|
||||
|
||||
// Local Defines ---------------------------------------------------------------
|
||||
|
||||
// Globals ---------------------------------------------------------------------
|
||||
|
||||
class AppRunTester : public TestCase
|
||||
{
|
||||
public:
|
||||
AppRunTester() {;}
|
||||
AppRunTester(std::string name) : TestCase(name) {;}
|
||||
|
||||
void RunTest1();
|
||||
void RunTest2();
|
||||
void RunTest3();
|
||||
void RunTest4();
|
||||
void RunTest5();
|
||||
void RunTest6();
|
||||
void RunTest7();
|
||||
void RunTest8();
|
||||
void RunTest9();
|
||||
void RunTest10();
|
||||
void RunTest11();
|
||||
void RunTest12();
|
||||
void RunTest13();
|
||||
void RunTest14();
|
||||
void RunTest15();
|
||||
void RunTest16();
|
||||
void RunTest17();
|
||||
void RunTest18();
|
||||
void RunTest19();
|
||||
void RunTest20();
|
||||
void RunTest21();
|
||||
void RunTest22();
|
||||
|
||||
static Test* Suite();
|
||||
};
|
||||
|
||||
#endif // APP_RUN_TESTER_H
|
||||
|
@ -4,15 +4,25 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <Messenger.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <TestShell.h>
|
||||
#include <TestUtils.h>
|
||||
#include <cppunit/TestAssert.h>
|
||||
|
||||
#include "AppRunner.h"
|
||||
|
||||
static const char *kAppRunnerTeamPort = "app runner team port";
|
||||
|
||||
// constructor
|
||||
AppRunner::AppRunner()
|
||||
: fOutputLock(),
|
||||
fPipe(NULL),
|
||||
fRemotePort(-1),
|
||||
fOutput(),
|
||||
fReader(-1)
|
||||
fReader(-1),
|
||||
fTeam(-1),
|
||||
fMessenger()
|
||||
{
|
||||
}
|
||||
|
||||
@ -20,7 +30,6 @@ AppRunner::AppRunner()
|
||||
AppRunner::~AppRunner()
|
||||
{
|
||||
if (fReader >= 0) {
|
||||
_ClosePipe();
|
||||
int32 result;
|
||||
wait_for_thread(fReader, &result);
|
||||
}
|
||||
@ -28,15 +37,55 @@ AppRunner::~AppRunner()
|
||||
|
||||
// Run
|
||||
status_t
|
||||
AppRunner::Run(const char *command)
|
||||
AppRunner::Run(const char *command, const char *args, bool findCommand)
|
||||
{
|
||||
status_t error = (HasQuitted() ? B_OK : B_ERROR);
|
||||
// get the app path
|
||||
BString appPath;
|
||||
if (findCommand) {
|
||||
appPath = BTestShell::GlobalTestDir();
|
||||
appPath.CharacterEscape(" \t\n!\"'`$&()?*+{}[]<>|", '\\');
|
||||
appPath += "/kits/app/";
|
||||
appPath += command;
|
||||
#ifdef TEST_R5
|
||||
appPath += "_r5";
|
||||
#endif
|
||||
command = appPath.String();
|
||||
}
|
||||
// add args, i.e. compose the command line
|
||||
BString cmdLine(command);
|
||||
if (args) {
|
||||
cmdLine += " ";
|
||||
cmdLine += args;
|
||||
}
|
||||
// lock the team port
|
||||
bool teamPortLocked = false;
|
||||
if (error == B_OK) {
|
||||
teamPortLocked = _LockTeamPort();
|
||||
if (!teamPortLocked)
|
||||
error = B_ERROR;
|
||||
}
|
||||
// run the command
|
||||
if (error == B_OK) {
|
||||
fPipe = popen(command, "r");
|
||||
if (!fPipe)
|
||||
cmdLine += " &";
|
||||
if (system(cmdLine.String()) != 0)
|
||||
error = errno;
|
||||
}
|
||||
// read the port ID
|
||||
if (error == B_OK) {
|
||||
fRemotePort = _ReadPortID(fMessenger);
|
||||
if (fRemotePort < 0)
|
||||
error = fRemotePort;
|
||||
}
|
||||
// unlock the team port
|
||||
if (teamPortLocked)
|
||||
_UnlockTeamPort();
|
||||
// get the team ID
|
||||
if (error == B_OK) {
|
||||
port_info info;
|
||||
error = get_port_info(fRemotePort, &info);
|
||||
fTeam = info.team;
|
||||
}
|
||||
// spawn the reader thread
|
||||
if (error == B_OK) {
|
||||
fReader = spawn_thread(&_ReaderEntry, "AppRunner reader",
|
||||
@ -52,10 +101,6 @@ AppRunner::Run(const char *command)
|
||||
kill_thread(fReader);
|
||||
fReader = -1;
|
||||
}
|
||||
if (fPipe) {
|
||||
pclose(fPipe);
|
||||
fPipe = NULL;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
@ -64,8 +109,55 @@ AppRunner::Run(const char *command)
|
||||
bool
|
||||
AppRunner::HasQuitted()
|
||||
{
|
||||
BAutolock locker(fOutputLock);
|
||||
return !fPipe;
|
||||
port_info info;
|
||||
return (get_port_info(fRemotePort, &info) != B_OK);
|
||||
}
|
||||
|
||||
// WaitFor
|
||||
void
|
||||
AppRunner::WaitFor(bool requestQuit)
|
||||
{
|
||||
if (!HasQuitted() && requestQuit)
|
||||
RequestQuit();
|
||||
while (!HasQuitted())
|
||||
snooze(10000);
|
||||
}
|
||||
|
||||
// Team
|
||||
team_id
|
||||
AppRunner::Team()
|
||||
{
|
||||
return fTeam;
|
||||
}
|
||||
|
||||
// RequestQuit
|
||||
status_t
|
||||
AppRunner::RequestQuit()
|
||||
{
|
||||
status_t error = B_OK;
|
||||
if (fTeam >= 0) {
|
||||
BMessenger messenger(fMessenger);
|
||||
error = messenger.SendMessage(B_QUIT_REQUESTED);
|
||||
} else
|
||||
error = fTeam;
|
||||
return error;
|
||||
}
|
||||
|
||||
// GetOutput
|
||||
status_t
|
||||
AppRunner::GetOutput(BString *buffer)
|
||||
{
|
||||
status_t error = (buffer ? B_OK : B_BAD_VALUE);
|
||||
if (error == B_OK) {
|
||||
BAutolock locker(fOutputLock);
|
||||
size_t size = fOutput.BufferLength();
|
||||
const void *output = fOutput.Buffer();
|
||||
if (size > 0)
|
||||
buffer->SetTo((const char*)output, size);
|
||||
else
|
||||
*buffer = "";
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ReadOutput
|
||||
@ -99,32 +191,62 @@ int32
|
||||
AppRunner::_ReaderLoop()
|
||||
{
|
||||
char buffer[10240];
|
||||
fOutputLock.Lock();
|
||||
FILE *pipe = fPipe;
|
||||
fOutputLock.Unlock();
|
||||
while (!feof(pipe)) {
|
||||
size_t bytes = fread(buffer, 1, sizeof(buffer), pipe);
|
||||
port_id port = fRemotePort;
|
||||
status_t error = B_OK;
|
||||
while (error == B_OK) {
|
||||
int32 code;
|
||||
ssize_t bytes = read_port(port, &code, buffer, sizeof(buffer) - 1);
|
||||
if (bytes > 0) {
|
||||
// write the buffer
|
||||
BAutolock locker(fOutputLock);
|
||||
off_t oldPosition = fOutput.Seek(0, SEEK_END);
|
||||
fOutput.Write(buffer, bytes);
|
||||
fOutput.Seek(oldPosition, SEEK_SET);
|
||||
}
|
||||
} else if (bytes < 0)
|
||||
error = bytes;
|
||||
}
|
||||
_ClosePipe();
|
||||
fRemotePort = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// _ClosePipe
|
||||
void
|
||||
AppRunner::_ClosePipe()
|
||||
// _LockTeamPort
|
||||
bool
|
||||
AppRunner::_LockTeamPort()
|
||||
{
|
||||
if (fOutputLock.Lock()) {
|
||||
if (fPipe) {
|
||||
pclose(fPipe);
|
||||
fPipe = NULL;
|
||||
bool result = fTeamPortLock.Lock();
|
||||
// lazy port creation
|
||||
if (result && fTeamPort < 0) {
|
||||
fTeamPort = create_port(5, kAppRunnerTeamPort);
|
||||
if (fTeamPort < 0) {
|
||||
fTeamPortLock.Unlock();
|
||||
result = false;
|
||||
}
|
||||
fOutputLock.Unlock();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// _UnlockTeamPort
|
||||
void
|
||||
AppRunner::_UnlockTeamPort()
|
||||
{
|
||||
fTeamPortLock.Unlock();
|
||||
}
|
||||
|
||||
// _ReadPortID
|
||||
port_id
|
||||
AppRunner::_ReadPortID(BMessenger &messenger)
|
||||
{
|
||||
port_id port = -1;
|
||||
ssize_t size = read_port(fTeamPort, &port, &messenger, sizeof(BMessenger));
|
||||
if (size < 0)
|
||||
port = size;
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
// fTeamPort
|
||||
port_id AppRunner::fTeamPort = -1;
|
||||
|
||||
// fTeamPortLock
|
||||
BLocker AppRunner::fTeamPortLock;
|
||||
|
||||
|
@ -13,22 +13,35 @@ public:
|
||||
AppRunner();
|
||||
~AppRunner();
|
||||
|
||||
status_t Run(const char *command);
|
||||
status_t Run(const char *command, const char *args = NULL,
|
||||
bool findCommand = true);
|
||||
bool HasQuitted();
|
||||
void WaitFor(bool requestQuit = false);
|
||||
team_id Team();
|
||||
status_t RequestQuit();
|
||||
|
||||
status_t GetOutput(BString *buffer);
|
||||
ssize_t ReadOutput(void *buffer, size_t size);
|
||||
ssize_t ReadOutputAt(off_t position, void *buffer, size_t size);
|
||||
|
||||
private:
|
||||
static int32 _ReaderEntry(void *data);
|
||||
int32 _ReaderLoop();
|
||||
void _ClosePipe();
|
||||
|
||||
static bool _LockTeamPort();
|
||||
static void _UnlockTeamPort();
|
||||
static port_id _ReadPortID(BMessenger &messenger);
|
||||
|
||||
private:
|
||||
BLocker fOutputLock;
|
||||
FILE *fPipe;
|
||||
port_id fRemotePort;
|
||||
BMallocIO fOutput;
|
||||
thread_id fReader;
|
||||
team_id fTeam;
|
||||
BMessenger fMessenger;
|
||||
|
||||
static port_id fTeamPort;
|
||||
static BLocker fTeamPortLock;
|
||||
};
|
||||
|
||||
#endif // APP_RUNNER_H
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "../common.h"
|
||||
#include "AppRunTester.h"
|
||||
#include "BApplicationTester.h"
|
||||
|
||||
CppUnit::Test* ApplicationTestSuite()
|
||||
{
|
||||
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
|
||||
|
||||
testSuite->addTest(AppRunTester::Suite());
|
||||
testSuite->addTest(TBApplicationTester::Suite());
|
||||
|
||||
return testSuite;
|
||||
|
@ -15,8 +15,116 @@ case 5: signature is a valid MIME string with "application" supertype,
|
||||
Shouldn't print anything at all and continue.
|
||||
InitCheck() should return B_OK.
|
||||
|
||||
|
||||
BApplication(const char *signature, status_t *error)
|
||||
cases similar to those of BApplication(const char *), if error is NULL,
|
||||
otherwise error is set to the same value as returned by InitCheck()
|
||||
otherwise the app does not quit and error is set to the same value as
|
||||
returned by InitCheck(), which is B_BAD_VALUE on error.
|
||||
|
||||
thread_id Run()
|
||||
case 1: launch the app two times: B_MULTIPLE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
case 2: launch the app two times: B_MULTIPLE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
case 3: launch the app two times: B_MULTIPLE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
case 4: launch the app two times: B_MULTIPLE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
case 5: launch the app two times: B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 6: launch the app two times: B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
case 7: launch the app two times: B_SINGLE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 8: launch the app two times: B_SINGLE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
case 9: launch two apps with the same signature: B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
case 10:launch two apps with the same signature: B_SINGLE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
case 11:launch two apps with the same signature: B_SINGLE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: ReadyToRun(), QuitRequested()
|
||||
case 12:launch two apps with the same signature: B_SINGLE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
case 13:launch the app two times: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 14:launch the app two times: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 15:launch the app two times: B_EXCLUSIVE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 16:launch the app two times: B_EXCLUSIVE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
case 17:launch two apps with the same signature:
|
||||
B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 18:launch two apps with the same signature:
|
||||
B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 19:launch two apps with the same signature: B_EXCLUSIVE_LAUNCH,
|
||||
no command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
case 20:launch two apps with the same signature: B_EXCLUSIVE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
case 21:launch the app two times: first: B_EXCLUSIVE_LAUNCH,
|
||||
second: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), ArgvReceived(),
|
||||
QuitRequested()
|
||||
second app: quits
|
||||
|
||||
case 22:launch the app two times: first: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY,
|
||||
second: B_EXCLUSIVE_LAUNCH,
|
||||
command line args, send B_QUIT_REQUESTED to both of them =>
|
||||
first app: ArgvReceived(), ReadyToRun(), QuitRequested()
|
||||
second app: quits
|
||||
|
||||
|
||||
void Quit()
|
||||
TODO
|
||||
|
||||
bool QuitRequested()
|
||||
TODO
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <cppunit/TestAssert.h>
|
||||
|
||||
// Local Includes --------------------------------------------------------------
|
||||
#include "AppRunner.h"
|
||||
#include "PipedAppRunner.h"
|
||||
#include "BApplicationTester.h"
|
||||
|
||||
// Local Defines ---------------------------------------------------------------
|
||||
@ -35,27 +35,17 @@ static
|
||||
void
|
||||
test_app(const char *app, const char *expectedResult)
|
||||
{
|
||||
// construct an absolute path to the app
|
||||
BString appPath(BTestShell::GlobalTestDir());
|
||||
appPath.CharacterEscape(" \t\n!\"'`$&()?*+{}[]<>|", '\\');
|
||||
appPath += "/kits/app/";
|
||||
appPath += app;
|
||||
#ifdef TEST_R5
|
||||
appPath += "_r5";
|
||||
#endif
|
||||
// run the app
|
||||
AppRunner runner;
|
||||
CHK(runner.Run(appPath.String()) == B_OK);
|
||||
while (!runner.HasQuitted())
|
||||
snooze(10000);
|
||||
// read the output and compare the result
|
||||
char buffer[1024];
|
||||
ssize_t read = runner.ReadOutput(buffer, sizeof(buffer) - 1);
|
||||
CHK(read >= 0);
|
||||
buffer[read] = '\0';
|
||||
if (strcmp(buffer, expectedResult))
|
||||
printf("result is `%s', but should be `%s'\n", buffer, expectedResult);
|
||||
CHK(!strcmp(buffer, expectedResult));
|
||||
PipedAppRunner runner;
|
||||
CHK(runner.Run(app) == B_OK);
|
||||
runner.WaitFor();
|
||||
// get the output and compare the result
|
||||
BString buffer;
|
||||
CHK(runner.GetOutput(&buffer) == B_OK);
|
||||
if (buffer != expectedResult)
|
||||
printf("result is `%s', but should be `%s'\n", buffer.String(),
|
||||
expectedResult);
|
||||
CHK(buffer == expectedResult);
|
||||
}
|
||||
|
||||
|
||||
@ -66,10 +56,19 @@ printf("result is `%s', but should be `%s'\n", buffer, expectedResult);
|
||||
*/
|
||||
void TBApplicationTester::BApplication1()
|
||||
{
|
||||
test_app("BApplicationTestApp1",
|
||||
"bad signature ((null)), must begin with \"application/\" and "
|
||||
"can't conflict with existing registered mime types inside "
|
||||
"the \"application\" media type.\n");
|
||||
const char *output1 =
|
||||
"bad signature ((null)), must begin with \"application/\" and "
|
||||
"can't conflict with existing registered mime types inside "
|
||||
"the \"application\" media type.\n";
|
||||
const char *output2 =
|
||||
"bad signature ((null)), must begin with \"application/\" and "
|
||||
"can't conflict with existing registered mime types inside "
|
||||
"the \"application\" media type.\n"
|
||||
"error: 80000005\n"
|
||||
"InitCheck(): 80000005\n";
|
||||
test_app("BApplicationTestApp1", output1);
|
||||
test_app("BApplicationTestApp1a", output1);
|
||||
test_app("BApplicationTestApp1b", output2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -79,10 +78,19 @@ void TBApplicationTester::BApplication1()
|
||||
*/
|
||||
void TBApplicationTester::BApplication2()
|
||||
{
|
||||
test_app("BApplicationTestApp2",
|
||||
"bad signature (no valid MIME string), must begin with "
|
||||
"\"application/\" and can't conflict with existing registered "
|
||||
"mime types inside the \"application\" media type.\n");
|
||||
const char *output1 =
|
||||
"bad signature (no valid MIME string), must begin with "
|
||||
"\"application/\" and can't conflict with existing registered "
|
||||
"mime types inside the \"application\" media type.\n";
|
||||
const char *output2 =
|
||||
"bad signature (no valid MIME string), must begin with "
|
||||
"\"application/\" and can't conflict with existing registered "
|
||||
"mime types inside the \"application\" media type.\n"
|
||||
"error: 80000005\n"
|
||||
"InitCheck(): 80000005\n";
|
||||
test_app("BApplicationTestApp2", output1);
|
||||
test_app("BApplicationTestApp2a", output1);
|
||||
test_app("BApplicationTestApp2b", output2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -93,10 +101,19 @@ void TBApplicationTester::BApplication2()
|
||||
*/
|
||||
void TBApplicationTester::BApplication3()
|
||||
{
|
||||
test_app("BApplicationTestApp3",
|
||||
"bad signature (image/gif), must begin with \"application/\" and "
|
||||
"can't conflict with existing registered mime types inside "
|
||||
"the \"application\" media type.\n");
|
||||
const char *output1 =
|
||||
"bad signature (image/gif), must begin with \"application/\" and "
|
||||
"can't conflict with existing registered mime types inside "
|
||||
"the \"application\" media type.\n";
|
||||
const char *output2 =
|
||||
"bad signature (image/gif), must begin with \"application/\" and "
|
||||
"can't conflict with existing registered mime types inside "
|
||||
"the \"application\" media type.\n"
|
||||
"error: 80000005\n"
|
||||
"InitCheck(): 80000005\n";
|
||||
test_app("BApplicationTestApp3", output1);
|
||||
test_app("BApplicationTestApp3a", output1);
|
||||
test_app("BApplicationTestApp3b", output2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -109,12 +126,20 @@ void TBApplicationTester::BApplication3()
|
||||
*/
|
||||
void TBApplicationTester::BApplication4()
|
||||
{
|
||||
test_app("BApplicationTestApp4",
|
||||
"Signature in rsrc doesn't match constructor arg. "
|
||||
"(application/x-vnd.obos-bapplication-testapp4,"
|
||||
"application/x-vnd.obos-bapplication-testapp4-or-not)\n"
|
||||
"InitCheck(): 0\n");
|
||||
|
||||
const char *output1 =
|
||||
"Signature in rsrc doesn't match constructor arg. "
|
||||
"(application/x-vnd.obos-bapplication-testapp4,"
|
||||
"application/x-vnd.obos-bapplication-testapp4-or-not)\n"
|
||||
"InitCheck(): 0\n";
|
||||
const char *output2 =
|
||||
"Signature in rsrc doesn't match constructor arg. "
|
||||
"(application/x-vnd.obos-bapplication-testapp4,"
|
||||
"application/x-vnd.obos-bapplication-testapp4-or-not)\n"
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n";
|
||||
test_app("BApplicationTestApp4", output1);
|
||||
test_app("BApplicationTestApp4a", output1);
|
||||
test_app("BApplicationTestApp4b", output2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -126,7 +151,13 @@ void TBApplicationTester::BApplication4()
|
||||
*/
|
||||
void TBApplicationTester::BApplication5()
|
||||
{
|
||||
test_app("BApplicationTestApp5", "InitCheck(): 0\n");
|
||||
const char *output1 = "InitCheck(): 0\n";
|
||||
const char *output2 =
|
||||
"error: 0\n"
|
||||
"InitCheck(): 0\n";
|
||||
test_app("BApplicationTestApp5", output1);
|
||||
test_app("BApplicationTestApp5a", output1);
|
||||
test_app("BApplicationTestApp5b", output2);
|
||||
}
|
||||
|
||||
|
||||
|
178
src/tests/kits/app/bapplication/PipedAppRunner.cpp
Normal file
178
src/tests/kits/app/bapplication/PipedAppRunner.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
// PipedAppRunner.cpp
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <TestShell.h>
|
||||
#include <TestUtils.h>
|
||||
#include <cppunit/TestAssert.h>
|
||||
|
||||
#include "PipedAppRunner.h"
|
||||
|
||||
// constructor
|
||||
PipedAppRunner::PipedAppRunner()
|
||||
: fOutputLock(),
|
||||
fPipe(NULL),
|
||||
fOutput(),
|
||||
fReader(-1)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
PipedAppRunner::~PipedAppRunner()
|
||||
{
|
||||
if (fReader >= 0) {
|
||||
_ClosePipe();
|
||||
int32 result;
|
||||
wait_for_thread(fReader, &result);
|
||||
}
|
||||
}
|
||||
|
||||
// Run
|
||||
status_t
|
||||
PipedAppRunner::Run(const char *command, const char *args, bool findCommand)
|
||||
{
|
||||
status_t error = (HasQuitted() ? B_OK : B_ERROR);
|
||||
// get the app path
|
||||
BString appPath;
|
||||
if (findCommand) {
|
||||
appPath = BTestShell::GlobalTestDir();
|
||||
appPath.CharacterEscape(" \t\n!\"'`$&()?*+{}[]<>|", '\\');
|
||||
appPath += "/kits/app/";
|
||||
appPath += command;
|
||||
#ifdef TEST_R5
|
||||
appPath += "_r5";
|
||||
#endif
|
||||
command = appPath.String();
|
||||
}
|
||||
// add args, i.e. compose the command line
|
||||
BString cmdLine(command);
|
||||
if (args) {
|
||||
cmdLine += " ";
|
||||
cmdLine += args;
|
||||
}
|
||||
// run the command
|
||||
if (error == B_OK) {
|
||||
fPipe = popen(cmdLine.String(), "r");
|
||||
if (!fPipe)
|
||||
error = errno;
|
||||
}
|
||||
// spawn the reader thread
|
||||
if (error == B_OK) {
|
||||
fReader = spawn_thread(&_ReaderEntry, "PipedAppRunner reader",
|
||||
B_NORMAL_PRIORITY, (void*)this);
|
||||
if (fReader >= 0)
|
||||
error = resume_thread(fReader);
|
||||
else
|
||||
error = fReader;
|
||||
}
|
||||
// cleanup on error
|
||||
if (error != B_OK) {
|
||||
if (fReader >= 0) {
|
||||
kill_thread(fReader);
|
||||
fReader = -1;
|
||||
}
|
||||
if (fPipe) {
|
||||
pclose(fPipe);
|
||||
fPipe = NULL;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// HasQuitted
|
||||
bool
|
||||
PipedAppRunner::HasQuitted()
|
||||
{
|
||||
BAutolock locker(fOutputLock);
|
||||
return !fPipe;
|
||||
}
|
||||
|
||||
// WaitFor
|
||||
void
|
||||
PipedAppRunner::WaitFor()
|
||||
{
|
||||
while (!HasQuitted())
|
||||
snooze(10000);
|
||||
}
|
||||
|
||||
// GetOutput
|
||||
status_t
|
||||
PipedAppRunner::GetOutput(BString *buffer)
|
||||
{
|
||||
status_t error = (buffer ? B_OK : B_BAD_VALUE);
|
||||
if (error == B_OK) {
|
||||
BAutolock locker(fOutputLock);
|
||||
size_t size = fOutput.BufferLength();
|
||||
const void *output = fOutput.Buffer();
|
||||
if (size > 0)
|
||||
buffer->SetTo((const char*)output, size);
|
||||
else
|
||||
*buffer = "";
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// ReadOutput
|
||||
ssize_t
|
||||
PipedAppRunner::ReadOutput(void *buffer, size_t size)
|
||||
{
|
||||
BAutolock locker(fOutputLock);
|
||||
return fOutput.Read(buffer, size);
|
||||
}
|
||||
|
||||
// ReadOutputAt
|
||||
ssize_t
|
||||
PipedAppRunner::ReadOutputAt(off_t position, void *buffer, size_t size)
|
||||
{
|
||||
BAutolock locker(fOutputLock);
|
||||
return fOutput.ReadAt(position, buffer, size);
|
||||
}
|
||||
|
||||
// _ReaderEntry
|
||||
int32
|
||||
PipedAppRunner::_ReaderEntry(void *data)
|
||||
{
|
||||
int32 result = 0;
|
||||
if (PipedAppRunner *me = (PipedAppRunner*)data)
|
||||
result = me->_ReaderLoop();
|
||||
return result;
|
||||
}
|
||||
|
||||
// _ReaderLoop
|
||||
int32
|
||||
PipedAppRunner::_ReaderLoop()
|
||||
{
|
||||
char buffer[10240];
|
||||
fOutputLock.Lock();
|
||||
FILE *pipe = fPipe;
|
||||
fOutputLock.Unlock();
|
||||
while (!feof(pipe)) {
|
||||
size_t bytes = fread(buffer, 1, sizeof(buffer), pipe);
|
||||
if (bytes > 0) {
|
||||
BAutolock locker(fOutputLock);
|
||||
off_t oldPosition = fOutput.Seek(0, SEEK_END);
|
||||
fOutput.Write(buffer, bytes);
|
||||
fOutput.Seek(oldPosition, SEEK_SET);
|
||||
}
|
||||
}
|
||||
_ClosePipe();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// _ClosePipe
|
||||
void
|
||||
PipedAppRunner::_ClosePipe()
|
||||
{
|
||||
if (fOutputLock.Lock()) {
|
||||
if (fPipe) {
|
||||
pclose(fPipe);
|
||||
fPipe = NULL;
|
||||
}
|
||||
fOutputLock.Unlock();
|
||||
}
|
||||
}
|
||||
|
37
src/tests/kits/app/bapplication/PipedAppRunner.h
Normal file
37
src/tests/kits/app/bapplication/PipedAppRunner.h
Normal file
@ -0,0 +1,37 @@
|
||||
// PipedAppRunner.h
|
||||
|
||||
#ifndef PIPED_APP_RUNNER_H
|
||||
#define PIPED_APP_RUNNER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <DataIO.h>
|
||||
#include <Locker.h>
|
||||
|
||||
class PipedAppRunner {
|
||||
public:
|
||||
PipedAppRunner();
|
||||
~PipedAppRunner();
|
||||
|
||||
status_t Run(const char *command, const char *args = NULL,
|
||||
bool findCommand = true);
|
||||
bool HasQuitted();
|
||||
void WaitFor();
|
||||
|
||||
status_t GetOutput(BString *buffer);
|
||||
ssize_t ReadOutput(void *buffer, size_t size);
|
||||
ssize_t ReadOutputAt(off_t position, void *buffer, size_t size);
|
||||
|
||||
private:
|
||||
static int32 _ReaderEntry(void *data);
|
||||
int32 _ReaderLoop();
|
||||
void _ClosePipe();
|
||||
|
||||
private:
|
||||
BLocker fOutputLock;
|
||||
FILE *fPipe;
|
||||
BMallocIO fOutput;
|
||||
thread_id fReader;
|
||||
};
|
||||
|
||||
#endif // PIPED_APP_RUNNER_H
|
26
src/tests/kits/app/bapplication/testapps/AppRunTestApp1.cpp
Normal file
26
src/tests/kits/app/bapplication/testapps/AppRunTestApp1.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// AppRunTestApp1.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "CommonTestApp.h"
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
// R5: doesn't set the error variable in case of success
|
||||
#ifdef TEST_R5
|
||||
status_t error = B_OK;
|
||||
#else
|
||||
status_t error = B_ERROR;
|
||||
#endif
|
||||
CommonTestApp app("application/x-vnd.obos-app-run-testapp1", &error);
|
||||
init_connection();
|
||||
report("error: %lx\n", error);
|
||||
report("InitCheck(): %lx\n", app.InitCheck());
|
||||
if (error == B_OK)
|
||||
app.Run();
|
||||
return 0;
|
||||
}
|
||||
|
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp1.rsrc
Normal file
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp1.rsrc
Normal file
Binary file not shown.
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp2.rsrc
Normal file
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp2.rsrc
Normal file
Binary file not shown.
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp3.rsrc
Normal file
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp3.rsrc
Normal file
Binary file not shown.
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp4.rsrc
Normal file
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp4.rsrc
Normal file
Binary file not shown.
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp5.rsrc
Normal file
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp5.rsrc
Normal file
Binary file not shown.
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp6.rsrc
Normal file
BIN
src/tests/kits/app/bapplication/testapps/AppRunTestApp6.rsrc
Normal file
Binary file not shown.
@ -1,11 +1,14 @@
|
||||
// BApplicationTestApp1.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app((const char*)NULL);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
// BApplicationTestApp1a.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app((const char*)NULL, NULL);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
// BApplicationTestApp1b.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
status_t error = B_OK;
|
||||
BApplication app((const char*)NULL, &error);
|
||||
printf("error: %lx\n", error);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
// BApplicationTestApp2.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app("no valid MIME string");
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
// BApplicationTestApp2a.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app("no valid MIME string", NULL);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
// BApplicationTestApp2b.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
status_t error = B_OK;
|
||||
BApplication app("no valid MIME string", &error);
|
||||
printf("error: %lx\n", error);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
// BApplicationTestApp3.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app("image/gif");
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
// BApplicationTestApp3a.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app("image/gif", NULL);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
// BApplicationTestApp3b.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
status_t error = B_OK;
|
||||
BApplication app("image/gif", &error);
|
||||
printf("error: %lx\n", error);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
// BApplicationTestApp4a.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-bapplication-testapp4", NULL);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
// BApplicationTestApp4b.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
status_t error = B_OK;
|
||||
BApplication app("application/x-vnd.obos-bapplication-testapp4", &error);
|
||||
printf("error: %lx\n", error);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
// BApplicationTestApp5a.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
BApplication app("application/x-vnd.obos-bapplication-testapp5", NULL);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
// BApplicationTestApp5b.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
status_t error = B_OK;
|
||||
BApplication app("application/x-vnd.obos-bapplication-testapp5", &error);
|
||||
printf("error: %lx\n", error);
|
||||
printf("InitCheck(): %lx\n", app.InitCheck());
|
||||
return 0;
|
||||
}
|
||||
|
175
src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp
Normal file
175
src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
// CommonTestApp.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "CommonTestApp.h"
|
||||
|
||||
// constructor
|
||||
CommonTestApp::CommonTestApp(const char *signature)
|
||||
: BApplication(signature),
|
||||
fQuitOnSecondTry(false),
|
||||
fQuitter(-1),
|
||||
fQuittingDelay(0),
|
||||
fQuittingTries(1)
|
||||
{
|
||||
}
|
||||
|
||||
// constructor
|
||||
CommonTestApp::CommonTestApp(const char *signature, status_t *result)
|
||||
: BApplication(signature, result)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
CommonTestApp::~CommonTestApp()
|
||||
{
|
||||
if (fQuitter >= 0) {
|
||||
int32 result;
|
||||
wait_for_thread(fQuitter, &result);
|
||||
}
|
||||
}
|
||||
|
||||
// ArgvReceived
|
||||
void
|
||||
CommonTestApp::ArgvReceived(int32 argc, char **argv)
|
||||
{
|
||||
report("BApplication::ArgvReceived()\n");
|
||||
if (argc > 1) {
|
||||
report("args:");
|
||||
for (int32 i = 1; i < argc; i++)
|
||||
report(" %s", argv[i]);
|
||||
report("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// QuitRequested
|
||||
bool
|
||||
CommonTestApp::QuitRequested()
|
||||
{
|
||||
report("BApplication::QuitRequested()\n");
|
||||
static bool firstTry = true;
|
||||
if (firstTry && fQuitOnSecondTry) {
|
||||
firstTry = false;
|
||||
return false;
|
||||
}
|
||||
return BApplication::QuitRequested();
|
||||
}
|
||||
|
||||
// ReadyToRun
|
||||
void
|
||||
CommonTestApp::ReadyToRun()
|
||||
{
|
||||
report("BApplication::ReadyToRun()\n");
|
||||
}
|
||||
|
||||
// Run
|
||||
thread_id
|
||||
CommonTestApp::Run()
|
||||
{
|
||||
thread_id result = BApplication::Run();
|
||||
report("BApplication::Run() done: %d\n", (result == find_thread(NULL)));
|
||||
return result;
|
||||
}
|
||||
|
||||
// SetQuittingPolicy
|
||||
void
|
||||
CommonTestApp::SetQuittingPolicy(bool onSecondTry)
|
||||
{
|
||||
fQuitOnSecondTry = onSecondTry;
|
||||
}
|
||||
|
||||
// RunQuitterThread
|
||||
status_t
|
||||
CommonTestApp::RunQuitterThread(bigtime_t delay, int32 tries)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
fQuittingDelay = delay;
|
||||
fQuittingTries = tries;
|
||||
// spawn the thread
|
||||
fQuitter = spawn_thread(&_QuitterEntry, "quitter thread",
|
||||
B_NORMAL_PRIORITY, this);
|
||||
if (fQuitter < 0)
|
||||
error = fQuitter;
|
||||
if (error == B_OK)
|
||||
error = resume_thread(fQuitter);
|
||||
// cleanup on error
|
||||
if (error != B_OK && fQuitter >= 0) {
|
||||
kill_thread(fQuitter);
|
||||
fQuitter = -1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// _QuitterEntry
|
||||
int32
|
||||
CommonTestApp::_QuitterEntry(void *data)
|
||||
{
|
||||
int32 result = 0;
|
||||
if (CommonTestApp *app = (CommonTestApp*)data)
|
||||
result = app->_QuitterLoop();
|
||||
return result;
|
||||
}
|
||||
|
||||
// _QuitterLoop
|
||||
int32
|
||||
CommonTestApp::_QuitterLoop()
|
||||
{
|
||||
for (; fQuittingTries > 0; fQuittingTries--) {
|
||||
snooze(fQuittingDelay);
|
||||
PostMessage(B_QUIT_REQUESTED, this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *kAppRunnerTeamPort = "app runner team port";
|
||||
|
||||
static port_id outputPort = -1;
|
||||
|
||||
// init_connection
|
||||
status_t
|
||||
init_connection()
|
||||
{
|
||||
status_t error = B_OK;
|
||||
// create a port
|
||||
outputPort = create_port(10, "common test app port");
|
||||
if (outputPort < 0)
|
||||
error = outputPort;
|
||||
// find the remote port
|
||||
port_id port = -1;
|
||||
if (error == B_OK) {
|
||||
port = find_port(kAppRunnerTeamPort);
|
||||
if (port < 0)
|
||||
error = port;
|
||||
}
|
||||
// send the port ID
|
||||
if (error == B_OK) {
|
||||
ssize_t written = write_port(port, outputPort, &be_app_messenger,
|
||||
sizeof(BMessenger));
|
||||
if (written < 0)
|
||||
error = written;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// report
|
||||
void
|
||||
report(const char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vreport(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// vreport
|
||||
void
|
||||
vreport(const char *format, va_list args)
|
||||
{
|
||||
char buffer[10240];
|
||||
vsprintf(buffer, format, args);
|
||||
int32 length = strlen(buffer);
|
||||
write_port(outputPort, 0, buffer, length);
|
||||
}
|
||||
|
40
src/tests/kits/app/bapplication/testapps/CommonTestApp.h
Normal file
40
src/tests/kits/app/bapplication/testapps/CommonTestApp.h
Normal file
@ -0,0 +1,40 @@
|
||||
// CommonTestApp.h
|
||||
|
||||
#ifndef COMMON_TEST_APP_H
|
||||
#define COMMON_TEST_APP_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
class CommonTestApp : public BApplication {
|
||||
public:
|
||||
CommonTestApp(const char *signature);
|
||||
CommonTestApp(const char *signature, status_t *result);
|
||||
virtual ~CommonTestApp();
|
||||
|
||||
virtual void ArgvReceived(int32 argc, char **argv);
|
||||
virtual bool QuitRequested();
|
||||
virtual void ReadyToRun();
|
||||
thread_id Run();
|
||||
|
||||
void SetQuittingPolicy(bool onSecondTry);
|
||||
|
||||
status_t RunQuitterThread(bigtime_t delay, int32 tries);
|
||||
|
||||
private:
|
||||
static int32 _QuitterEntry(void *data);
|
||||
int32 _QuitterLoop();
|
||||
|
||||
private:
|
||||
bool fQuitOnSecondTry;
|
||||
thread_id fQuitter;
|
||||
bigtime_t fQuittingDelay;
|
||||
int32 fQuittingTries;
|
||||
};
|
||||
|
||||
status_t init_connection();
|
||||
void report(const char *format,...);
|
||||
void vreport(const char *format, va_list args);
|
||||
|
||||
#endif // COMMON_TEST_APP_H
|
@ -1,45 +1,83 @@
|
||||
SubDir OBOS_TOP src tests kits app bapplication testapps ;
|
||||
|
||||
CommonUnitTest BApplicationTestApp1
|
||||
: BApplicationTestApp1.cpp
|
||||
: kits app
|
||||
: <boot!home!config!lib>libopenbeos.so be stdc++.r4
|
||||
: be stdc++.r4
|
||||
: app support
|
||||
;
|
||||
rule SimpleBAppTestApp
|
||||
{
|
||||
# SimpleBAppTestApp <sources> : <resources> ;
|
||||
local sources = $(1) ;
|
||||
local resources = $(2) ;
|
||||
local name = $(sources[1]) ;
|
||||
name = $(name:B) ;
|
||||
SimpleBAppTestApp2 $(name) : $(sources) : $(resources) ;
|
||||
}
|
||||
|
||||
CommonUnitTest BApplicationTestApp2
|
||||
: BApplicationTestApp2.cpp
|
||||
: kits app
|
||||
: <boot!home!config!lib>libopenbeos.so be stdc++.r4
|
||||
: be stdc++.r4
|
||||
: app support
|
||||
;
|
||||
rule SimpleBAppTestApp2
|
||||
{
|
||||
# SimpleBAppTestApp <name> : <sources> : <resources> ;
|
||||
local name = $(1) ;
|
||||
local sources = $(2) ;
|
||||
local resources = $(3) ;
|
||||
local r5name = $(name)_r5 ;
|
||||
|
||||
CommonUnitTest BApplicationTestApp3
|
||||
: BApplicationTestApp3.cpp
|
||||
: kits app
|
||||
: <boot!home!config!lib>libopenbeos.so be stdc++.r4
|
||||
: be stdc++.r4
|
||||
: app support
|
||||
;
|
||||
if $(resources) {
|
||||
AddResources $(name) : $(resources) ;
|
||||
AddResources $(r5name) : $(resources) ;
|
||||
}
|
||||
CommonUnitTest $(name)
|
||||
: $(sources)
|
||||
: kits app
|
||||
: <boot!home!config!lib>libopenbeos.so be stdc++.r4
|
||||
: be stdc++.r4
|
||||
: app support
|
||||
;
|
||||
}
|
||||
|
||||
AddResources BApplicationTestApp4 : BApplicationTestApp4.rsrc ;
|
||||
AddResources BApplicationTestApp4_r5 : BApplicationTestApp4.rsrc ;
|
||||
CommonUnitTest BApplicationTestApp4
|
||||
: BApplicationTestApp4.cpp
|
||||
: kits app
|
||||
: <boot!home!config!lib>libopenbeos.so be stdc++.r4
|
||||
: be stdc++.r4
|
||||
: app support
|
||||
;
|
||||
rule CopyBAppTestApp
|
||||
{
|
||||
# CopyBAppTestApp <target> : <source> ;
|
||||
local target = $(1) ;
|
||||
local source = $(2) ;
|
||||
local r5target = $(target)_r5 ;
|
||||
local r5source = $(source)_r5 ;
|
||||
MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) kits app ] ;
|
||||
MakeLocate $(r5target) : [ FDirName $(OBOS_TEST_DIR) kits app ] ;
|
||||
File $(target) : $(source) ;
|
||||
File $(r5target) : $(r5source) ;
|
||||
local file ;
|
||||
for file in $(target) $(r5target) {
|
||||
MODE on $(file) = $(EXEMODE) ;
|
||||
MimeSet $(file) ;
|
||||
}
|
||||
}
|
||||
|
||||
AddResources BApplicationTestApp5 : BApplicationTestApp5.rsrc ;
|
||||
AddResources BApplicationTestApp5_r5 : BApplicationTestApp5.rsrc ;
|
||||
CommonUnitTest BApplicationTestApp5
|
||||
: BApplicationTestApp5.cpp
|
||||
: kits app
|
||||
: <boot!home!config!lib>libopenbeos.so be stdc++.r4
|
||||
: be stdc++.r4
|
||||
: app support
|
||||
;
|
||||
SimpleBAppTestApp BApplicationTestApp1.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp1a.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp1b.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp2.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp2a.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp2b.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp3.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp3a.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp3b.cpp ;
|
||||
SimpleBAppTestApp BApplicationTestApp4.cpp : BApplicationTestApp4.rsrc ;
|
||||
SimpleBAppTestApp BApplicationTestApp4a.cpp : BApplicationTestApp4.rsrc ;
|
||||
SimpleBAppTestApp BApplicationTestApp4b.cpp : BApplicationTestApp4.rsrc ;
|
||||
SimpleBAppTestApp BApplicationTestApp5.cpp : BApplicationTestApp5.rsrc ;
|
||||
SimpleBAppTestApp BApplicationTestApp5a.cpp : BApplicationTestApp5.rsrc ;
|
||||
SimpleBAppTestApp BApplicationTestApp5b.cpp : BApplicationTestApp5.rsrc ;
|
||||
|
||||
SimpleBAppTestApp AppRunTestApp1.cpp CommonTestApp.cpp : AppRunTestApp1.rsrc ;
|
||||
SimpleBAppTestApp2 AppRunTestApp2 : AppRunTestApp1.o CommonTestApp.o
|
||||
: AppRunTestApp2.rsrc ;
|
||||
SimpleBAppTestApp2 AppRunTestApp3 : AppRunTestApp1.o CommonTestApp.o
|
||||
: AppRunTestApp3.rsrc ;
|
||||
SimpleBAppTestApp2 AppRunTestApp4 : AppRunTestApp1.o CommonTestApp.o
|
||||
: AppRunTestApp4.rsrc ;
|
||||
SimpleBAppTestApp2 AppRunTestApp5 : AppRunTestApp1.o CommonTestApp.o
|
||||
: AppRunTestApp5.rsrc ;
|
||||
SimpleBAppTestApp2 AppRunTestApp6 : AppRunTestApp1.o CommonTestApp.o
|
||||
: AppRunTestApp6.rsrc ;
|
||||
|
||||
CopyBAppTestApp AppRunTestApp3a : AppRunTestApp3 ;
|
||||
CopyBAppTestApp AppRunTestApp4a : AppRunTestApp4 ;
|
||||
CopyBAppTestApp AppRunTestApp5a : AppRunTestApp5 ;
|
||||
CopyBAppTestApp AppRunTestApp6a : AppRunTestApp6 ;
|
||||
|
Loading…
Reference in New Issue
Block a user