[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Thu Nov 18 22:04:02 MST 2010


The branch, master has been updated
       via  fcb7729 wintest: the start of a S3 testing script for wintest
       via  7bfc60e wintest: added del_files, write_file and casefold
       via  8f1df57 wintest: move conf files to conf/
       via  10c2465 wintest: rename test-howto.py to test-s4-howto.py
       via  24e8bc5 wintest: moved to top level
       via  999f3ed talloc: added TALLOC_FREE_FILL environment variable
      from  58c43f7 s4-wintest: reliability and usability improvements

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit fcb7729c6cb3430b35ac58fd96b433ba7179d297
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Nov 19 14:08:56 2010 +1100

    wintest: the start of a S3 testing script for wintest
    
    this is just a skeleton at this stage.
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Fri Nov 19 06:03:55 CET 2010 on sn-devel-104

commit 7bfc60e40cae4d71301be27d5c44ce99a471a62b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Nov 19 14:08:18 2010 +1100

    wintest: added del_files, write_file and casefold

commit 8f1df5726576f045f9c9a3305f388d7d823750e6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Nov 19 14:07:37 2010 +1100

    wintest: move conf files to conf/

commit 10c246567c002f5ae0206b44b0d240814a5eef6b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Nov 19 12:07:02 2010 +1100

    wintest: rename test-howto.py to test-s4-howto.py
    
    ready for test-s3.py

commit 24e8bc544169eff6895d73045439ab32e7afa507
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Nov 19 12:06:02 2010 +1100

    wintest: moved to top level
    
    the plan is to expand wintest to test a lot more of Samba against
    windows, including testing the Samba3 file server, winbind, nmbd etc

commit 999f3ed2ce656ecf97b95afa85823115939f9360
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Nov 19 11:04:33 2010 +1100

    talloc: added TALLOC_FREE_FILL environment variable
    
    when this environment variable is set, talloc will fill freed memory
    with the value from that environment variable. This can be used to
    help find use after free bugs when valgrind is too slow to be used

-----------------------------------------------------------------------

Summary of changes:
 lib/talloc/talloc.c                                |   30 +++
 .../devel/wintest => wintest/conf}/tridge.conf     |    0
 wintest/test-s3.py                                 |  202 ++++++++++++++++++++
 .../test-howto.py => wintest/test-s4-howto.py      |   33 ++--
 .../scripting/devel/wintest => wintest}/wintest.py |   24 ++-
 5 files changed, 272 insertions(+), 17 deletions(-)
 rename {source4/scripting/devel/wintest => wintest/conf}/tridge.conf (100%)
 create mode 100755 wintest/test-s3.py
 rename source4/scripting/devel/wintest/test-howto.py => wintest/test-s4-howto.py (98%)
 rename {source4/scripting/devel/wintest => wintest}/wintest.py (92%)


Changeset truncated at 500 lines:

diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index 84947a7..ec67a46 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -104,6 +104,17 @@
 static void *null_context;
 static void *autofree_context;
 
+/* used to enable fill of memory on free, which can be useful for
+ * catching use after free errors when valgrind is too slow
+ */
+static struct {
+	bool initialised;
+	bool enabled;
+	uint8_t fill_value;
+} talloc_fill;
+
+#define TALLOC_FILL_ENV "TALLOC_FREE_FILL"
+
 struct talloc_reference_handle {
 	struct talloc_reference_handle *next, *prev;
 	void *ptr;
@@ -567,6 +578,16 @@ static inline int _talloc_free_internal(void *ptr, const char *location)
 		return -1;
 	}
 
