Skip to content

Commit 6117dcd

Browse files
committed
issue2551141 - roundup-admin returns no such class when restoring item with duplicate key
Fix the error by splitting the class name lookup and the restore opertation. Both can return KeyErrors. Set up two different try blocks for each case. Also test restore/retire.
1 parent 6f4ff61 commit 6117dcd

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ Fixed:
127127
find(). (John Rouillard)
128128
- Fix traceback caused by calling history() with arguments in a
129129
non-item context.
130+
- issue2551141 - roudup-admin returns no such class when restoring
131+
item with duplicate key. Fix incorrect error message when using
132+
roundup-admin to restore a user when the username is aleady in use.
133+
(John Rouillard)
130134

131135
Features:
132136
- issue2550522 - Add 'filter' command to command-line

roundup/admin.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1250,9 +1250,13 @@ def do_restore(self, args):
12501250
except hyperdb.DesignatorError as message:
12511251
raise UsageError(message)
12521252
try:
1253-
self.db.getclass(classname).restore(nodeid)
1253+
dbclass = self.db.getclass(classname)
12541254
except KeyError:
12551255
raise UsageError(_('no such class "%(classname)s"') % locals())
1256+
try:
1257+
dbclass.restore(nodeid)
1258+
except KeyError as e:
1259+
raise UsageError(e.args[0])
12561260
except IndexError:
12571261
raise UsageError(_('no such %(classname)s node '
12581262
'" % (nodeid)s"')%locals())

test/test_admin.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,94 @@ def testSpecification(self):
10441044
print(outlist)
10451045
self.assertEqual(sorted(outlist), sorted(spec))
10461046

1047+
def testRetireRestore(self):
1048+
''' Note the tests will fail if you run this under pdb.
1049+
the context managers capture the pdb prompts and this screws
1050+
up the stdout strings with (pdb) prefixed to the line.
1051+
'''
1052+
import sys
1053+
1054+
# create user1 at id 3
1055+
self.install_init()
1056+
self.admin=AdminTool()
1057+
with captured_output() as (out, err):
1058+
sys.argv=['main', '-i', self.dirname, 'create', 'user',
1059+
'username=user1', 'address=user1' ]
1060+
ret = self.admin.main()
1061+
1062+
out = out.getvalue().strip()
1063+
print(out)
1064+
self.assertEqual(out, '3')
1065+
1066+
# retire user1 at id 3
1067+
self.admin=AdminTool()
1068+
with captured_output() as (out, err):
1069+
sys.argv=['main', '-i', self.dirname, 'retire', 'user3']
1070+
ret = self.admin.main()
1071+
out = out.getvalue().strip()
1072+
print(out)
1073+
self.assertEqual(out, '')
1074+
1075+
# create new user1 at id 4 - note need unique address to succeed.
1076+
self.admin=AdminTool()
1077+
with captured_output() as (out, err):
1078+
sys.argv=['main', '-i', self.dirname, 'create', 'user',
1079+
'username=user1', 'address=user1a' ]
1080+
ret = self.admin.main()
1081+
1082+
out = out.getvalue().strip()
1083+
print(out)
1084+
self.assertEqual(out, '4')
1085+
1086+
# fail to restore old user1 at id 3
1087+
self.admin=AdminTool()
1088+
with captured_output() as (out, err):
1089+
sys.argv=['main', '-i', self.dirname, 'restore', 'user3']
1090+
ret = self.admin.main()
1091+
out = out.getvalue().strip()
1092+
print(out)
1093+
self.assertIn('Error: Key property (username) of retired node clashes with existing one (user1)', out)
1094+
1095+
# verify that user4 is listed
1096+
self.admin=AdminTool()
1097+
with captured_output() as (out, err):
1098+
sys.argv=['main', '-i', self.dirname, 'list', 'user']
1099+
ret = self.admin.main()
1100+
out = out.getvalue().strip()
1101+
print(out)
1102+
expected="1: admin\n 2: anonymous\n 4: user1"
1103+
self.assertEqual(out, expected)
1104+
1105+
# retire user4
1106+
self.admin=AdminTool()
1107+
with captured_output() as (out, err):
1108+
sys.argv=['main', '-i', self.dirname, 'retire', 'user4']
1109+
ret = self.admin.main()
1110+
out = out.getvalue().strip()
1111+
print(out)
1112+
self.assertEqual(out, '')
1113+
1114+
# now we can restore user3
1115+
self.admin=AdminTool()
1116+
with captured_output() as (out, err):
1117+
sys.argv=['main', '-i', self.dirname, 'restore', 'user3']
1118+
ret = self.admin.main()
1119+
out = out.getvalue().strip()
1120+
print(out)
1121+
self.assertEqual(out, '')
1122+
1123+
# verify that user3 is listed
1124+
self.admin=AdminTool()
1125+
with captured_output() as (out, err):
1126+
sys.argv=['main', '-i', self.dirname, 'list', 'user']
1127+
ret = self.admin.main()
1128+
out = out.getvalue().strip()
1129+
print(out)
1130+
expected="1: admin\n 2: anonymous\n 3: user1"
1131+
self.assertEqual(out, expected)
1132+
1133+
1134+
10471135
def testTable(self):
10481136
''' Note the tests will fail if you run this under pdb.
10491137
the context managers capture the pdb prompts and this screws

0 commit comments

Comments
 (0)