add new AUTH_ERROR exit status to signal an invalid api key. fixes #41.
This commit is contained in:
parent
98de22c3a8
commit
33a87b9877
4 changed files with 118 additions and 48 deletions
|
@ -1,5 +1,5 @@
|
|||
Traceback (most recent call last):
|
||||
File "{file}", line 230, in parseArguments
|
||||
File "{file}", line {lineno}, in parseArguments
|
||||
args.timeout = int(configs.get('settings', 'timeout'))
|
||||
ValueError: invalid literal for int() with base 10: 'abc'
|
||||
|
||||
|
|
|
@ -6,8 +6,15 @@ from wakatime.packages import requests
|
|||
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import sys
|
||||
from wakatime.compat import u
|
||||
from wakatime.constants import (
|
||||
API_ERROR,
|
||||
AUTH_ERROR,
|
||||
CONFIG_FILE_PARSE_ERROR,
|
||||
SUCCESS,
|
||||
)
|
||||
from wakatime.packages.requests.models import Response
|
||||
from . import utils
|
||||
|
||||
|
@ -54,7 +61,7 @@ class BaseTestCase(utils.TestCase):
|
|||
args = ['--file', entity, '--key', '123', '--config', config]
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 0)
|
||||
self.assertEquals(retval, SUCCESS)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -107,10 +114,11 @@ class BaseTestCase(utils.TestCase):
|
|||
config = 'tests/samples/configs/has_everything.cfg'
|
||||
args = ['--file', entity, '--config', config]
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 0)
|
||||
self.assertEquals(retval, SUCCESS)
|
||||
expected_stdout = open('tests/samples/output/main_test_good_config_file').read()
|
||||
traceback_file = os.path.realpath('wakatime/main.py')
|
||||
self.assertEquals(sys.stdout.getvalue(), expected_stdout.format(file=traceback_file))
|
||||
lineno = int(re.search(r' line (\d+),', sys.stdout.getvalue()).group(1))
|
||||
self.assertEquals(sys.stdout.getvalue(), expected_stdout.format(file=traceback_file, lineno=lineno))
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
self.patched['wakatime.session_cache.SessionCache.get'].assert_called_once_with()
|
||||
|
@ -129,7 +137,7 @@ class BaseTestCase(utils.TestCase):
|
|||
config = 'tests/samples/configs/sample_alternate_apikey.cfg'
|
||||
args = ['--file', entity, '--config', config]
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 0)
|
||||
self.assertEquals(retval, SUCCESS)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -145,7 +153,7 @@ class BaseTestCase(utils.TestCase):
|
|||
config = 'tests/samples/configs/bad_config.cfg'
|
||||
args = ['--file', entity, '--config', config]
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 103)
|
||||
self.assertEquals(retval, CONFIG_FILE_PARSE_ERROR)
|
||||
self.assertIn('ParsingError', sys.stdout.getvalue())
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
self.patched['wakatime.offlinequeue.Queue.push'].assert_not_called()
|
||||
|
@ -165,7 +173,7 @@ class BaseTestCase(utils.TestCase):
|
|||
args = ['--file', entity, '--key', '123', '--config', config, '--time', now]
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -206,7 +214,7 @@ class BaseTestCase(utils.TestCase):
|
|||
args = ['--file', entity, '--key', '123', '--config', config, '--time', now]
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -266,7 +274,7 @@ class BaseTestCase(utils.TestCase):
|
|||
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -307,7 +315,7 @@ class BaseTestCase(utils.TestCase):
|
|||
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -318,6 +326,47 @@ class BaseTestCase(utils.TestCase):
|
|||
self.patched['wakatime.offlinequeue.Queue.push'].assert_not_called()
|
||||
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
||||
|
||||
def test_401_response(self):
|
||||
response = Response()
|
||||
response.status_code = 401
|
||||
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||
|
||||
now = u(int(time.time()))
|
||||
|
||||
args = ['--file', 'tests/samples/codefiles/twolinefile.txt', '--key', '123',
|
||||
'--config', 'tests/samples/configs/paranoid.cfg', '--time', now]
|
||||
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, AUTH_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
self.patched['wakatime.session_cache.SessionCache.delete'].assert_called_once_with()
|
||||
self.patched['wakatime.session_cache.SessionCache.get'].assert_called_once_with()
|
||||
self.patched['wakatime.session_cache.SessionCache.save'].assert_not_called()
|
||||
|
||||
heartbeat = {
|
||||
'language': 'Text only',
|
||||
'lines': 2,
|
||||
'entity': 'HIDDEN.txt',
|
||||
'project': os.path.basename(os.path.abspath('.')),
|
||||
'branch': os.environ.get('TRAVIS_COMMIT', ANY),
|
||||
'time': float(now),
|
||||
'type': 'file',
|
||||
}
|
||||
stats = {
|
||||
u('cursorpos'): None,
|
||||
u('dependencies'): [],
|
||||
u('language'): u('Text only'),
|
||||
u('lineno'): None,
|
||||
u('lines'): 2,
|
||||
}
|
||||
|
||||
self.patched['wakatime.offlinequeue.Queue.push'].assert_called_once_with(heartbeat, ANY, None)
|
||||
self.assertEquals(stats, json.loads(self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][1]))
|
||||
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
||||
|
||||
def test_alternate_project(self):
|
||||
response = Response()
|
||||
response.status_code = 0
|
||||
|
@ -330,7 +379,7 @@ class BaseTestCase(utils.TestCase):
|
|||
args = ['--file', entity, '--alternate-project', 'xyz', '--config', config, '--time', now]
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -371,7 +420,7 @@ class BaseTestCase(utils.TestCase):
|
|||
args = ['--file', entity, '--project', 'xyz', '--config', config, '--time', now]
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -409,7 +458,7 @@ class BaseTestCase(utils.TestCase):
|
|||
config = 'tests/samples/configs/good_config.cfg'
|
||||
args = ['--file', entity, '--config', config]
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 0)
|
||||
self.assertEquals(retval, SUCCESS)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -429,7 +478,7 @@ class BaseTestCase(utils.TestCase):
|
|||
config = 'tests/samples/configs/good_config.cfg'
|
||||
args = ['--file', entity, '--config', config, '--proxy', 'localhost:1234']
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 0)
|
||||
self.assertEquals(retval, SUCCESS)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -454,7 +503,7 @@ class BaseTestCase(utils.TestCase):
|
|||
args = ['--entity', entity, '--entitytype', 'domain', '--config', config, '--time', now]
|
||||
retval = execute(args)
|
||||
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
@ -491,7 +540,7 @@ class BaseTestCase(utils.TestCase):
|
|||
args = ['--entity', entity, '--entitytype', 'app', '--config', config, '--time', now]
|
||||
retval = execute(args)
|
||||
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(retval, API_ERROR)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
|
|
|
@ -13,3 +13,4 @@
|
|||
SUCCESS = 0
|
||||
API_ERROR = 102
|
||||
CONFIG_FILE_PARSE_ERROR = 103
|
||||
AUTH_ERROR = 104
|
||||
|
|
|
@ -30,7 +30,12 @@ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pac
|
|||
|
||||
from .__about__ import __version__
|
||||
from .compat import u, open, is_py3
|
||||
from .constants import SUCCESS, API_ERROR, CONFIG_FILE_PARSE_ERROR
|
||||
from .constants import (
|
||||
API_ERROR,
|
||||
AUTH_ERROR,
|
||||
CONFIG_FILE_PARSE_ERROR,
|
||||
SUCCESS,
|
||||
)
|
||||
from .logger import setup_logging
|
||||
from .offlinequeue import Queue
|
||||
from .packages import argparse
|
||||
|
@ -289,6 +294,9 @@ def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None,
|
|||
timestamp=None, isWrite=None, plugin=None, offline=None, entity_type='file',
|
||||
hidefilenames=None, proxy=None, api_url=None, timeout=None, **kwargs):
|
||||
"""Sends heartbeat as POST request to WakaTime api server.
|
||||
|
||||
Returns `SUCCESS` when heartbeat was sent, otherwise returns an
|
||||
error code constant.
|
||||
"""
|
||||
|
||||
if not api_url:
|
||||
|
@ -375,7 +383,7 @@ def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None,
|
|||
'response_code': response_code,
|
||||
})
|
||||
session_cache.save(session)
|
||||
return True
|
||||
return SUCCESS
|
||||
if offline:
|
||||
if response_code != 400:
|
||||
queue = Queue()
|
||||
|
@ -385,6 +393,8 @@ def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None,
|
|||
'response_code': response_code,
|
||||
'response_content': response_content,
|
||||
})
|
||||
session_cache.delete()
|
||||
return AUTH_ERROR
|
||||
elif log.isEnabledFor(logging.DEBUG):
|
||||
log.warn({
|
||||
'response_code': response_code,
|
||||
|
@ -401,7 +411,39 @@ def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None,
|
|||
'response_content': response_content,
|
||||
})
|
||||
session_cache.delete()
|
||||
return False
|
||||
return API_ERROR
|
||||
|
||||
|
||||
def sync_offline_heartbeats(args, hostname):
|
||||
"""Sends all heartbeats which were cached in the offline Queue."""
|
||||
|
||||
queue = Queue()
|
||||
while True:
|
||||
heartbeat = queue.pop()
|
||||
if heartbeat is None:
|
||||
break
|
||||
status = send_heartbeat(
|
||||
project=heartbeat['project'],
|
||||
entity=heartbeat['entity'],
|
||||
timestamp=heartbeat['time'],
|
||||
branch=heartbeat['branch'],
|
||||
hostname=hostname,
|
||||
stats=json.loads(heartbeat['stats']),
|
||||
key=args.key,
|
||||
isWrite=heartbeat['is_write'],
|
||||
plugin=heartbeat['plugin'],
|
||||
offline=args.offline,
|
||||
hidefilenames=args.hidefilenames,
|
||||
entity_type=heartbeat['type'],
|
||||
proxy=args.proxy,
|
||||
api_url=args.api_url,
|
||||
timeout=args.timeout,
|
||||
)
|
||||
if status != SUCCESS:
|
||||
if status == AUTH_ERROR:
|
||||
return AUTH_ERROR
|
||||
break
|
||||
return SUCCESS
|
||||
|
||||
|
||||
def execute(argv=None):
|
||||
|
@ -438,37 +480,15 @@ def execute(argv=None):
|
|||
kwargs['project'] = project
|
||||
kwargs['branch'] = branch
|
||||
kwargs['stats'] = stats
|
||||
kwargs['hostname'] = args.hostname or socket.gethostname()
|
||||
hostname = args.hostname or socket.gethostname()
|
||||
kwargs['hostname'] = hostname
|
||||
kwargs['timeout'] = args.timeout
|
||||
|
||||
if send_heartbeat(**kwargs):
|
||||
queue = Queue()
|
||||
while True:
|
||||
heartbeat = queue.pop()
|
||||
if heartbeat is None:
|
||||
break
|
||||
sent = send_heartbeat(
|
||||
project=heartbeat['project'],
|
||||
entity=heartbeat['entity'],
|
||||
timestamp=heartbeat['time'],
|
||||
branch=heartbeat['branch'],
|
||||
hostname=kwargs['hostname'],
|
||||
stats=json.loads(heartbeat['stats']),
|
||||
key=args.key,
|
||||
isWrite=heartbeat['is_write'],
|
||||
plugin=heartbeat['plugin'],
|
||||
offline=args.offline,
|
||||
hidefilenames=args.hidefilenames,
|
||||
entity_type=heartbeat['type'],
|
||||
proxy=args.proxy,
|
||||
api_url=args.api_url,
|
||||
timeout=args.timeout,
|
||||
)
|
||||
if not sent:
|
||||
break
|
||||
return SUCCESS
|
||||
|
||||
return API_ERROR
|
||||
status = send_heartbeat(**kwargs)
|
||||
if status == SUCCESS:
|
||||
return sync_offline_heartbeats(args, hostname)
|
||||
else:
|
||||
return status
|
||||
|
||||
else:
|
||||
log.debug('File does not exist; ignoring this heartbeat.')
|
||||
|
|
Loading…
Reference in a new issue