1import logging
2import os
3
4import pytest
5import salt.serializers.json as jsonserializer
6import salt.serializers.msgpack as msgpackserializer
7import salt.serializers.plist as plistserializer
8import salt.serializers.python as pythonserializer
9import salt.serializers.yaml as yamlserializer
10import salt.states.file as filestate
11import salt.utils.files
12import salt.utils.json
13import salt.utils.platform
14import salt.utils.win_functions
15import salt.utils.yaml
16from tests.support.mock import MagicMock, mock_open, patch
17
18log = logging.getLogger(__name__)
19
20
21@pytest.fixture
22def configure_loader_modules():
23    return {
24        filestate: {
25            "__env__": "base",
26            "__salt__": {"file.manage_file": False},
27            "__serializers__": {
28                "yaml.serialize": yamlserializer.serialize,
29                "yaml.seserialize": yamlserializer.serialize,
30                "python.serialize": pythonserializer.serialize,
31                "json.serialize": jsonserializer.serialize,
32                "plist.serialize": plistserializer.serialize,
33                "msgpack.serialize": msgpackserializer.serialize,
34            },
35            "__opts__": {"test": False, "cachedir": ""},
36            "__instance_id__": "",
37            "__low__": {},
38            "__utils__": {},
39        }
40    }
41
42
43# 'comment' function tests: 1
44def test_comment():
45    """
46    Test to comment out specified lines in a file.
47    """
48    with patch.object(os.path, "exists", MagicMock(return_value=True)):
49        name = "/etc/aliases" if salt.utils.platform.is_darwin() else "/etc/fstab"
50        regex = "bind 127.0.0.1"
51
52        ret = {"name": name, "result": False, "comment": "", "changes": {}}
53
54        comt = "Must provide name to file.comment"
55        ret.update({"comment": comt, "name": ""})
56        assert filestate.comment("", regex) == ret
57
58        mock_t = MagicMock(return_value=True)
59        mock_f = MagicMock(return_value=False)
60        with patch.object(os.path, "isabs", mock_f):
61            comt = "Specified file {} is not an absolute path".format(name)
62            ret.update({"comment": comt, "name": name})
63            assert filestate.comment(name, regex) == ret
64
65        with patch.object(os.path, "isabs", mock_t):
66            with patch.dict(
67                filestate.__salt__,
68                {"file.search": MagicMock(side_effect=[False, True, False, False])},
69            ):
70                comt = "Pattern already commented"
71                ret.update({"comment": comt, "result": True})
72                assert filestate.comment(name, regex) == ret
73
74                comt = "{}: Pattern not found".format(regex)
75                ret.update({"comment": comt, "result": False})
76                assert filestate.comment(name, regex) == ret
77
78            with patch.dict(
79                filestate.__salt__,
80                {
81                    "file.search": MagicMock(side_effect=[True, True, True]),
82                    "file.comment": mock_t,
83                    "file.comment_line": mock_t,
84                },
85            ):
86                with patch.dict(filestate.__opts__, {"test": True}):
87                    comt = "File {} is set to be updated".format(name)
88                    ret.update(
89                        {"comment": comt, "result": None, "changes": {name: "updated"}}
90                    )
91                    assert filestate.comment(name, regex) == ret
92
93                with patch.dict(filestate.__opts__, {"test": False}):
94                    with patch.object(
95                        salt.utils.files, "fopen", MagicMock(mock_open())
96                    ):
97                        comt = "Commented lines successfully"
98                        ret.update({"comment": comt, "result": True, "changes": {}})
99                        assert filestate.comment(name, regex) == ret
100
101
102# 'uncomment' function tests: 1
103def test_uncomment():
104    """
105    Test to uncomment specified commented lines in a file
106    """
107    with patch.object(os.path, "exists", MagicMock(return_value=True)):
108        name = "/etc/aliases" if salt.utils.platform.is_darwin() else "/etc/fstab"
109        regex = "bind 127.0.0.1"
110
111        ret = {"name": name, "result": False, "comment": "", "changes": {}}
112
113        comt = "Must provide name to file.uncomment"
114        ret.update({"comment": comt, "name": ""})
115        assert filestate.uncomment("", regex) == ret
116
117        mock_t = MagicMock(return_value=True)
118        mock_f = MagicMock(return_value=False)
119        mock = MagicMock(side_effect=[False, True, False, False, True, True, True])
120        with patch.object(os.path, "isabs", mock_f):
121            comt = "Specified file {} is not an absolute path".format(name)
122            ret.update({"comment": comt, "name": name})
123            assert filestate.uncomment(name, regex) == ret
124
125        with patch.object(os.path, "isabs", mock_t):
126            with patch.dict(
127                filestate.__salt__,
128                {
129                    "file.search": mock,
130                    "file.uncomment": mock_t,
131                    "file.comment_line": mock_t,
132                },
133            ):
134                comt = "Pattern already uncommented"
135                ret.update({"comment": comt, "result": True})
136                assert filestate.uncomment(name, regex) == ret
137
138                comt = "{}: Pattern not found".format(regex)
139                ret.update({"comment": comt, "result": False})
140                assert filestate.uncomment(name, regex) == ret
141
142                with patch.dict(filestate.__opts__, {"test": True}):
143                    comt = "File {} is set to be updated".format(name)
144                    ret.update(
145                        {"comment": comt, "result": None, "changes": {name: "updated"}}
146                    )
147                    assert filestate.uncomment(name, regex) == ret
148
149                with patch.dict(filestate.__opts__, {"test": False}):
150                    with patch.object(
151                        salt.utils.files, "fopen", MagicMock(mock_open())
152                    ):
153                        comt = "Uncommented lines successfully"
154                        ret.update({"comment": comt, "result": True, "changes": {}})
155                        assert filestate.uncomment(name, regex) == ret
156