220 lines
11 KiB
Python
220 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
|
|
from wakatime.main import execute
|
|
from wakatime.packages import requests
|
|
|
|
import logging
|
|
import os
|
|
import shutil
|
|
import sys
|
|
from testfixtures import log_capture
|
|
from wakatime.compat import u
|
|
from wakatime.constants import API_ERROR, SUCCESS
|
|
from wakatime.packages.requests.models import Response
|
|
from . import utils
|
|
|
|
try:
|
|
from mock import ANY, call
|
|
except ImportError:
|
|
from unittest.mock import ANY, call
|
|
|
|
|
|
class ProxyTestCase(utils.TestCase):
|
|
patch_these = [
|
|
'wakatime.packages.requests.adapters.HTTPAdapter.send',
|
|
'wakatime.offlinequeue.Queue.push',
|
|
['wakatime.offlinequeue.Queue.pop', None],
|
|
['wakatime.offlinequeue.Queue.connect', None],
|
|
'wakatime.session_cache.SessionCache.save',
|
|
'wakatime.session_cache.SessionCache.delete',
|
|
['wakatime.session_cache.SessionCache.get', requests.session],
|
|
['wakatime.session_cache.SessionCache.connect', None],
|
|
]
|
|
|
|
def test_proxy_without_protocol(self):
|
|
response = Response()
|
|
response.status_code = 201
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
|
|
|
with utils.TemporaryDirectory() as tempdir:
|
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
|
proxy = 'user:pass@localhost:12345'
|
|
config = 'tests/samples/configs/good_config.cfg'
|
|
args = ['--file', entity, '--config', config, '--proxy', proxy]
|
|
|
|
retval = execute(args)
|
|
self.assertEquals(retval, SUCCESS)
|
|
self.assertEquals(sys.stdout.getvalue(), '')
|
|
self.assertEquals(sys.stderr.getvalue(), '')
|
|
|
|
self.patched['wakatime.session_cache.SessionCache.get'].assert_called_once_with()
|
|
self.patched['wakatime.session_cache.SessionCache.delete'].assert_not_called()
|
|
self.patched['wakatime.session_cache.SessionCache.save'].assert_called_once_with(ANY)
|
|
|
|
self.patched['wakatime.offlinequeue.Queue.push'].assert_not_called()
|
|
self.patched['wakatime.offlinequeue.Queue.pop'].assert_called_once_with()
|
|
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].assert_called_once_with(ANY, cert=None, proxies={'https': proxy}, stream=False, timeout=60, verify=True)
|
|
|
|
def test_https_proxy(self):
|
|
response = Response()
|
|
response.status_code = 201
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
|
|
|
with utils.TemporaryDirectory() as tempdir:
|
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
|
proxy = 'https://user:pass@localhost:12345'
|
|
config = 'tests/samples/configs/good_config.cfg'
|
|
args = ['--file', entity, '--config', config, '--proxy', proxy]
|
|
|
|
retval = execute(args)
|
|
self.assertEquals(retval, SUCCESS)
|
|
self.assertEquals(sys.stdout.getvalue(), '')
|
|
self.assertEquals(sys.stderr.getvalue(), '')
|
|
|
|
self.patched['wakatime.session_cache.SessionCache.get'].assert_called_once_with()
|
|
self.patched['wakatime.session_cache.SessionCache.delete'].assert_not_called()
|
|
self.patched['wakatime.session_cache.SessionCache.save'].assert_called_once_with(ANY)
|
|
|
|
self.patched['wakatime.offlinequeue.Queue.push'].assert_not_called()
|
|
self.patched['wakatime.offlinequeue.Queue.pop'].assert_called_once_with()
|
|
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].assert_called_once_with(ANY, cert=None, proxies={'https': proxy}, stream=False, timeout=60, verify=True)
|
|
|
|
def test_socks_proxy(self):
|
|
response = Response()
|
|
response.status_code = 201
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
|
|
|
with utils.TemporaryDirectory() as tempdir:
|
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
|
proxy = 'socks5://user:pass@localhost:12345'
|
|
config = 'tests/samples/configs/good_config.cfg'
|
|
args = ['--file', entity, '--config', config, '--proxy', proxy]
|
|
|
|
retval = execute(args)
|
|
self.assertEquals(retval, SUCCESS)
|
|
self.assertEquals(sys.stdout.getvalue(), '')
|
|
self.assertEquals(sys.stderr.getvalue(), '')
|
|
|
|
self.patched['wakatime.session_cache.SessionCache.get'].assert_called_once_with()
|
|
self.patched['wakatime.session_cache.SessionCache.delete'].assert_not_called()
|
|
self.patched['wakatime.session_cache.SessionCache.save'].assert_called_once_with(ANY)
|
|
|
|
self.patched['wakatime.offlinequeue.Queue.push'].assert_not_called()
|
|
self.patched['wakatime.offlinequeue.Queue.pop'].assert_called_once_with()
|
|
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].assert_called_once_with(ANY, cert=None, proxies={'https': proxy}, stream=False, timeout=60, verify=True)
|
|
|
|
def test_ntlm_proxy_used_after_trying_normal_proxy(self):
|
|
response = Response()
|
|
response.status_code = 400
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
|
|
|
with utils.TemporaryDirectory() as tempdir:
|
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
|
proxy = 'domain\\user:pass'
|
|
config = 'tests/samples/configs/good_config.cfg'
|
|
args = ['--file', entity, '--config', config, '--proxy', proxy]
|
|
|
|
retval = execute(args)
|
|
self.assertEquals(retval, API_ERROR)
|
|
self.assertEquals(sys.stdout.getvalue(), '')
|
|
self.assertEquals(sys.stderr.getvalue(), '')
|
|
|
|
self.patched['wakatime.session_cache.SessionCache.get'].assert_has_calls([call(), call()])
|
|
self.patched['wakatime.session_cache.SessionCache.delete'].assert_called_once_with()
|
|
self.patched['wakatime.session_cache.SessionCache.save'].assert_not_called()
|
|
|
|
self.patched['wakatime.offlinequeue.Queue.push'].assert_not_called()
|
|
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
|
|
|
expected_calls = [
|
|
call(ANY, cert=None, proxies={'https': proxy}, stream=False, timeout=60, verify=True),
|
|
call(ANY, cert=None, proxies={}, stream=False, timeout=60, verify=True),
|
|
]
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].assert_has_calls(expected_calls)
|
|
|
|
@log_capture()
|
|
def test_ntlm_proxy_used_after_normal_proxy_raises_exception(self, logs):
|
|
logging.disable(logging.NOTSET)
|
|
|
|
ex_msg = 'after exception, should still try ntlm proxy'
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].side_effect = RuntimeError(ex_msg)
|
|
|
|
with utils.TemporaryDirectory() as tempdir:
|
|
|
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
|
proxy = 'domain\\user:pass'
|
|
config = 'tests/samples/configs/good_config.cfg'
|
|
args = ['--file', entity, '--config', config, '--proxy', proxy]
|
|
|
|
retval = execute(args)
|
|
|
|
self.assertEquals(retval, API_ERROR)
|
|
self.assertEquals(sys.stdout.getvalue(), '')
|
|
self.assertEquals(sys.stderr.getvalue(), '')
|
|
|
|
log_output = u("\n").join([u(' ').join(x) for x in logs.actual()])
|
|
self.assertIn(ex_msg, log_output)
|
|
|
|
self.patched['wakatime.session_cache.SessionCache.get'].assert_has_calls([call(), call()])
|
|
self.patched['wakatime.session_cache.SessionCache.delete'].assert_called_once_with()
|
|
self.patched['wakatime.session_cache.SessionCache.save'].assert_not_called()
|
|
|
|
self.patched['wakatime.offlinequeue.Queue.push'].assert_called_once_with(ANY, ANY, None)
|
|
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
|
|
|
expected_calls = [
|
|
call(ANY, cert=None, proxies={'https': proxy}, stream=False, timeout=60, verify=True),
|
|
call(ANY, cert=None, proxies={}, stream=False, timeout=60, verify=True),
|
|
]
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].assert_has_calls(expected_calls)
|
|
|
|
@log_capture()
|
|
def test_invalid_proxy(self, logs):
|
|
logging.disable(logging.NOTSET)
|
|
|
|
response = Response()
|
|
response.status_code = 201
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
|
|
|
with utils.TemporaryDirectory() as tempdir:
|
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
|
proxy = 'invaliddd:proxyarg'
|
|
config = 'tests/samples/configs/good_config.cfg'
|
|
args = ['--file', entity, '--config', config, '--proxy', proxy]
|
|
|
|
with self.assertRaises(SystemExit) as e:
|
|
execute(args)
|
|
|
|
self.assertEquals(int(str(e.exception)), 2)
|
|
self.assertEquals(sys.stdout.getvalue(), '')
|
|
expected = 'error: Invalid proxy. Must be in format https://user:pass@host:port or socks5://user:pass@host:port or domain\\user:pass.'
|
|
self.assertIn(expected, sys.stderr.getvalue())
|
|
|
|
log_output = u("\n").join([u(' ').join(x) for x in logs.actual()])
|
|
expected = ''
|
|
self.assertEquals(log_output, expected)
|
|
|
|
self.patched['wakatime.session_cache.SessionCache.get'].assert_not_called()
|
|
self.patched['wakatime.session_cache.SessionCache.delete'].assert_not_called()
|
|
self.patched['wakatime.session_cache.SessionCache.save'].assert_not_called()
|
|
|
|
self.patched['wakatime.offlinequeue.Queue.push'].assert_not_called()
|
|
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
|
|
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].assert_not_called()
|