8
from lib389 import DirSrv, Entry, tools
9
from lib389.tools import DirSrvTools
10
from lib389._constants import *
11
from lib389.properties import *
12
from constants import *
14
log = logging.getLogger(__name__)
16
installation_prefix = None
19
class TopologyStandalone(object):
20
def __init__(self, standalone):
22
self.standalone = standalone
25
pytest.fixture(scope="module")
26
def topology(request):
28
This fixture is used to standalone topology for the 'module'.
29
At the beginning, It may exists a standalone instance.
30
It may also exists a backup for the standalone instance.
33
If standalone instance exists:
35
If backup of standalone exists:
36
create/rebind to standalone
38
restore standalone instance from backup
46
global installation_prefix
48
if installation_prefix:
49
args_instance[SER_DEPLOYED_DIR] = installation_prefix
51
standalone = DirSrv(verbose=False)
53
# Args for the standalone instance
54
args_instance[SER_HOST] = HOST_STANDALONE
55
args_instance[SER_PORT] = PORT_STANDALONE
56
args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
57
args_standalone = args_instance.copy()
58
standalone.allocate(args_standalone)
60
# Get the status of the backups
61
backup_standalone = standalone.checkBackupFS()
63
# Get the status of the instance and restart it if it exists
64
instance_standalone = standalone.exists()
65
if instance_standalone:
66
# assuming the instance is already stopped, just wait 5 sec max
67
standalone.stop(timeout=5)
68
standalone.start(timeout=10)
71
# The backup exist, assuming it is correct
72
# we just re-init the instance with it
73
if not instance_standalone:
75
# Used to retrieve configuration information (dbdir, confdir...)
78
# restore standalone instance from backup
79
standalone.stop(timeout=10)
80
standalone.restoreFS(backup_standalone)
81
standalone.start(timeout=10)
84
# We should be here only in two conditions
85
# - This is the first time a test involve standalone instance
86
# - Something weird happened (instance/backup destroyed)
87
# so we discard everything and recreate all
89
# Remove the backup. So even if we have a specific backup file
90
# (e.g backup_standalone) we clear backup that an instance may have created
92
standalone.clearBackupFS()
95
if instance_standalone:
101
# Used to retrieve configuration information (dbdir, confdir...)
104
# Time to create the backups
105
standalone.stop(timeout=10)
106
standalone.backupfile = standalone.backupFS()
107
standalone.start(timeout=10)
110
# Here we have standalone instance up and running
111
# Either coming from a backup recovery
112
# or from a fresh (re)init
113
# Time to return the topology
114
return TopologyStandalone(standalone)
117
def test_ticket47815(topology):
119
Test betxn plugins reject an invalid option, and make sure that the rejected entry
120
is not in the entry cache.
122
Enable memberOf, automember, and retrocl plugins
123
Add the automember config entry
124
Add the automember group
125
Add a user that will be rejected by a betxn plugin - result error 53
126
Attempt the same add again, and it should result in another error 53 (not error 68)
131
log.info('Testing Ticket 47815 - Add entries that should be rejected by the betxn plugins, and are not left in the entry cache')
133
# Enabled the plugins
134
topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
135
topology.standalone.plugins.enable(name=PLUGIN_AUTOMEMBER)
136
topology.standalone.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
138
# configure automember config entry
139
log.info('Adding automember config')
141
topology.standalone.add_s(Entry(('cn=group cfg,cn=Auto Membership Plugin,cn=plugins,cn=config', {
142
'objectclass': 'top autoMemberDefinition'.split(),
143
'autoMemberScope': 'dc=example,dc=com',
144
'autoMemberFilter': 'cn=user',
145
'autoMemberDefaultGroup': 'cn=group,dc=example,dc=com',
146
'autoMemberGroupingAttr': 'member:dn',
147
'cn': 'group cfg'})))
149
log.error('Failed to add automember config')
152
topology.standalone.stop(timeout=120)
154
topology.standalone.start(timeout=120)
157
# need to reopen a connection toward the instance
158
topology.standalone.open()
160
# add automember group
161
log.info('Adding automember group')
163
topology.standalone.add_s(Entry(('cn=group,dc=example,dc=com', {
164
'objectclass': 'top groupOfNames'.split(),
167
log.error('Failed to add automember group')
170
# add user that should result in an error 53
171
log.info('Adding invalid entry')
174
topology.standalone.add_s(Entry(('cn=user,dc=example,dc=com', {
175
'objectclass': 'top person'.split(),
178
except ldap.UNWILLING_TO_PERFORM:
179
log.debug('Adding invalid entry failed as expected')
181
except ldap.LDAPError, e:
182
log.error('Unexpected result ' + e.message['desc'])
185
log.error('Add operation unexpectedly succeeded')
188
# Attempt to add user again, should result in error 53 again
190
topology.standalone.add_s(Entry(('cn=user,dc=example,dc=com', {
191
'objectclass': 'top person'.split(),
194
except ldap.UNWILLING_TO_PERFORM:
195
log.debug('2nd add of invalid entry failed as expected')
197
except ldap.LDAPError, e:
198
log.error('Unexpected result ' + e.message['desc'])
201
log.error('2nd Add operation unexpectedly succeeded')
204
# If we got here we passed!
205
log.info('Ticket47815 Test - Passed')
208
def test_ticket47815_final(topology):
209
topology.standalone.stop(timeout=10)
214
run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
215
To run isolated without py.test, you need to
216
- edit this file and comment '@pytest.fixture' line before 'topology' function.
217
- set the installation prefix
220
global installation_prefix
221
installation_prefix = None
223
topo = topology(True)
224
test_ticket47815(topo)
226
if __name__ == '__main__':