2010-06-24 08:33:58 +04:00
#!/usr/bin/env python
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
2010-09-22 23:52:29 +04:00
import subprocess
2007-12-20 01:27:31 +03:00
import tempfile
2007-12-17 05:25:28 +03:00
2011-11-17 05:30:38 +04:00
samba . ensure_external_module ( " testtools " , " testtools " )
2010-06-19 19:48:05 +04:00
# Other modules import these two classes from here, for convenience:
2010-12-15 16:57:43 +03:00
from testtools . testcase import (
TestCase as TesttoolsTestCase ,
TestSkipped ,
)
2010-06-19 19:48:05 +04:00
2010-12-15 16:57:43 +03:00
class TestCase ( TesttoolsTestCase ) :
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
class LdbTestCase ( TesttoolsTestCase ) :
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 ( )
def tearDown ( self ) :
super ( TestCaseInTempDir , self ) . tearDown ( )
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 )
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 :
raise Exception ( " SMB_CONF_PATH not set " )
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
2011-02-20 05:15:08 +03:00
class BlackboxProcessError ( subprocess . CalledProcessError ) :
""" This exception is raised when a process run by check_output() 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 ) """
def __init__ ( self , returncode , cmd , stdout , stderr ) :
super ( BlackboxProcessError , self ) . __init__ ( returncode , cmd )
self . stdout = stdout
self . stderr = stderr
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 )
2010-09-22 23:52:29 +04:00
subprocess . check_call ( line , shell = True )
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
2010-11-28 05:15:36 +03:00
def connect_samdb ( samdb_url , lp = None , session_info = None , credentials = None ,
flags = 0 , ldb_options = None , ldap_only = False ) :
""" 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 .
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
"""
samdb_url = samdb_url . lower ( )
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 ,
options = ldb_options )
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
2010-11-24 18:47:27 +03:00
def delete_force ( samdb , dn ) :
try :
samdb . delete ( dn )
except ldb . LdbError , ( num , _ ) :
assert ( num == ldb . ERR_NO_SUCH_OBJECT )