Skip to content

Commit 612da8e

Browse files
author
Ralf Schlatterbeck
committed
Journal and database testing.
- Add to Import/Export test to also test that journals are correctly retrieved - Fix a bug in anydbm backend that didn't export journal 'set' actions where the previous value was None -- all other backends export them correctly so I consider this a bug of anydbm - Fix journal import/export of Date and Interval for metakit - Fix journal import of Password for metakit - Fix setting of Password oldvalue for metakit -- this would be written as the string "None" instead of the value None. Note that existing databases *will* have wrong log-entries. Since this is only for passwords -- and old passwords aren't of much importance -- I consider this fix to be enough... This fix makes the Journal import/export test run for metakit.
1 parent b337955 commit 612da8e

File tree

4 files changed

+54
-13
lines changed

4 files changed

+54
-13
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Feature:
77
still limited to 1970-2038.
88
Fixed:
99
- Handling of unset Link search in RDBMS backend
10+
- Journal import/export for metakit backend
11+
- Journal export of anydbm didn't correctly export previously empty values
1012

1113

1214
2007-02-15 1.3.3

roundup/backends/back_anydbm.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: back_anydbm.py,v 1.202 2006-08-29 04:20:50 richard Exp $
18+
#$Id: back_anydbm.py,v 1.203 2007-03-14 15:23:11 schlatterbeck Exp $
1919
'''This module defines a backend that saves the hyperdatabase in a
2020
database chosen by anydbm. It is guaranteed to always be available in python
2121
versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several
@@ -1962,8 +1962,7 @@ def export_journals(self):
19621962
prop = properties[propname]
19631963
# make sure the params are eval()'able
19641964
if value is None:
1965-
# don't export empties
1966-
continue
1965+
pass
19671966
elif isinstance(prop, hyperdb.Date):
19681967
# this is a hack - some dates are stored as strings
19691968
if not isinstance(value, type('')):

roundup/backends/back_metakit.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Id: back_metakit.py,v 1.113 2006-08-29 04:20:50 richard Exp $
1+
# $Id: back_metakit.py,v 1.114 2007-03-14 15:23:11 schlatterbeck Exp $
22
'''Metakit backend for Roundup, originally by Gordon McMillan.
33
44
Known Current Bugs:
@@ -735,7 +735,10 @@ def set_inner(self, nodeid, **propvalues):
735735
if value is None:
736736
value = ''
737737
setattr(row, key, str(value))
738-
changes[key] = str(oldvalue)
738+
if oldvalue is None:
739+
changes[key] = oldvalue
740+
else:
741+
changes[key] = str(oldvalue)
739742
propvalues[key] = str(value)
740743

741744
elif isinstance(prop, hyperdb.Date):
@@ -1668,8 +1671,8 @@ def export_journals(self):
16681671
properties = self.getprops()
16691672
r = []
16701673
for nodeid in self.getnodeids():
1671-
for nodeid, date, user, action, params in self.history(nodeid):
1672-
date = date.get_tuple()
1674+
for nodeid, dt, user, action, params in self.history(nodeid):
1675+
dt = dt.get_tuple()
16731676
if action == 'set':
16741677
export_data = {}
16751678
for propname, value in params.items():
@@ -1682,14 +1685,18 @@ def export_journals(self):
16821685
if value is None:
16831686
pass
16841687
elif isinstance(prop, Date):
1688+
if isinstance(value, str):
1689+
value = date.Date(value)
16851690
value = value.get_tuple()
16861691
elif isinstance(prop, Interval):
1692+
if isinstance(value, str):
1693+
value = date.Interval(value)
16871694
value = value.get_tuple()
16881695
elif isinstance(prop, Password):
16891696
value = str(value)
16901697
export_data[propname] = value
16911698
params = export_data
1692-
l = [nodeid, date, user, action, params]
1699+
l = [nodeid, dt, user, action, params]
16931700
r.append(map(repr, l))
16941701
return r
16951702

