Skip to content

Commit c06ba33

Browse files
committed
Add windows to ci github action
1 parent 70e6cf6 commit c06ba33

17 files changed

+139
-57
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ jobs:
1414
runs-on: ${{ matrix.os }}
1515
strategy:
1616
matrix:
17-
os: [ubuntu-latest, macos-latest]
18-
python: ['3.6', '3.7', '3.8', '3.9']
17+
os: [windows-latest]
18+
python: ['3.8', '3.9']
1919
steps:
2020
- uses: actions/checkout@v2
2121
- uses: actions/setup-python@v2

testing/mocks.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""This is a collection of utility functions for easier, DRY testing."""
22
import io
3+
import os
4+
import tempfile
35
from collections import defaultdict
46
from contextlib import contextmanager
57
from types import ModuleType
@@ -88,3 +90,17 @@ def disable_gibberish_filter() -> Iterator[None]:
8890
return_value=False,
8991
):
9092
yield
93+
94+
95+
@contextmanager
96+
def mock_baseline_file(mode: str = 'w+b') -> Iterator[IO[Any]]:
97+
"""
98+
Used to create a mock temporary baseline file. To avoid operating system differences,
99+
specifically Linux vs. Windows on how "NamedTemporaryFile" operate, we will perform
100+
the creation and cleanup of the temporary file here.
101+
"""
102+
with tempfile.NamedTemporaryFile(mode=mode, delete=False) as f:
103+
yield f
104+
105+
f.close()
106+
os.unlink(f.name)

tests/audit/analytics_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import json
22
import random
33
import string
4-
import tempfile
54
from contextlib import contextmanager
65

76
import pytest
@@ -11,6 +10,7 @@
1110
from detect_secrets.main import main
1211
from detect_secrets.plugins.basic_auth import BasicAuthDetector
1312
from testing.factories import potential_secret_factory as original_potential_secret_factory
13+
from testing.mocks import mock_baseline_file
1414

1515

1616
def potential_secret_factory(**kwargs):
@@ -59,7 +59,7 @@ def test_basic_statistics_json(printer):
5959
def test_no_divide_by_zero(secret):
6060
secrets = SecretsCollection()
6161
secrets['file'].add(secret)
62-
with tempfile.NamedTemporaryFile() as f:
62+
with mock_baseline_file() as f:
6363
baseline.save_to_file(secrets, f.name)
6464
f.seek(0)
6565

@@ -84,7 +84,7 @@ def labelled_secrets():
8484
potential_secret_factory(is_secret=False),
8585
}
8686

87-
with tempfile.NamedTemporaryFile() as f:
87+
with mock_baseline_file() as f:
8888
baseline.save_to_file(secrets, f.name)
8989
f.seek(0)
9090

tests/audit/audit_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22
import random
3-
import tempfile
43
from typing import List
54
from typing import Optional
65
from unittest import mock
@@ -12,6 +11,7 @@
1211
from detect_secrets.main import main
1312
from detect_secrets.settings import transient_settings
1413
from testing.factories import potential_secret_factory
14+
from testing.mocks import mock_baseline_file
1515

1616

1717
def test_nothing_to_audit(printer):
@@ -166,7 +166,7 @@ def run_logic(
166166
:param input: if provided, will automatically quit at the end of input string.
167167
otherwise, will assert that no user input is requested.
168168
"""
169-
with tempfile.NamedTemporaryFile() as f:
169+
with mock_baseline_file() as f:
170170
baseline.save_to_file(secrets, f.name)
171171
f.seek(0)
172172

tests/audit/compare_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import re
2-
import tempfile
32
from contextlib import contextmanager
43
from unittest import mock
54

@@ -11,6 +10,7 @@
1110
from detect_secrets.main import main
1211
from detect_secrets.plugins.basic_auth import BasicAuthDetector
1312
from testing.factories import potential_secret_factory as original_potential_secret_factory
13+
from testing.mocks import mock_baseline_file
1414

1515

1616
def potential_secret_factory(secret: str, **kwargs):
@@ -139,7 +139,7 @@ def test_fails_when_no_line_number(printer):
139139

140140

141141
def run_logic(secretsA: SecretsCollection, secretsB: SecretsCollection):
142-
with tempfile.NamedTemporaryFile() as f, tempfile.NamedTemporaryFile() as g:
142+
with mock_baseline_file() as f, mock_baseline_file() as g:
143143
baseline.save_to_file(secretsA, f.name)
144144
baseline.save_to_file(secretsB, g.name)
145145

tests/audit/report_test.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import random
23
import string
34
import tempfile
@@ -14,6 +15,7 @@
1415
from detect_secrets.plugins.basic_auth import BasicAuthDetector
1516
from detect_secrets.plugins.jwt import JwtTokenDetector
1617
from detect_secrets.settings import transient_settings
18+
from testing.mocks import mock_baseline_file
1719

1820

