summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/test/3rdparty/testtools-0.9.34/testtools/matchers/_filesystem.py
blob: 54f749b1359c627a83cfc6d73b779b8b81841e18 (plain)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# Copyright (c) 2009-2012 testtools developers. See LICENSE for details.

"""Matchers for things related to the filesystem."""

__all__ = [
    'FileContains',
    'DirExists',
    'FileExists',
    'HasPermissions',
    'PathExists',
    'SamePath',
    'TarballContains',
    ]

import os
import tarfile

from ._basic import Equals
from ._higherorder import (
    MatchesAll,
    MatchesPredicate,
    )
from ._impl import (
    Matcher,
    )


def PathExists():
    """Matches if the given path exists.

    Use like this::

      assertThat('/some/path', PathExists())
    """
    return MatchesPredicate(os.path.exists, "%s does not exist.")


def DirExists():
    """Matches if the path exists and is a directory."""
    return MatchesAll(
        PathExists(),
        MatchesPredicate(os.path.isdir, "%s is not a directory."),
        first_only=True)


def FileExists():
    """Matches if the given path exists and is a file."""
    return MatchesAll(
        PathExists(),
        MatchesPredicate(os.path.isfile, "%s is not a file."),
        first_only=True)


class DirContains(Matcher):
    """Matches if the given directory contains files with the given names.

    That is, is the directory listing exactly equal to the given files?
    """

    def __init__(self, filenames=None, matcher=None):
        """Construct a ``DirContains`` matcher.

        Can be used in a basic mode where the whole directory listing is
        matched against an expected directory listing (by passing
        ``filenames``).  Can also be used in a more advanced way where the
        whole directory listing is matched against an arbitrary matcher (by
        passing ``matcher`` instead).

        :param filenames: If specified, match the sorted directory listing
            against this list of filenames, sorted.
        :param matcher: If specified, match the sorted directory listing
            against this matcher.
        """
        if filenames == matcher == None:
            raise AssertionError(
                "Must provide one of `filenames` or `matcher`.")
        if None not in (filenames, matcher):
            raise AssertionError(
                "Must provide either `filenames` or `matcher`, not both.")
        if filenames is None:
            self.matcher = matcher
        else:
            self.matcher = Equals(sorted(filenames))

    def match(self, path):
        mismatch = DirExists().match(path)
        if mismatch is not None:
            return mismatch
        return self.matcher.match(sorted(os.listdir(path)))


class FileContains(Matcher):
    """Matches if the given file has the specified contents."""

    def __init__(self, contents=None, matcher=None):
        """Construct a ``FileContains`` matcher.

        Can be used in a basic mode where the file contents are compared for
        equality against the expected file contents (by passing ``contents``).
        Can also be used in a more advanced way where the file contents are
        matched against an arbitrary matcher (by passing ``matcher`` instead).

        :param contents: If specified, match the contents of the file with
            these contents.
        :param matcher: If specified, match the contents of the file against
            this matcher.
        """
        if contents == matcher == None:
            raise AssertionError(
                "Must provide one of `contents` or `matcher`.")
        if None not in (contents, matcher):
            raise AssertionError(
                "Must provide either `contents` or `matcher`, not both.")
        if matcher is None:
            self.matcher = Equals(contents)
        else:
            self.matcher = matcher

    def match(self, path):
        mismatch = PathExists().match(path)
        if mismatch is not None:
            return mismatch
        f = open(path)
        try:
            actual_contents = f.read()
            return self.matcher.match(actual_contents)
        finally:
            f.close()

    def __str__(self):
        return "File at path exists and contains %s" % self.contents


class HasPermissions(Matcher):
    """Matches if a file has the given permissions.

    Permissions are specified and matched as a four-digit octal string.
    """

    def __init__(self, octal_permissions):
        """Construct a HasPermissions matcher.

        :param octal_permissions: A four digit octal string, representing the
            intended access permissions. e.g. '0775' for rwxrwxr-x.
        """
        super(HasPermissions, self).__init__()
        self.octal_permissions = octal_permissions

    def match(self, filename):
        permissions = oct(os.stat(filename).st_mode)[-4:]
        return Equals(self.octal_permissions).match(permissions)


class SamePath(Matcher):
    """Matches if two paths are the same.

    That is, the paths are equal, or they point to the same file but in
    different ways.  The paths do not have to exist.
    """

    def __init__(self, path):
        super(SamePath, self).__init__()
        self.path = path

    def match(self, other_path):
        f = lambda x: os.path.abspath(os.path.realpath(x))
        return Equals(f(self.path)).match(f(other_path))


class TarballContains(Matcher):
    """Matches if the given tarball contains the given paths.

    Uses TarFile.getnames() to get the paths out of the tarball.
    """

    def __init__(self, paths):
        super(TarballContains, self).__init__()
        self.paths = paths
        self.path_matcher = Equals(sorted(self.paths))

    def match(self, tarball_path):
        # Open underlying file first to ensure it's always closed:
        # <http://bugs.python.org/issue10233>
        f = open(tarball_path, "rb")
        try:
            tarball = tarfile.open(tarball_path, fileobj=f)
            try:
                return self.path_matcher.match(sorted(tarball.getnames()))
            finally:
                tarball.close()
        finally:
            f.close()