From c9640d94a3b08cd4aaf02df8a4e008894b06f1e0 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 3 Aug 2002 16:07:02 +0000 Subject: [PATCH] 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 --- src/tests/kits/app/Jamfile | 2 + .../kits/app/bapplication/AppRunTester.cpp | 819 ++++++++++++++++++ .../kits/app/bapplication/AppRunTester.h | 55 ++ src/tests/kits/app/bapplication/AppRunner.cpp | 176 +++- src/tests/kits/app/bapplication/AppRunner.h | 19 +- .../kits/app/bapplication/ApplicationTest.cpp | 2 + .../kits/app/bapplication/BApplicationCases | 110 ++- .../app/bapplication/BApplicationTester.cpp | 111 ++- .../kits/app/bapplication/PipedAppRunner.cpp | 178 ++++ .../kits/app/bapplication/PipedAppRunner.h | 37 + .../bapplication/testapps/AppRunTestApp1.cpp | 26 + .../bapplication/testapps/AppRunTestApp1.rsrc | Bin 0 -> 2866 bytes .../bapplication/testapps/AppRunTestApp2.rsrc | Bin 0 -> 2866 bytes .../bapplication/testapps/AppRunTestApp3.rsrc | Bin 0 -> 2866 bytes .../bapplication/testapps/AppRunTestApp4.rsrc | Bin 0 -> 2866 bytes .../bapplication/testapps/AppRunTestApp5.rsrc | Bin 0 -> 2866 bytes .../bapplication/testapps/AppRunTestApp6.rsrc | Bin 0 -> 2866 bytes .../testapps/BApplicationTestApp1.cpp | 3 + .../testapps/BApplicationTestApp1a.cpp | 14 + .../testapps/BApplicationTestApp1b.cpp | 16 + .../testapps/BApplicationTestApp2.cpp | 3 + .../testapps/BApplicationTestApp2a.cpp | 14 + .../testapps/BApplicationTestApp2b.cpp | 16 + .../testapps/BApplicationTestApp3.cpp | 3 + .../testapps/BApplicationTestApp3a.cpp | 14 + .../testapps/BApplicationTestApp3b.cpp | 16 + .../testapps/BApplicationTestApp4a.cpp | 14 + .../testapps/BApplicationTestApp4b.cpp | 16 + .../testapps/BApplicationTestApp5a.cpp | 14 + .../testapps/BApplicationTestApp5b.cpp | 16 + .../bapplication/testapps/CommonTestApp.cpp | 175 ++++ .../app/bapplication/testapps/CommonTestApp.h | 40 + .../kits/app/bapplication/testapps/Jamfile | 116 ++- 33 files changed, 1915 insertions(+), 110 deletions(-) create mode 100644 src/tests/kits/app/bapplication/AppRunTester.cpp create mode 100644 src/tests/kits/app/bapplication/AppRunTester.h create mode 100644 src/tests/kits/app/bapplication/PipedAppRunner.cpp create mode 100644 src/tests/kits/app/bapplication/PipedAppRunner.h create mode 100644 src/tests/kits/app/bapplication/testapps/AppRunTestApp1.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/AppRunTestApp1.rsrc create mode 100644 src/tests/kits/app/bapplication/testapps/AppRunTestApp2.rsrc create mode 100644 src/tests/kits/app/bapplication/testapps/AppRunTestApp3.rsrc create mode 100644 src/tests/kits/app/bapplication/testapps/AppRunTestApp4.rsrc create mode 100644 src/tests/kits/app/bapplication/testapps/AppRunTestApp5.rsrc create mode 100644 src/tests/kits/app/bapplication/testapps/AppRunTestApp6.rsrc create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp1a.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp1b.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp2a.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp2b.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp3a.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp3b.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp4a.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp4b.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp5a.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp5b.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/CommonTestApp.h diff --git a/src/tests/kits/app/Jamfile b/src/tests/kits/app/Jamfile index f49078ad89..df22c59c28 100644 --- a/src/tests/kits/app/Jamfile +++ b/src/tests/kits/app/Jamfile @@ -13,7 +13,9 @@ CommonTestLib libapptest.so # BApplication ApplicationTest.cpp AppRunner.cpp + AppRunTester.cpp BApplicationTester.cpp + PipedAppRunner.cpp # BHandler HandlerTest.cpp diff --git a/src/tests/kits/app/bapplication/AppRunTester.cpp b/src/tests/kits/app/bapplication/AppRunTester.cpp new file mode 100644 index 0000000000..b88c6c9b2b --- /dev/null +++ b/src/tests/kits/app/bapplication/AppRunTester.cpp @@ -0,0 +1,819 @@ +//------------------------------------------------------------------------------ +// AppRunTester.cpp +// +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include + +// System Includes ------------------------------------------------------------- +#include +#include + +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ +#include +#include +#include + +// 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; +} + + + diff --git a/src/tests/kits/app/bapplication/AppRunTester.h b/src/tests/kits/app/bapplication/AppRunTester.h new file mode 100644 index 0000000000..81e49c28d6 --- /dev/null +++ b/src/tests/kits/app/bapplication/AppRunTester.h @@ -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 + diff --git a/src/tests/kits/app/bapplication/AppRunner.cpp b/src/tests/kits/app/bapplication/AppRunner.cpp index c654bc302f..e539120944 100644 --- a/src/tests/kits/app/bapplication/AppRunner.cpp +++ b/src/tests/kits/app/bapplication/AppRunner.cpp @@ -4,15 +4,25 @@ #include #include +#include +#include + +#include +#include +#include #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; + diff --git a/src/tests/kits/app/bapplication/AppRunner.h b/src/tests/kits/app/bapplication/AppRunner.h index 843ed42427..4950d2450d 100644 --- a/src/tests/kits/app/bapplication/AppRunner.h +++ b/src/tests/kits/app/bapplication/AppRunner.h @@ -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 diff --git a/src/tests/kits/app/bapplication/ApplicationTest.cpp b/src/tests/kits/app/bapplication/ApplicationTest.cpp index bf39d2d0d5..c31bc1663a 100644 --- a/src/tests/kits/app/bapplication/ApplicationTest.cpp +++ b/src/tests/kits/app/bapplication/ApplicationTest.cpp @@ -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; diff --git a/src/tests/kits/app/bapplication/BApplicationCases b/src/tests/kits/app/bapplication/BApplicationCases index 4903b9777f..01233d6374 100644 --- a/src/tests/kits/app/bapplication/BApplicationCases +++ b/src/tests/kits/app/bapplication/BApplicationCases @@ -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 + diff --git a/src/tests/kits/app/bapplication/BApplicationTester.cpp b/src/tests/kits/app/bapplication/BApplicationTester.cpp index 1a68743f7d..1885ff5cd9 100644 --- a/src/tests/kits/app/bapplication/BApplicationTester.cpp +++ b/src/tests/kits/app/bapplication/BApplicationTester.cpp @@ -21,7 +21,7 @@ #include // 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); } diff --git a/src/tests/kits/app/bapplication/PipedAppRunner.cpp b/src/tests/kits/app/bapplication/PipedAppRunner.cpp new file mode 100644 index 0000000000..098e8fdd67 --- /dev/null +++ b/src/tests/kits/app/bapplication/PipedAppRunner.cpp @@ -0,0 +1,178 @@ +// PipedAppRunner.cpp + +#include +#include + +#include +#include + +#include +#include +#include + +#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(); + } +} + diff --git a/src/tests/kits/app/bapplication/PipedAppRunner.h b/src/tests/kits/app/bapplication/PipedAppRunner.h new file mode 100644 index 0000000000..832d7dce7b --- /dev/null +++ b/src/tests/kits/app/bapplication/PipedAppRunner.h @@ -0,0 +1,37 @@ +// PipedAppRunner.h + +#ifndef PIPED_APP_RUNNER_H +#define PIPED_APP_RUNNER_H + +#include + +#include +#include + +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 diff --git a/src/tests/kits/app/bapplication/testapps/AppRunTestApp1.cpp b/src/tests/kits/app/bapplication/testapps/AppRunTestApp1.cpp new file mode 100644 index 0000000000..95cc9e9f7b --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/AppRunTestApp1.cpp @@ -0,0 +1,26 @@ +// AppRunTestApp1.cpp + +#include + +#include + +#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; +} + diff --git a/src/tests/kits/app/bapplication/testapps/AppRunTestApp1.rsrc b/src/tests/kits/app/bapplication/testapps/AppRunTestApp1.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..5e9cb6ed400ae9146f46952617e562a40efbc1b9 GIT binary patch literal 2866 zcmWFvW?*0t@ONPWQZ69O1|-M;AiWGgy)T&|W@Ioz*dXEmKmZb_1$!|U14B2^V37H1 z*clj!H6Ievqv0?b4x?#cG!2ZV0m{-q zVnIPpW^!UlW`3T2g>G41ik?%dZfZ_iYDH>tX-Q&IPAUVYlKiCnVqKuHZc%BTZb@o! z36O0FamOe*8Ulkn1UP~23-M{ literal 0 HcmV?d00001 diff --git a/src/tests/kits/app/bapplication/testapps/AppRunTestApp2.rsrc b/src/tests/kits/app/bapplication/testapps/AppRunTestApp2.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..cdda562a322c4bc6a9dfb05d5b421beb816e3ad3 GIT binary patch literal 2866 zcmWFvW?*0t@ONPWQZ69O1|-M;AiWGgy)T&|W@Ioz*dXEmKmZb_1$!|U14B2^V37H1 z*cli={s4guK=ukI2s;9(MgziRXaKU6p==OEOSg@hPrG;@4cpPM9ZdtHX<($K0bsQ{ z3PwXlT&f>6WAxmjKy@44CSiQgu^v z(o!o@lS@kylX6lS+yVj|fh|e~5awraa`g|katsKFck^*{4+gj4K<&6Ns3K6aPY|If y%rz+3)87xSEZEo67i12oMaqj%7VPQH0MZF+L2^NaLm~rQ;o7zyKRX8~#Q*>*ia5pq literal 0 HcmV?d00001 diff --git a/src/tests/kits/app/bapplication/testapps/AppRunTestApp4.rsrc b/src/tests/kits/app/bapplication/testapps/AppRunTestApp4.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..f7428f57384b3e4de05fe25645328b91bfbe73a1 GIT binary patch literal 2866 zcmWFvW?*0t@ONPWQZ69O1|-M;AiWGgy)T&|W@Ioz*dXEmKmZb_1$!|U14B2^V37H1 z*cli={s4guK=ukI2s;9(MgziRXaKU6p==OEOSg@hPrG;@4cpPM9ZdtHX<#I#0g#_Z z!Dt8!_7F%cD9Fi7PAtjH&(p8aEz3*M%TLNL)&&ad7M14dmZTP!0NI8NnChHTbyIWF zQY%uEOG^@ya#9)G0sn~$S=Ft`l|YR82^6@i+4f(S)n xu0g?`{(f*}!M>ipAag)1QeK3zU{7}jkWNqwk_#dn5*gqM*S7We**QQd1^_XRILH71 literal 0 HcmV?d00001 diff --git a/src/tests/kits/app/bapplication/testapps/AppRunTestApp6.rsrc b/src/tests/kits/app/bapplication/testapps/AppRunTestApp6.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..3f61b197cde2730a1b62dcf594e68695fb8c2883 GIT binary patch literal 2866 zcmWFvW?*0t@ONPWQZ69O1|-M;AiWGgy)T&|W@Ioz*dXEmKmZb_1$!|U14B2^V37H1 z*cli={s4guK=ukI2s;9(MgziRXaKU6p==OEOSg@hPrG;@4cpPM9ZdtHX<($K0ce#5 z^7beg4S_)&0*M6$Iho0cC7Jno`W3omc`17NN%_UPKw;gY(mdUg)Z!8#+mHcMol~lA zYED{eMQU1p1vS+KrK>UgtA~ycLtD7Pz#a^A{-JK;0o8a_4wI2Kq&?Q6@ECt literal 0 HcmV?d00001 diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp index 0de6ca9acc..5e5ff98281 100644 --- a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp @@ -1,11 +1,14 @@ // BApplicationTestApp1.cpp +#include + #include int main() { BApplication app((const char*)NULL); + printf("InitCheck(): %lx\n", app.InitCheck()); return 0; } diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1a.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1a.cpp new file mode 100644 index 0000000000..ce25273322 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1a.cpp @@ -0,0 +1,14 @@ +// BApplicationTestApp1a.cpp + +#include + +#include + +int +main() +{ + BApplication app((const char*)NULL, NULL); + printf("InitCheck(): %lx\n", app.InitCheck()); + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1b.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1b.cpp new file mode 100644 index 0000000000..cb26c9f2c8 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1b.cpp @@ -0,0 +1,16 @@ +// BApplicationTestApp1b.cpp + +#include + +#include + +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; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2.cpp index 00e1334356..86cca09de0 100644 --- a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2.cpp +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2.cpp @@ -1,11 +1,14 @@ // BApplicationTestApp2.cpp +#include + #include int main() { BApplication app("no valid MIME string"); + printf("InitCheck(): %lx\n", app.InitCheck()); return 0; } diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2a.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2a.cpp new file mode 100644 index 0000000000..2997f3192c --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2a.cpp @@ -0,0 +1,14 @@ +// BApplicationTestApp2a.cpp + +#include + +#include + +int +main() +{ + BApplication app("no valid MIME string", NULL); + printf("InitCheck(): %lx\n", app.InitCheck()); + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2b.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2b.cpp new file mode 100644 index 0000000000..94f94649fe --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp2b.cpp @@ -0,0 +1,16 @@ +// BApplicationTestApp2b.cpp + +#include + +#include + +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; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3.cpp index bb432124d2..805d2d5691 100644 --- a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3.cpp +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3.cpp @@ -1,11 +1,14 @@ // BApplicationTestApp3.cpp +#include + #include int main() { BApplication app("image/gif"); + printf("InitCheck(): %lx\n", app.InitCheck()); return 0; } diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3a.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3a.cpp new file mode 100644 index 0000000000..59cad8f39c --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3a.cpp @@ -0,0 +1,14 @@ +// BApplicationTestApp3a.cpp + +#include + +#include + +int +main() +{ + BApplication app("image/gif", NULL); + printf("InitCheck(): %lx\n", app.InitCheck()); + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3b.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3b.cpp new file mode 100644 index 0000000000..1fafa55905 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp3b.cpp @@ -0,0 +1,16 @@ +// BApplicationTestApp3b.cpp + +#include + +#include + +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; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp4a.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp4a.cpp new file mode 100644 index 0000000000..6c320a5418 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp4a.cpp @@ -0,0 +1,14 @@ +// BApplicationTestApp4a.cpp + +#include + +#include + +int +main() +{ + BApplication app("application/x-vnd.obos-bapplication-testapp4", NULL); + printf("InitCheck(): %lx\n", app.InitCheck()); + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp4b.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp4b.cpp new file mode 100644 index 0000000000..c4ec388b61 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp4b.cpp @@ -0,0 +1,16 @@ +// BApplicationTestApp4b.cpp + +#include + +#include + +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; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp5a.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp5a.cpp new file mode 100644 index 0000000000..b4a1f6548a --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp5a.cpp @@ -0,0 +1,14 @@ +// BApplicationTestApp5a.cpp + +#include + +#include + +int +main() +{ + BApplication app("application/x-vnd.obos-bapplication-testapp5", NULL); + printf("InitCheck(): %lx\n", app.InitCheck()); + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp5b.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp5b.cpp new file mode 100644 index 0000000000..9096398d11 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp5b.cpp @@ -0,0 +1,16 @@ +// BApplicationTestApp5b.cpp + +#include + +#include + +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; +} + diff --git a/src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp b/src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp new file mode 100644 index 0000000000..4ad2dfc233 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp @@ -0,0 +1,175 @@ +// CommonTestApp.cpp + +#include + +#include + +#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); +} + diff --git a/src/tests/kits/app/bapplication/testapps/CommonTestApp.h b/src/tests/kits/app/bapplication/testapps/CommonTestApp.h new file mode 100644 index 0000000000..a53971d665 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/CommonTestApp.h @@ -0,0 +1,40 @@ +// CommonTestApp.h + +#ifndef COMMON_TEST_APP_H +#define COMMON_TEST_APP_H + +#include + +#include + +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 diff --git a/src/tests/kits/app/bapplication/testapps/Jamfile b/src/tests/kits/app/bapplication/testapps/Jamfile index 56748a6647..53fc915d9e 100644 --- a/src/tests/kits/app/bapplication/testapps/Jamfile +++ b/src/tests/kits/app/bapplication/testapps/Jamfile @@ -1,45 +1,83 @@ SubDir OBOS_TOP src tests kits app bapplication testapps ; -CommonUnitTest BApplicationTestApp1 - : BApplicationTestApp1.cpp - : kits app - : libopenbeos.so be stdc++.r4 - : be stdc++.r4 - : app support -; +rule SimpleBAppTestApp +{ + # SimpleBAppTestApp : ; + local sources = $(1) ; + local resources = $(2) ; + local name = $(sources[1]) ; + name = $(name:B) ; + SimpleBAppTestApp2 $(name) : $(sources) : $(resources) ; +} -CommonUnitTest BApplicationTestApp2 - : BApplicationTestApp2.cpp - : kits app - : libopenbeos.so be stdc++.r4 - : be stdc++.r4 - : app support -; +rule SimpleBAppTestApp2 +{ + # SimpleBAppTestApp : : ; + local name = $(1) ; + local sources = $(2) ; + local resources = $(3) ; + local r5name = $(name)_r5 ; -CommonUnitTest BApplicationTestApp3 - : BApplicationTestApp3.cpp - : kits app - : libopenbeos.so be stdc++.r4 - : be stdc++.r4 - : app support -; + if $(resources) { + AddResources $(name) : $(resources) ; + AddResources $(r5name) : $(resources) ; + } + CommonUnitTest $(name) + : $(sources) + : kits app + : 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 - : libopenbeos.so be stdc++.r4 - : be stdc++.r4 - : app support -; +rule CopyBAppTestApp +{ + # CopyBAppTestApp : ; + 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 - : 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 ;