diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch) | |
tree | 67208f7c145782a7e90b123b982ca78d88cc2c87 /karm/test | |
download | tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'karm/test')
-rw-r--r-- | karm/test/Makefile.am | 18 | ||||
-rw-r--r-- | karm/test/README | 80 | ||||
-rw-r--r-- | karm/test/__httpd.py | 39 | ||||
-rwxr-xr-x | karm/test/__korg.sh | 134 | ||||
-rw-r--r-- | karm/test/__lib.sh | 79 | ||||
-rwxr-xr-x | karm/test/__webdav.pl | 57 | ||||
-rwxr-xr-x | karm/test/booktime-baddate.sh | 22 | ||||
-rwxr-xr-x | karm/test/booktime-badduration.sh | 22 | ||||
-rwxr-xr-x | karm/test/booktime-badtime.sh | 22 | ||||
-rwxr-xr-x | karm/test/booktime-baduid.sh | 22 | ||||
-rwxr-xr-x | karm/test/booktime-works.sh | 30 | ||||
-rwxr-xr-x | karm/test/bug94447.sh | 30 | ||||
-rwxr-xr-x | karm/test/delete.sh | 33 | ||||
-rw-r--r-- | karm/test/example.ics | 173 | ||||
-rw-r--r-- | karm/test/lifetest.php | 221 | ||||
-rw-r--r-- | karm/test/lockerthread.cpp | 44 | ||||
-rw-r--r-- | karm/test/lockerthread.h | 21 | ||||
-rw-r--r-- | karm/test/locking.cpp | 151 | ||||
-rwxr-xr-x | karm/test/refresh_on_change.sh | 57 | ||||
-rwxr-xr-x | karm/test/remote_storage.sh | 58 | ||||
-rw-r--r-- | karm/test/runscripts.cpp | 130 | ||||
-rw-r--r-- | karm/test/script.cpp | 115 | ||||
-rw-r--r-- | karm/test/script.h | 52 | ||||
-rwxr-xr-x | karm/test/version.sh | 24 | ||||
-rwxr-xr-x | karm/test/webdav.sh | 58 |
25 files changed, 1692 insertions, 0 deletions
diff --git a/karm/test/Makefile.am b/karm/test/Makefile.am new file mode 100644 index 000000000..7205a5995 --- /dev/null +++ b/karm/test/Makefile.am @@ -0,0 +1,18 @@ +METASOURCES = AUTO + +check_PROGRAMS = runscripts locking + +runscripts_SOURCES = script.cpp runscripts.cpp +runscripts_LDFLAGS = $(all_libraries) $(KDE_RPATH) +runscripts_LDADD = $(LIB_QT) $(LIB_KDECORE) + +locking_SOURCES = locking.cpp lockerthread.cpp +locking_LDFLAGS = $(all_libraries) $(KDE_RPATH) +locking_LDADD = $(LIB_QT) $(top_builddir)/libkcal/libkcal.la + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +INCLUDES = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/libkcal $(all_includes) + +#TESTS = runscripts locking +TESTS = locking diff --git a/karm/test/README b/karm/test/README new file mode 100644 index 000000000..31dbc8d24 --- /dev/null +++ b/karm/test/README @@ -0,0 +1,80 @@ +This directory holds automated tests for karm. + +It's in very rough shape. + + +How you start: + + (1) get and install kdepim including karm + + (2) get and install xautomation from http://hoopajoo.net/projects/xautomation.html + + (3) get and install Net::DAV::Server with CPAN + + (4) get and install Net::Virtual::Plain with CPAN + + (5) get and install File::Find::Rule::Filesys::Virtual with CPAN + + (6) start the automated tests with the command make check + + +Here are some of the issues: + + (1) The tests require KDE to be running in English. + + The automated XTests use shortcut keys to drive the app. These key + combinations are language specific. + + (2) The tests require that you "make install" first. + + The XAutomation tests and tests that use DCOP run karm from the bash + prompt. + + (3) The tests are destructive. + + If you have an already running instance of karm, the tests will kill + that instance. So you cannot, for example, record time spent running + karm automated tests. + + The tests are smart enough to use test iCalendar files. But they will + alter the karm storage settings for the ics file name. + + (4) The runscripts program does not kill scripts that never return. + + You have to monitor the progress and press Control-C if you think a + script is hung. + + (5) No attempt is made to check for installed script interpreters. + + In addition to required interpreters (Python 2.2, for example), the bash + scripts use xte, which on Debian is in the xautomation package. + + If a required library is not found, runscripts will consider this a + script failure and stop. + + (6) I have only tested this with Bash on GNU/Linux. + + (7) When a test fails, it is really hard to figure out why. There is too + much stuff mixed together on the console output, and the tests + themselves do not give much info when they fail. + +That having been said, I find it so useful that I will keep working on this so +it should get better shortly. + + +Some notes on runscripts.cpp: + + Parses this directory for script files (Python, PHP, Perl and Bash). It + identifies a script file by the extension. + + It runs any script files it finds. Within each script type, it runs the + scripts in alphabetical order. Scripts that start with a double underscore + are skipped. + + When a script fails runscripts stops. + + Script files should return a non-zero exit code to indicate a failure. + +-- +Mark Bucciarelli <mark@hubcapconsulting.com> +December 6, 2004 diff --git a/karm/test/__httpd.py b/karm/test/__httpd.py new file mode 100644 index 000000000..ba87113be --- /dev/null +++ b/karm/test/__httpd.py @@ -0,0 +1,39 @@ +'''Runs an HTTP server on port 8000 (or the first command line argument).''' + +import BaseHTTPServer +import SimpleHTTPServer +import sys +import os.path + +class MyHandler( SimpleHTTPServer.SimpleHTTPRequestHandler ): + + def do_PUT( self ): + '''Just enough to work with karm.''' + path = self.translate_path(self.path) + + rval = 200 + if not os.path.exists( path ): rval = 201 + + f = file( path, "w" ) + lines = [] + while 1: + line = self.rfile.readline() + lines.append( line ) + if line == '\r\n' or line == '\n' or line == '': + break + f.writelines( lines ) + self.send_response( rval ) + + +DEFAULT_PORT = 8000 + +if sys.argv[1:]: port = int(sys.argv[1]) +else: port = DEFAULT_PORT +server_address = ('', port) + +SimpleHTTPServer.SimpleHTTPRequestHandler.protocol_version = "HTTP/1.0" +httpd = BaseHTTPServer.HTTPServer(server_address, MyHandler ) + +sa = httpd.socket.getsockname() +print "Serving HTTP on", sa[0], "port", sa[1], "..." +httpd.serve_forever() diff --git a/karm/test/__korg.sh b/karm/test/__korg.sh new file mode 100755 index 000000000..e7fa9629f --- /dev/null +++ b/karm/test/__korg.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +# Example of how to use xautomation. +# +# Notes: +# +# - This test fails for korg, as it opens a modal dialog box, even +# after changes are saved (ref bug #94537). +# +# - The xte str command is broken (it types to fast). To be safe, +# put in characters one-by-one using the key command. Writing a +# bash function that does this for a given string would be helpful. +# +# - This script uses hardcoded English short cut keys. To make generic: +# +# 1. Get two char language code from OS (or KDE?) +# +# 2. Source bash script for language (e.g. source __shortcuts.en) +# +# 3. Call functions from that script (e.g. open_file $FILENAME) +# +# - Using killall isn't great. karm has a quit() dcop function for clean +# shutdown. Need to check if korgac or korganizer provide this interface. + + +# kill any running processes +killall korganizer +killall korgac + +# start korganizer +korganizer& + +# make sure it's done opening +sleep 10 + +# open file in korganizer. +# Note: this opens a second korg instance +xte 'keydown Alt_L' +xte 'key F' +xte 'keyup Alt_L' +xte 'key O' + +# wait for open file dialog to come up +sleep 1 + +# put focus on file name control +xte 'keydown Alt_L' +xte 'key L' +xte 'keyup Alt_L' +xte 'key ~' +xte 'key /' +xte 'key t' +xte 'key e' +xte 'key s' +xte 'key t' +xte 'key .' +xte 'key i' +xte 'key c' +xte 'key s' + +# save new storage file +xte 'keydown Alt_L' +xte 'key O' +xte 'keyup Alt_L' + +sleep 1 + +# open new to-do dialog +xte 'keydown Alt_L' +xte 'key A' +xte 'keup Alt_L' +xte 'key v' + +sleep 1 + +# set focus to title +xte 'keydown Alt_L' +xte 'key I' +xte 'keyup Alt_L' + +# type in test task name (you have to type slowly for xte) +xte 'key T' +xte 'key e' +xte 'key s' +xte 'key t' +xte 'key -' +xte 'key t' +xte 'key a' +xte 'key s' +xte 'key k' +xte 'key -' +xte 'key 1' + +sleep 1 + +# save new todo +xte 'keydown Alt_L' +xte 'key O' +xte 'keyup Alt_L' + +sleep 1 + +# save changes to file +xte 'keydown Alt_L' +xte 'key F' +xte 'keyup Alt_L' +xte 'key S' + +sleep 1 + +# Quit below fails. +# +# korg pops up a dialog that says: +# +# The calendar contains unsaved changes. +# Do you want to save them before exiting? + +# quit korganizer +xte 'keydown Control_L' +xte 'key q' +xte 'keyup Control_L' + +# quit first korganizer view +xte 'keydown Control_L' +xte 'key q' +xte 'keyup Control_L' + +sleep 1 + +killall korgac + +# 1. cleanup +rm "~/test.ics" + diff --git a/karm/test/__lib.sh b/karm/test/__lib.sh new file mode 100644 index 000000000..06fd9df62 --- /dev/null +++ b/karm/test/__lib.sh @@ -0,0 +1,79 @@ + +# Expects karm test file in $TESTFILE +# Returns dcop id in $DCOP_ID +function set_up() +{ + DCOPID=`dcop 2>/dev/null | grep karm` + + if [ -n "$DCOPID" ]; then dcop $DCOPID KarmDCOPIface quit; fi; + + if [ "x$SKIP_TESTFILE_DELETE" != "xtrue" ]; then + if [ -e "$TESTFILE" ]; then rm $TESTFILE; fi + fi + + #echo "__lib.sh - starting karm with $TESTFILE" + karm "$TESTFILE" & + + # Make sure karm is up and running + limit=10 + idx=0 + DCOPID="" + while [ "$idx" -lt "$limit" ] + do + #echo "__lib.sh: dcop 2>/dev/null | grep karm" + DCOPID=`dcop 2>/dev/null | grep karm` + if [ -n "$DCOPID" ] + then + break + else + let "idx += 1" + fi + sleep 1 + done + + # It's not enough to get the dcop id, as this is available almost + # immediately. We need to make sure karm (and fam) is done loading data. + limit=20 + idx=0 + KARM_VERSION="" + while [ "$idx" -lt "$limit" ] + do + #echo "__lib.sh: dcop $DCOPID KarmDCOPIface version 2>/dev/null" + KARM_VERSION=`dcop $DCOPID KarmDCOPIface version 2>/dev/null` + if [ -n "$KARM_VERSION" ] + then + break + else + let "idx += 1" + fi + sleep 1 + done + + if [ "x$DCOPID" = x ] + then + echo "__lib.sh set_up error: could not start karm--no dcop id." + exit 1 + else + echo "__lib.sh: DCOPID = $DCOPID, KARM_VERSION = $KARM_VERSION" + fi + + if [ "x$KARM_VERSION" = x ] + then + echo "__lib.sh set_up error: karm did not return a version string." + exit 1 + fi +} + +function test_func() +{ + echo "Yep, that works." +} + +function tear_down() +{ + if [ -n "$DCOPID" ]; then dcop "$DCOPID" KarmDCOPIface quit; fi; + + if [ "x$SKIP_TESTFILE_DELETE" != "xtrue" ]; then + if [ -e "$TESTFILE" ]; then rm "$TESTFILE"; fi + fi +} diff --git a/karm/test/__webdav.pl b/karm/test/__webdav.pl new file mode 100755 index 000000000..b09875755 --- /dev/null +++ b/karm/test/__webdav.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl -w + +# This script requires the following Perl modules: +# +# $ perl -MCPAN -e 'shell' +# cpan> install Net::DAV::Server +# cpan> install Filesys::Virtual::Plain +# cpan> install File::Find::Rule::Filesys::Virtual +# cpan> install XML::LibXML +# +# The last Perl module needs the libxml2 development libraries installed +# (the libxml2-dev package on Debian). + +use Net::DAV::Server; +use Filesys::Virtual::Plain; +use HTTP::Daemon; + +# If 1, output request and response headers +my $DEBUG=0; + +my $filesys = Filesys::Virtual::Plain->new(); +$filesys->root_path('/tmp'); +$filesys->cwd('/tmp'); +#print foreach ($filesys->list('/')); + +my $webdav = Net::DAV::Server->new(); +$webdav->filesys($filesys); + +my $d = new HTTP::Daemon + LocalAddr => 'localhost', + LocalPort => 4242, + ReuseAddr => 1 || die; +print "Please contact me at: ", $d->url, "\n"; +while (my $c = $d->accept) { + while (my $request = $c->get_request) { + if ( $DEBUG ) { + print qq|------------------------------------------------------------ +REQUEST +------------------------------------------------------------\n|; + while ( ($k,$v) = each %{$request} ) { + print " $k => $v\n"; + } + } + my $response = $webdav->run($request); + if ( $DEBUG ) { + print qq|------------------------------------------------------------ +RESPONSE +------------------------------------------------------------\n|; + while ( ($k,$v) = each %{$response} ) { + print " $k => $v\n"; + } + } + $c->send_response ($response); + } + $c->close; + undef($c); +} diff --git a/karm/test/booktime-baddate.sh b/karm/test/booktime-baddate.sh new file mode 100755 index 000000000..d89e54cb1 --- /dev/null +++ b/karm/test/booktime-baddate.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +TESTFILE="/tmp/testkarm1.ics" + +source __lib.sh + +set_up + +dcop $DCOPID KarmDCOPIface addTask Task1 2>/dev/null +TASKID=`dcop $DCOPID KarmDCOPIface taskIdFromName Task1 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface bookTime $TASKID notadate 360 2>/dev/null` + +tear_down + +EXPECTED=5 +if [ "$RVAL" == "$EXPECTED" ]; then + echo "PASS $0" + exit 0; +else + echo "FAIL $0: got /$RVAL/, expected /$EXPECTED/" + exit 1; +fi diff --git a/karm/test/booktime-badduration.sh b/karm/test/booktime-badduration.sh new file mode 100755 index 000000000..2b1e8c96b --- /dev/null +++ b/karm/test/booktime-badduration.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +TESTFILE="/tmp/testkarm1.ics" + +source __lib.sh + +set_up + +dcop $DCOPID KarmDCOPIface addTask Task1 2>/dev/null +TASKID=`dcop $DCOPID KarmDCOPIface taskIdFromName Task1 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface bookTime $TASKID 20050619 notanumber 2>/dev/null` + +tear_down + +EXPECTED=7 +if [ "$RVAL" == "$EXPECTED" ]; then + echo "PASS $0" + exit 0; +else + echo "FAIL $0: got /$RVAL/, expected /$EXPECTED/" + exit 1; +fi diff --git a/karm/test/booktime-badtime.sh b/karm/test/booktime-badtime.sh new file mode 100755 index 000000000..1bbaa3d53 --- /dev/null +++ b/karm/test/booktime-badtime.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +TESTFILE="/tmp/testkarm1.ics" + +source __lib.sh + +set_up + +dcop $DCOPID KarmDCOPIface addTask Task1 2>/dev/null +TASKID=`dcop $DCOPID KarmDCOPIface taskIdFromName Task1 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface bookTime $TASKID 20050619Tabc 360 2>/dev/null` + +tear_down + +EXPECTED=5 +if [ "$RVAL" == "$EXPECTED" ]; then + echo "PASS $0" + exit 0; +else + echo "FAIL $0: got /$RVAL/, expected /$EXPECTED/" + exit 1; +fi diff --git a/karm/test/booktime-baduid.sh b/karm/test/booktime-baduid.sh new file mode 100755 index 000000000..8cb064244 --- /dev/null +++ b/karm/test/booktime-baduid.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# First test, just check version. + +TESTFILE="/tmp/testkarm1.ics" + +source __lib.sh + +set_up + +RVAL=`dcop $DCOPID KarmDCOPIface bookTime bad-uid 20050619 360 2>/dev/null` + +tear_down + +EXPECTED=4 +if [ "$RVAL" == "$EXPECTED" ]; then + echo "PASS $0" + exit 0; +else + echo "FAIL $0: got /$RVAL/, expected /$EXPECTED/" + exit 1; +fi diff --git a/karm/test/booktime-works.sh b/karm/test/booktime-works.sh new file mode 100755 index 000000000..280e1231b --- /dev/null +++ b/karm/test/booktime-works.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +TESTFILE="/tmp/testkarm1.ics" + +source __lib.sh + +set_up + +DURATION=12 +dcop $DCOPID KarmDCOPIface addTask Task1 2>/dev/null +TASKID=`dcop $DCOPID KarmDCOPIface taskIdFromName Task1 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface bookTime $TASKID 2005-06-19 $DURATION 2>/dev/null` + +if [ "x$RVAL" != "x0" ]; then + echo "FAIL $0: got /$RVAL/, expected /$EXPECTED/" + exit 1; +fi + +RVAL=`dcop $DCOPID KarmDCOPIface totalMinutesForTaskId $TASKID 2>/dev/null` + +SKIP_TESTFILE_DELETE=true +tear_down + +if [ "x$RVAL" == "x$DURATION" ]; then + echo "PASS $0" + exit 0; +else + echo "FAIL $0: got /$RVAL/, expected /$DURATION/" + exit 1; +fi diff --git a/karm/test/bug94447.sh b/karm/test/bug94447.sh new file mode 100755 index 000000000..fa163735b --- /dev/null +++ b/karm/test/bug94447.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# Create files relative to current directory if no "/" prefix +# in file name given on command line + +exec >>check.log 2>&1 + +TESTFILE="testkarm.ics" +TESTTODO="testtodo" + +source __lib.sh + +set_up + +# make karm create the file. +dcop $DCOPID KarmDCOPIface addtodo "$TESTTODO" + +RVAL=1 +if [ -e $TESTFILE ]; then RVAL=0; fi + +tear_down + +if [ $RVAL -eq 0 ] +then + echo "PASS $0" + exit 0 +else + echo "FAIL $0" + exit 1 +fi diff --git a/karm/test/delete.sh b/karm/test/delete.sh new file mode 100755 index 000000000..78f04a7de --- /dev/null +++ b/karm/test/delete.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# check if deleting a task works + +exec >> check.log 2>&1 + +TESTFILE="/tmp/testkarm1.ics" +rm $TESTFILE + +source __lib.sh + +set_up + +# do not prompt on deleting a task +GPOD=`dcop $DCOPID KarmDCOPIface getpromptdelete 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface setpromptdelete 0 2>/dev/null` + +RVAL=`dcop $DCOPID KarmDCOPIface addTask todo1 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface addTask todo2 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface deletetodo 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface deletetodo 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface setpromptdelete $GPOD 2>/dev/null` +RVAL=`dcop $DCOPID KarmDCOPIface version 2>/dev/null` + +tear_down + +if [ "$RVAL" == "" ]; then + echo "FAIL $0: got no version." + exit 1; +else + echo "PASS $0" + exit 0; +fi diff --git a/karm/test/example.ics b/karm/test/example.ics new file mode 100644 index 000000000..8cfe93525 --- /dev/null +++ b/karm/test/example.ics @@ -0,0 +1,173 @@ +BEGIN:VCALENDAR +PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN +VERSION:2.0 +BEGIN:VTODO +DTSTAMP:20061125T204432Z +ORGANIZER;CN=root:MAILTO: +X-KDE-karm-totalSessionTime:0 +X-KDE-karm-totalTaskTime:0 +CREATED:20061118T183926Z +UID:libkcal-1156600660.458 +SEQUENCE:0 +LAST-MODIFIED:20061125T204432Z +SUMMARY:customer BÄR +CLASS:PUBLIC +PRIORITY:3 +PERCENT-COMPLETE:0 +END:VTODO + +BEGIN:VTODO +DTSTAMP:20061125T204432Z +ORGANIZER;CN=root:MAILTO: +X-KDE-karm-totalSessionTime:0 +X-KDE-karm-totalTaskTime:0 +CREATED:20061118T183934Z +UID:libkcal-1923273586.967 +SEQUENCE:0 +LAST-MODIFIED:20061125T204432Z +SUMMARY:documenting +CLASS:PUBLIC +PRIORITY:3 +RELATED-TO:libkcal-1156600660.458 +PERCENT-COMPLETE:0 +END:VTODO + +BEGIN:VTODO +DTSTAMP:20061125T204432Z +ORGANIZER;CN=root:MAILTO: +X-KDE-karm-totalSessionTime:90 +X-KDE-karm-totalTaskTime:90 +CREATED:20061118T184032Z +UID:libkcal-61950406.193 +SEQUENCE:0 +LAST-MODIFIED:20061125T204432Z +SUMMARY:analysis +CLASS:PUBLIC +PRIORITY:3 +RELATED-TO:libkcal-1156600660.458 +PERCENT-COMPLETE:0 +END:VTODO + +BEGIN:VTODO +DTSTAMP:20061125T204432Z +ORGANIZER;CN=root:MAILTO: +X-KDE-karm-totalSessionTime:184 +X-KDE-karm-totalTaskTime:184 +CREATED:20061118T184044Z +UID:libkcal-1755408865.833 +SEQUENCE:0 +LAST-MODIFIED:20061125T204432Z +SUMMARY:programming +CLASS:PUBLIC +PRIORITY:3 +RELATED-TO:libkcal-1156600660.458 +PERCENT-COMPLETE:0 +END:VTODO + +BEGIN:VTODO +DTSTAMP:20061125T204432Z +ORGANIZER;CN=root:MAILTO: +X-KDE-karm-totalSessionTime:156 +X-KDE-karm-totalTaskTime:156 +CREATED:20061118T184054Z +UID:libkcal-1177224330.526 +SEQUENCE:0 +LAST-MODIFIED:20061125T204432Z +SUMMARY:phone with mother +CLASS:PUBLIC +PRIORITY:3 +PERCENT-COMPLETE:0 +END:VTODO + +BEGIN:VEVENT +DTSTAMP:20061125T204432Z +ORGANIZER:MAILTO: +X-KDE-karm-duration:9360 +CREATED:20061118T184102Z +UID:libkcal-733807033.405 +SEQUENCE:0 +LAST-MODIFIED:20061118T184102Z +SUMMARY:phone with mother +CLASS:PUBLIC +PRIORITY:3 +CATEGORIES:KArm +RELATED-TO:libkcal-1177224330.526 +DTSTART:20061118T184054Z +DTEND:20061118T211654Z +TRANSP:OPAQUE +END:VEVENT + +BEGIN:VEVENT +DTSTAMP:20061125T204432Z +ORGANIZER:MAILTO: +X-KDE-karm-duration:5400 +CREATED:20061118T184114Z +UID:libkcal-552065854.752 +SEQUENCE:0 +LAST-MODIFIED:20061118T184114Z +SUMMARY:analysis +CLASS:PUBLIC +PRIORITY:3 +CATEGORIES:KArm +RELATED-TO:libkcal-61950406.193 +DTSTART:20061118T184032Z +DTEND:20061118T201032Z +TRANSP:OPAQUE +END:VEVENT + +BEGIN:VEVENT +DTSTAMP:20061125T204432Z +ORGANIZER:MAILTO: +X-KDE-karm-duration:10920 +CREATED:20061118T184125Z +UID:libkcal-691043213.294 +SEQUENCE:0 +LAST-MODIFIED:20061118T184125Z +SUMMARY:programming +CLASS:PUBLIC +PRIORITY:3 +CATEGORIES:KArm +RELATED-TO:libkcal-1755408865.833 +DTSTART:20061118T184044Z +DTEND:20061118T214244Z +TRANSP:OPAQUE +END:VEVENT + +BEGIN:VEVENT +DTSTAMP:20061125T204432Z +ORGANIZER:MAILTO: +X-KDE-karm-duration:2 +CREATED:20061118T183930Z +UID:libkcal-251324967.864 +SEQUENCE:0 +LAST-MODIFIED:20061118T183930Z +SUMMARY:cr +CLASS:PUBLIC +PRIORITY:3 +CATEGORIES:KArm +RELATED-TO:libkcal-1156600660.458 +DTSTART:20061118T183928Z +DTEND:20061118T183930Z +TRANSP:OPAQUE +END:VEVENT + +BEGIN:VEVENT +DTSTAMP:20061125T204432Z +ORGANIZER:MAILTO: +X-KDE-karm-duration:95 +CREATED:20061118T184306Z +UID:libkcal-729762004.89 +SEQUENCE:0 +LAST-MODIFIED:20061118T184306Z +SUMMARY:programming +CLASS:PUBLIC +PRIORITY:3 +CATEGORIES:KArm +RELATED-TO:libkcal-1755408865.833 +DTSTART:20061118T184130Z +DTEND:20061118T184305Z +TRANSP:OPAQUE +END:VEVENT + +END:VCALENDAR + diff --git a/karm/test/lifetest.php b/karm/test/lifetest.php new file mode 100644 index 000000000..7a24bd3d7 --- /dev/null +++ b/karm/test/lifetest.php @@ -0,0 +1,221 @@ +#!/usr/bin/php +<? + +// Description: +// This program starts karm and simulates keypresses to do a real life-test of karm. +// This program returns zero if all tests went ok, else an error code. +// You need a US or DE keyboard to run this. + +// for those who do not know php: +// for a tutorial about php, check out www.usegroup.de +// for a reference about php, surf to www.php.net + +// TODO +// prepare Windows-port + +function createplannerexample() +{ +$handle=fopen("/tmp/example.planner","w"); +fwrite($handle, +'<?xml version="1.0"?> +<project name="" company="" manager="" phase="" project-start="20041101T000000Z" mrproject-version="2" calendar="1"> + <properties> + <property name="cost" type="cost" owner="resource" label="Cost" description="standard cost for a resource"/> + </properties> + <phases/> + <calendars> + <day-types> + <day-type id="0" name="Working" description="Ein Vorgabe-Arbeitstag"/> + <day-type id="1" name="Nonworking" description="Ein Vorgabetag, an dem nicht gearbeitet wird"/> + <day-type id="2" name="Basis verwenden" description="Use day from base calendar"/> + </day-types> + <calendar id="1" name="Vorgabe"> + <default-week mon="0" tue="0" wed="0" thu="0" fri="0" sat="1" sun="1"/> + <overridden-day-types> + <overridden-day-type id="0"> + <interval start="0800" end="1200"/> + <interval start="1300" end="1700"/> + </overridden-day-type> + </overridden-day-types> + <days/> + </calendar> + </calendars> + <tasks> + <task id="1" name="task 1" note="" work="28800" start="20041101T000000Z" end="20041101T170000Z" percent-complete="0" priority="0" type="normal" scheduling="fixed-work"/> + <task id="2" name="task 2" note="" work="28800" start="20041101T000000Z" end="20041101T170000Z" percent-complete="0" priority="0" type="normal" scheduling="fixed-work"> + <task id="3" name="subtask 1-1" note="" work="28800" start="20041101T000000Z" end="20041101T170000Z" percent-complete="0" priority="0" type="normal" scheduling="fixed-work"/> + <task id="4" name="subtask 1-2" note="" work="28800" start="20041101T000000Z" end="20041101T170000Z" percent-complete="0" priority="0" type="normal" scheduling="fixed-work"/> + </task> + </tasks> + <resource-groups/> + <resources/> + <allocations/> +</project> +'); +fclose($handle); +}; + +function simkey($s) +// This function simulates keypresses that form the string $s, e.g. for $s==hallo, it simulates the keypress of h, then a, then l and so on. +// find a useful list of keycodes under /usr/include/X11/keysymdef.h +{ + for ($i=0; $i<strlen($s); $i++) + { + usleep(10000); # this is just for the user to see what happens + if ($s[$i]=="/") system("xte 'key KP_Divide'"); + else system("xte 'key ".$s[$i]."'"); + usleep(10000); + } +} + +function keysim($s) +// remove everything that makes you have to think twice!! +{ + simkey($s); +} + +function funkeysim($s, $count=1) +// same as keysim, but interprets $s as function key name to be used by xte and expects a $count to indicate how often key is to be pressed +{ + for ($i=1; $i<=$count; $i++) + { + usleep(10000); + $rc=exec("xte 'key $s'"); + usleep(10000); + } + return $rc; +} + +// int main() +if ($argv[1]!="--batch") +{ + echo "\nThis is lifetest.php, a program to test karm by starting it and simulating keypresses.\n"; + echo "It is intended for developers who do changes to karm's sourcecode.\n"; + echo "Before publishing these changes, they should\n"; + echo "(a) resolve all conflicts with the latest karm sourcecode (cvs up)\n"; + echo "(b) make sure the code still builds (make)\n"; + echo "(c) run automated test routines like this (make check)\n\n"; + + echo "This program simulates keypresses, so please leave the keyboard alone during the test. Please use a us or de keyboardlayout (setxkbmap us). This must be run in X environment.\n + You must have XAutomation installed to run this."; + system("xte -h 2&>/dev/null",$rc); + if ($rc==0) echo " You have.\n"; + if ($rc==127) echo " You do not have, please get it from http://hoopajoo.net/projects/xautomation.html .\n"; + echo "This program will test karm by issueing karm, so, make sure, this calls the version you want to test (make install).\n\n"; + + echo "This program will now stop unless you give the parameter --batch (confirming that you do not touch the keyboard)\n"; + + $err=""; + $exit=0; +} +else +{ + if ( system( "which xte 2> /dev/null" ) == "" ) { + echo "xte not found\n"; + exit(0); + } + switch (funkeysim("Alt_L")) + { + case 1: + $err.="this must be run in an X environment\n"; + break; + case 127: + $err.="you do not have XAutomation installed, get it from http://hoopajoo.net/projects/xautomation.html\n"; + break; + } + // the following is the same as 'if file_exist(...) unlink(...)', but atomic + @unlink ("/tmp/karmtest.ics"); + @unlink ("/tmp/example.planner"); + if ($err=="") + { + // start and wait till mainwindow is up + // the mouse can be in the way, so, move it out. This here even works with "focus strictly under mouse". + system("xte 'mousemove 1 1'"); + echo "\nStarting karm"; + $process=popen("karm --geometry 200x100+0+0 /tmp/karmtest.ics >/dev/null 2>&1", 'w'); + $rc=1; + while ($rc==1) system("dcop `dcop 2>/dev/null | grep karm` KarmDCOPIface version",$rc); + echo "mainwindow is ready"; + sleep (1); + + funkeysim("Alt_L"); + + funkeysim("Right",3); + funkeysim("Down",2); + funkeysim("Return"); + sleep (1); + funkeysim("Down",2); + funkeysim("Tab",5); + simkey("/tmp/karmtest.ics"); + sleep (1); + funkeysim("Return"); + sleep (1); + funkeysim("Return"); + sleep (1); + + # add a new task + funkeysim("Alt_L"); + funkeysim("Right",2); + funkeysim("Down"); + sleep (1); + funkeysim("Return"); + sleep (1); + simkey("example 1"); + funkeysim("Return"); + sleep (1); + + echo "\nCreating a planner project file..."; + createplannerexample(); + + # import planner project file + funkeysim("Alt_L"); + funkeysim("Down",5); + funkeysim("Right"); + funkeysim("Down"); + funkeysim("Return"); + sleep (2); + keysim("/tmp/example.planner"); + sleep (1); + funkeysim("Return"); + sleep (1); + + # export to CSV file + funkeysim("Alt_L"); + funkeysim("Down",5); + funkeysim("Right"); + funkeysim("Down",2); + funkeysim("Return"); + sleep(2); + keysim("/tmp/exporttest.csv"); + sleep(1); + funkeysim("Tab",6); + system ("xte 'keydown Alt_L'"); + system ("xte 'key m'"); + system ("xte 'keyup Alt_L'"); + sleep(1); + funkeysim("Return"); + + # send CTRL_Q + sleep (2); + echo "\nsending CTRL_Q...\n"; + system ("xte 'keydown Control_L'"); + system ("xte 'key Q'"); + system ("xte 'keyup Control_L'"); + + $content=file_get_contents("/tmp/karmtest.ics"); + $lines=explode("\n",$content); + if (!preg_match("/DTSTAMP:[0-9]{1,8}T[0-9]{1,6}Z/", $lines[4])) $err.="iCal file: wrong dtstamp"; + if ($lines[12]<>"SUMMARY:example 1") $err.="iCal file: wrong task, should be example 1, but is $lines[12]"; + if ($lines[16]<>"END:VTODO") $err.="iCal file: wrong end of vtodo"; + $content=file_get_contents("/tmp/exporttest.csv"); + $lines=explode("\n",$content); + if (!preg_match("/\"example 1\",,0[,|.]00,0[,|.]00,0[,|.]00,0[,|.]00/", $lines[0])) $err.="csv export is wrong"; + pclose($process); + if ($err == "") @unlink ("/tmp/karmtest.ics"); + @unlink ("/tmp/example.planner"); + if ($err == "") @unlink ("/tmp/exporttest.csv"); + } +} + echo $err; + if ($err!="") exit(1); +?>
\ No newline at end of file diff --git a/karm/test/lockerthread.cpp b/karm/test/lockerthread.cpp new file mode 100644 index 000000000..6ec6e7ba2 --- /dev/null +++ b/karm/test/lockerthread.cpp @@ -0,0 +1,44 @@ +#include <qthread.h> +#include <qstring.h> + +#include <resourcecalendar.h> +#include <resourcelocal.h> +#include <calendarresources.h> + +#include "lockerthread.h" + +LockerThread::LockerThread( const QString &icsfile ) +{ + m_gotlock = false; + m_icsfile = icsfile; +} + +/* +void LockerThread::setIcsFile( const QString &filename ) +{ + m_icsfile = filename; +} +*/ + +void LockerThread::run() +{ + KCal::CalendarResources *calendars = 0; + KCal::ResourceCalendar *calendar = 0; + KCal::CalendarResources::Ticket *lock = 0; + + calendars = new KCal::CalendarResources( QString::fromLatin1( "UTC" ) ); + calendar = new KCal::ResourceLocal( m_icsfile ); + lock = calendars->requestSaveTicket( calendar ); + if ( lock ) + { + m_gotlock = true; + calendars->releaseSaveTicket( lock ); + } + else + { + m_gotlock = false; + } + + delete calendar; + delete calendars; +} diff --git a/karm/test/lockerthread.h b/karm/test/lockerthread.h new file mode 100644 index 000000000..d40f234ad --- /dev/null +++ b/karm/test/lockerthread.h @@ -0,0 +1,21 @@ +#include <qthread.h> + +class QString; + +/** + * Attempt to open and lock a calendar resource in a seperate thread. + * + * Result of attempt returned by gotlock(). + */ +class LockerThread : public QThread +{ + public: + LockerThread( const QString &filename ); + //void setIcsFile( const QString &filename ); + void run(); + bool gotlock() const { return m_gotlock; }; + + private: + QString m_icsfile; + bool m_gotlock; +}; diff --git a/karm/test/locking.cpp b/karm/test/locking.cpp new file mode 100644 index 000000000..49c7637d3 --- /dev/null +++ b/karm/test/locking.cpp @@ -0,0 +1,151 @@ +#include <assert.h> + +#include <qstring.h> +#include <qfile.h> +#include <qdir.h> +#include <kcmdlineargs.h> +#include <kapplication.h> + +#include <resourcecalendar.h> +#include <resourcelocal.h> +#include <calendarresources.h> + +#include "lockerthread.h" + +const QString icalfilename = "karmtest.ics"; + +// If one thread has the file is locked, the other cannot get the lock. +short test1() +{ + short rval = 0; + + KCal::CalendarResources *calendars = 0; + KCal::ResourceCalendar *calendar = 0; + KCal::CalendarResources::Ticket *lock = 0; + + calendars = new KCal::CalendarResources( QString::fromLatin1( "UTC" ) ); + calendar = new KCal::ResourceLocal( icalfilename ); + lock = calendars->requestSaveTicket( calendar ); + + if ( !lock ) + { + kdDebug( 5970 ) << "test1(): failed to lock " << icalfilename << endl; + rval = 1; + } + + if ( !rval ) + { + LockerThread thread( icalfilename ); + thread.run(); + if ( thread.gotlock() ) + { + kdDebug( 5970 ) << "test1(): second thread was able to lock " << icalfilename << endl; + rval = 1; + } + } + + // This frees the lock memory. + calendars->releaseSaveTicket( lock ); + + delete calendar; + delete calendars; + + return rval; +} + +// First thread opens but doesn't lock, second should get lock. +short test2() +{ + short rval = 0; + + KCal::CalendarResources *calendars = 0; + KCal::ResourceCalendar *calendar = 0; + KCal::CalendarResources::Ticket *lock = 0; + + calendars = new KCal::CalendarResources( QString::fromLatin1( "UTC" ) ); + calendar = new KCal::ResourceLocal( icalfilename ); + + LockerThread thread( icalfilename ); + thread.run(); + if ( !thread.gotlock() ) + { + kdDebug(5970) << "test2(): second thread was not able to lock " << icalfilename << endl; + rval = 1; + } + + delete calendar; + delete calendars; + + return rval; +} + +// First thread locks, then unlocks--second should get lock. +short test3() +{ + short rval = 0; + + KCal::CalendarResources *calendars = 0; + KCal::ResourceCalendar *calendar = 0; + KCal::CalendarResources::Ticket *lock = 0; + + calendars = new KCal::CalendarResources( QString::fromLatin1( "UTC" ) ); + calendar = new KCal::ResourceLocal( icalfilename ); + + // lock then unlock + lock = calendars->requestSaveTicket( calendar ); + if ( !lock ) + { + kdDebug( 5970 ) << "test1(): failed to lock " << icalfilename << endl; + rval = 1; + } + calendars->releaseSaveTicket( lock ); + + // second thread should get lock + if ( !rval ) + { + LockerThread thread( icalfilename ); + thread.run(); + if ( !thread.gotlock() ) + { + kdDebug( 5970 ) << "test1(): second thread was not able to lock " << icalfilename << endl; + rval = 1; + } + } + + + delete calendar; + delete calendars; + + return rval; +} + +// TODO: +// If one thread changes the file, the other is notified. +// What happens if we lock one incident and try to change another? + +int main( int argc, char *argv[] ) +{ + short rval = 0; + + // Use another directory than the real one, just to keep things clean + // KDEHOME needs to be writable though, for a ksycoca database + // FIXME: Delete this directory when done with test. + setenv( "KDEHOME", QFile::encodeName( QDir::homeDirPath() + "/.kde-testresource" ), true ); + + // Copied from Till's test in libkcal. Not sure what this is for. + setenv( "KDE_FORK_SLAVES", "yes", true ); // simpler, for the final cleanup + + // Copied from Till's test in libkcal. Not sure what this is for. + KApplication::disableAutoDcopRegistration(); + + KCmdLineArgs::init(argc,argv,"testresourcelocking", 0, 0, 0, 0); + + KApplication app( false, false ); + + // basic libkcal locking stuff + if ( !rval ) rval = test1(); + if ( !rval ) rval = test2(); + if ( !rval ) rval = test3(); + + return rval; +} diff --git a/karm/test/refresh_on_change.sh b/karm/test/refresh_on_change.sh new file mode 100755 index 000000000..6253c63b6 --- /dev/null +++ b/karm/test/refresh_on_change.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# I cannot get this test to work reliably! +# I suspect the culprit is FAM. +# -- Mark + +exec >>check.log 2>&1 + +source __lib.sh + +TESTFILE="/tmp/testkarm.ics" + +set_up + +TODO_NAME=$0 +TODO_UID=abc-123 +TODO_TIME=`date +%Y%m%dT%H%M%SZ` + +sleep 1 # make sure kdirstat can recognize the change in last change date + +cat >> $TESTFILE << endl +BEGIN:VCALENDAR +PRODID:-//K Desktop Environment//NONSGML KArm Test Scripts//EN +VERSION:2.0 + +BEGIN:VTODO +DTSTAMP:$TODO_TIME +ORGANIZER;CN=Anonymous:MAILTO:nobody@nowhere +CREATED:$TODO_TIME +UID:$TODO_UID +SEQUENCE:0 +LAST-MODIFIED:$TODO_TIME +SUMMARY:$TODO_NAME +CLASS:PUBLIC +PRIORITY:5 +PERCENT-COMPLETE:0 +END:VTODO + +END:VCALENDAR +endl + +# wait so FAM and KDirWatcher tell karm and karm refreshes view +sleep 2 + +RVAL=`dcop $DCOPID KarmDCOPIface taskIdFromName $TODO_NAME` +#echo "RVAL = $RVAL" + +tear_down + +# check that todo was found +if [ "$RVAL" == "$TODO_UID" ]; then + echo "PASS $0" + exit 0; +else + echo "FAIL $0: got /$RVAL/, expected /$TODO_UID/" + exit 1; +fi diff --git a/karm/test/remote_storage.sh b/karm/test/remote_storage.sh new file mode 100755 index 000000000..a4335b6c1 --- /dev/null +++ b/karm/test/remote_storage.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# Karm can read and write to an FTP server for storage file. + +exec >>check.log 2>&1 + +PORT=8000 +TESTFILE="http://localhost:$PORT/testkarm.ics" +TESTFILE_LOCAL="testkarm.ics" +TESTTODO="testtodo" + +# Start with clean environment +# If runscripts sees output on stderr, it thinks script failed. +DCOPID=`dcop | grep karm 2>/dev/null` +if [ -n $DCOPID ]; then dcop $DCOPID KarmDCOPIface quit; fi; +if [ -e $TESTFILE_LOCAL ]; then rm $TESTFILE_LOCAL; fi + +# if the file does not exist, kresources pops up a modal dialog box +# telling us that a file does not exist. + +touch $TESTFILE_LOCAL + +python __httpd.py $PORT & + +sleep 2 + +HTTPD_PID=`ps -C "python __httpd.py" -o pid=` + +karm $TESTFILE & + +sleep 2 + +DCOPID=`dcop | grep karm` + +# karm does not write file until data is saved. + +echo "DEBUG: dcop $DCOPID KarmDCOPIface addtodo \"$TESTTODO\"" +dcop $DCOPID KarmDCOPIface addtodo "$TESTTODO" + +sleep 1 + +RVAL=1 +if [ -e $TESTFILE_LOCAL ]; then RVAL=0; fi + +# clean up +if [ -n $DCOPID ]; then dcop $DCOPID KarmDCOPIface quit; fi; +if [ -e $TESTFILE_LOCAL ]; then rm $TESTFILE_LOCAL; fi +if [ -n $HTTPD_PID ]; then kill $HTTPD_PID; fi + +# return 0 on success, 1 on failure +if [ $RVAL -eq 0 ] +then + echo "PASS $0" + exit 0 +else + echo "FAIL $0" + exit 1 +fi diff --git a/karm/test/runscripts.cpp b/karm/test/runscripts.cpp new file mode 100644 index 000000000..aa5449541 --- /dev/null +++ b/karm/test/runscripts.cpp @@ -0,0 +1,130 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Mark Bucciarelli <mark@hubcapconsulting.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <kdebug.h> +#include <qdir.h> +#include <qfile.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qtextstream.h> + +#include "script.h" + +static QString srcdir(); +static int runscripts +( const QString &interpreter, const QString &extension, const QString &path ); + +const QString dots = ".................................................."; +const QString not_a_test_filename_prefix = "__"; + +// Read srcdir from Makefile (for builddir != srcdir). +QString srcdir() +{ + bool found = false; + QString dir; + + QFile file( "Makefile" ); + if ( !file.open( IO_ReadOnly | IO_Translate ) ) return ""; + + QTextStream in( &file ); + QString line; + while ( !found && !in.atEnd() ) + { + line = in.readLine(); + if ( line.startsWith( "srcdir = " ) ) + { + dir = line.mid( 9 ); + found = true; + } + } + + if ( !found ) dir = ""; + + return dir; +} + +int runscripts +( const QString &interpreter, const QString &extension, const QString &path ) +{ + int rval = 0; + int oneBadApple = 0; + QStringList files; + + QDir dir( path ); + + Script* s = new Script( dir ); + + dir.setNameFilter( extension ); + dir.setFilter( QDir::Files ); + dir.setSorting( QDir::Name | QDir::IgnoreCase ); + const QFileInfoList *list = dir.entryInfoList(); + QFileInfoListIterator it( *list ); + QFileInfo *fi; + while ( !rval && ( fi = it.current() ) != 0 ) + { + // Don't run scripts that are shared routines. + if ( ! fi->fileName().startsWith( not_a_test_filename_prefix ) ) + { + s->addArgument( interpreter ); + s->addArgument( path + QDir::separator() + fi->fileName().latin1() ); + + // Thorsten's xautomation tests run with user interaction by default. + if ( interpreter == "sh" ) s->addArgument( "--batch" ); + if ( interpreter == "php" ) s->addArgument( "--batch" ); + + rval = s->run(); + + kdDebug() << "runscripts: " << fi->fileName() + << " " << dots.left( dots.length() - fi->fileName().length() ) + << " " << ( ! rval ? "PASS" : "FAIL" ) << endl; + + // Don't abort if one test files--run them all + if ( rval ) + { + oneBadApple = 1; + rval = 0; + } + + delete s; + s = new Script( dir ); + } + ++it; + } + delete s; + s = 0; + + return oneBadApple; +} + +int main( int, char** ) +{ + int rval = 0; + + QString path = srcdir(); + + if ( !rval ) rval = runscripts( "python", "*.py *.Py *.PY *.pY", path ); + + if ( !rval ) rval = runscripts( "sh", "*.sh *.Sh *.SH *.sH", path ); + + if ( !rval ) rval = runscripts( "perl", "*.pl *.Pl *.PL *.pL", path ); + + if ( !rval ) rval = runscripts( "php", "*.php *.php3 *.php4 *.php5", path ); + + return rval; +} diff --git a/karm/test/script.cpp b/karm/test/script.cpp new file mode 100644 index 000000000..37fe058d3 --- /dev/null +++ b/karm/test/script.cpp @@ -0,0 +1,115 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Anders Lund <anders@alweb.dk> + Copyright (C) 2004 Mark Bucciarelli <mark@hubcapconsulting.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include <qdir.h> +#include <qprocess.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qtimer.h> + +#include <kdebug.h> + +#include "script.h" + +/* + n.b. Do not use kdDebug statements in this file. + + With qt-copy 3_3_BRANCH, they cause a Valgrind error. + Ref: KDE bug #95237. +*/ + +// Wait for terminate() attempt to return before using kill() +// kill() doesn't let script interpreter try to clean up. +const int NICE_KILL_TIMEOUT_IN_SECS = 5; + +Script::Script( const QDir& workingDirectory ) +{ + m_status = 0; + m_stderr = false; + m_timeoutInSeconds = 5; + + m_proc = new QProcess( this ); + m_proc->setWorkingDirectory( workingDirectory ); + + connect ( m_proc, SIGNAL( readyReadStdout() ), + this , SLOT ( stdout() ) + ); + connect ( m_proc, SIGNAL( readyReadStderr() ), + this , SLOT ( stderr() ) + ); + connect ( m_proc, SIGNAL( processExited() ), + this , SLOT ( exit() ) + ); +} + +Script::~Script() +{ + delete m_proc; + m_proc = 0; +} + +void Script::addArgument( const QString &arg ) +{ + m_proc->addArgument( arg ); +} + +void Script::setTimeout( int seconds ) +{ + if ( seconds <= 0 ) return; + m_timeoutInSeconds = seconds; +} + +int Script::run() +{ + m_proc->start(); + // This didn't work. But Ctrl-C does. :P + //QTimer::singleShot( m_timeoutInSeconds * 1000, m_proc, SLOT( kill() ) ); + //while ( ! m_proc->normalExit() ); + while ( m_proc->isRunning() ); + return m_status; +} + +void Script::terminate() +{ + // These both trigger processExited, so exit() will run. + m_proc->tryTerminate(); + QTimer::singleShot( NICE_KILL_TIMEOUT_IN_SECS*1000, m_proc, SLOT( kill() ) ); +} + +void Script::exit() +{ + m_status = m_proc->exitStatus(); + delete m_proc; + m_proc = 0; +} + +void Script::stderr() +{ + // Treat any output to std err as a script failure + m_status = 1; + QString data = QString( m_proc->readStderr() ); + m_stderr= true; +} + +void Script::stdout() +{ + QString data = QString( m_proc->readStdout() ); +} + +#include "script.moc" diff --git a/karm/test/script.h b/karm/test/script.h new file mode 100644 index 000000000..f5ae1e227 --- /dev/null +++ b/karm/test/script.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Mark Bucciarelli <mark@hubcapconsulting.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _script_h_ +#define _script_h_ + +//#include <qvariant.h> +#include <qobject.h> + +class QDir; +class QProcess; +class QString; +class QStringList; + +class Script : public QObject +{ + Q_OBJECT +public: + Script( const QDir& workingDirectory ); + virtual ~Script(); + void addArgument( const QString &arg ); + void setTimeout( int seconds ); + int run(); +private slots: + void exit(); + void stderr(); + void stdout(); + void terminate(); +private: + QProcess *m_proc; + int m_status; + bool m_stderr; + int m_timeoutInSeconds; +}; + +#endif // _script_h_ diff --git a/karm/test/version.sh b/karm/test/version.sh new file mode 100755 index 000000000..64fbc8fb0 --- /dev/null +++ b/karm/test/version.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# First test, just check version. + +exec >>check.log 2>&1 + +TESTFILE="/tmp/testkarm1.ics" +VERSION="1.6.0" + +source __lib.sh + +set_up + +RVAL=`dcop $DCOPID KarmDCOPIface version 2>/dev/null` + +tear_down + +if [ "$RVAL" == "$VERSION" ]; then + echo "PASS $0" + exit 0; +else + echo "FAIL $0: got /$RVAL/, expected /$VERSION/" + exit 1; +fi diff --git a/karm/test/webdav.sh b/karm/test/webdav.sh new file mode 100755 index 000000000..8d51db92c --- /dev/null +++ b/karm/test/webdav.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# Add a todo to an iCal file stored on a webdav server. + +exec >>check.log 2>&1 + +source __lib.sh + +# check for required perl stuff +perl -e "use Net::DAV::Server;" > /dev/null 2>&1 +if ! [ $? = 0 ]; then + echo "PASS" + exit 0 +fi + +# Start webdav server +perl __webdav.pl & +sleep 2 +WEBDAV_PID=`ps -C "perl __webdav.pl" -o pid=` + +# Start karm +TESTFILE="http://localhost:4242/testkarm.ics" +TESTFILE_LOCAL="/tmp/testkarm.ics" +TESTTODO="testtodo" +SKIP_TESTFILE_DELETE=true +# Need this or karm complains there is no file +rm -f $TESTFILE_LOCAL +touch $TESTFILE_LOCAL +set_up +#wait till download is ready +sleep 3 + +# add a todo +dcop $DCOPID KarmDCOPIface addTask "$TESTTODO" +sleep 1 +dcop $DCOPID KarmDCOPIface save + +sleep 1 + +if grep $TESTTODO $TESTFILE_LOCAL + then RVAL=0 + else RVAL=1 +fi + +# clean up +tear_down +#if [ -e $TESTFILE_LOCAL ]; then rm $TESTFILE_LOCAL; fi +if [ -n $WEBDAV_PID ]; then kill $WEBDAV_PID; fi + +# return 0 on success, 1 on failure +if [ $RVAL -eq 0 ] +then + echo "PASS $0" + exit 0 +else + echo "FAIL $0" + exit 1 +fi |