--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MANIFEST.in Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,10 @@
+include *.py
+include ChangeLog
+
+recursive-include views *.py
+recursive-include entities *.py
+recursive-include sobjects *.py
+recursive-include schema Include *.py *.sql.postgres
+recursive-include data external_resources *.gif *.png *.css *.ico *.js
+recursive-include i18n *.pot *.po
+recursive-include migration *.sql *.py depends.map
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/__init__.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,4 @@
+"""cubicweb-apycot application package
+
+store apycot data and extract reports from them
+"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/__pkginfo__.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,55 @@
+# pylint: disable-msg=W0622
+"""cubicweb-apycot application packaging information"""
+
+distname = 'cubicweb-apycot'
+
+numversion = (0, 1, 0)
+version = '.'.join(str(num) for num in numversion)
+
+license = 'LCL'
+copyright = '''Copyright (c) 2008 LOGILAB S.A. (Paris, FRANCE).
+http://www.logilab.fr/ -- mailto:contact@logilab.fr'''
+
+author = 'Logilab'
+author_email = 'contact@logilab.fr'
+
+short_desc = 'store apycot data and extract reports from them'
+long_desc = '''store apycot data and extract reports from them'''
+
+from os import listdir as _listdir
+from os.path import join, isdir
+
+web = ''
+
+pyversions = ['2.4']
+
+#from cubicweb.devtools.pkginfo import get_distutils_datafiles
+CUBES_DIR = join('share', 'cubicweb', 'cubes')
+THIS_CUBE_DIR = join(CUBES_DIR, 'apycot')
+
+def listdir(dirpath):
+ return [join(dirpath, fname) for fname in _listdir(dirpath)
+ if fname[0] != '.' and not fname.endswith('.pyc')
+ and not fname.endswith('~')]
+
+from glob import glob
+try:
+ data_files = [
+ # common files
+ [THIS_CUBE_DIR, [fname for fname in glob('*.py') if fname != 'setup.py']],
+ ]
+
+ # check for possible extended cube layout
+ for dirname in ('entities', 'views', 'sobjects', 'schema', 'data', 'i18n', 'migration'):
+ if isdir(dirname):
+ data_files.append([join(THIS_CUBE_DIR, dirname), listdir(dirname)])
+ # Note: here, you'll need to add subdirectories if you want
+ # them to be included in the debian package
+except OSError:
+ # we are in an installed directory
+ pass
+
+
+cube_eid = None # <=== FIXME if you need direct bug-subscription
+__use__ = ()
+__recommend__ = ('jpl',)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/data/cubes.apycot.css Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,235 @@
+/* sample css file for APyCoT HTML reports
+ *
+ * Copyright (c) 2003-2004 LOGILAB S.A. (Paris, FRANCE).
+ * http://www.logilab.fr/ -- mailto:contact@logilab.fr
+ */
+
+/* old report style css, for backward compat *********************************/
+
+/* h1 { */
+/* text-align : center; */
+/* border-bottom: 2px solid lightgrey; */
+/* } */
+
+/* h2 { */
+/* text-align : left; */
+/* background-color : lightgray; */
+/* } */
+
+/* h3 { */
+/* text-align : center; */
+/* border-top: 1px solid lightgrey; */
+/* } */
+
+/* h2 a, h3 a { */
+/* text-decoration : none; */
+/* } */
+
+.summary {
+ margin-bottom: 2em;
+}
+.summary td {
+ padding-left: 2em;
+}
+.summary a {
+ text-decoration: underline;
+ color: black;
+/* line-height: 0.5em; */
+/* margin-bottom: 1em; */
+/* margin-top: 0; */
+/* list-style-type: decimal; */
+}
+
+/* .summary ul { */
+/* list-style-type: lower-alpha; */
+/* } */
+
+/* .summary a{ */
+/* text-decoration: none; */
+/* } */
+
+/* div.check { */
+/* margin-top : 2em; */
+/* } */
+
+/* div.test { */
+/* margin-top : 1em; */
+/* } */
+
+/* a { */
+/* color : black; */
+/* } */
+
+/* table.toplinks { */
+/* text-align : center; */
+/* width : 100%; */
+/* } */
+/* table.result { */
+/* width : 100%; */
+/* margin-top : 5px; */
+/* cell-spacing : 0; */
+/* } */
+
+/* table.result th { */
+/* text-align : left; */
+/* } */
+
+/* table.info tr th { */
+/* text-align : left; */
+/* } */
+
+/* table.info tr td { */
+/* font-style: italic; */
+/* padding-left : 1em; */
+/* } */
+
+/* table.raw tr th { */
+/* text-align : left; */
+/* } */
+
+/* tr.odd { */
+/* background-color : 0EFEFEF; */
+/* } */
+
+/* tr.even { */
+/* } */
+
+/* td, th { */
+/* vertical-align : top; */
+/* } */
+
+.status_success, .status_success a, .status_success em {
+ text-align : justify;
+ text-decoration : none;
+ color : green;
+}
+
+.status_partial, .status_partial a, .status_partial em {
+ text-align : justify;
+ text-decoration : none;
+ color : orange;
+}
+
+.status_failure, .status_failure a, .status_failure em {
+ text-align : justify;
+ text-decoration : none;
+ color : red;
+ font-weight: bold;
+}
+
+.status_error, .status_error a, .status_error em {
+ text-align : justify;
+ text-decoration : none;
+ color : blue;
+ font-weight: bold;
+}
+
+.status_killed, .status_killed a, .status_killed em {
+ text-align : justify;
+ text-decoration : none;
+ color : blue;
+ font-weight: bold;
+}
+
+.status_skipped, .status_skipped a, .status_skipped em {
+ text-align : justify;
+ text-decoration : none;
+ color : rgb(195, 176, 145);
+ font-weight: bold;
+}
+
+.status_missing, .status_missing a, .status_missing em {
+ text-align : justify;
+ text-decoration : none;
+ color : purple ;
+ font-weight: bold;
+}
+
+.status_nodata, .status_nodata a, .status_nodata em {
+ text-align : justify;
+ text-decoration : none;
+ color : #0095B6 ;
+ font-weight: bold;
+}
+
+/* .active, .active a, .active em { */
+/* text-align : justify; */
+/* text-decoration : none; */
+/* color : green; */
+/* } */
+
+/* .sleep, .sleep a, .sleep em { */
+/* text-align : justify; */
+/* text-decoration : none; */
+/* } */
+
+/* .path, .line, .severity { */
+/* font-style: italic; */
+/* } */
+
+/* .msg { */
+/* width : 100%; */
+/* text-align : justify; */
+/* } */
+
+/* pre { */
+/* margin-top: 0.1em; */
+/* margin-bottom: 0.2em; */
+/* } */
+
+/* td a { */
+/* } */
+
+/* .msg, .line, .severity { */
+/* } */
+
+/* .testname { */
+/* width : 100%; */
+/* text-align : left; */
+/* text-decoration: none; */
+/* text-transform : uppercase; */
+/* font-weight: bold; */
+/* } */
+
+
+/* .testinfo { */
+/* float: right; */
+/* text-decoration: none; */
+/* font-style: italic; */
+/* white-space: nowrap; */
+/* font-size: 70%; */
+/* } */
+
+/* .checkname { */
+/* text-align : justify; */
+/* text-decoration : none; */
+/* } */
+
+/* .sep { */
+/* border-top: 2px solid lightgrey; */
+/* } */
+
+/* /\* new report style css ******************************************************\/ */
+
+/* div.navlinks { */
+/* width : 100%; */
+/* text-align : center; */
+/* } */
+
+/* div.navlinks a { */
+/* color : blue; */
+/* text-decoration : none; */
+/* margin-left: 1em; */
+/* margin-right: 1em; */
+/* } */
+
+/* table.field { */
+/* border: 1px solid grey; */
+/* margin-top: 1em; */
+/* margin-bottom: 1em; */
+/* font-size: 80%; */
+/* } */
+
+/* th { */
+/* background-color : #DDDDDD; */
+/* } */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/data/cubes.apycot.js Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,1 @@
+// This contains template-specific javascript
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/changelog Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,6 @@
+cubicweb-apycot (0.1.0-1) unstable; urgency=low
+
+ * initial release
+
+ --
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/compat Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,1 @@
+5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/control Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,19 @@
+Source: cubicweb-apycot
+Section: web
+Priority: optional
+Maintainer: Logilab Packaging Team <contact@logilab.fr>
+Uploaders: Sylvain Thenault <sylvain.thenault@logilab.fr>
+Build-Depends: debhelper (>= 5.0.37.1), python (>=2.4), python-dev (>=2.4)
+Standards-Version: 3.8.0
+
+
+Package: cubicweb-apycot
+Architecture: all
+Depends: cubicweb-common (>= 2.99.1)
+Description: store apycot data and extract reports from them
+ CubicWeb is a semantic web application framework.
+ .
+ store apycot data and extract reports from them
+ .
+ This package will install all the components you need to run the
+ cubicweb-apycot application (cube :)..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/copyright Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,14 @@
+This package was debianized by Logilab <contact@logilab.fr>
+
+Upstream Author:
+
+ Logilab <contact@logilab.fr>
+
+Copyright:
+
+Copyright (c) 2008 LOGILAB S.A. (Paris, FRANCE).
+http://www.logilab.fr/ -- mailto:contact@logilab.fr
+
+Logilab Closed source License. This code is *NOT* open-source. Usage of this
+code is subject to a licence agreement. If you want to use it, you should
+contact logilab's sales service at commercial@logilab.fr .
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/cubicweb-apycot.prerm Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,27 @@
+#!/bin/sh -e
+
+delete_pyo_pyc () {
+ find /usr/share/cubicweb/cubes/apycot -name "*.pyc" | xargs rm -f
+ find /usr/share/cubicweb/cubes/apycot -name "*.pyo" | xargs rm -f
+}
+
+
+case "$1" in
+ failed-upgrade|abort-install|abort-upgrade|disappear)
+ ;;
+ upgrade)
+ delete_pyo_pyc
+ ;;
+ remove)
+ delete_pyo_pyc
+ ;;
+ purge)
+ ;;
+
+ *)
+ echo "postrm called with unknown argument \`$1'" >&2
+ exit 1
+
+esac
+
+#DEBHELPER#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/rules Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,51 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+build: build-stamp
+build-stamp:
+ dh_testdir
+ python setup.py -q build
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+ rm -rf build
+ find . -name "*.pyc" | xargs rm -f
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs -i
+ python setup.py -q install --no-compile --prefix=debian/cubicweb-apycot/usr/
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+ dh_testdir
+ dh_testroot
+ dh_install -i
+ dh_installchangelogs -i
+ dh_installexamples -i
+ dh_installdocs -i
+ dh_installman -i
+ dh_link -i
+ dh_compress -i -X.py -X.ini -X.xml -Xtest
+ dh_fixperms -i
+ dh_installdeb -i
+ dh_gencontrol -i
+ dh_md5sums -i
+ dh_builddeb -i
+
+
+# Build architecture-dependent files here.
+binary-arch:
+
+binary: binary-indep
+.PHONY: build clean binary-arch binary-indep binary
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/entities.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,97 @@
+"""this contains the cube-specific entities' classes
+
+:organization: Logilab
+:copyright: 2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+:license: General Public License version 2 - http://www.gnu.org/licenses
+"""
+__docformat__ = "restructuredtext en"
+
+from logilab.common.textutils import TIME_UNITS, BYTE_UNITS, apply_units, get_csv
+
+from cubicweb.entities import AnyEntity
+
+def text_to_dict(text):
+ res = {}
+ if not text:
+ return res
+ for line in text.splitlines():
+ line = line.strip()
+ if line:
+ key, value = line.split('=', 1)
+ res[key.strip()] = value.strip()
+ return res
+
+
+class ProjectApycotConfig(AnyEntity):
+ id = 'ProjectApycotConfig'
+ widgets = {'vcs_repository': 'StringWidget',
+ 'vcs_path': 'StringWidget',
+ 'checks': 'StringWidget',
+ }
+
+ @property
+ def environment(self):
+ return text_to_dict(self.check_environment)
+
+ @property
+ def testconfig(self):
+ config = text_to_dict(self.check_config)
+ for option in ('max-cpu-time', 'max-reprieve', 'max-time'):
+ if option in config:
+ config[option] = apply_units(config[option], TIME_UNITS)
+ if 'max-memory' in config:
+ config['max-memory'] = apply_units(config['max-memory'], BYTE_UNITS)
+ return config
+
+ @property
+ def preprocessors(self):
+ return text_to_dict(self.check_preprocessors)
+
+ @property
+ def repository_def(self):
+ return {
+ 'repository_type': self.vcs_repository_type,
+ 'repository': self.vcs_repository,
+ 'path': self.vcs_path,
+ 'tag': self.vcs_tag,
+ # view_url / view_root
+ }
+
+ @property
+ def default_checks(self):
+ return get_csv(self.checks)
+
+ def repository(self):
+ from apycotbot.repositories import get_repository
+ return get_repository(self.repository_def)
+
+ def dependencies(self, _done=None):
+ if _done is None:
+ _done = set()
+ _done.add(self.eid)
+ result = []
+ for pac in self.needs_checkout:
+ if pac.eid in _done:
+ continue
+ result.append(pac)
+ result += pac.dependencies(_done)
+ return result
+
+ def preprocessor_fact(self, pptype):
+ from apycotbot import get_registered
+ try:
+ return get_registered('preprocessor', self.preprocessors[pptype])
+ except KeyError:
+ return None
+
+class ApycotExecution(AnyEntity):
+ id = 'ApycotExecution'
+ @property
+ def apycot_config(self):
+ return self.using_config[0]
+
+ def dc_title(self):
+ return self.req._('Execution for config %(config)s on %(date)s') % {
+ 'config': self.apycot_config.name,
+ 'date': self.format_date(self.starttime, time=True)}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/en.po Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,7 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/fr.po Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,13 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: 2.0\n"
+"POT-Creation-Date: 2006-01-12 17:35+CET\n"
+"PO-Revision-Date: 2008-02-15 12:55+0100\n"
+"Last-Translator: Logilab\n"
+"Language-Team: French <devel@logilab.fr.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/migration/postcreate.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,2 @@
+# postcreate script. You could setup a workflow here for example
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/schema.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,88 @@
+"""apycot cube's specific schema
+
+:organization: Logilab
+:copyright: 2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+"""
+__docformat__ = "restructuredtext en"
+
+
+class ProjectApycotConfig(EntityType):
+ """apycot configuration to register a project branch to test"""
+ name = String(required=True, unique=True, maxsize=128,
+ description='name for this configuration')
+ vcs_repository_type = String(required=True,
+ vocabulary=(u'hg', u'svn', u'cvs', u'fs'),
+ description='kind of version control system (vcs): mercurial, subversion, cvs, file system (eg no version control)')
+ vcs_repository = String(required=True,
+ description='path or url to the vcs repository containing the project')
+ vcs_path = String(description='relative path to the project into the repository')
+ vcs_tag = String(description='vcs tag or branch to use for test\'s checkout', maxsize=200)
+
+ checks = String(description=_('comma separated list of checks to execute by default for this project'))
+ check_preprocessors = String(description=_('preprocessors to use for this project for install, debian, build_doc... (one per line)'))
+ check_environment = String(description=_('environment variables to be set in the check process environment (one per line)'))
+ check_config = String(description=_('preprocessor/checker options (one per line)'))
+
+ needs_checkout = SubjectRelation('ProjectApycotConfig',
+ description=_('project\'s dependencies that should be installed from their repository during checks requiring installtion'))
+ # XXX groups
+
+class ApycotExecution(EntityType):
+ starttime = Datetime(required=True)
+ endtime = Datetime()
+ using_config = SubjectRelation('ProjectApycotConfig', cardinality='1*', composite='object')
+
+class CheckResult(EntityType):
+ """group results of execution of a specific test on a project"""
+ # add: apycotbot
+ name = String(required=True, maxsize=128, description='check name')
+ status = String(required=True,
+ vocabulary=(u'success', u'partial', u'failure', u'error', u'nodata',
+ u'missing', 'skipped', 'killed',
+ u'processing'))
+ starttime = Datetime()
+ endtime = Datetime()
+ during_execution = SubjectRelation('ApycotExecution', cardinality='1*', composite='object')
+
+
+class CheckResultLog(EntityType):
+ """log message which has occured during execution of a specific test on a project"""
+ # add: apycotbot
+ path = String()
+ line = Int()
+ severity = Int(vocabulary=range(4)) # INFO, WARNING, ERROR, FATAL
+ msg = String()
+
+ for_check = SubjectRelation(('CheckResult', 'ApycotExecution'), cardinality='1*', composite='object')
+
+
+class CheckResultInfo(EntityType):
+ """arbitrary information about execution of a specific test on a project"""
+ # add: apycotbot
+ type = String(internationalizable=True)
+ label = String(required=True, internationalizable=True)
+ value = String(required=True, internationalizable=True)
+
+ for_check = SubjectRelation(('CheckResult', 'ApycotExecution'), cardinality='1*', composite='object')
+
+
+class for_check(RelationType):
+ inlined = True
+
+class using_config(RelationType):
+ inlined = True
+
+class during_execution(RelationType):
+ inlined = True
+
+
+
+# jpl extension
+if 'Project' in defined_types:
+
+ class has_apycot_config(RelationDefinition):
+ subject = 'Project'
+ object = 'ProjectApycotConfig'
+ cardinality = '*?'
+ composite = 'subject'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# pylint: disable-msg=W0404,W0622,W0704,W0613,W0152
+# Copyright (c) 2003-2004 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+""" Generic Setup script, takes package info from __pkginfo__.py file """
+
+import os
+import sys
+import shutil
+from distutils.core import setup
+from distutils import command
+from distutils.command import install_lib
+from os.path import isdir, exists, join, walk
+
+# import required features
+from __pkginfo__ import distname, version, license, short_desc, long_desc, \
+ web, author, author_email
+try:
+ from __pkginfo__ import scripts
+except ImportError:
+ scripts = []
+try:
+ from __pkginfo__ import data_files
+except ImportError:
+ data_files = None
+
+def ensure_scripts(linux_scripts):
+ """creates the proper script names required for each platform
+ (taken from 4Suite)
+ """
+ from distutils import util
+ if util.get_platform()[:3] == 'win':
+ scripts_ = [script + '.bat' for script in linux_scripts]
+ else:
+ scripts_ = linux_scripts
+ return scripts_
+
+def install(**kwargs):
+ """setup entry point"""
+ return setup(name=distname,
+ version=version,
+ license =license,
+ description=short_desc,
+ long_description=long_desc,
+ author=author,
+ author_email=author_email,
+ url=web,
+ scripts=ensure_scripts(scripts),
+ data_files=data_files,
+ **kwargs)
+
+if __name__ == '__main__' :
+ install()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/bootstrap_cubes Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,1 @@
+apycot
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/pytestconf.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,37 @@
+import os
+import pwd
+
+from logilab.common.pytest import PyTester
+
+def getlogin():
+ """avoid usinng os.getlogin() because of strange tty / stdin problems
+ (man 3 getlogin)
+ Another solution would be to use $LOGNAME, $USER or $USERNAME
+ """
+ return pwd.getpwuid(os.getuid())[0]
+
+
+def update_parser(parser):
+ login = getlogin()
+ parser.add_option('-r', '--rebuild-database', dest='rebuild_db',
+ default=False, action="store_true",
+ help="remove tmpdb and rebuilds the test database")
+ parser.add_option('-u', '--dbuser', dest='dbuser', action='store',
+ default=login, help="database user")
+ parser.add_option('-w', '--dbpassword', dest='dbpassword', action='store',
+ default=login, help="database name")
+ parser.add_option('-n', '--dbname', dest='dbname', action='store',
+ default=None, help="database name")
+ parser.add_option('--euser', dest='euser', action='store',
+ default=login, help="esuer name")
+ parser.add_option('--epassword', dest='epassword', action='store',
+ default=login, help="euser's password' name")
+ return parser
+
+
+class CustomPyTester(PyTester):
+ def __init__(self, cvg, options):
+ super(CustomPyTester, self).__init__(cvg, options)
+ if options.rebuild_db:
+ os.unlink('tmpdb')
+ os.unlink('tmpdb-template')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/realdb_test_apycot.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,31 @@
+from cubicweb.devtools import buildconfig, loadconfig
+from cubicweb.devtools.testlib import RealDBTest
+
+def setup_module(options):
+ if options.source:
+ configcls = loadconfig(options.source)
+ elif options.dbname is None:
+ raise Exception('either <sourcefile> or <dbname> options are required')
+ else:
+ configcls = buildconfig(options.dbuser, options.dbpassword,
+ options.dbname, options.euser,
+ options.epassword)
+ RealDatabaseTC.configcls = configcls
+
+class RealDatabaseTC(RealDBTest):
+ configcls = None # set by setup_module()
+
+ def test_all_primaries(self):
+ for rset in self.iter_individual_rsets(limit=50):
+ yield self.view, 'primary', rset, rset.req.reset_headers()
+
+ ## startup views
+ def test_startup_views(self):
+ for vid in self.list_startup_views():
+ req = self.request()
+ yield self.view, vid, None, req
+
+
+if __name__ == '__main__':
+ from logilab.common.testlib import unittest_main
+ unittest_main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test_apycot.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,16 @@
+"""template automatic tests"""
+
+from logilab.common.testlib import TestCase, unittest_main
+
+class DefaultTC(TestCase):
+ def test_something(self):
+ self.skip('this cube has no test')
+
+## uncomment the import if you want to activate automatic test for your
+## template
+
+# from cubicweb.devtools.testlib import AutomaticWebTest
+
+
+if __name__ == '__main__':
+ unittest_main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/views/__init__.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,1 @@
+'''apycot reports'''
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/views/primary.py Fri Dec 05 17:32:51 2008 +0100
@@ -0,0 +1,176 @@
+from cubicweb.web.views.baseviews import PrimaryView
+
+class InfoLogMixin(object):
+ def render_entity_metadata(self, entity):
+ pass
+
+ def display_info_section(self, entity):
+ req = self.req
+ inforset = req.execute(
+ 'Any T,L,V ORDERBY T,L WHERE X is CheckResultInfo, '
+ 'X type T, X label L, X value V, X for_check AE, AE eid %(ae)s',
+ {'ae': entity.eid}, 'ae')
+ if inforset:
+ self.w(u'<h5>%s</h5>' % req._('execution information'))
+ self.view('table', inforset, w=self.w)
+
+ def display_log_section(self, entity):
+ req = self.req
+ logrset = req.execute(
+ 'Any P,L,S,M ORDERBY P,L,S WHERE X is CheckResultLog, '
+ 'X path P, X line L, X severity S, X msg M, X for_check AE, '
+ 'AE eid %(ae)s', {'ae': entity.eid}, 'ae')
+ if logrset:
+ self.w(u'<h5>%s</h5>' % req._('logs'))
+ self.view('table', logrset, w=self.w)
+
+
+class ApycotExecutionPrimaryView(InfoLogMixin, PrimaryView):
+ accepts = ('ApycotExecution',)
+ skip_attrs = PrimaryView.skip_attrs + ()
+
+ def render_entity_title(self, entity):
+ self.w('<h1>%s</h1>' % entity.dc_title())
+
+ def render_entity_relations(self, entity, siderelations):
+ self.req.add_css('cubes.apycot.css')
+ self.display_info_section(entity)
+ self.display_log_section(entity)
+ if entity.reverse_during_execution:
+ self.w(u'<h3>%s</h3>' % self.req._('checks'))
+ self.w(u'<table class="summary">')
+ for check in entity.reverse_during_execution:
+ self.w(u'<tr><td><a href="%s#%s">%s</a></td><td class="status_%s">%s</td></tr>'
+ % (self.req.url(), check.name, check.name, check.status, check.status))
+ self.w(u'</table>')
+ for check in entity.reverse_during_execution:
+ check.view('primary', w=self.w)
+
+
+class CheckResultPrimaryView(InfoLogMixin, PrimaryView):
+ accepts = ('CheckResult',)
+ skip_attrs = PrimaryView.skip_attrs + ('name', 'status')
+
+ def render_entity_title(self, entity):
+ self.w('<a name="%s"/>' % entity.name)
+ self.w('<h4>%s [<span class="status_%s">%s</span>]</h4>'
+ % (entity.name, entity.status, entity.status))
+
+ def render_entity_relations(self, entity, siderelations):
+ self.display_info_section(entity)
+ self.display_log_section(entity)
+
+
+# class DetailedReporter(SimpleReporter):
+# """detailed reporter, including tests configuration, log messages with
+# severity greater than a given treshold and raw values
+# """
+# __implements__ = IReporter
+# __name__ = 'detailed_report'
+# default_id = 'detailed'
+
+# def __init__(self, name, transport, formatter, all_reporters, verbosity=0):
+# SimpleReporter.__init__(self, name, transport, formatter,
+# all_reporters, verbosity)
+# self.section = None
+# self.test_section = None
+# self._tresh = ERROR
+# self._raws = None
+# self._logs = None
+# self._test_path = self._test_repo = self._test_tag = None
+
+
+# def node_section_title(self, node):
+# """return a title for a section associated to a node"""
+# label = SimpleReporter.node_section_title(self, node)
+# statut = node.get('status')
+# if statut is None:
+# return label
+# else:
+# return '%s (%s)' % (label, statut)
+
+# def reset(self):
+# """reset reporting variables"""
+# self._tresh = self.get_treshold()
+
+# def cb_open_testsdata(self, node):
+# """open a testsdata node (ie the root) hook"""
+# self.reset()
+# self.section = Section(title=self.document_title(node), klass='result')
+# self.navigation(self.section, node)
+# self.field_info(self.section, node)
+
+# def cb_close_testsdata(self, node):
+# """close a testsdata node (ie the root) hook"""
+# self.navigation(self.section, node)
+# summary = self.summary(self.section)
+# if summary:
+# self.section.insert(0, summary)
+# self.post_layout(self.section, self.document_id(node))
+
+# def cb_open_test(self, node):
+# """open test node hook"""
+# try:
+# self._test_repo = get_repository(dict(node.attrib))
+# except ConfigError:
+# self._test_repo = None
+# title = self.node_section_title(node)
+# self.test_section = Section(title=title,
+# id=self.relative_url(node),
+# klass='test')
+# self.test_section.node = node
+# self.section.append(self.test_section)
+# self.field_info(self.test_section, node)
+
+# def cb_open_check(self, node):
+# """open check node hook"""
+# self._raws = []
+# self._logs = []
+
+# def cb_close_check(self, node):
+# """close check node hook"""
+# title = self.node_section_title(node)
+# check_section = Section(title=title, id=self.relative_url(node),
+# klass='check')
+# check_section.node = node
+# self.test_section.append(check_section)
+# self.field_info(check_section, node)
+# if self._raws:
+# table = Table(cols=2, klass="field", rheaders=1)
+# for node in self._raws:
+# table.append(Text(node.get('class')))
+# table.append(Text(self.text_value(node)))
+# check_section.append(table)
+# if self._logs:
+# table = Table(cols=4, klass="result", rheaders=1, cheaders=1)
+# table.append(Text('path'))
+# table.append(Text('line'))
+# table.append(Text('severity'))
+# table.append(Text('message'))
+# repo = self._test_repo
+# for node in self._logs:
+# path = node.get('path', '')
+# vurl = repo and repo.view_url_for(path)
+# if vurl:
+# path = Link(vurl, path)
+# else:
+# path = Text(path)
+# table.append(Span([path], klass="path"))
+# table.append(Span([Text(node.get('line', ''))], klass="line"))
+# table.append(Span([Text(node.get('severity'))],
+# klass="severity"))
+# table.append(Span([VerbatimText(self.text_value(node).strip())],
+# klass="msg"))
+# check_section.append(table)
+
+# def cb_open_log(self, node):
+# """open log node hook"""
+# severity = node.get('severity')
+# if eval(severity) < self._tresh:
+# return
+# self._logs.append( (node) )
+
+# def cb_open_raw(self, node):
+# """open raw node hook"""
+# self._raws.append( (node) )
+