+	/* possibly initialised the talloc fill value */
+	if (!talloc_fill.initialised) {
+		const char *fill = getenv(TALLOC_FILL_ENV);
+		if (fill != NULL) {
+			talloc_fill.enabled = true;
+			talloc_fill.fill_value = strtoul(fill, NULL, 0);
+		}
+		talloc_fill.initialised = true;
+	}
+
 	tc = talloc_chunk_from_ptr(ptr);
 
 	if (unlikely(tc->refs)) {
@@ -662,10 +683,19 @@ static inline int _talloc_free_internal(void *ptr, const char *location)
 		*pool_object_count -= 1;
 
 		if (*pool_object_count == 0) {
+			if (talloc_fill.enabled) {
+				memset(TC_PTR_FROM_CHUNK(pool), talloc_fill.fill_value, pool->size);
+			}
 			free(pool);
 		}
 	}
 	else {
+		if (talloc_fill.enabled) {
+			/* don't wipe the header, to allow the
+			   double-free logic to still work
+			*/
+			memset(TC_PTR_FROM_CHUNK(tc), talloc_fill.fill_value, tc->size);
+		}
 		free(tc);
 	}
 	return 0;
diff --git a/source4/scripting/devel/wintest/tridge.conf b/wintest/conf/tridge.conf
similarity index 100%
rename from source4/scripting/devel/wintest/tridge.conf
rename to wintest/conf/tridge.conf
diff --git a/wintest/test-s3.py b/wintest/test-s3.py
new file mode 100755
index 0000000..9241ecb
--- /dev/null
+++ b/wintest/test-s3.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+
+'''automated testing of Samba3 against windows'''
+
+import sys, os
+import optparse
+import wintest
+
+def check_prerequesites(t):
+    t.info("Checking prerequesites")
+    t.setvar('HOSTNAME', t.cmd_output("hostname -s").strip())
+    if os.getuid() != 0:
+        raise Exception("You must run this script as root")
+    t.putenv("LD_LIBRARY_PATH", "${PREFIX}/lib")
+
+
+def build_s3(t):
+    '''build samba3'''
+    t.info('Building s3')
+    t.chdir('${SOURCETREE}/source3')
+    t.putenv('CC', 'ccache gcc')
+    t.run_cmd("./autogen.sh")
+    t.run_cmd("./configure -C --prefix=${PREFIX} --enable-developer")
+    t.run_cmd('make basics')
+    t.run_cmd('make -j4')
+    t.run_cmd('rm -rf ${PREFIX}')
+    t.run_cmd('make install')
+
+def start_s3(t, interfaces=None):
+    t.info('Starting Samba3')
+    t.chdir("${PREFIX}")
+    t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
+    t.run_cmd("rm -f var/locks/*.pid")
+    t.run_cmd(['sbin/nmbd', "-D"])
+    t.run_cmd(['sbin/winbindd', "-D"])
+    t.run_cmd(['sbin/smbd', "-D"])
+    t.port_wait("localhost", 139)
+
+def test_wbinfo(t):
+    t.info('Testing wbinfo')
+    t.chdir('${PREFIX}')
+    t.cmd_contains("bin/wbinfo --version", ["Version 3."])
+    t.cmd_contains("bin/wbinfo -p", ["Ping to winbindd succeeded"])
+    t.retry_cmd("bin/wbinfo --online-status",
+                ["BUILTIN : online",
+                 "${HOSTNAME} : online",
+                 "${WIN_DOMAIN} : online"],
+                casefold=True)
+    t.cmd_contains("bin/wbinfo -u",
+                   ["${WIN_DOMAIN}/administrator",
+                    "${WIN_DOMAIN}/krbtgt" ],
+                   casefold=True)
+    t.cmd_contains("bin/wbinfo -g",
+                   ["${WIN_DOMAIN}/domain users",
+                    "${WIN_DOMAIN}/domain guests",
+                    "${WIN_DOMAIN}/domain admins"],
+                   casefold=True)
+    t.cmd_contains("bin/wbinfo --name-to-sid administrator",
+                   "S-1-5-.*-500 SID_USER .1",
+                   regex=True)
+    t.cmd_contains("bin/wbinfo --name-to-sid 'domain users'",
+                   "S-1-5-.*-513 SID_DOM_GROUP .2",
+                   regex=True)
+
+    t.retry_cmd("bin/wbinfo --authenticate=administrator%${WIN_PASS}",
+                ["plaintext password authentication succeeded",
+                 "challenge/response password authentication succeeded"])
+
+
+def test_smbclient(t):
+    t.info('Testing smbclient')
+    t.chdir('${PREFIX}')
+    t.cmd_contains("bin/smbclient --version", ["Version 3."])
+    t.cmd_contains('bin/smbclient -L localhost -U%', ["Domain=[${WIN_DOMAIN}]", "test", "IPC$", "Samba 3."],
+                   casefold=True)
+    child = t.pexpect_spawn('bin/smbclient //${HOSTNAME}/test -Uadministrator%${WIN_PASS}')
+    child.expect("smb:")
+    child.sendline("dir")
+    child.expect("blocks available")
+    child.sendline("mkdir testdir")
+    child.expect("smb:")
+    child.sendline("cd testdir")
+    child.expect('testdir')
+    child.sendline("cd ..")
+    child.sendline("rmdir testdir")
+
+
+def create_shares(t):
+    t.info("Adding test shares")
+    t.chdir('${PREFIX}')
+    t.write_file("lib/smb.conf", '''
+[test]
+       path = ${PREFIX}/test
+       read only = no
+       ''',
+                 mode='a')
+    t.run_cmd("mkdir -p test")
+
+
+def join_as_member(t, vm):
+    '''join a windows domain as a member server'''
+    t.setwinvars(vm)
+    t.info("Joining ${WIN_VM} as a member using net ads join")
+    t.chdir('${PREFIX}')
+    t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
+    t.vm_poweroff("${WIN_VM}", checkfail=False)
+    t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
+    t.ping_wait("${WIN_HOSTNAME}")
+    child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_time=True)
+    t.del_files(["var", "private"])
+    t.write_file("lib/smb.conf", '''
+[global]
+	netbios name = ${HOSTNAME}
+	log level = ${DEBUGLEVEL}
+        realm = ${WIN_REALM}
+        workgroup = ${WIN_DOMAIN}
+        security = ADS
+        interfaces = ${INTERFACES}
+        winbind separator = /
+        idmap uid = 1000000-2000000
+        idmap gid = 1000000-2000000
+        winbind enum users = yes
+        winbind enum groups = yes
+        max protocol = SMB2
+        map hidden = no
+        map system = no
+        ea support = yes
+        panic action = xterm -e gdb --pid %d
+    ''')
+    t.cmd_contains("bin/net ads join -Uadministrator%${WIN_PASS}", ["Joined"])
+    t.cmd_contains("bin/net ads testjoin", ["Join is OK"])
+
+
+def test_join_as_member(t, vm):
+    '''test the domain join'''
+    t.setwinvars(vm)
+    t.info('Testing join as member')
+    t.chdir('${PREFIX}')
+    t.cmd_contains('bin/net ads user add root -Uadministrator%${WIN_PASS}')
+    test_wbinfo(t)
+    test_smbclient(t)
+
+
+def test_s3(t):
+    '''basic s3 testing'''
+
+    check_prerequesites(t)
+
+    # we don't need fsync safety in these tests
+    t.putenv('TDB_NO_FSYNC', '1')
+
+    if not t.skip("build"):
+        build_s3(t)
+
+    if t.have_var('W2K8R2A_VM') and not t.skip("join_w2k8r2"):
+        join_as_member(t, "W2K8R2A")
+        create_shares(t)
+        start_s3(t, interfaces='${INTERFACES}')
+        test_join_as_member(t, "W2K8R2A")
+
+    t.info("S3 test: All OK")
+
+if __name__ == '__main__':
+    parser = optparse.OptionParser("test-howto.py")
+    parser.add_option("--conf", type='string', default='', help='config file')
+    parser.add_option("--skip", type='string', default='', help='list of steps to skip (comma separated)')
+    parser.add_option("--list", action='store_true', default=False, help='list the available steps')
+    parser.add_option("--rebase", action='store_true', default=False, help='do a git pull --rebase')
+    parser.add_option("--clean", action='store_true', default=False, help='clean the tree')
+    parser.add_option("--prefix", type='string', default=None, help='override install prefix')
+    parser.add_option("--sourcetree", type='string', default=None, help='override sourcetree location')
+
+    opts, args = parser.parse_args()
+
+    if not opts.conf:
+        print("Please specify a config file with --conf")
+        sys.exit(1)
+
+    t = wintest.wintest()
+    t.load_config(opts.conf)
+    t.set_skip(opts.skip)
+
+    if opts.list:
+        t.list_steps_mode()
+
+    if opts.prefix:
+        t.setvar('PREFIX', opts.prefix)
+
+    if opts.sourcetree:
+        t.setvar('SOURCETREE', opts.sourcetree)
+
+    if opts.rebase:
+        t.info('rebasing')
+        t.chdir('${SOURCETREE}')
+        t.run_cmd('git pull --rebase')
+
+    if opts.clean:
+        t.info('rebasing')
+        t.chdir('${SOURCETREE}/source3')
+        t.run_cmd('make clean')
+
+    test_s3(t)
diff --git a/source4/scripting/devel/wintest/test-howto.py b/wintest/test-s4-howto.py
similarity index 98%
rename from source4/scripting/devel/wintest/test-howto.py
rename to wintest/test-s4-howto.py
index 402519f..b925973 100755
--- a/source4/scripting/devel/wintest/test-howto.py
+++ b/wintest/test-s4-howto.py
@@ -6,8 +6,6 @@ import sys, os
 import optparse
 import wintest
 
