traffic: new version of model with packet_rate, version number
[samba.git] / python / samba / tests / domain_backup_offline.py
1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Andrew Bartlett <abartlet@samba.org>
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 #
17
18 import tarfile
19 import os
20 import shutil
21 import tempfile
22 from samba.tests import BlackboxTestCase
23 from samba.netcmd import CommandError
24
25 # The backup tests require that a completely clean LoadParm object gets used
26 # for the restore. Otherwise the same global LP gets re-used, and the LP
27 # settings can bleed from one test case to another.
28 # To do this, these tests should use check_output(), which executes the command
29 # in a separate process (as opposed to runcmd(), runsubcmd()).
30 # So although this is a samba-tool test, we don't inherit from SambaToolCmdTest
31 # so that we never inadvertently use .runcmd() by accident.
32 class DomainBackupOfflineCmp(BlackboxTestCase):
33
34     def test_domain_backup_offline_untar_tdb(self):
35         self.untar_testcase('tdb')
36
37     def test_domain_backup_offline_untar_mbd(self):
38         self.untar_testcase('mdb')
39
40     def test_domain_backup_offline_restore_tdb(self):
41         self.restore_testcase('tdb')
42
43     def test_domain_backup_offline_restore_mbd(self):
44         self.restore_testcase('mdb')
45
46     def restore_testcase(self, backend):
47         prov_dir, backup_file = self.provision_and_backup(backend)
48
49         extract_dir = tempfile.mkdtemp(dir=self.tempdir)
50         cmd = ("samba-tool domain backup restore --backup-file={f}"
51                " --targetdir={d} "
52                "--newservername=NEWSERVER").format(f=backup_file, d=extract_dir)
53         self.check_output(cmd)
54
55         # attrs that are altered by the restore process
56         ignore_attrs = ["servicePrincipalName", "lastLogonTimestamp",
57                         "rIDAllocationPool", "rIDAvailablePool",
58                         "localPolicyFlags", "operatingSystem", "displayName",
59                         "dnsRecord", "dNSTombstoned",
60                         "msDS-NC-Replica-Locations", "msDS-HasInstantiatedNCs",
61                         "interSiteTopologyGenerator"]
62         filter_arg = "--filter=" + ",".join(ignore_attrs)
63         args = ["--two", filter_arg]
64         self.ldapcmp(prov_dir, extract_dir, args)
65
66         shutil.rmtree(prov_dir)
67         shutil.rmtree(extract_dir)
68
69     def untar_testcase(self, backend):
70         prov_dir, backup_file = self.provision_and_backup(backend)
71
72         extract_dir = tempfile.mkdtemp(dir=self.tempdir)
73         tf = tarfile.open(backup_file)
74         tf.extractall(extract_dir)
75
76         self.ldapcmp(prov_dir, extract_dir)
77
78         shutil.rmtree(prov_dir)
79         shutil.rmtree(extract_dir)
80
81     def ldapcmp(self, prov_dir, ex_dir, args=[]):
82         sam_fn = os.path.join("private", "sam.ldb")
83         url1 = "tdb://" + os.path.join(os.path.realpath(prov_dir), sam_fn)
84         url2 = "tdb://" + os.path.join(os.path.realpath(ex_dir), sam_fn)
85
86         # Compare the restored sam.ldb with the old one
87         for partition in ["domain", "configuration", "schema",
88                           "dnsdomain", "dnsforest"]:
89             cmd = "samba-tool ldapcmp " + " ".join([url1, url2, partition] + args)
90             self.check_output(cmd)
91
92     # Test the "samba-tool domain backup" command with ldapcmp
93     def provision_and_backup(self, backend):
94         prov_dir = tempfile.mkdtemp(dir=self.tempdir)
95
96         # Provision domain.  Use fake ACLs and store xattrs in tdbs so that
97         # NTACL backup will work inside the testenv.
98         # host-name option must be given because if this test runs on a
99         # system with a very long hostname, it will be shortened in certain
100         # circumstances, causing the ldapcmp to fail.
101         prov_cmd = "samba-tool domain provision " +\
102                    "--domain FOO --realm foo.example.com " +\
103                    "--targetdir {prov_dir} " +\
104                    "--backend-store {backend} " +\
105                    "--host-name OLDSERVER "+\
106                    "--option=\"vfs objects=fake_acls xattr_tdb\""
107         prov_cmd = prov_cmd.format(prov_dir=prov_dir, backend=backend)
108         self.check_output(prov_cmd)
109
110         # Run the backup and check we got one backup tar file
111         cmd = ("samba-tool domain backup offline --targetdir={prov_dir} "
112                "-s {prov_dir}/etc/smb.conf").format(prov_dir=prov_dir)
113         self.check_output(cmd)
114
115         tar_files = [fn for fn in os.listdir(prov_dir)
116                      if fn.startswith("samba-backup-") and
117                      fn.endswith(".tar.bz2")]
118         if len(tar_files) != 1:
119             raise CommandError("expected domain backup to create one tar" +
120                                " file but got {0}".format(len(tar_files)))
121
122         backup_file = os.path.join(prov_dir, tar_files[0])
123         return prov_dir, backup_file