File: roottest.py

package info (click to toggle)
duplicity 3.0.5.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,260 kB
  • sloc: python: 25,089; sh: 934; ansic: 392; makefile: 83
file content (136 lines) | stat: -rwxr-xr-x 4,796 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/python3

# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
#
# Copyright 2002 Ben Escoto
# Copyright 2007 Kenneth Loafman
#
# This file is part of duplicity.
#
# Duplicity 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 2 of the License, or (at your
# option) any later version.
#
# Duplicity 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.
#
# You should have received a copy of the GNU General Public License
# along with duplicity; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

import sys
import unittest

sys.path.insert(0, "../")

from duplicity import diffdir
from duplicity import patchdir
from duplicity import selection
from duplicity.path import *  # pylint: disable=unused-wildcard-import,redefined-builtin

config.setup()


class RootTest(unittest.TestCase):
    """Test doing operations that only root can"""

    def setUp(self):
        super().setUp()
        # must run with euid/egid of root
        assert os.geteuid() == 0
        # make sure uid/gid match euid/egid
        os.setuid(os.geteuid())
        os.setgid(os.getegid())
        assert not os.system("tar xzf manual/rootfiles.tar.gz > /dev/null 2>&1")

    def tearDown(self):
        assert not os.system("rm -rf /tmp/testfiles tempdir temp2.tar")
        super().tearDown()

    def copyfileobj(self, infp, outfp):
        """Copy in fileobj to out, closing afterwards"""
        blocksize = 32 * 1024
        while True:
            buf = infp.read(blocksize)
            if not buf:
                break
            outfp.write(buf)
        assert not infp.close()
        assert not outfp.close()

    def deltmp(self):
        """Delete temporary directories"""
        assert not os.system("rm -rf /tmp/testfiles/output")
        os.mkdir("/tmp/testfiles/output")

    def get_sel(self, path):
        """Get selection iter over the given directory"""
        return selection.Select(path).set_iter()

    def total_sequence(self, filelist):
        """Test signatures, diffing, and patching on directory list"""
        assert len(filelist) >= 2
        self.deltmp()
        assert not os.system(f"cp -pR {filelist[0]} /tmp/testfiles/output/sequence")
        seq_path = Path("/tmp/testfiles/output/sequence")
        sig = Path("/tmp/testfiles/output/sig.tar")
        diff = Path("/tmp/testfiles/output/diff.tar")
        for dirname in filelist[1:]:
            new_path = Path(dirname)
            diffdir.write_block_iter(diffdir.DirSig(selection.Select(seq_path).set_iter()), sig)

            diffdir.write_block_iter(
                diffdir.DirDelta(selection.Select(new_path).set_iter(), sig.open("rb")),
                diff,
            )

            patchdir.Patch(seq_path, diff.open("rb"))

            assert seq_path.compare_recursive(new_path, 1)

    def test_basic_cycle(self):
        """Test cycle on dir with devices, changing uid/gid, etc."""
        self.total_sequence(["/tmp/testfiles/root1", "/tmp/testfiles/root2"])

    def test_patchdir(self):
        """Test changing uid/gid, devices"""
        self.deltmp()
        os.system("cp -pR /tmp/testfiles/root1 /tmp/testfiles/output/sequence")
        seq_path = Path("/tmp/testfiles/output/sequence")
        new_path = Path("/tmp/testfiles/root2")
        sig = Path("/tmp/testfiles/output/sig.tar")
        diff = Path("/tmp/testfiles/output/diff.tar")

        diffdir.write_block_iter(diffdir.DirSig(self.get_sel(seq_path)), sig)
        deltablock = diffdir.DirDelta(self.get_sel(new_path), sig.open("rb"))
        diffdir.write_block_iter(deltablock, diff)

        patchdir.Patch(seq_path, diff.open("rb"))

        # since we are not running as root, don't even both comparing,
        # just make sure file5 exists and file4 doesn't.
        file5 = seq_path.append("file5")
        assert file5.isreg()
        file4 = seq_path.append("file4")
        assert file4.type is None

    def test_patchdir2(self):
        """Again test files we don't have access to, this time Tar_WriteSig"""
        self.deltmp()
        sig_path = Path("/tmp/testfiles/output/sig.sigtar")
        tar_path = Path("/tmp/testfiles/output/tar.tar")
        basis_path = Path("/tmp/testfiles/root1")

        deltablock = diffdir.DirFull_WriteSig(self.get_sel(basis_path), sig_path.open("wb"))
        diffdir.write_block_iter(deltablock, tar_path)


def runtests():
    unittest.main()


if __name__ == "__main__":
    unittest.main()