2007-12-17 05:25:28 +03:00
# Unix SMB/CIFS implementation.
2010-11-28 05:15:36 +03:00
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2010
#
2007-12-17 05:25:28 +03:00
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
2010-11-28 05:15:36 +03:00
#
2007-12-17 05:25:28 +03:00
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
2010-11-28 05:15:36 +03:00
#
2007-12-17 05:25:28 +03:00
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
2007-12-30 03:14:15 +03:00
""" Samba Python tests. """
2007-12-17 05:25:28 +03:00
import os
import ldb
import samba
2010-09-29 03:58:23 +04:00
import samba . auth
2010-06-13 18:38:24 +04:00
from samba import param
2010-11-28 05:15:36 +03:00
from samba . samdb import SamDB
2014-11-05 08:26:25 +03:00
from samba import credentials
2010-09-22 23:52:29 +04:00
import subprocess
2007-12-20 01:27:31 +03:00
import tempfile
2014-12-14 22:59:13 +03:00
import unittest
2007-12-17 05:25:28 +03:00
2014-12-14 22:59:13 +03:00
try :
2014-12-14 23:03:28 +03:00
from unittest import SkipTest
2014-12-14 22:59:13 +03:00
except ImportError :
2014-12-14 23:03:28 +03:00
class SkipTest ( Exception ) :
2014-12-14 22:59:13 +03:00
""" Test skipped. """
2011-11-17 05:30:38 +04:00
2010-06-19 19:48:05 +04:00
2014-12-14 22:59:13 +03:00
class TestCase ( unittest . TestCase ) :
2011-01-05 03:09:25 +03:00
""" A Samba test case. """
def setUp ( self ) :
super ( TestCase , self ) . setUp ( )
test_debug_level = os . getenv ( " TEST_DEBUG_LEVEL " )
if test_debug_level is not None :
test_debug_level = int ( test_debug_level )
self . _old_debug_level = samba . get_debug_level ( )
samba . set_debug_level ( test_debug_level )
self . addCleanup ( samba . set_debug_level , test_debug_level )
2010-12-15 16:57:43 +03:00
def get_loadparm ( self ) :
return env_loadparm ( )
def get_credentials ( self ) :
return cmdline_credentials
2015-01-27 05:44:10 +03:00
# These functions didn't exist before Python2.7:
2014-12-15 20:35:24 +03:00
if not getattr ( unittest . TestCase , " skipTest " , None ) :
def skipTest ( self , reason ) :
raise SkipTest ( reason )
2015-01-27 05:40:34 +03:00
if not getattr ( unittest . TestCase , " assertIs " , None ) :
def assertIs ( self , a , b ) :
self . assertTrue ( a is b )
if not getattr ( unittest . TestCase , " assertIsNot " , None ) :
def assertIsNot ( self , a , b ) :
self . assertTrue ( a is not b )
2015-01-29 01:17:13 +03:00
if not getattr ( unittest . TestCase , " assertIsInstance " , None ) :
def assertIsInstance ( self , a , b ) :
self . assertTrue ( isinstance ( a , b ) )
2015-01-27 05:44:10 +03:00
if not getattr ( unittest . TestCase , " addCleanup " , None ) :
def addCleanup ( self , fn , * args , * * kwargs ) :
self . _cleanups = getattr ( self , " _cleanups " , [ ] ) + [
( fn , args , kwargs ) ]
2015-01-30 04:16:05 +03:00
def run ( self , result = None ) :
ret = super ( TestCase , self ) . run ( result = result )
2015-01-27 05:44:10 +03:00
for ( fn , args , kwargs ) in reversed ( getattr ( self , " _cleanups " , [ ] ) ) :
fn ( * args , * * kwargs )
2015-01-30 04:16:05 +03:00
return ret
2015-01-27 05:44:10 +03:00
2010-12-15 16:57:43 +03:00
2015-01-30 04:06:33 +03:00
class LdbTestCase ( TestCase ) :
2007-12-30 03:14:15 +03:00
""" Trivial test case for running tests against a LDB. """
2010-06-19 20:58:18 +04:00
2007-12-17 05:25:28 +03:00
def setUp ( self ) :
2010-06-19 20:58:18 +04:00
super ( LdbTestCase , self ) . setUp ( )
2007-12-17 05:25:28 +03:00
self . filename = os . tempnam ( )
self . ldb = samba . Ldb ( self . filename )
2007-12-17 13:12:36 +03:00
def set_modules ( self , modules = [ ] ) :
2007-12-30 03:14:15 +03:00
""" Change the modules for this Ldb. """
2007-12-17 05:25:28 +03:00
m = ldb . Message ( )
m . dn = ldb . Dn ( self . ldb , " @MODULES " )
m [ " @LIST " ] = " , " . join ( modules )
self . ldb . add ( m )
self . ldb = samba . Ldb ( self . filename )
2010-06-19 19:48:05 +04:00
class TestCaseInTempDir ( TestCase ) :
2009-04-06 01:03:13 +04:00
2007-12-20 01:27:31 +03:00
def setUp ( self ) :
super ( TestCaseInTempDir , self ) . setUp ( )
self . tempdir = tempfile . mkdtemp ( )
2012-10-27 03:58:06 +04:00
self . addCleanup ( self . _remove_tempdir )
2007-12-20 01:27:31 +03:00
2012-10-27 03:58:06 +04:00
def _remove_tempdir ( self ) :
2008-05-29 19:29:56 +04:00
self . assertEquals ( [ ] , os . listdir ( self . tempdir ) )
2007-12-26 01:36:31 +03:00
os . rmdir ( self . tempdir )
2012-10-27 03:58:06 +04:00
self . tempdir = None
2007-12-20 01:27:31 +03:00
2010-06-13 18:38:24 +04:00
def env_loadparm ( ) :
lp = param . LoadParm ( )
try :
lp . load ( os . environ [ " SMB_CONF_PATH " ] )
except KeyError :
2014-12-02 07:04:40 +03:00
raise KeyError ( " SMB_CONF_PATH not set " )
2010-06-13 18:38:24 +04:00
return lp
2010-11-28 05:34:47 +03:00
2010-09-29 15:53:12 +04:00
def env_get_var_value ( var_name ) :
""" Returns value for variable in os.environ
Function throws AssertionError if variable is defined .
Unit - test based python tests require certain input params
to be set in environment , otherwise they can ' t be run
"""
assert var_name in os . environ . keys ( ) , " Please supply %s in environment " % var_name
return os . environ [ var_name ]
2008-04-14 21:13:41 +04:00
cmdline_credentials = None
2008-04-14 20:30:07 +04:00
2010-06-19 19:48:05 +04:00
class RpcInterfaceTestCase ( TestCase ) :
2010-12-15 16:57:43 +03:00
""" DCE/RPC Test case. """
2009-04-06 01:17:43 +04:00
2010-06-19 19:48:05 +04:00
class ValidNetbiosNameTests ( TestCase ) :
2009-04-06 01:17:43 +04:00
def test_valid ( self ) :
2009-04-20 13:11:25 +04:00
self . assertTrue ( samba . valid_netbios_name ( " FOO " ) )
2009-04-06 01:17:43 +04:00
def test_too_long ( self ) :
2009-04-20 13:11:25 +04:00
self . assertFalse ( samba . valid_netbios_name ( " FOO " * 10 ) )
2009-04-06 01:17:43 +04:00
def test_invalid_characters ( self ) :
2009-04-20 13:11:25 +04:00
self . assertFalse ( samba . valid_netbios_name ( " *BLA " ) )
2010-09-22 23:52:29 +04:00
2012-01-09 14:55:08 +04:00
class BlackboxProcessError ( Exception ) :
""" This is raised when check_output() process returns a non-zero exit status
Exception instance should contain the exact exit code ( S . returncode ) ,
command line ( S . cmd ) , process output ( S . stdout ) and process error stream
( S . stderr )
"""
2011-02-20 05:15:08 +03:00
def __init__ ( self , returncode , cmd , stdout , stderr ) :
2012-01-09 14:55:08 +04:00
self . returncode = returncode
self . cmd = cmd
2011-02-20 05:15:08 +03:00
self . stdout = stdout
self . stderr = stderr
2012-01-09 14:55:08 +04:00
2011-02-20 05:15:08 +03:00
def __str__ ( self ) :
return " Command ' %s ' ; exit status %d ; stdout: ' %s ' ; stderr: ' %s ' " % ( self . cmd , self . returncode ,
self . stdout , self . stderr )
2010-09-22 23:52:29 +04:00
class BlackboxTestCase ( TestCase ) :
""" Base test case for blackbox tests. """
2011-02-09 04:40:17 +03:00
def _make_cmdline ( self , line ) :
2010-09-22 23:52:29 +04:00
bindir = os . path . abspath ( os . path . join ( os . path . dirname ( __file__ ) , " ../../../../bin " ) )
parts = line . split ( " " )
if os . path . exists ( os . path . join ( bindir , parts [ 0 ] ) ) :
parts [ 0 ] = os . path . join ( bindir , parts [ 0 ] )
line = " " . join ( parts )
2011-02-09 04:40:17 +03:00
return line
def check_run ( self , line ) :
line = self . _make_cmdline ( line )
2012-01-09 16:21:49 +04:00
p = subprocess . Popen ( line , stdout = subprocess . PIPE , stderr = subprocess . PIPE , shell = True )
retcode = p . wait ( )
if retcode :
raise BlackboxProcessError ( retcode , line , p . stdout . read ( ) , p . stderr . read ( ) )
2010-09-29 03:58:23 +04:00
2011-02-09 04:01:16 +03:00
def check_output ( self , line ) :
2011-02-09 04:40:17 +03:00
line = self . _make_cmdline ( line )
2011-02-20 05:17:25 +03:00
p = subprocess . Popen ( line , stdout = subprocess . PIPE , stderr = subprocess . PIPE , shell = True , close_fds = True )
2011-02-09 04:01:16 +03:00
retcode = p . wait ( )
if retcode :
2011-02-20 05:17:25 +03:00
raise BlackboxProcessError ( retcode , line , p . stdout . read ( ) , p . stderr . read ( ) )
2011-02-09 04:01:16 +03:00
return p . stdout . read ( )
2010-09-29 03:58:23 +04:00
2014-10-13 08:11:22 +04:00
2010-11-28 05:15:36 +03:00
def connect_samdb ( samdb_url , lp = None , session_info = None , credentials = None ,
2014-10-13 08:11:22 +04:00
flags = 0 , ldb_options = None , ldap_only = False , global_schema = True ) :
2010-11-28 05:15:36 +03:00
""" Create SamDB instance and connects to samdb_url database.
2010-09-29 03:58:23 +04:00
: param samdb_url : Url for database to connect to .
: param lp : Optional loadparm object
: param session_info : Optional session information
: param credentials : Optional credentials , defaults to anonymous .
: param flags : Optional LDB flags
: param ldap_only : If set , only remote LDAP connection will be created .
2014-10-13 08:11:22 +04:00
: param global_schema : Whether to use global schema .
2010-09-29 03:58:23 +04:00
Added value for tests is that we have a shorthand function
to make proper URL for ldb . connect ( ) while using default
parameters for connection based on test environment
"""
if not " :// " in samdb_url :
if not ldap_only and os . path . isfile ( samdb_url ) :
samdb_url = " tdb:// %s " % samdb_url
else :
samdb_url = " ldap:// %s " % samdb_url
# use 'paged_search' module when connecting remotely
if samdb_url . startswith ( " ldap:// " ) :
ldb_options = [ " modules:paged_searches " ]
2010-11-28 05:15:36 +03:00
elif ldap_only :
raise AssertionError ( " Trying to connect to %s while remote "
" connection is required " % samdb_url )
2010-09-29 03:58:23 +04:00
# set defaults for test environment
2010-11-28 05:15:36 +03:00
if lp is None :
lp = env_loadparm ( )
if session_info is None :
session_info = samba . auth . system_session ( lp )
if credentials is None :
credentials = cmdline_credentials
2010-09-29 03:58:23 +04:00
return SamDB ( url = samdb_url ,
lp = lp ,
session_info = session_info ,
credentials = credentials ,
flags = flags ,
2014-10-13 08:11:22 +04:00
options = ldb_options ,
global_schema = global_schema )
2010-11-22 16:03:59 +03:00
2010-11-28 05:15:36 +03:00
def connect_samdb_ex ( samdb_url , lp = None , session_info = None , credentials = None ,
flags = 0 , ldb_options = None , ldap_only = False ) :
2010-11-22 16:03:59 +03:00
""" Connects to samdb_url database
: param samdb_url : Url for database to connect to .
: param lp : Optional loadparm object
: param session_info : Optional session information
: param credentials : Optional credentials , defaults to anonymous .
: param flags : Optional LDB flags
: param ldap_only : If set , only remote LDAP connection will be created .
: return : ( sam_db_connection , rootDse_record ) tuple
"""
2010-11-28 05:15:36 +03:00
sam_db = connect_samdb ( samdb_url , lp , session_info , credentials ,
2010-11-22 16:03:59 +03:00
flags , ldb_options , ldap_only )
# fetch RootDse
2010-11-28 05:15:36 +03:00
res = sam_db . search ( base = " " , expression = " " , scope = ldb . SCOPE_BASE ,
attrs = [ " * " ] )
2010-11-22 16:03:59 +03:00
return ( sam_db , res [ 0 ] )
2010-11-24 18:47:27 +03:00
2010-11-28 05:15:36 +03:00
2014-11-05 08:26:25 +03:00
def connect_samdb_env ( env_url , env_username , env_password , lp = None ) :
""" Connect to SamDB by getting URL and Credentials from environment
: param env_url : Environment variable name to get lsb url from
: param env_username : Username environment variable
: param env_password : Password environment variable
: return : sam_db_connection
"""
samdb_url = env_get_var_value ( env_url )
creds = credentials . Credentials ( )
if lp is None :
# guess Credentials parameters here. Otherwise workstation
# and domain fields are NULL and gencache code segfalts
lp = param . LoadParm ( )
creds . guess ( lp )
creds . set_username ( env_get_var_value ( env_username ) )
creds . set_password ( env_get_var_value ( env_password ) )
return connect_samdb ( samdb_url , credentials = creds , lp = lp )
2010-11-24 18:47:27 +03:00
def delete_force ( samdb , dn ) :
try :
samdb . delete ( dn )
2014-11-02 19:11:20 +03:00
except ldb . LdbError , ( num , errstr ) :
assert num == ldb . ERR_NO_SUCH_OBJECT , " ldb.delete() failed: %s " % errstr