Completed
Pull Request — master (#868)
by
unknown
01:15
created

test_copytree_error_copy2()   B

Complexity

Conditions 3

Size

Total Lines 36

Duplication

Lines 36
Ratio 100 %

Importance

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