1921
url_format = 'http://username:{}@www.example.com/auth'
@@ -166,11 +168,14 @@ def count_results(data):
166168

167169
@contextmanager
168170
def create_file_with_content(content):
169-
with tempfile.NamedTemporaryFile() as f:
171+
with tempfile.NamedTemporaryFile(delete=False) as f:
170172
f.write(content.encode())
171173
f.seek(0)
172174
yield f.name
173175

176+
f.close()
177+
os.unlink(f.name)
178+
174179

175180
@pytest.fixture
176181
def baseline_file():
@@ -187,7 +192,7 @@ def baseline_file():
187192

188193
with create_file_with_content(first_content) as first_file, \
189194
create_file_with_content(second_content) as second_file, \
190-
tempfile.NamedTemporaryFile() as baseline_file, \
195+
mock_baseline_file() as baseline_file, \
191196
transient_settings({
192197
'plugins_used': [
193198
{'name': 'BasicAuthDetector'},

tests/core/baseline_test.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import json
2+
import os
23
import subprocess
34
import tempfile
5+
from pathlib import Path
46
from unittest import mock
57

68
import pytest
@@ -39,8 +41,8 @@ def test_basic_usage(path):
3941
secrets = baseline.create(path)
4042

4143
assert len(secrets.data.keys()) == 2
42-
assert len(secrets['test_data/files/file_with_secrets.py']) == 1
43-
assert len(secrets['test_data/files/tmp/file_with_secrets.py']) == 2
44+
assert len(secrets[str(Path('test_data/files/file_with_secrets.py'))]) == 1
45+
assert len(secrets[str(Path('test_data/files/tmp/file_with_secrets.py'))]) == 2
4446

4547
@staticmethod
4648
def test_error_when_getting_git_tracked_files():
@@ -69,7 +71,9 @@ def test_no_files_in_git_repo():
6971

7072
@staticmethod
7173
def test_scan_all_files():
72-
with tempfile.NamedTemporaryFile(dir='test_data/files/tmp', suffix='.py') as f:
74+
with tempfile.NamedTemporaryFile(
75+
dir='test_data/files/tmp', suffix='.py', delete=False,
76+
) as f:
7377
f.write(b'"2b00042f7481c7b056c4b410d28f33cf"')
7478
f.seek(0)
7579

@@ -79,6 +83,9 @@ def test_scan_all_files():
7983
secrets = baseline.create('test_data/files/tmp', should_scan_all_files=True)
8084
assert get_relative_path_if_in_cwd(f.name) in secrets.data
8185

86+
f.close()
87+
os.unlink(f.name)
88+
8289

8390
def test_load_and_output():
8491
with open('.secrets.baseline') as f:

tests/core/scan_test.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import tempfile
33
import textwrap
4+
from pathlib import Path
45

56
import pytest
67

@@ -53,11 +54,11 @@ def test_handles_each_path_separately(non_tracked_file):
5354

5455
@staticmethod
5556
def test_handles_multiple_directories():
56-
directories = ['test_data/short_files', 'test_data/files']
57+
directories = [Path('test_data/short_files'), Path('test_data/files')]
5758
results = list(scan.get_files_to_scan(*directories))
5859

5960
for prefix in directories:
60-
assert len(list(filter(lambda x: x.startswith(prefix), results))) > 1
61+
assert len(list(filter(lambda x: x.startswith(str(prefix)), results))) > 1
6162

6263
@staticmethod
6364
@pytest.fixture(autouse=True, scope='class')
@@ -74,7 +75,7 @@ def non_tracked_file():
7475
class TestScanFile:
7576
@staticmethod
7677
def test_handles_broken_yaml_gracefully():
77-
with tempfile.NamedTemporaryFile(suffix='.yaml') as f:
78+
with tempfile.NamedTemporaryFile(suffix='.yaml', delete=False) as f:
7879
f.write(
7980
textwrap.dedent("""
8081
metadata:
@@ -85,16 +86,22 @@ def test_handles_broken_yaml_gracefully():
8586

8687
assert not list(scan.scan_file(f.name))
8788

89+
f.close()
90+
os.unlink(f.name)
91+
8892
@staticmethod
8993
def test_handles_binary_files_gracefully():
9094
# NOTE: This suffix needs to be something that isn't in the known file types, as determined
9195
# by `detect_secrets.util.filetype.determine_file_type`.
92-
with tempfile.NamedTemporaryFile(suffix='.woff2') as f:
96+
with tempfile.NamedTemporaryFile(suffix='.woff2', delete=False) as f:
9397
f.write(b'\x86')
9498
f.seek(0)
9599

96100
assert not list(scan.scan_file(f.name))
97101

102+
f.close()
103+
os.unlink(f.name)
104+
98105

99106
@pytest.fixture(autouse=True)
100107
def configure_plugins():

tests/core/usage/baseline_usage_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import json
2-
import tempfile
32
from contextlib import contextmanager
43

54
import pytest
65

76
from detect_secrets.core.plugins.util import get_mapping_from_secret_type_to_class
87
from detect_secrets.core.usage import ParserBuilder
98
from detect_secrets.settings import get_settings
9+
from testing.mocks import mock_baseline_file
1010

1111

1212
@pytest.fixture
@@ -60,7 +60,7 @@ def test_success(parser):
6060

6161
@contextmanager
6262
def _mock_file(content: str):
63-
with tempfile.NamedTemporaryFile() as f:
63+
with mock_baseline_file() as f:
6464
f.write(content.encode())
6565
f.seek(0)
6666

tests/core/usage/filters_usage_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import tempfile
21
import uuid
32

43
import pytest
@@ -10,11 +9,12 @@
109
from detect_secrets.settings import default_settings
1110
from detect_secrets.settings import get_settings
1211
from detect_secrets.settings import transient_settings
12+
from testing.mocks import mock_baseline_file
1313

1414

1515
def test_no_verify_overrides_baseline_settings(parser):
1616
secrets = SecretsCollection()
17-
with tempfile.NamedTemporaryFile() as f, transient_settings({
17+
with mock_baseline_file() as f, transient_settings({
1818
'filters_used': [{
1919
'path': 'detect_secrets.filters.common.is_ignored_due_to_verification_policies',
2020
'min_level': VerifiedResult.UNVERIFIED.value,
@@ -30,7 +30,7 @@ def test_no_verify_overrides_baseline_settings(parser):
3030

3131
def test_only_verified_overrides_baseline_settings(parser):
3232
secrets = SecretsCollection()
33-
with tempfile.NamedTemporaryFile() as f, transient_settings({
33+
with mock_baseline_file() as f, transient_settings({
3434
'filters_used': [{
3535
'path': 'detect_secrets.filters.common.is_ignored_due_to_verification_policies',
3636
'min_level': VerifiedResult.UNVERIFIED.value,
@@ -134,7 +134,7 @@ def test_module_failure(parser, filepath):
134134

135135

136136
def test_disable_filter(parser):
137-
with tempfile.NamedTemporaryFile() as f:
137+
with mock_baseline_file() as f:
138138
f.write(f'secret = "{uuid.uuid4()}"'.encode())
139139

140140
# First, make sure that we actually catch it.

tests/core/usage/plugins_usage_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22
import os
3-
import tempfile
43

54
import pytest
65

@@ -9,6 +8,7 @@
98
from detect_secrets.core.secrets_collection import SecretsCollection
109
from detect_secrets.core.usage import ParserBuilder
1110
from detect_secrets.settings import get_settings
11+
from testing.mocks import mock_baseline_file
1212

1313

1414
@pytest.fixture
@@ -48,7 +48,7 @@ def test_failure(parser, flag, value):
4848

4949
@staticmethod
5050
def test_precedence_with_only_baseline(parser):
51-
with tempfile.NamedTemporaryFile() as f:
51+
with mock_baseline_file() as f:
5252
f.write(
5353
json.dumps({
5454
'version': '0.0.1',
@@ -69,7 +69,7 @@ def test_precedence_with_only_baseline(parser):
6969

7070
@staticmethod
7171
def test_precedence_with_baseline_and_explicit_value(parser):
72-
with tempfile.NamedTemporaryFile() as f:
72+
with mock_baseline_file() as f:
7373
f.write(
7474
json.dumps({
7575
'version': '0.0.1',
@@ -115,7 +115,7 @@ def test_invalid_classname(parser):
115115

116116
@staticmethod
117117
def test_precedence_with_baseline(parser):
118-
with tempfile.NamedTemporaryFile() as f:
118+
with mock_baseline_file() as f:
119119
f.write(
120120
json.dumps({
121121
'version': '0.0.1',
@@ -148,7 +148,7 @@ def test_success(parser):
148148
# Ensure it serializes accordingly.
149149
parser.parse_args(['-p', 'testing/plugins.py'])
150150

151-
with tempfile.NamedTemporaryFile() as f:
151+
with mock_baseline_file() as f:
152152
baseline.save_to_file(SecretsCollection(), f.name)
153153
f.seek(0)
154154

tests/core/usage/scan_usage_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import json
2-
import tempfile
32

43
import pytest
54

65
from detect_secrets.core import plugins
76
from detect_secrets.core.plugins.util import get_mapping_from_secret_type_to_class
87
from detect_secrets.core.usage import ParserBuilder
98
from detect_secrets.settings import get_settings
9+
from testing.mocks import mock_baseline_file
1010

1111

1212
@pytest.fixture
@@ -15,7 +15,7 @@ def parser():
1515

1616

1717
def test_force_use_all_plugins(parser):
18-
with tempfile.NamedTemporaryFile() as f:
18+
with mock_baseline_file() as f:
1919
f.write(
2020
json.dumps({
2121
'version': '0.0.1',

0 commit comments

Comments
 (0)