diff --git a/dev-requirements.txt b/dev-requirements.txt index ab26e09e..bc71f9c9 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,6 +2,7 @@ coverage coveralls Jinja2 pip>=18.0 +pproxy==2.2.0 pytest recommonmark Sphinx diff --git a/requirements.txt b/requirements.txt index 2a13e43f..5fc4a04c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ +geojson>=2.3.0,<3 +PySocks==1.7.1,<2 requests>=2.20.0,<3 -geojson>=2.3.0,<3 \ No newline at end of file +requests[socks] \ No newline at end of file diff --git a/tests/proxy/__init__.py b/tests/proxy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/proxy/proxy_http.json b/tests/proxy/proxy_http.json new file mode 100644 index 00000000..b65408ac --- /dev/null +++ b/tests/proxy/proxy_http.json @@ -0,0 +1,15 @@ +{ + "api_key": "b1b15e88fa797225412429c1c50c122a", + "subscription_type": "free", + "language": "en", + "connection": { + "use_ssl": true, + "verify_ssl_certs": false, + "use_proxy": true, + "timeout_secs": 5 + }, + "proxies": { + "http": "http://user:pass@127.0.0.1:8899", + "https": "https://user:pass@127.0.0.1:8899" + } +} \ No newline at end of file diff --git a/tests/proxy/proxy_socks.json b/tests/proxy/proxy_socks.json new file mode 100644 index 00000000..cb5b11b8 --- /dev/null +++ b/tests/proxy/proxy_socks.json @@ -0,0 +1,15 @@ +{ + "api_key": "b1b15e88fa797225412429c1c50c122a", + "subscription_type": "free", + "language": "en", + "connection": { + "use_ssl": true, + "verify_ssl_certs": false, + "use_proxy": true, + "timeout_secs": 5 + }, + "proxies": { + "http": "socks5://127.0.0.1:8899", + "https": "socks5://127.0.0.1:8899" + } +} \ No newline at end of file diff --git a/tests/proxy/selfsigned.crt b/tests/proxy/selfsigned.crt new file mode 100644 index 00000000..0f36de8d --- /dev/null +++ b/tests/proxy/selfsigned.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID5zCCAs+gAwIBAgIUWVG9t0QFZLIKXdt8PZl9dqsqdykwDQYJKoZIhvcNAQEL +BQAwgYIxCzAJBgNVBAYTAklUMRIwEAYDVQQIDAlOZXZlcmxhbmQxFDASBgNVBAcM +C0dvdGhhbSBDaXR5MQ0wCwYDVQQKDARBQ01FMQswCQYDVQQLDAJJVDELMAkGA1UE +AwwCQ1MxIDAeBgkqhkiG9w0BCQEWEWNzcGFycGFAZ21haWwuY29tMB4XDTE5MTEx +MzIxMDYzOVoXDTIwMTExMjIxMDYzOVowgYIxCzAJBgNVBAYTAklUMRIwEAYDVQQI +DAlOZXZlcmxhbmQxFDASBgNVBAcMC0dvdGhhbSBDaXR5MQ0wCwYDVQQKDARBQ01F +MQswCQYDVQQLDAJJVDELMAkGA1UEAwwCQ1MxIDAeBgkqhkiG9w0BCQEWEWNzcGFy +cGFAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr+Fv +FxgOqncbxHwTr8pcrEYwO/GXwRwvTD1vWgMjdX7kDSh3Mlgd6TdRvmaojtXaNAaf +iTyrsPBS8LAPIZR+/8Fhxuc+tT5ClrJdK5XLM0Z3xhvAVyiwQOWxJwNapDD2cQ2W +VbT6OorVAlLD9QjToGjCasx+eyL2hOVWAqK0funmHAytA1VzRVcv9ZzWZNWIvpp2 +qkkznQyipIl/+Pub2GkeKXjSwzlfAYGFAWN9NcLxUn2NOw9+5FkPeg19YCGBmUJx +KxLq2B8gjLLtd6TYgdreJSpAwsb1PPFTvF2J4EVfiY+NfQtwzDIhGva4FfLeCvHL +qOEwYblx0pkRJ5swKwIDAQABo1MwUTAdBgNVHQ4EFgQUVvFAYKIXJLLje+RRC40A +SCvlAPcwHwYDVR0jBBgwFoAUVvFAYKIXJLLje+RRC40ASCvlAPcwDwYDVR0TAQH/ +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAWXjbYM8G8E9M0LLu6a5HsHvOUCI6 +SDA4XT09tWz5zgltHKj9WQzKTEi0ggO3LwUiTuJhhCMUL8S64lPPbNwUXpU8Mmmr +dHn3F4hXPJfOClCfVK+VPf1wEgvjHx2ajxrac7N7NCGYhfblpWy4lVQWFoY3219J +KKfeHKbIQjo2dmm2NyXzyBDWjcH3YPlNDUwr+fOhmMDAHS94Dlji/Cdpd25vPLj/ +58/ZFkJ46PGEAcisvT9Rjylw1qo0LJ3xFzvWdS9vWThH3inBCUpeoyebdhlpljW8 +da0N8MkhHMy3uZs70y/8xjtp5mO/pQjtzOijz9YV6uQs0zRoWHfGs3fT5Q== +-----END CERTIFICATE----- diff --git a/tests/proxy/test_integration_proxy.py b/tests/proxy/test_integration_proxy.py new file mode 100644 index 00000000..2902b35b --- /dev/null +++ b/tests/proxy/test_integration_proxy.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import pathlib +import unittest +from pyowm import OWM +from pyowm.weatherapi25.observation import Observation +from pyowm.utils import config + + +class TesIntegrationProxy(unittest.TestCase): + + _api_key = os.getenv('OWM_API_KEY', None) + + def test_call_api_behind_http_proxy(self): + # fetch config and overwrite API Key as per env variable + config_file_name = 'proxy_http.json' + path = (pathlib.Path() / config_file_name).absolute() + cfg = config.get_config_from(path) + cfg['api_key'] = self._api_key + + # go + owm = OWM(cfg['api_key'], cfg) + wm = owm.weather_manager() + result = wm.weather_at_place('London,GB') + self.assertIsInstance(result, Observation) + + def test_call_api_behind_socks_proxy(self): + # fetch config and overwrite API Key as per env variable + config_file_name = 'proxy_socks.json' + path = (pathlib.Path() / config_file_name).absolute() + cfg = config.get_config_from(path) + cfg['api_key'] = self._api_key + + # go + owm = OWM(cfg['api_key'], cfg) + wm = owm.weather_manager() + result = wm.weather_at_place('London,GB') + self.assertIsInstance(result, Observation) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/proxy/tox.ini b/tests/proxy/tox.ini new file mode 100644 index 00000000..3cdd633b --- /dev/null +++ b/tests/proxy/tox.ini @@ -0,0 +1,11 @@ +[tox] +envlist = + py37, py38 +skip_missing_interpreters = + True +skipsdist = True + +[testenv] +passenv = OWM_API_KEY +deps = -rproxyreqs.txt +commands = pytest . \ No newline at end of file diff --git a/tests/run_proxy_tests.sh b/tests/run_proxy_tests.sh new file mode 100644 index 00000000..4c779ce7 --- /dev/null +++ b/tests/run_proxy_tests.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +if [ -z "$OWM_API_KEY" ]; then + echo "*** OWM_API_KEY env variable is not set: aborting" + exit 1 +fi + +export OWM_API_KEY + +cd proxy + +# Build one-off dependency file +DEPS_FILE="$(readlink . -f)/proxyreqs.txt" +echo 'pytest' | cat - ../../requirements.txt > $DEPS_FILE + + +# Run proxy server +PID_FILE="$(readlink . -f)/proxy.pid" +export PID_FILE + +#proxy.py --num-workers 1 --hostname 127.0.0.1 --port 8899 --basic-auth user:pass --pid-file "$PID_FILE" > /dev/null 2>&1 & +pproxy -l http+socks4+socks5://127.0.0.1:8899 --ssl selfsigned.crt > /dev/null 2>&1 & +echo $$ >"$PID_FILE" + +# Run tests +echo "*** Running tests... " +tox + + +# Shut down proxy +echo "*** Killing proxy... " +PID=$(cat $PID_FILE) +rm "$PID_FILE" +rm "$DEPS_FILE" + +kill -9 "$PID" + +echo "*** End of proxy tests" \ No newline at end of file