Integration testing (#243)

* Add tests for public/private/csr generation

* Add integration testing skeleton for mac and ubuntu

* Merge integration within lib test to avoid too many workflows

* Disable integration testing on windows for now

* Use sudo to start integration test script as lsof fails on MacOS.

lsof: WARNING: can't stat() vmhgfs file system

* Add basic integration testing for now to assert proxy works as expected when started out of develop branch

* Add a call to inbuilt http server to verify it works

* wait for server to accept requests
This commit is contained in:
Abhinav Singh 2019-12-25 16:39:18 -08:00 committed by GitHub
parent 8babac3da2
commit e84c212465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 109 additions and 5 deletions

View File

@ -27,11 +27,15 @@ jobs:
run: | run: |
flake8 --ignore=W504 --max-line-length=127 --max-complexity=19 proxy/ tests/ setup.py flake8 --ignore=W504 --max-line-length=127 --max-complexity=19 proxy/ tests/ setup.py
mypy --strict --ignore-missing-imports proxy/ tests/ setup.py mypy --strict --ignore-missing-imports proxy/ tests/ setup.py
- name: Build PyPi Package
run: python setup.py sdist
- name: Run Tests - name: Run Tests
run: pytest --cov=proxy tests/ run: pytest --cov=proxy tests/
- name: Upload coverage to Codecov - name: Upload coverage to Codecov
env: env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: codecov run: codecov
- name: Integration testing
if: matrix.os != 'windows'
run: |
python setup.py install
proxy --hostname 127.0.0.1 --enable-web-server --pid-file proxy.pid --log-file proxy.log &
./tests/integration/main.sh

View File

@ -8,9 +8,12 @@
:copyright: (c) 2013-present by Abhinav Singh and contributors. :copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
import os
import tempfile
import unittest import unittest
import subprocess import subprocess
from unittest import mock from unittest import mock
from typing import Tuple
from proxy.common import pki from proxy.common import pki
@ -73,13 +76,43 @@ class TestPki(unittest.TestCase):
b'\nsubjectAltName=DNS:proxy.py') b'\nsubjectAltName=DNS:proxy.py')
def test_gen_private_key(self) -> None: def test_gen_private_key(self) -> None:
pass key_path, nopass_key_path = self._gen_private_key()
self.assertTrue(os.path.exists(key_path))
self.assertTrue(os.path.exists(nopass_key_path))
os.remove(key_path)
os.remove(nopass_key_path)
def test_gen_public_key(self) -> None: def test_gen_public_key(self) -> None:
pass key_path, nopass_key_path, crt_path = self._gen_public_private_key()
self.assertTrue(os.path.exists(crt_path))
# TODO: Assert generated public key matches private key
os.remove(crt_path)
os.remove(key_path)
os.remove(nopass_key_path)
def test_gen_csr(self) -> None: def test_gen_csr(self) -> None:
pass key_path, nopass_key_path, crt_path = self._gen_public_private_key()
csr_path = os.path.join(tempfile.gettempdir(), 'test_gen_public.csr')
pki.gen_csr(csr_path, key_path, 'password', crt_path)
self.assertTrue(os.path.exists(csr_path))
# TODO: Assert CSR is valid for provided crt and key
os.remove(csr_path)
os.remove(crt_path)
os.remove(key_path)
os.remove(nopass_key_path)
def test_sign_csr(self) -> None: def test_sign_csr(self) -> None:
pass pass
def _gen_public_private_key(self) -> Tuple[str, str, str]:
key_path, nopass_key_path = self._gen_private_key()
crt_path = os.path.join(tempfile.gettempdir(), 'test_gen_public.crt')
pki.gen_public_key(crt_path, key_path, 'password', '/CN=example.com')
return (key_path, nopass_key_path, crt_path)
def _gen_private_key(self) -> Tuple[str, str]:
key_path = os.path.join(tempfile.gettempdir(), 'test_gen_private.key')
nopass_key_path = os.path.join(tempfile.gettempdir(), 'test_gen_private_nopass.key')
pki.gen_private_key(key_path, 'password')
pki.remove_passphrase(key_path, 'password', nopass_key_path)
return (key_path, nopass_key_path)

67
tests/integration/main.sh Executable file
View File

@ -0,0 +1,67 @@
#!/bin/bash
# TODO: Option to also shutdown proxy.py after
# integration testing is done. Atleast on
# macOS and ubuntu, pkill and kill commands
# will do the job.
#
# For github action, we simply bank upon GitHub
# to clean up any background process including
# proxy.py
# Wait for server to come up
while true; do
if [[ $(lsof -i TCP:8899 | wc -l | tr -d ' ') == 0 ]]; then
echo "Waiting for proxy..."
sleep 1
else
break
fi
done
# Wait for http proxy and web server to start
while true; do
curl -v \
--max-time 1 \
--connect-timeout 1 \
-x localhost:8899 \
http://localhost:8899/ 2>/dev/null
if [[ $? == 0 ]]; then
break
fi
echo "Waiting for web server to start accepting requests..."
sleep 1
done
# Check if proxy was started with integration
# testing web server plugin. If detected, use
# internal web server for integration testing.
# If integration testing plugin is not found,
# detect if we have internet access. If we do,
# then use httpbin.org for integration testing.
curl -v \
-x localhost:8899 \
http://httpbin.org/get
if [[ $? != 0 ]]; then
echo "http request failed"
exit 1
fi
curl -v \
-x localhost:8899 \
https://httpbin.org/get
if [[ $? != 0 ]]; then
echo "https request failed"
exit 1
fi
curl -v \
-x localhost:8899 \
http://localhost:8899/
if [[ $? != 0 ]]; then
echo "http request to built in webserver failed"
exit 1
fi
exit 0