--- a/doc/book/en/devrepo/testing.rst Wed Aug 04 11:16:40 2010 +0200
+++ b/doc/book/en/devrepo/testing.rst Fri Aug 06 17:49:20 2010 +0200
@@ -145,7 +145,7 @@
connection from another !
Email notifications tests
--------------------------
+`````````````````````````
When running tests potentially generated e-mails are not really sent
but is found in the list `MAILBOX` of module
@@ -212,6 +212,21 @@
auto_populate cannot guess by itself; these must yield resultsets
against which views may be selected.
+Testing with other cubes
+------------------------
+
+Sometimes a small component cannot be tested all by itself, so one
+needs to specify other cubes to be used as part of the the unit test
+suite. This is handled by the ``bootstrap_cubes`` file located under
+``mycube\test\data``. One example from the `preview` cube::
+
+ card, file, preview
+
+The format is:
+
+* possibly several empy lines or lines starting with ``#`` (comment lines)
+* one line containing a coma separated list of cube names.
+
Test APIS
---------
--- a/hooks/syncschema.py Wed Aug 04 11:16:40 2010 +0200
+++ b/hooks/syncschema.py Fri Aug 06 17:49:20 2010 +0200
@@ -104,6 +104,28 @@
session.info('added index on %s(%s)', table, column)
+def insert_rdef_on_subclasses(session, eschema, rschema, rdefdef, props):
+ # XXX 'infered': True/False, not clear actually
+ props.update({'constraints': rdefdef.constraints,
+ 'description': rdefdef.description,
+ 'cardinality': rdefdef.cardinality,
+ 'permissions': rdefdef.get_permissions(),
+ 'order': rdefdef.order,
+ 'infered': False, 'eid': None
+ })
+ cstrtypemap = ss.cstrtype_mapping(session)
+ groupmap = group_mapping(session)
+ object = rschema.schema.eschema(rdefdef.object)
+ for specialization in eschema.specialized_by(False):
+ if (specialization, rdefdef.object) in rschema.rdefs:
+ continue
+ print 'adding infered', specialization, rschema.type, object
+ sperdef = RelationDefinitionSchema(specialization, rschema,
+ object, props)
+ ss.execschemarql(session.execute, sperdef,
+ ss.rdef2rql(sperdef, cstrtypemap, groupmap))
+
+
def check_valid_changes(session, entity, ro_attrs=('name', 'final')):
errors = {}
# don't use getattr(entity, attr), we would get the modified value if any
@@ -454,25 +476,7 @@
# if relation type has been inserted in the same transaction, its final
# attribute is still set to False, so we've to ensure it's False
rschema.final = True
- # XXX 'infered': True/False, not clear actually
- props.update({'constraints': rdefdef.constraints,
- 'description': rdefdef.description,
- 'cardinality': rdefdef.cardinality,
- 'constraints': rdefdef.constraints,
- 'permissions': rdefdef.get_permissions(),
- 'order': rdefdef.order,
- 'infered': False, 'eid': None
- })
- cstrtypemap = ss.cstrtype_mapping(session)
- groupmap = group_mapping(session)
- object = schema.eschema(rdefdef.object)
- for specialization in eschema.specialized_by(False):
- if (specialization, rdefdef.object) in rschema.rdefs:
- continue
- sperdef = RelationDefinitionSchema(specialization, rschema,
- object, props)
- ss.execschemarql(session.execute, sperdef,
- ss.rdef2rql(sperdef, cstrtypemap, groupmap))
+ insert_rdef_on_subclasses(session, eschema, rschema, rdefdef, props)
# set default value, using sql for performance and to avoid
# modification_date update
if default:
@@ -514,6 +518,9 @@
# first occurence of "Subject relation Something" whatever Something
if len(rschema.objects(rdefdef.subject)) == 1:
add_inline_relation_column(session, rdefdef.subject, rtype)
+ eschema = schema[rdefdef.subject]
+ insert_rdef_on_subclasses(session, eschema, rschema, rdefdef,
+ {'composite': entity.composite})
else:
# need to create the relation if no relation definition in the
# schema and if it has not been added during other event of the same
--- a/server/migractions.py Wed Aug 04 11:16:40 2010 +0200
+++ b/server/migractions.py Fri Aug 06 17:49:20 2010 +0200
@@ -378,9 +378,13 @@
for gname in newgroups:
if not confirm or self.confirm('Grant %s permission of %s to %s?'
% (action, erschema, gname)):
- self.rqlexec('SET T %s G WHERE G eid %%(x)s, T eid %s'
- % (perm, teid),
- {'x': gm[gname]}, ask_confirm=False)
+ try:
+ self.rqlexec('SET T %s G WHERE G eid %%(x)s, T eid %s'
+ % (perm, teid),
+ {'x': gm[gname]}, ask_confirm=False)
+ except KeyError:
+ self.error('can grant %s perm to unexistant group %s',
+ action, gname)
# handle rql expressions
newexprs = dict((expr.expression, expr) for expr in erschema.get_rqlexprs(action))
for expreid, expression in self.rqlexec('Any E, EX WHERE T %s E, E expression EX, '
@@ -876,7 +880,15 @@
self.sqlexec('UPDATE %s_relation SET eid_to=%s WHERE eid_to=%s'
% (rtype, new.eid, oldeid), ask_confirm=False)
# delete relations using SQL to avoid relations content removal
- # triggered by schema synchronization hooks
+ # triggered by schema synchronization hooks. Should add deleted eids
+ # into pending eids else we may get some validation error on commit
+ # since integrity hooks may think some required relation is
+ # missing...
+ pending = self.session.transaction_data.setdefault('pendingeids', set())
+ for eid, in self.sqlexec('SELECT cw_eid FROM cw_CWRelation '
+ 'WHERE cw_from_entity=%(eid)s OR cw_to_entity=%(eid)s',
+ {'eid': oldeid}, ask_confirm=False):
+ pending.add(eid)
self.sqlexec('DELETE FROM cw_CWRelation '
'WHERE cw_from_entity=%(eid)s OR cw_to_entity=%(eid)s',
{'eid': oldeid}, ask_confirm=False)
@@ -911,10 +923,15 @@
self.commit()
gmap = self.group_mapping()
cmap = self.cstrtype_mapping()
+ done = set()
for rdef in rschema.rdefs.itervalues():
if not (reposchema.has_entity(rdef.subject)
and reposchema.has_entity(rdef.object)):
continue
+ # symmetric relations appears twice
+ if (rdef.subject, rdef.object) in done:
+ continue
+ done.add( (rdef.subject, rdef.object) )
self._set_rdef_eid(rdef)
ss.execschemarql(execute, rdef,
ss.rdef2rql(rdef, cmap, gmap))
--- a/server/serverctl.py Wed Aug 04 11:16:40 2010 +0200
+++ b/server/serverctl.py Fri Aug 06 17:49:20 2010 +0200
@@ -71,13 +71,13 @@
'on the database:')
print special_privs
print
- default_user = source.get('db-user', os.environ.get('USER', ''))
- user = raw_input('Connect as user ? [%r]: ' % default_user)
- user = user or default_user
- if user == source.get('db-user') and source.get('db-password'):
- password = source['db-password']
- else:
- password = getpass('password: ')
+ default_user = source.get('db-user', os.environ.get('USER', ''))
+ user = raw_input('Connect as user ? [%r]: ' % default_user)
+ user = user or default_user
+ if user == source.get('db-user') and source.get('db-password'):
+ password = source['db-password']
+ else:
+ password = getpass('password: ')
else:
user = password = None
extra_args = source.get('db-extra-arguments')
--- a/server/session.py Wed Aug 04 11:16:40 2010 +0200
+++ b/server/session.py Fri Aug 06 17:49:20 2010 +0200
@@ -1025,7 +1025,7 @@
def __init__(self, repo, cnxprops=None):
super(InternalSession, self).__init__(InternalManager(), repo, cnxprops,
_id='internal')
- self.user.req = self # XXX remove when "vreg = user.req.vreg" hack in entity.py is gone
+ self.user._cw = self # XXX remove when "vreg = user._cw.vreg" hack in entity.py is gone
self.cnxtype = 'inmemory'
self.disable_hook_categories('integrity')
--- a/web/views/primary.py Wed Aug 04 11:16:40 2010 +0200
+++ b/web/views/primary.py Fri Aug 06 17:49:20 2010 +0200
@@ -130,7 +130,7 @@
display_attributes = []
for rschema, _, role, dispctrl in self._section_def(entity, 'attributes'):
vid = dispctrl.get('vid', 'reledit')
- if rschema.final or vid == 'reledit':
+ if rschema.final or vid == 'reledit' or dispctrl.get('rtypevid'):
value = entity.view(vid, rtype=rschema.type, role=role)
else:
rset = self._relation_rset(entity, rschema, role, dispctrl)