From 8909e4ba29125ec1292ea6181f60d8e82dc87c06 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 31 Jul 2002 00:36:22 +0000 Subject: [PATCH] Added first BApplication test. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@541 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/app/AppKitTestAddon.cpp | 2 + src/tests/kits/app/Jamfile | 7 + src/tests/kits/app/bapplication/AppRunner.cpp | 130 ++++++++++++++++++ src/tests/kits/app/bapplication/AppRunner.h | 34 +++++ .../kits/app/bapplication/ApplicationTest.cpp | 12 ++ .../kits/app/bapplication/ApplicationTest.h | 9 ++ .../kits/app/bapplication/BApplicationCases | 22 +++ .../app/bapplication/BApplicationTester.cpp | 82 +++++++++++ .../app/bapplication/BApplicationTester.h | 34 +++++ src/tests/kits/app/bapplication/Jamfile | 3 + .../testapps/BApplicationTestApp1.cpp | 11 ++ .../kits/app/bapplication/testapps/Jamfile | 9 ++ 12 files changed, 355 insertions(+) create mode 100644 src/tests/kits/app/bapplication/AppRunner.cpp create mode 100644 src/tests/kits/app/bapplication/AppRunner.h create mode 100644 src/tests/kits/app/bapplication/ApplicationTest.cpp create mode 100644 src/tests/kits/app/bapplication/ApplicationTest.h create mode 100644 src/tests/kits/app/bapplication/BApplicationCases create mode 100644 src/tests/kits/app/bapplication/BApplicationTester.cpp create mode 100644 src/tests/kits/app/bapplication/BApplicationTester.h create mode 100644 src/tests/kits/app/bapplication/Jamfile create mode 100644 src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp create mode 100644 src/tests/kits/app/bapplication/testapps/Jamfile diff --git a/src/tests/kits/app/AppKitTestAddon.cpp b/src/tests/kits/app/AppKitTestAddon.cpp index 7c9dc82120..5972b84584 100644 --- a/src/tests/kits/app/AppKitTestAddon.cpp +++ b/src/tests/kits/app/AppKitTestAddon.cpp @@ -2,6 +2,7 @@ #include // ##### Include headers for your tests here ##### +#include "bapplication/ApplicationTest.h" #include "bhandler/HandlerTest.h" #include "blooper/LooperTest.h" #include "bmessagequeue/MessageQueueTest.h" @@ -11,6 +12,7 @@ BTestSuite* getTestSuite() { BTestSuite *suite = new BTestSuite("App"); // ##### Add test suites here ##### + suite->addTest("BApplication", ApplicationTestSuite()); suite->addTest("BHandler", HandlerTestSuite()); suite->addTest("BLooper", LooperTestSuite()); suite->addTest("BMessageQueue", MessageQueueTestSuite()); diff --git a/src/tests/kits/app/Jamfile b/src/tests/kits/app/Jamfile index 5b6415460b..f49078ad89 100644 --- a/src/tests/kits/app/Jamfile +++ b/src/tests/kits/app/Jamfile @@ -1,6 +1,7 @@ SubDir OBOS_TOP src tests kits app ; # Let Jam know where to find some of our source files +SEARCH_SOURCE += [ FDirName $(SUBDIR) bapplication ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) bhandler ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) blooper ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) bmessagequeue ] ; @@ -9,6 +10,11 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) bmessenger ] ; CommonTestLib libapptest.so : AppKitTestAddon.cpp + # BApplication + ApplicationTest.cpp + AppRunner.cpp + BApplicationTester.cpp + # BHandler HandlerTest.cpp AddFilterTest.cpp @@ -68,6 +74,7 @@ CommonTestLib libapptest.so : app support ; +SubInclude OBOS_TOP src tests kits app bapplication ; #SubInclude OBOS_TOP src tests kits app bhandler ; #SubInclude OBOS_TOP src tests kits app blooper ; #SubInclude OBOS_TOP src tests kits app bmessageQueue ; diff --git a/src/tests/kits/app/bapplication/AppRunner.cpp b/src/tests/kits/app/bapplication/AppRunner.cpp new file mode 100644 index 0000000000..c654bc302f --- /dev/null +++ b/src/tests/kits/app/bapplication/AppRunner.cpp @@ -0,0 +1,130 @@ +// AppRunner.cpp + +#include +#include + +#include + +#include "AppRunner.h" + +// constructor +AppRunner::AppRunner() + : fOutputLock(), + fPipe(NULL), + fOutput(), + fReader(-1) +{ +} + +// destructor +AppRunner::~AppRunner() +{ + if (fReader >= 0) { + _ClosePipe(); + int32 result; + wait_for_thread(fReader, &result); + } +} + +// Run +status_t +AppRunner::Run(const char *command) +{ + status_t error = (HasQuitted() ? B_OK : B_ERROR); + // run the command + if (error == B_OK) { + fPipe = popen(command, "r"); + if (!fPipe) + error = errno; + } + // spawn the reader thread + if (error == B_OK) { + fReader = spawn_thread(&_ReaderEntry, "AppRunner 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 +AppRunner::HasQuitted() +{ + BAutolock locker(fOutputLock); + return !fPipe; +} + +// ReadOutput +ssize_t +AppRunner::ReadOutput(void *buffer, size_t size) +{ + BAutolock locker(fOutputLock); + return fOutput.Read(buffer, size); +} + +// ReadOutputAt +ssize_t +AppRunner::ReadOutputAt(off_t position, void *buffer, size_t size) +{ + BAutolock locker(fOutputLock); + return fOutput.ReadAt(position, buffer, size); +} + +// _ReaderEntry +int32 +AppRunner::_ReaderEntry(void *data) +{ + int32 result = 0; + if (AppRunner *me = (AppRunner*)data) + result = me->_ReaderLoop(); + return result; +} + +// _ReaderLoop +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); + 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 +AppRunner::_ClosePipe() +{ + if (fOutputLock.Lock()) { + if (fPipe) { + pclose(fPipe); + fPipe = NULL; + } + fOutputLock.Unlock(); + } +} + diff --git a/src/tests/kits/app/bapplication/AppRunner.h b/src/tests/kits/app/bapplication/AppRunner.h new file mode 100644 index 0000000000..843ed42427 --- /dev/null +++ b/src/tests/kits/app/bapplication/AppRunner.h @@ -0,0 +1,34 @@ +// AppRunner.h + +#ifndef APP_RUNNER_H +#define APP_RUNNER_H + +#include + +#include +#include + +class AppRunner { +public: + AppRunner(); + ~AppRunner(); + + status_t Run(const char *command); + bool HasQuitted(); + + 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 // APP_RUNNER_H diff --git a/src/tests/kits/app/bapplication/ApplicationTest.cpp b/src/tests/kits/app/bapplication/ApplicationTest.cpp new file mode 100644 index 0000000000..bf39d2d0d5 --- /dev/null +++ b/src/tests/kits/app/bapplication/ApplicationTest.cpp @@ -0,0 +1,12 @@ +#include "../common.h" +#include "BApplicationTester.h" + +CppUnit::Test* ApplicationTestSuite() +{ + CppUnit::TestSuite *testSuite = new CppUnit::TestSuite(); + + testSuite->addTest(TBApplicationTester::Suite()); + + return testSuite; +} + diff --git a/src/tests/kits/app/bapplication/ApplicationTest.h b/src/tests/kits/app/bapplication/ApplicationTest.h new file mode 100644 index 0000000000..c9c508c18a --- /dev/null +++ b/src/tests/kits/app/bapplication/ApplicationTest.h @@ -0,0 +1,9 @@ +#ifndef _application_test_h_ +#define _application_test_h_ + +class CppUnit::Test; + +CppUnit::Test* ApplicationTestSuite(); + +#endif // _application_test_h_ + diff --git a/src/tests/kits/app/bapplication/BApplicationCases b/src/tests/kits/app/bapplication/BApplicationCases new file mode 100644 index 0000000000..4903b9777f --- /dev/null +++ b/src/tests/kits/app/bapplication/BApplicationCases @@ -0,0 +1,22 @@ +BApplication(const char *signature) +case 1: signature is NULL => + Should print error message and quit. +case 2: signature is no valid MIME string => + Should print error message and quit. +case 3: signature is a valid MIME string, but doesn't have the "application" + supertype => + Should print error message and quit. +case 4: signature is a valid MIME string with "application" supertype, + but a different one than in the app attributes/resources => + Should print warning message and continue. + InitCheck() should return B_OK. +case 5: signature is a valid MIME string with "application" supertype, + and the same as in the app attributes/resources => + 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() + + diff --git a/src/tests/kits/app/bapplication/BApplicationTester.cpp b/src/tests/kits/app/bapplication/BApplicationTester.cpp new file mode 100644 index 0000000000..ea2869dfac --- /dev/null +++ b/src/tests/kits/app/bapplication/BApplicationTester.cpp @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +// BApplicationTester.cpp +// +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include + +// System Includes ------------------------------------------------------------- +#include +#include + +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ +#include +#include +#include + +// Local Includes -------------------------------------------------------------- +#include "AppRunner.h" +#include "BApplicationTester.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ + +// test_app +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; + // run the app + AppRunner runner; + CHK(runner.Run(appPath.String()) == B_OK); + snooze(100000); + // 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)); +} + + +/* + BApplication(const char *signature) + @case 1 signature is NULL + @results Should print error message and quit. + */ +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"); +} + + +Test* TBApplicationTester::Suite() +{ + TestSuite* SuiteOfTests = new TestSuite; + + ADD_TEST4(BApplication, SuiteOfTests, TBApplicationTester, BApplication1); + + return SuiteOfTests; +} + + + diff --git a/src/tests/kits/app/bapplication/BApplicationTester.h b/src/tests/kits/app/bapplication/BApplicationTester.h new file mode 100644 index 0000000000..9429f8ec8a --- /dev/null +++ b/src/tests/kits/app/bapplication/BApplicationTester.h @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// BApplicationTester.h +// +//------------------------------------------------------------------------------ + +#ifndef B_APPLICATION_TESTER_H +#define B_APPLICATION_TESTER_H + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- +#include "../common.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +class TBApplicationTester : public TestCase +{ + public: + TBApplicationTester() {;} + TBApplicationTester(std::string name) : TestCase(name) {;} + + void BApplication1(); + + static Test* Suite(); +}; + +#endif // B_APPLICATION_TESTER_H + diff --git a/src/tests/kits/app/bapplication/Jamfile b/src/tests/kits/app/bapplication/Jamfile new file mode 100644 index 0000000000..e2e6e3415a --- /dev/null +++ b/src/tests/kits/app/bapplication/Jamfile @@ -0,0 +1,3 @@ +SubDir OBOS_TOP src tests kits app bapplication ; + +SubInclude OBOS_TOP src tests kits app bapplication testapps ; diff --git a/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp new file mode 100644 index 0000000000..0de6ca9acc --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/BApplicationTestApp1.cpp @@ -0,0 +1,11 @@ +// BApplicationTestApp1.cpp + +#include + +int +main() +{ + BApplication app((const char*)NULL); + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/Jamfile b/src/tests/kits/app/bapplication/testapps/Jamfile new file mode 100644 index 0000000000..c90e81fcd7 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/Jamfile @@ -0,0 +1,9 @@ +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 +;