Skip to content

Commit

Permalink
Add windows to ci github action
Browse files Browse the repository at this point in the history
  • Loading branch information
jpdakran committed Apr 5, 2022
1 parent 70e6cf6 commit a9f4a35
Show file tree
Hide file tree
Showing 17 changed files with 103 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
python: ['3.6', '3.7', '3.8', '3.9']
steps:
- uses: actions/checkout@v2
Expand Down
16 changes: 16 additions & 0 deletions testing/mocks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""This is a collection of utility functions for easier, DRY testing."""
import io
import os
import tempfile
from collections import defaultdict
from contextlib import contextmanager
from types import ModuleType
Expand Down Expand Up @@ -88,3 +90,17 @@ def disable_gibberish_filter() -> Iterator[None]:
return_value=False,
):
yield


@contextmanager
def mock_baseline_file(mode: str = 'w+b') -> Iterator[IO[Any]]:
"""
Used to create a mock temporary baseline file. To avoid operating system differences,
specifically Linux vs. Windows on how "NamedTemporaryFile" operate, we will perform
the creation and cleanup of the temporary file here.
"""
with tempfile.NamedTemporaryFile(mode=mode, delete=False) as f:
yield f

f.close()
os.unlink(f.name)
6 changes: 3 additions & 3 deletions tests/audit/analytics_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json
import random
import string
import tempfile
from contextlib import contextmanager

import pytest
Expand All @@ -11,6 +10,7 @@
from detect_secrets.main import main
from detect_secrets.plugins.basic_auth import BasicAuthDetector
from testing.factories import potential_secret_factory as original_potential_secret_factory
from testing.mocks import mock_baseline_file


def potential_secret_factory(**kwargs):
Expand Down Expand Up @@ -59,7 +59,7 @@ def test_basic_statistics_json(printer):
def test_no_divide_by_zero(secret):
secrets = SecretsCollection()
secrets['file'].add(secret)
with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
baseline.save_to_file(secrets, f.name)
f.seek(0)

Expand All @@ -84,7 +84,7 @@ def labelled_secrets():
potential_secret_factory(is_secret=False),
}

with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
baseline.save_to_file(secrets, f.name)
f.seek(0)

Expand Down
4 changes: 2 additions & 2 deletions tests/audit/audit_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
import random
import tempfile
from typing import List
from typing import Optional
from unittest import mock
Expand All @@ -12,6 +11,7 @@
from detect_secrets.main import main
from detect_secrets.settings import transient_settings
from testing.factories import potential_secret_factory
from testing.mocks import mock_baseline_file


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

Expand Down
4 changes: 2 additions & 2 deletions tests/audit/compare_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import re
import tempfile
from contextlib import contextmanager
from unittest import mock

Expand All @@ -11,6 +10,7 @@
from detect_secrets.main import main
from detect_secrets.plugins.basic_auth import BasicAuthDetector
from testing.factories import potential_secret_factory as original_potential_secret_factory
from testing.mocks import mock_baseline_file


def potential_secret_factory(secret: str, **kwargs):
Expand Down Expand Up @@ -139,7 +139,7 @@ def test_fails_when_no_line_number(printer):


def run_logic(secretsA: SecretsCollection, secretsB: SecretsCollection):
with tempfile.NamedTemporaryFile() as f, tempfile.NamedTemporaryFile() as g:
with mock_baseline_file() as f, mock_baseline_file() as g:
baseline.save_to_file(secretsA, f.name)
baseline.save_to_file(secretsB, g.name)

Expand Down
9 changes: 7 additions & 2 deletions tests/audit/report_test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import random
import string
import tempfile
Expand All @@ -14,6 +15,7 @@
from detect_secrets.plugins.basic_auth import BasicAuthDetector
from detect_secrets.plugins.jwt import JwtTokenDetector
from detect_secrets.settings import transient_settings
from testing.mocks import mock_baseline_file


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

@contextmanager
def create_file_with_content(content):
with tempfile.NamedTemporaryFile() as f:
with tempfile.NamedTemporaryFile(delete=False) as f:
f.write(content.encode())
f.seek(0)
yield f.name

f.close()
os.unlink(f.name)


@pytest.fixture
def baseline_file():
Expand All @@ -187,7 +192,7 @@ def baseline_file():

with create_file_with_content(first_content) as first_file, \
create_file_with_content(second_content) as second_file, \
tempfile.NamedTemporaryFile() as baseline_file, \
mock_baseline_file() as baseline_file, \
transient_settings({
'plugins_used': [
{'name': 'BasicAuthDetector'},
Expand Down
13 changes: 10 additions & 3 deletions tests/core/baseline_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import json
import os
import subprocess
import tempfile
from pathlib import Path
from unittest import mock

import pytest
Expand Down Expand Up @@ -39,8 +41,8 @@ def test_basic_usage(path):
secrets = baseline.create(path)

assert len(secrets.data.keys()) == 2
assert len(secrets['test_data/files/file_with_secrets.py']) == 1
assert len(secrets['test_data/files/tmp/file_with_secrets.py']) == 2
assert len(secrets[str(Path('test_data/files/file_with_secrets.py'))]) == 1
assert len(secrets[str(Path('test_data/files/tmp/file_with_secrets.py'))]) == 2

@staticmethod
def test_error_when_getting_git_tracked_files():
Expand Down Expand Up @@ -69,7 +71,9 @@ def test_no_files_in_git_repo():

@staticmethod
def test_scan_all_files():
with tempfile.NamedTemporaryFile(dir='test_data/files/tmp', suffix='.py') as f:
with tempfile.NamedTemporaryFile(
dir='test_data/files/tmp', suffix='.py', delete=False,
) as f:
f.write(b'"2b00042f7481c7b056c4b410d28f33cf"')
f.seek(0)

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

f.close()
os.unlink(f.name)


def test_load_and_output():
with open('.secrets.baseline') as f:
Expand Down
15 changes: 11 additions & 4 deletions tests/core/scan_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import tempfile
import textwrap
from pathlib import Path

import pytest

Expand Down Expand Up @@ -53,11 +54,11 @@ def test_handles_each_path_separately(non_tracked_file):

@staticmethod
def test_handles_multiple_directories():
directories = ['test_data/short_files', 'test_data/files']
directories = [Path('test_data/short_files'), Path('test_data/files')]
results = list(scan.get_files_to_scan(*directories))

for prefix in directories:
assert len(list(filter(lambda x: x.startswith(prefix), results))) > 1
assert len(list(filter(lambda x: x.startswith(str(prefix)), results))) > 1

@staticmethod
@pytest.fixture(autouse=True, scope='class')
Expand All @@ -74,7 +75,7 @@ def non_tracked_file():
class TestScanFile:
@staticmethod
def test_handles_broken_yaml_gracefully():
with tempfile.NamedTemporaryFile(suffix='.yaml') as f:
with tempfile.NamedTemporaryFile(suffix='.yaml', delete=False) as f:
f.write(
textwrap.dedent("""
metadata:
Expand All @@ -85,16 +86,22 @@ def test_handles_broken_yaml_gracefully():

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

