Added first BApplication test.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@541 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2002-07-31 00:36:22 +00:00
parent 1314ca6a7f
commit 8909e4ba29
12 changed files with 355 additions and 0 deletions
+2
View File
@@ -2,6 +2,7 @@
#include <TestSuiteAddon.h>
// ##### 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());
+7
View File
@@ -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 ;
@@ -0,0 +1,130 @@
// AppRunner.cpp
#include <errno.h>
#include <unistd.h>
#include <Autolock.h>
#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();
}
}
@@ -0,0 +1,34 @@
// AppRunner.h
#ifndef APP_RUNNER_H
#define APP_RUNNER_H
#include <stdio.h>
#include <DataIO.h>
#include <Locker.h>
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
@@ -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;
}
@@ -0,0 +1,9 @@
#ifndef _application_test_h_
#define _application_test_h_
class CppUnit::Test;
CppUnit::Test* ApplicationTestSuite();
#endif // _application_test_h_
@@ -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()
@@ -0,0 +1,82 @@
//------------------------------------------------------------------------------
// BApplicationTester.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 "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;
}
@@ -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
+3
View File
@@ -0,0 +1,3 @@
SubDir OBOS_TOP src tests kits app bapplication ;
SubInclude OBOS_TOP src tests kits app bapplication testapps ;
@@ -0,0 +1,11 @@
// BApplicationTestApp1.cpp
#include <Application.h>
int
main()
{
BApplication app((const char*)NULL);
return 0;
}
@@ -0,0 +1,9 @@
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
;