cardstories part 10: packaging and testing

A python package, a Debian GNU/Linux package and a twistd plugin were bundled together. The server side tests and client side tests can be run with a single command.

setup.py

A setup.py was created in conformance to the distutils python requirements. The reference documentation for each fields complements the guide. It is best understood by reading an example such as the django setup.py.
The setup.py file alone describes the binary distribution created with

python setup.py bdist

but it must be complemented with a MANIFEST.in file as explained in the source distribution documentation.

python setup.py sdist

There is no support to run tests at this time.

Debian GNU/Linux

A native package has been created, meaning the debian package is part of the source distribution and is maintained by the author of the package. The static files, including the JavaScript client are copied to /usr/share/cardstories. The database is stored in /var/cache/cardstories. The daemon is launched by an init file using the twistd plugin architecture.
The presence of the setup.py file at the root of the source tree is automatically detected by debhelper 7 and used to figure out the layout of the
Debian package.

twistd plugin

The plugin is installed in /etc/cardstories and its integration can be seen with :

$ PYTHONPATH=/etc/cardstories twistd --help
...
   cardstories        Find out a card using a sentence made up by another
                       player
...

If it needs to be run manually, the usage can be displayed with:

$ PYTHONPATH=/etc/cardstories twistd cardstories --help
Usage: twistd [options] cardstories [-h|--help] [-p|--port=] [-s|--ssl-port=] [-P|--ssl-pem=] [-d|--db=] [-v|--verbose]
Options:
  -v, --verbose     verbosity level
  -i, --interface=  Interface to which the server must be bound [default:
                    127.0.0.1]
  -p, --port=       Port on which to listen [default: 4923]
  -s, --ssl-port=   Port on which to listen for SSL
  -P, --ssl-pem=    certificate path name [default: /etc/cardstories/cert.pem]
  -d, --db=         sqlite3 game database path [default:
                    /var/cache/cardstories/cardstories.sqlite]
  -a, --auth=       authentication plugin values : basic
      --auth-db=    sqlite3 auth database path [default:
                    /var/cache/cardstories/auth.sqlite]
      --loop=       Number of ping batchs to run, -1 means forever, 0 means
                    never [default: -1]
      --static=     directory where /static files will be fetched [default:
                    /usr/share/cardstories]
      --version
      --help        Display this help and exit.

Find out a card using a sentence made up by another player

Running tests

The maintain.mk file at the root of the source tree runs the tests with

$ make -f maintain.mk check
make -C tests check
python-coverage -e
PYTHONPATH=.. python-coverage -x test_auth.py
__main__.AuthTestInit.test00_create ... [OK]
__main__.AuthTest.test00 ... [OK]

-------------------------------------------------------------------------------
Ran 2 tests in 0.326s

PASSED (successes=2)
PYTHONPATH=.. python-coverage -x test_service.py
__main__.CardstoriesServiceTestInit.test00_startService ... [OK]
__main__.CardstoriesServiceTest.test01_create ... [OK]
__main__.CardstoriesServiceTest.test02_participate ... [OK]
__main__.CardstoriesServiceTest.test03_player2game ... [OK]
__main__.CardstoriesServiceTest.test04_pick ... [OK]
__main__.CardstoriesServiceTest.test05_state_vote ... [OK]
__main__.CardstoriesServiceTest.test06_vote ... [OK]
__main__.CardstoriesServiceTest.test07_complete ... [OK]
__main__.CardstoriesServiceTest.test08_game ... [OK]
__main__.CardstoriesServiceTest.test09_invitation ... [OK]
__main__.CardstoriesServiceTest.test10_lobby ... [OK]
__main__.CardstoriesServiceTestHandle.test01_required ... [OK]
__main__.CardstoriesServiceTestHandle.test02_handle ... [OK]
__main__.CardstoriesServiceTestRun.test00_run ... [OK]

-------------------------------------------------------------------------------
Ran 14 tests in 2.926s

PASSED (successes=14)
PYTHONPATH=.. python-coverage -x test_site.py
__main__.CardstoriesSiteTest.test00_render ... [OK]
__main__.CardstoriesSiteTest.test00_render_static ... [OK]
__main__.CardstoriesSiteTest.test01_wrap_http ... [OK]
__main__.CardstoriesSiteTest.test02_wrap_http_fail ... [OK]
__main__.CardstoriesSiteTest.test03_handle ... [OK]
__main__.AGPLResourceTest.test00_render ... [OK]
__main__.AGPLResourceTest.test01_agpl ... [OK]

-------------------------------------------------------------------------------
Ran 7 tests in 0.050s

PASSED (successes=7)
PYTHONPATH=.. python-coverage -x test_tap.py
__main__.CardstoriesServerTest.test01_connect ... [OK]
__main__.CardstoriesServerTest.test02_parseOptions ... [OK]
__main__.CardstoriesServerTestSSL.test01 ... [OK]

-------------------------------------------------------------------------------
Ran 3 tests in 0.153s

PASSED (successes=3)
python-coverage -m -a -r ../cardstories/*.py
Name                      Stmts   Exec  Cover   Missing
-------------------------------------------------------
../cardstories/__init__       1      1   100%
../cardstories/auth          38     38   100%
../cardstories/service      248    240    96%   112-114, 183, 186, 252, 330, 334
../cardstories/site          71     67    94%   36, 61, 64, 108
../cardstories/tap           21     21   100%
-------------------------------------------------------
TOTAL                       379    367    96%

The client side tests are run from a web browser and should display at the bottom of the page:

158 tests of 158 passed, 0 failed.

Future direction

The lintian warnings should be addressed. An ITP should be posted. The client tests should be run server side using node.js