f.close()
os.unlink(f.name)

@staticmethod
def test_handles_binary_files_gracefully():
# NOTE: This suffix needs to be something that isn't in the known file types, as determined
# by `detect_secrets.util.filetype.determine_file_type`.
with tempfile.NamedTemporaryFile(suffix='.woff2') as f:
with tempfile.NamedTemporaryFile(suffix='.woff2', delete=False) as f:
f.write(b'\x86')
f.seek(0)

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

f.close()
os.unlink(f.name)


@pytest.fixture(autouse=True)
def configure_plugins():
Expand Down
4 changes: 2 additions & 2 deletions tests/core/usage/baseline_usage_test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import json
import tempfile
from contextlib import contextmanager

import pytest

from detect_secrets.core.plugins.util import get_mapping_from_secret_type_to_class
from detect_secrets.core.usage import ParserBuilder
from detect_secrets.settings import get_settings
from testing.mocks import mock_baseline_file


@pytest.fixture
Expand Down Expand Up @@ -60,7 +60,7 @@ def test_success(parser):

@contextmanager
def _mock_file(content: str):
with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
f.write(content.encode())
f.seek(0)

Expand Down
8 changes: 4 additions & 4 deletions tests/core/usage/filters_usage_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import tempfile
import uuid

import pytest
Expand All @@ -10,11 +9,12 @@
from detect_secrets.settings import default_settings
from detect_secrets.settings import get_settings
from detect_secrets.settings import transient_settings
from testing.mocks import mock_baseline_file


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

def test_only_verified_overrides_baseline_settings(parser):
secrets = SecretsCollection()
with tempfile.NamedTemporaryFile() as f, transient_settings({
with mock_baseline_file() as f, transient_settings({
'filters_used': [{
'path': 'detect_secrets.filters.common.is_ignored_due_to_verification_policies',
'min_level': VerifiedResult.UNVERIFIED.value,
Expand Down Expand Up @@ -134,7 +134,7 @@ def test_module_failure(parser, filepath):


def test_disable_filter(parser):
with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
f.write(f'secret = "{uuid.uuid4()}"'.encode())

# First, make sure that we actually catch it.
Expand Down
10 changes: 5 additions & 5 deletions tests/core/usage/plugins_usage_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
import os
import tempfile

import pytest

Expand All @@ -9,6 +8,7 @@
from detect_secrets.core.secrets_collection import SecretsCollection
from detect_secrets.core.usage import ParserBuilder
from detect_secrets.settings import get_settings
from testing.mocks import mock_baseline_file


@pytest.fixture
Expand Down Expand Up @@ -48,7 +48,7 @@ def test_failure(parser, flag, value):

@staticmethod
def test_precedence_with_only_baseline(parser):
with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
f.write(
json.dumps({
'version': '0.0.1',
Expand All @@ -69,7 +69,7 @@ def test_precedence_with_only_baseline(parser):

@staticmethod
def test_precedence_with_baseline_and_explicit_value(parser):
with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
f.write(
json.dumps({
'version': '0.0.1',
Expand Down Expand Up @@ -115,7 +115,7 @@ def test_invalid_classname(parser):

@staticmethod
def test_precedence_with_baseline(parser):
with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
f.write(
json.dumps({
'version': '0.0.1',
Expand Down Expand Up @@ -148,7 +148,7 @@ def test_success(parser):
# Ensure it serializes accordingly.
parser.parse_args(['-p', 'testing/plugins.py'])

with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
baseline.save_to_file(SecretsCollection(), f.name)
f.seek(0)

Expand Down
4 changes: 2 additions & 2 deletions tests/core/usage/scan_usage_test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import json
import tempfile

import pytest

from detect_secrets.core import plugins
from detect_secrets.core.plugins.util import get_mapping_from_secret_type_to_class
from detect_secrets.core.usage import ParserBuilder
from detect_secrets.settings import get_settings
from testing.mocks import mock_baseline_file


@pytest.fixture
Expand All @@ -15,7 +15,7 @@ def parser():


def test_force_use_all_plugins(parser):
with tempfile.NamedTemporaryFile() as f:
with mock_baseline_file() as f:
f.write(
json.dumps({
'version': '0.0.1',
Expand Down
Loading

0 comments on commit a9f4a35

Please sign in to comment.