Completed
Pull Request — master (#868)
by
unknown
54s
created

test_symlink()   A

Complexity

Conditions 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 0
loc 13
rs 9.2
1
# -*- coding: utf-8 -*-
2
3
"""
4
test_win_utils
5
------------
6
7
Tests for `cookiecutter.win_utils` module.
8
"""
9
10
import os
11
import pytest
12
import subprocess
13
import sys
14
import tempfile
15
16
import shutil
17
18
from cookiecutter import win_utils
19
20
21
def link_target_with_mklink(junction=False):
22
    """ Helper function to make link not using our win_utils
23
    """
24
    target = tempfile.mkdtemp(suffix='_tmp_target')
25
    source = str(target) + '_link'
26
27
    subprocess.check_output([
28
        'cmd',
29
        '/c',
30
        'mklink',
31
        '/d' if not junction else '/j',
32
        source,
33
        target
34
    ])
35
36
    return (source, target)
37
38
39
@pytest.fixture(scope='function')
40
def link_target_symlink():
41
    link, target = link_target_with_mklink()
42
    yield (link, target)
43
    os.rmdir(link)
44
    os.rmdir(target)
45
46
47
@pytest.fixture(scope='function')
48
def link_target_junction():
49
    link, target = link_target_with_mklink(junction=True)
50
    yield (link, target)
51
    os.rmdir(link)
52
    os.rmdir(target)
53
54
55
def test_islink(link_target_symlink):
56
    if not sys.platform.startswith('win'):
57
        pass
58
    else:
59
        source, target = link_target_symlink
60
        assert win_utils.islink(source)
61
62
63
def test_islink_invalid_attributes():
64
    if not sys.platform.startswith('win'):
65
        pass
66
    else:
67
        with pytest.raises(WindowsError):
68
            win_utils.islink("c:\\doesnotexistspath")
69
70
71
def test_readlink(link_target_symlink):
72
    if not sys.platform.startswith('win'):
73
        pass
74
    else:
75
        source, target = link_target_symlink
76
        assert win_utils.readlink(source) == target
77
78
79
def test_readlink_junction(link_target_junction):
80
    if not sys.platform.startswith('win'):
81
        pass
82
    else:
83
        source, target = link_target_junction
84
        assert win_utils.readlink(source) == target
85
86
87
def test_readlink_invalid(mocker, link_target_symlink):
88
    if not sys.platform.startswith('win'):
89
        pass
90
    else:
91
        # invalid path
92
        with pytest.raises(WindowsError):
93
            win_utils.readlink("c:\\iamnotarealpath")
94
95
        # valid path, not a symlink
96
        source, target = link_target_symlink
97
        with pytest.raises(WindowsError):
98
            win_utils.readlink(target)
99
100
        # non-symlink reparse tag
101
        class MockReparse():
102
            ReparseTag = 0
103
104
        mocker.patch(
105
            'cookiecutter.win_utils.REPARSE_DATA_BUFFER.from_buffer',
106
            return_value=MockReparse()
107
        )
108
109
        with pytest.raises(ValueError):
110
            win_utils.readlink(source)
111
112
113
def test_symlink(link_target_symlink):
114
    if not sys.platform.startswith('win'):
115
        pass
116
    else:
117
        source, target = link_target_symlink
118
        new_link = source + "_new_link"
119
120
        win_utils.symlink(target, new_link)
121
122
        assert win_utils.islink(new_link)
123
        assert win_utils.readlink(new_link) == target
124
125
        os.rmdir(new_link)
126
127
128
def test_symlink_error(link_target_symlink):
129
    if not sys.platform.startswith('win'):
130
        pass
131
    else:
132
        source, target = link_target_symlink
133
134
        # error on file exists
135
        with pytest.raises(WindowsError):
136
            win_utils.symlink(target, source)
137
138
139
def test_copytree(link_target_symlink):
140
    if not sys.platform.startswith('win'):
141
        pass
142
    else:
143
        source, target = link_target_symlink
144
145
        subdir1 = os.path.join(target, 'sub1')
146
        subdir2 = os.path.join(target, 'sub2')
147
148
        os.makedirs(subdir1)
149
        os.makedirs(subdir2)
150
151
        new_link = str(subdir1) + "_link"
152
        win_utils.symlink(subdir1, new_link)
153
154
        copied_tree_root = tempfile.mkdtemp(suffix='_copy_trees')
155
156
        # don't copy symlinks
157
        no_syms_root = os.path.join(copied_tree_root, 'no_syms')
158
        win_utils.copytree(target, no_syms_root)
159
160
        assert not win_utils.islink(os.path.join(no_syms_root, 'sub1_link'))
161
        shutil.rmtree(no_syms_root)
162
163
        # copy with symlinks
164
        syms_root = os.path.join(copied_tree_root, 'syms')
165
        win_utils.copytree(target, syms_root, symlinks=True)
166
167
        assert win_utils.islink(os.path.join(syms_root, 'sub1_link'))
168
        assert win_utils.readlink(os.path.join(syms_root, 'sub1_link')) == \
169
            os.path.join(target, 'sub1')
170
        shutil.rmtree(syms_root)
171
172
        os.rmdir(subdir1)
173
        os.rmdir(subdir2)
174
        os.rmdir(new_link)
175
        os.rmdir(copied_tree_root)
176
177
178 View Code Duplication
def test_copytree_error_copy2(mocker, link_target_symlink):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
179
    if not sys.platform.startswith('win'):
180
        pass
181
    else:
182
        source, target = link_target_symlink
183
184
        subdir1 = os.path.join(target, 'sub1')
185
        subdir2 = os.path.join(target, 'sub2')
186
        temp_file = os.path.join(subdir1, 'a.txt')
187
188
        os.makedirs(subdir1)
189
        os.makedirs(subdir2)
190
        with open(temp_file, 'w') as f:
191
            f.write('test file')
192
193
        new_link = str(subdir1) + "_link"
194
        win_utils.symlink(subdir1, new_link)
195
196
        copied_tree_root = tempfile.mkdtemp(suffix='_copy_trees')
197
198
        # raise errors on copy
199
        mocker.patch(
200
            'cookiecutter.win_utils.copy2',
201
            side_effect=OSError('asdf')
202
        )
203
204
        # don't copy symlinks
205
        no_syms_root = os.path.join(copied_tree_root, 'no_syms')
206
        with pytest.raises(shutil.Error):
207
            win_utils.copytree(target, no_syms_root)
208
209
        shutil.rmtree(no_syms_root)
210
211
        os.remove(temp_file)
212
        os.rmdir(subdir1)
213
        os.rmdir(subdir2)
214
        os.rmdir(new_link)
215
        os.rmdir(copied_tree_root)
216
217
218 View Code Duplication
def test_copytree_error_copystat(mocker, link_target_symlink):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
219
    if not sys.platform.startswith('win'):
220
        pass
221
    else:
222
        source, target = link_target_symlink
223
224
        subdir1 = os.path.join(target, 'sub1')
225
        subdir2 = os.path.join(target, 'sub2')
226
        temp_file = os.path.join(subdir1, 'a.txt')
227
228
        os.makedirs(subdir1)
229
        os.makedirs(subdir2)
230
        with open(temp_file, 'w') as f:
231
            f.write('test file')
232
233
        new_link = str(subdir1) + "_link"
234
        win_utils.symlink(subdir1, new_link)
235
236
        copied_tree_root = tempfile.mkdtemp(suffix='_copy_trees')
237
238
        # raise errors on copystat
239
        mocked_copy2 = mocker.patch(
240
            'cookiecutter.win_utils.copystat',
241
            side_effect=OSError('asdf')
242
        )
243
        mocked_copy2.side_effect.winerror = None
244
245
        # don't copy symlinks
246
        no_syms_root = os.path.join(copied_tree_root, 'no_syms')
247
        with pytest.raises(shutil.Error):
248
            win_utils.copytree(target, no_syms_root)
249
250
        shutil.rmtree(no_syms_root)
251
252
        os.remove(temp_file)
253
        os.rmdir(subdir1)
254
        os.rmdir(subdir2)
255
        os.rmdir(new_link)
256
        os.rmdir(copied_tree_root)
257