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:
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
;
|
||||
Reference in New Issue
Block a user