@@ -1710,13 +1717,13 @@ def import_journals(self, entries):
17101717
if value is None:
17111718
pass
17121719
elif isinstance(prop, hyperdb.Date):
1713-
value = date.Date(value)
1720+
value = str(date.Date(value))
17141721
elif isinstance(prop, hyperdb.Interval):
1715-
value = date.Interval(value)
1722+
value = str (date.Interval(value))
17161723
elif isinstance(prop, hyperdb.Password):
17171724
pwd = password.Password()
17181725
pwd.unpack(value)
1719-
value = pwd
1726+
value = str(pwd)
17201727
params[propname] = value
17211728
action = _names_to_actionnames[action]
17221729
r.append((nodeid, jdate, user, action, params))

test/db_test_base.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: db_test_base.py,v 1.83 2007-03-09 10:25:10 schlatterbeck Exp $
18+
# $Id: db_test_base.py,v 1.84 2007-03-14 15:23:11 schlatterbeck Exp $
1919

2020
import unittest, os, shutil, errno, imp, sys, time, pprint, sets
2121

@@ -1484,15 +1484,33 @@ def testFilteringSortId(self):
14841484
def testImportExport(self):
14851485
# use the filtering setup to create a bunch of items
14861486
ae, filt = self.filteringSetup()
1487+
# Get some stuff into the journal for testing import/export of
1488+
# journal data:
1489+
self.db.user.set('4', password = password.Password('xyzzy'))
1490+
self.db.user.set('4', age = 3)
1491+
self.db.user.set('4', assignable = True)
1492+
self.db.issue.set('1', title = 'i1', status = '3')
1493+
self.db.issue.set('1', deadline = date.Date('2007'))
1494+
self.db.issue.set('1', foo = date.Interval('1:20'))
1495+
p = self.db.priority.create(name = 'some_prio_without_order')
1496+
self.db.commit()
1497+
self.db.user.set('4', password = password.Password('123xyzzy'))
1498+
self.db.user.set('4', assignable = False)
1499+
self.db.priority.set(p, order = '4711')
1500+
self.db.commit()
1501+
14871502
self.db.user.retire('3')
14881503
self.db.issue.retire('2')
14891504

14901505
# grab snapshot of the current database
14911506
orig = {}
1507+
origj = {}
14921508
for cn,klass in self.db.classes.items():
14931509
cl = orig[cn] = {}
1510+
jn = origj[cn] = {}
14941511
for id in klass.list():
14951512
it = cl[id] = {}
1513+
jn[id] = self.db.getjournal(cn, id)
14961514
for name in klass.getprops().keys():
14971515
it[name] = klass.get(id, name)
14981516

@@ -1531,11 +1549,13 @@ def testImportExport(self):
15311549
maxid = max(maxid, id)
15321550
self.db.setid(cn, str(maxid+1))
15331551
klass.import_journals(journals[cn])
1552+
# This is needed, otherwise journals won't be there for anydbm
1553+
self.db.commit()
15341554
finally:
15351555
shutil.rmtree('_test_export')
15361556

15371557
# compare with snapshot of the database
1538-
for cn, items in orig.items():
1558+
for cn, items in orig.iteritems():
15391559
klass = self.db.classes[cn]
15401560
propdefs = klass.getprops(1)
15411561
# ensure retired items are retired :)
@@ -1555,6 +1575,19 @@ def testImportExport(self):
15551575
raise
15561576
# don't get hung up on rounding errors
15571577
assert not l.__cmp__(value, int_seconds=1)
1578+
for jc, items in origj.iteritems():
1579+
for id, oj in items.iteritems():
1580+
rj = self.db.getjournal(jc, id)
1581+
# Both mysql and postgresql have some minor issues with
1582+
# rounded seconds on export/import, so we compare only
1583+
# the integer part.
1584+
for j in oj:
1585+
j[1].second = float(int(j[1].second))
1586+
for j in rj:
1587+
j[1].second = float(int(j[1].second))
1588+
oj.sort()
1589+
rj.sort()
1590+
ae(oj, rj)
15581591

15591592
# make sure the retired items are actually imported
15601593
ae(self.db.user.get('4', 'username'), 'blop')

0 commit comments

Comments
 (0)