-vars = {}
-
 def check_prerequesites(t):
     t.info("Checking prerequesites")
     t.setvar('HOSTNAME', t.cmd_output("hostname -s").strip())
@@ -30,8 +28,7 @@ def provision_s4(t, func_level="2008", interfaces=None):
     '''provision s4 as a DC'''
     t.info('Provisioning s4')
     t.chdir('${PREFIX}')
-    t.run_cmd("rm -rf etc private")
-    t.run_cmd("find var -type f | xargs rm -f")
+    t.del_files(["var", "etc", "private"])
     options=' --function-level=%s -d${DEBUGLEVEL}' % func_level
     if interfaces:
         options += ' --option=interfaces=%s' % interfaces
@@ -68,16 +65,15 @@ def test_smbclient(t):
 def create_shares(t):
     t.info("Adding test shares")
     t.chdir('${PREFIX}')
-    f = open("etc/smb.conf", mode='a')
-    f.write(t.substitute('''
+    t.write_file("etc/smb.conf", '''
 [test]
        path = ${PREFIX}/test
        read only = no
 [profiles]
        path = ${PREFIX}/var/profiles
        read only = no
-    '''))
-    f.close()
+    ''',
+                 mode='a')
     t.run_cmd("mkdir -p test")
     t.run_cmd("mkdir -p var/profiles")
 
@@ -150,7 +146,7 @@ def test_winjoin(t, vm):
 def run_dcpromo(t, vm):
     '''run a dcpromo on windows'''
     t.setwinvars(vm)
-    
+
     t.info("Joining a windows VM ${WIN_VM} to the domain as a DC using dcpromo")
     t.vm_poweroff("${WIN_VM}", checkfail=False)
     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
@@ -523,7 +519,7 @@ def test_howto(t):
         test_kerberos(t)
     if not t.skip("dyndns"):
         test_dyndns(t)
-    
+
     if t.have_var('WINDOWS7_VM') and not t.skip("windows7"):
         run_winjoin(t, "WINDOWS7")
         test_winjoin(t, "WINDOWS7")
@@ -531,7 +527,7 @@ def test_howto(t):
     if t.have_var('WINXP_VM') and not t.skip("winxp"):
         run_winjoin(t, "WINXP")
         test_winjoin(t, "WINXP")
-    
+
     if t.have_var('W2K8R2C_VM') and not t.skip("dcpromo_rodc"):
         t.info("Testing w2k8r2 RODC dcpromo")
         run_dcpromo_rodc(t, "W2K8R2C")
@@ -560,7 +556,7 @@ def test_howto(t):
         test_dyndns(t)
         run_dcpromo(t, "W2K3B")
         test_dcpromo(t, "W2K3B")
-    
+
     if t.have_var('W2K8R2A_VM') and not t.skip("join_w2k8r2"):
         join_as_dc(t, "W2K8R2A")
         create_shares(t)
@@ -574,7 +570,7 @@ def test_howto(t):
         start_s4(t, interfaces='${INTERFACES}')
         test_dyndns(t)
         test_join_as_rodc(t, "W2K8R2A")
-    
+
     if t.have_var('W2K3A_VM') and not t.skip("join_w2k3"):
         join_as_dc(t, "W2K3A")
         create_shares(t)
@@ -592,19 +588,28 @@ if __name__ == '__main__':
     parser.add_option("--list", action='store_true', default=False, help='list the available steps')
     parser.add_option("--rebase", action='store_true', default=False, help='do a git pull --rebase')
     parser.add_option("--clean", action='store_true', default=False, help='clean the tree')
+    parser.add_option("--prefix", type='string', default=None, help='override install prefix')
+    parser.add_option("--sourcetree", type='string', default=None, help='override sourcetree location')
 
     opts, args = parser.parse_args()
 
     if not opts.conf:
-        t.info("Please specify a config file with --conf")
+        print("Please specify a config file with --conf")
         sys.exit(1)
 
     t = wintest.wintest()
     t.load_config(opts.conf)
     t.set_skip(opts.skip)
+
     if opts.list:
         t.list_steps_mode()
 
+    if opts.prefix:
+        t.setvar('PREFIX', opts.prefix)
+
+    if opts.sourcetree:
+        t.setvar('SOURCETREE', opts.sourcetree)
+
     if opts.rebase:
         t.info('rebasing')
         t.chdir('${SOURCETREE}')
diff --git a/source4/scripting/devel/wintest/wintest.py b/wintest/wintest.py
similarity index 92%
rename from source4/scripting/devel/wintest/wintest.py
rename to wintest/wintest.py
index f871462..5706f88 100644
--- a/source4/scripting/devel/wintest/wintest.py
+++ b/wintest/wintest.py
@@ -96,6 +96,16 @@ class wintest():
         '''chdir with substitution'''
         os.chdir(self.substitute(dir))
 
+    def del_files(self, dirs):
+        '''delete all files in the given directory'''
+        for d in dirs:
+            self.run_cmd("find %s -type f | xargs rm -f" % d)
+
+    def write_file(self, filename, text, mode='w'):
+        '''write to a file'''
+        f = open(self.substitute(filename), mode=mode)
+        f.write(self.substitute(text))
+        f.close()
 
     def run_cmd(self, cmd, dir=".", show=None, output=False, checkfail=True):
         cmd = self.substitute(cmd)
@@ -120,8 +130,13 @@ class wintest():
         cmd = self.substitute(cmd)
         return self.run_cmd(cmd, output=True)
 
-    def cmd_contains(self, cmd, contains, nomatch=False, ordered=False, regex=False):
+    def cmd_contains(self, cmd, contains, nomatch=False, ordered=False, regex=False,
+                     casefold=False):
         '''check that command output contains the listed strings'''
+
+        if isinstance(contains, str):
+            contains = [contains]
+
         out = self.cmd_output(cmd)
         self.info(out)
         for c in self.substitute(contains):
@@ -133,6 +148,9 @@ class wintest():
                 else:
                     start = m.start()
                     end = m.end()
+            elif casefold:
+                start = out.upper().find(c.upper())
+                end = start + len(c)
             else:
                 start = out.find(c)
                 end = start + len(c)
@@ -146,12 +164,12 @@ class wintest():
                 out = out[end:]
 
     def retry_cmd(self, cmd, contains, retries=30, delay=2, wait_for_fail=False,
-                  ordered=False, regex=False):
+                  ordered=False, regex=False, casefold=False):
         '''retry a command a number of times'''
         while retries > 0:
             try:
                 self.cmd_contains(cmd, contains, nomatch=wait_for_fail,
-                                  ordered=ordered, regex=regex)
+                                  ordered=ordered, regex=regex, casefold=casefold)
                 return
             except:
                 time.sleep(delay)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list