@@ -111,7 +111,7 @@ class Slapd:
111111 :param port: The port on which the slapd server will listen to.
112112 If `None` a random available port will be chosen.
113113
114- :param log_level: The verbosity of Slapd..
114+ :param log_level: The verbosity of Slapd.
115115 The default value is `logging.WARNING`.
116116
117117 :param suffix: The LDAP suffix for all objects. The default is
@@ -236,7 +236,7 @@ def _find_command(self, cmd, in_sbin=False):
236236 )
237237 return command
238238
239- def setup_rundir (self ):
239+ def _setup_rundir (self ):
240240 """
241241 creates rundir structure
242242
@@ -281,7 +281,7 @@ def _avail_tcpport(self):
281281 self .logger .info ("Found available port %d" , port )
282282 return port
283283
284- def gen_config (self ):
284+ def _gen_config (self ):
285285 """
286286 generates a slapd.conf and returns it as one string
287287
@@ -307,7 +307,7 @@ def _write_config(self):
307307 """Loads the slapd.d configuration."""
308308 self .logger .debug ("importing configuration: %s" , self ._slapd_conf )
309309
310- self .slapadd (self .gen_config (), ["-n0" ])
310+ self .slapadd (self ._gen_config (), ["-n0" ])
311311 ldif_paths = [
312312 schema if os .path .exists (schema ) else os .path .join (self .SCHEMADIR , schema )
313313 for schema in self .schemas
@@ -384,7 +384,7 @@ def start(self):
384384
385385 atexit .register (self .stop )
386386 self ._cleanup_rundir ()
387- self .setup_rundir ()
387+ self ._setup_rundir ()
388388 self ._write_config ()
389389 self ._test_config ()
390390 self ._start_slapd ()
@@ -445,8 +445,16 @@ def _cli_auth_args(self):
445445 return authc_args
446446
447447 def _cli_popen (
448- self , ldapcommand , extra_args = None , ldap_uri = None , stdin_data = None
448+ self ,
449+ ldapcommand ,
450+ extra_args = None ,
451+ ldap_uri = None ,
452+ stdin_data = None ,
453+ expected = 0 ,
449454 ):
455+ if isinstance (expected , int ):
456+ expected = [expected ]
457+
450458 if ldap_uri is None :
451459 ldap_uri = self .default_ldap_uri
452460
@@ -464,74 +472,122 @@ def _cli_popen(
464472 self .logger .debug (
465473 "stdin_data=%s" , stdin_data .decode ("utf-8" ) if stdin_data else stdin_data
466474 )
475+
467476 if proc .stdout is not None :
468477 self .logger .debug ("stdout=%s" , proc .stdout .decode ("utf-8" ))
478+
469479 if proc .stderr is not None :
470480 self .logger .debug ("stderr=%s" , proc .stderr .decode ("utf-8" ))
471- if proc .returncode != 0 :
472- raise RuntimeError ("Process failed: {!r}" .format (" " .join (args )))
481+
482+ if proc .returncode not in expected :
483+ raise RuntimeError (
484+ "Unexpected process return code (expected {}, got {}): {!r}" .format (
485+ expected , proc .returncode , " " .join (args )
486+ )
487+ )
473488 return proc
474489
475- def ldapwhoami (self , extra_args = None ):
490+ def ldapwhoami (self , extra_args = None , expected = 0 ):
476491 """
477492 Runs ldapwhoami on this slapd instance
478493
479- :return: A :class:`subprocess.CompletedProcess` with the execution data.
494+ :param extra_args: Extra argument to pass to *ldapwhoami*.
495+ :param expected: Expected return code. Defaults to `0`.
496+ :type expected: An integer or a list of integers
497+
498+ :return: A :class:`subprocess.CompletedProcess` with the *ldapwhoami* execution data.
480499 """
481- return self ._cli_popen (self .PATH_LDAPWHOAMI , extra_args = extra_args )
500+ return self ._cli_popen (
501+ self .PATH_LDAPWHOAMI , extra_args = extra_args , expected = expected
502+ )
482503
483- def ldapadd (self , ldif , extra_args = None ):
504+ def ldapadd (self , ldif , extra_args = None , expected = 0 ):
484505 """
485506 Runs ldapadd on this slapd instance, passing it the ldif content
486507
487- :return: A :class:`subprocess.CompletedProcess` with the execution data.
508+ :param ldif: The ldif content to pass to the *ldapadd* standard input.
509+ :param extra_args: Extra argument to pass to *ldapadd*.
510+ :param expected: Expected return code. Defaults to `0`.
511+ :type expected: An integer or a list of integers
512+
513+ :return: A :class:`subprocess.CompletedProcess` with the *ldapadd* execution data.
488514 """
489515 return self ._cli_popen (
490- self .PATH_LDAPADD , extra_args = extra_args , stdin_data = ldif .encode ("utf-8" )
516+ self .PATH_LDAPADD ,
517+ extra_args = extra_args ,
518+ stdin_data = ldif .encode ("utf-8" ) if ldif else None ,
519+ expected = expected ,
491520 )
492521
493- def ldapmodify (self , ldif , extra_args = None ):
522+ def ldapmodify (self , ldif , extra_args = None , expected = 0 ):
494523 """
495524 Runs ldapadd on this slapd instance, passing it the ldif content
496525
497- :return: A :class:`subprocess.CompletedProcess` with the execution data.
526+ :param ldif: The ldif content to pass to the *ldapmodify* standard input.
527+ :param extra_args: Extra argument to pass to *ldapmodify*.
528+ :param expected: Expected return code. Defaults to `0`.
529+ :type expected: An integer or a list of integers
530+
531+ :return: A :class:`subprocess.CompletedProcess` with the *ldapmodify* execution data.
498532 """
499533 return self ._cli_popen (
500- self .PATH_LDAPMODIFY , extra_args = extra_args , stdin_data = ldif .encode ("utf-8" )
534+ self .PATH_LDAPMODIFY ,
535+ extra_args = extra_args ,
536+ stdin_data = ldif .encode ("utf-8" ) if ldif else None ,
537+ expected = expected ,
501538 )
502539
503- def ldapdelete (self , dn , recursive = False , extra_args = None ):
540+ def ldapdelete (self , dn , recursive = False , extra_args = None , expected = 0 ):
504541 """
505542 Runs ldapdelete on this slapd instance, deleting 'dn'
506543
507- :return: A :class:`subprocess.CompletedProcess` with the execution data.
544+ :param dn: The distinguished name of the element to delete.
545+ :param recursive: Whether to delete sub-elements. Defaults to `False`.
546+ :param extra_args: Extra argument to pass to *ldapdelete*.
547+ :param expected: Expected return code. Defaults to `0`.
548+ :type expected: An integer or a list of integers
549+
550+ :return: A :class:`subprocess.CompletedProcess` with the *ldapdelete* execution data.
508551 """
509552 if extra_args is None :
510553 extra_args = []
511554 if recursive :
512555 extra_args .append ("-r" )
513556 extra_args .append (dn )
514- return self ._cli_popen (self .PATH_LDAPDELETE , extra_args = extra_args )
557+ return self ._cli_popen (
558+ self .PATH_LDAPDELETE , extra_args = extra_args , expected = expected
559+ )
515560
516- def slapadd (self , ldif , extra_args = None ):
561+ def slapadd (self , ldif , extra_args = None , expected = 0 ):
517562 """
518563 Runs slapadd on this slapd instance, passing it the ldif content
519564
520- :return: A :class:`subprocess.CompletedProcess` with the execution data.
565+ :param ldif: The ldif content to pass to the *slapadd* standard input.
566+ :param extra_args: Extra argument to pass to *slapadd*.
567+ :param expected: Expected return code. Defaults to `0`.
568+ :type expected: An integer or a list of integers
569+
570+ :return: A :class:`subprocess.CompletedProcess` with the *slapadd* execution data.
521571 """
522572 return self ._cli_popen (
523573 self .PATH_SLAPADD ,
524574 stdin_data = ldif .encode ("utf-8" ) if ldif else None ,
525575 extra_args = extra_args ,
576+ expected = expected ,
526577 )
527578
528- def slapcat (self , extra_args = None ):
579+ def slapcat (self , extra_args = None , expected = 0 ):
529580 """
530581 Runs slapadd on this slapd instance, passing it the ldif content
531582
532- :return: A :class:`subprocess.CompletedProcess` with the execution data.
583+ :param extra_args: Extra argument to pass to *slapcat*.
584+ :param expected: Expected return code. Defaults to `0`.
585+ :type expected: An integer or a list of integers
586+
587+ :return: A :class:`subprocess.CompletedProcess` with the *slapcat* execution data.
533588 """
534589 return self ._cli_popen (
535590 self .PATH_SLAPCAT ,
536591 extra_args = extra_args ,
592+ expected = expected ,
537593 )
0 commit comments