handle null extra heartbeats
This commit is contained in:
parent
28cb3e2b28
commit
40c8a53019
5 changed files with 215 additions and 56 deletions
|
@ -809,6 +809,126 @@ class ArgumentsTestCase(TestCase):
|
||||||
self.assertOfflineHeartbeatsSynced()
|
self.assertOfflineHeartbeatsSynced()
|
||||||
self.assertSessionCacheSaved()
|
self.assertSessionCacheSaved()
|
||||||
|
|
||||||
|
@log_capture()
|
||||||
|
def test_extra_heartbeats_with_null_heartbeat(self, logs):
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
response = CustomResponse()
|
||||||
|
response.response_text = '[[{"id":1},201], [{"id":1},201]]'
|
||||||
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
|
now1 = u(int(time.time()))
|
||||||
|
project1 = os.path.basename(os.path.abspath('.'))
|
||||||
|
project_not_used = 'xyz'
|
||||||
|
entity1 = os.path.abspath('tests/samples/codefiles/emptyfile.txt')
|
||||||
|
entity2 = os.path.abspath('tests/samples/codefiles/twolinefile.txt')
|
||||||
|
config = 'tests/samples/configs/good_config.cfg'
|
||||||
|
args = ['--time', now1, '--file', entity1, '--config', config, '--extra-heartbeats']
|
||||||
|
|
||||||
|
with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
||||||
|
now2 = int(time.time())
|
||||||
|
heartbeats = json.dumps([
|
||||||
|
None,
|
||||||
|
{
|
||||||
|
'timestamp': now2,
|
||||||
|
'entity': entity2,
|
||||||
|
'entity_type': 'file',
|
||||||
|
'alternate_project': project_not_used,
|
||||||
|
'is_write': True,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
mock_stdin.readline.return_value = heartbeats
|
||||||
|
|
||||||
|
retval = execute(args)
|
||||||
|
|
||||||
|
self.assertEquals(retval, SUCCESS)
|
||||||
|
self.assertNothingPrinted()
|
||||||
|
self.assertNothingLogged(logs)
|
||||||
|
|
||||||
|
heartbeat = {
|
||||||
|
'language': 'Text only',
|
||||||
|
'lines': 0,
|
||||||
|
'entity': entity1,
|
||||||
|
'project': project1,
|
||||||
|
'branch': ANY,
|
||||||
|
'time': float(now1),
|
||||||
|
'is_write': False,
|
||||||
|
'type': 'file',
|
||||||
|
'dependencies': [],
|
||||||
|
'user_agent': ANY,
|
||||||
|
}
|
||||||
|
extra_heartbeats = [{
|
||||||
|
'language': 'Text only',
|
||||||
|
'lines': 2,
|
||||||
|
'entity': entity2,
|
||||||
|
'project': ANY,
|
||||||
|
'branch': ANY,
|
||||||
|
'time': float(now2),
|
||||||
|
'is_write': True,
|
||||||
|
'type': 'file',
|
||||||
|
'dependencies': [],
|
||||||
|
'user_agent': ANY,
|
||||||
|
}]
|
||||||
|
self.assertHeartbeatSent(heartbeat, extra_heartbeats=extra_heartbeats)
|
||||||
|
|
||||||
|
self.assertHeartbeatNotSavedOffline()
|
||||||
|
self.assertOfflineHeartbeatsSynced()
|
||||||
|
self.assertSessionCacheSaved()
|
||||||
|
|
||||||
|
@log_capture()
|
||||||
|
def test_extra_heartbeats_with_skipped_heartbeat(self, logs):
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
response = CustomResponse()
|
||||||
|
response.response_text = '[[{"id":1},201], [{"id":1},201]]'
|
||||||
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
|
now1 = u(int(time.time()))
|
||||||
|
project_not_used = 'xyz'
|
||||||
|
entity1 = os.path.abspath('tests/samples/codefiles/emptyfile.txt')
|
||||||
|
entity2 = os.path.abspath('tests/samples/codefiles/twolinefile.txt')
|
||||||
|
config = 'tests/samples/configs/good_config.cfg'
|
||||||
|
args = ['--time', now1, '--file', entity1, '--config', config, '--extra-heartbeats', '--exclude', 'twoline']
|
||||||
|
|
||||||
|
with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
||||||
|
now2 = int(time.time())
|
||||||
|
heartbeats = json.dumps([
|
||||||
|
{
|
||||||
|
'timestamp': now2,
|
||||||
|
'entity': entity2,
|
||||||
|
'entity_type': 'file',
|
||||||
|
'alternate_project': project_not_used,
|
||||||
|
'is_write': True,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
mock_stdin.readline.return_value = heartbeats
|
||||||
|
|
||||||
|
retval = execute(args)
|
||||||
|
|
||||||
|
self.assertEquals(retval, SUCCESS)
|
||||||
|
self.assertNothingPrinted()
|
||||||
|
actual = self.getLogOutput(logs)
|
||||||
|
expected = 'WakaTime WARNING Results from api not matching heartbeats sent.'
|
||||||
|
self.assertIn(expected, actual)
|
||||||
|
|
||||||
|
heartbeat = {
|
||||||
|
'language': 'Text only',
|
||||||
|
'lines': 0,
|
||||||
|
'entity': entity1,
|
||||||
|
'project': ANY,
|
||||||
|
'branch': ANY,
|
||||||
|
'time': float(now1),
|
||||||
|
'is_write': False,
|
||||||
|
'type': 'file',
|
||||||
|
'dependencies': [],
|
||||||
|
'user_agent': ANY,
|
||||||
|
}
|
||||||
|
self.assertHeartbeatSent(heartbeat)
|
||||||
|
|
||||||
|
self.assertHeartbeatNotSavedOffline()
|
||||||
|
self.assertOfflineHeartbeatsSynced()
|
||||||
|
self.assertSessionCacheSaved()
|
||||||
|
|
||||||
@log_capture()
|
@log_capture()
|
||||||
def test_uses_wakatime_home_env_variable(self, logs):
|
def test_uses_wakatime_home_env_variable(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
|
@ -15,11 +15,10 @@ from testfixtures import log_capture
|
||||||
from wakatime.compat import u
|
from wakatime.compat import u
|
||||||
from wakatime.constants import API_ERROR, AUTH_ERROR, SUCCESS
|
from wakatime.constants import API_ERROR, AUTH_ERROR, SUCCESS
|
||||||
from wakatime.packages.requests.models import Response
|
from wakatime.packages.requests.models import Response
|
||||||
from . import utils
|
from .utils import mock, json, ANY, CustomResponse, NamedTemporaryFile, TemporaryDirectory, TestCase
|
||||||
from .utils import ANY, json, CustomResponse
|
|
||||||
|
|
||||||
|
|
||||||
class OfflineQueueTestCase(utils.TestCase):
|
class OfflineQueueTestCase(TestCase):
|
||||||
patch_these = [
|
patch_these = [
|
||||||
'wakatime.packages.requests.adapters.HTTPAdapter.send',
|
'wakatime.packages.requests.adapters.HTTPAdapter.send',
|
||||||
'wakatime.session_cache.SessionCache.save',
|
'wakatime.session_cache.SessionCache.save',
|
||||||
|
@ -29,8 +28,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
]
|
]
|
||||||
|
|
||||||
def test_heartbeat_saved_from_error_response(self):
|
def test_heartbeat_saved_from_error_response(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -49,8 +48,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
|
self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
|
||||||
|
|
||||||
def test_heartbeat_discarded_from_400_response(self):
|
def test_heartbeat_discarded_from_400_response(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -69,8 +68,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
self.assertEquals(None, saved_heartbeat)
|
self.assertEquals(None, saved_heartbeat)
|
||||||
|
|
||||||
def test_offline_heartbeat_sent_after_success_response(self):
|
def test_offline_heartbeat_sent_after_success_response(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -94,8 +93,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
self.assertEquals(None, saved_heartbeat)
|
self.assertEquals(None, saved_heartbeat)
|
||||||
|
|
||||||
def test_all_offline_heartbeats_sent_after_success_response(self):
|
def test_all_offline_heartbeats_sent_after_success_response(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -170,8 +169,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_heartbeats_sent_not_saved_from_bulk_response(self, logs):
|
def test_heartbeats_sent_not_saved_from_bulk_response(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
entities = [
|
entities = [
|
||||||
|
@ -181,7 +180,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
'go.go',
|
'go.go',
|
||||||
]
|
]
|
||||||
|
|
||||||
with utils.TemporaryDirectory() as tempdir:
|
with TemporaryDirectory() as tempdir:
|
||||||
for entity in entities:
|
for entity in entities:
|
||||||
shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
|
shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
|
||||||
|
|
||||||
|
@ -194,7 +193,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
response.response_text = '[[{"id":1},201], [{"error":"error 2"},500], [{"id":3},201], [{"error":4},500]]'
|
response.response_text = '[[{"id":1},201], [{"error":"error 2"},500], [{"id":3},201], [{"error":4},500]]'
|
||||||
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
||||||
heartbeats = json.dumps([{
|
heartbeats = json.dumps([{
|
||||||
'timestamp': now,
|
'timestamp': now,
|
||||||
'entity': os.path.join(tempdir, entity),
|
'entity': os.path.join(tempdir, entity),
|
||||||
|
@ -203,7 +202,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
} for entity in entities[1:]])
|
} for entity in entities[1:]])
|
||||||
mock_stdin.readline.return_value = heartbeats
|
mock_stdin.readline.return_value = heartbeats
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue.pop') as mock_pop:
|
with mock.patch('wakatime.offlinequeue.Queue.pop') as mock_pop:
|
||||||
mock_pop.return_value = None
|
mock_pop.return_value = None
|
||||||
|
|
||||||
retval = execute(args)
|
retval = execute(args)
|
||||||
|
@ -253,8 +252,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_offline_heartbeats_sent_after_partial_success_from_bulk_response(self, logs):
|
def test_offline_heartbeats_sent_after_partial_success_from_bulk_response(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
entities = [
|
entities = [
|
||||||
|
@ -264,7 +263,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
'go.go',
|
'go.go',
|
||||||
]
|
]
|
||||||
|
|
||||||
with utils.TemporaryDirectory() as tempdir:
|
with TemporaryDirectory() as tempdir:
|
||||||
for entity in entities:
|
for entity in entities:
|
||||||
shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
|
shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
|
||||||
|
|
||||||
|
@ -277,7 +276,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
response.response_text = '[[{"id":1},201], [{"error":"error 2"},500], [{"id":3},201], [{"error":4},500]]'
|
response.response_text = '[[{"id":1},201], [{"error":"error 2"},500], [{"id":3},201], [{"error":4},500]]'
|
||||||
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
||||||
heartbeats = json.dumps([{
|
heartbeats = json.dumps([{
|
||||||
'timestamp': now,
|
'timestamp': now,
|
||||||
'entity': os.path.join(tempdir, entity),
|
'entity': os.path.join(tempdir, entity),
|
||||||
|
@ -306,8 +305,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_leftover_heartbeats_saved_when_bulk_response_not_matching_length(self, logs):
|
def test_leftover_heartbeats_saved_when_bulk_response_not_matching_length(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
entities = [
|
entities = [
|
||||||
|
@ -319,7 +318,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
'php.php',
|
'php.php',
|
||||||
]
|
]
|
||||||
|
|
||||||
with utils.TemporaryDirectory() as tempdir:
|
with TemporaryDirectory() as tempdir:
|
||||||
for entity in entities:
|
for entity in entities:
|
||||||
shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
|
shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
|
||||||
|
|
||||||
|
@ -332,7 +331,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
response.response_text = '[[{"id":1},201], [{"id":3},201]]'
|
response.response_text = '[[{"id":1},201], [{"id":3},201]]'
|
||||||
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
|
||||||
heartbeats = json.dumps([{
|
heartbeats = json.dumps([{
|
||||||
'timestamp': now,
|
'timestamp': now,
|
||||||
'entity': os.path.join(tempdir, entity),
|
'entity': os.path.join(tempdir, entity),
|
||||||
|
@ -358,8 +357,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
self.assertEquals(len(saved_heartbeats), 2)
|
self.assertEquals(len(saved_heartbeats), 2)
|
||||||
|
|
||||||
def test_auth_error_when_sending_offline_heartbeats(self):
|
def test_auth_error_when_sending_offline_heartbeats(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -404,8 +403,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
self.assertEquals(len(saved_heartbeats), 2)
|
self.assertEquals(len(saved_heartbeats), 2)
|
||||||
|
|
||||||
def test_500_error_when_sending_offline_heartbeats(self):
|
def test_500_error_when_sending_offline_heartbeats(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -450,8 +449,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
self.assertEquals(len(saved_heartbeats), 2)
|
self.assertEquals(len(saved_heartbeats), 2)
|
||||||
|
|
||||||
def test_empty_project_can_be_saved(self):
|
def test_empty_project_can_be_saved(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -470,9 +469,9 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
self.assertNothingPrinted()
|
self.assertNothingPrinted()
|
||||||
self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
|
self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
|
||||||
|
|
||||||
def test_get_handles_connection_exception(self):
|
def test_get_handles_exception_on_connect(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -486,7 +485,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
args = ['--file', entity, '--config', config, '--time', now]
|
args = ['--file', entity, '--config', config, '--time', now]
|
||||||
execute(args)
|
execute(args)
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
|
with mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
|
||||||
mock_connect.side_effect = sqlite3.Error('')
|
mock_connect.side_effect = sqlite3.Error('')
|
||||||
|
|
||||||
response.status_code = 201
|
response.status_code = 201
|
||||||
|
@ -500,9 +499,9 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
saved_heartbeat = queue.pop()
|
saved_heartbeat = queue.pop()
|
||||||
self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
|
self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
|
||||||
|
|
||||||
def test_push_handles_connection_exception(self):
|
def test_push_handles_exception_on_connect(self):
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
|
@ -513,7 +512,7 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
entity = 'tests/samples/codefiles/twolinefile.txt'
|
entity = 'tests/samples/codefiles/twolinefile.txt'
|
||||||
config = 'tests/samples/configs/good_config.cfg'
|
config = 'tests/samples/configs/good_config.cfg'
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
|
with mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
|
||||||
mock_connect.side_effect = sqlite3.Error('')
|
mock_connect.side_effect = sqlite3.Error('')
|
||||||
|
|
||||||
args = ['--file', entity, '--config', config, '--time', now]
|
args = ['--file', entity, '--config', config, '--time', now]
|
||||||
|
@ -526,6 +525,43 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
saved_heartbeat = queue.pop()
|
saved_heartbeat = queue.pop()
|
||||||
self.assertEquals(None, saved_heartbeat)
|
self.assertEquals(None, saved_heartbeat)
|
||||||
|
|
||||||
|
@log_capture()
|
||||||
|
def test_push_handles_exception_on_query(self, logs):
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
with NamedTemporaryFile() as fh:
|
||||||
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
|
response = Response()
|
||||||
|
response.status_code = 500
|
||||||
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
|
now = u(int(time.time()))
|
||||||
|
entity = 'tests/samples/codefiles/twolinefile.txt'
|
||||||
|
config = 'tests/samples/configs/good_config.cfg'
|
||||||
|
|
||||||
|
mock_exec = mock.MagicMock()
|
||||||
|
mock_exec.execute.side_effect = sqlite3.Error('')
|
||||||
|
|
||||||
|
mock_conn = mock.MagicMock()
|
||||||
|
mock_conn.execute.side_effect = sqlite3.Error('')
|
||||||
|
|
||||||
|
with mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
|
||||||
|
mock_connect.return_value = (mock_conn, mock_exec)
|
||||||
|
|
||||||
|
args = ['--file', entity, '--config', config, '--time', now]
|
||||||
|
execute(args)
|
||||||
|
|
||||||
|
response.status_code = 201
|
||||||
|
execute(args)
|
||||||
|
|
||||||
|
queue = Queue(None, None)
|
||||||
|
saved_heartbeat = queue.pop()
|
||||||
|
self.assertEquals(None, saved_heartbeat)
|
||||||
|
|
||||||
|
self.assertNothingPrinted()
|
||||||
|
|
||||||
def test_uses_home_folder_by_default(self):
|
def test_uses_home_folder_by_default(self):
|
||||||
queue = Queue(None, None)
|
queue = Queue(None, None)
|
||||||
db_file = queue._get_db_file()
|
db_file = queue._get_db_file()
|
||||||
|
@ -535,10 +571,10 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_uses_wakatime_home_env_variable(self):
|
def test_uses_wakatime_home_env_variable(self):
|
||||||
queue = Queue(None, None)
|
queue = Queue(None, None)
|
||||||
|
|
||||||
with utils.TemporaryDirectory() as tempdir:
|
with TemporaryDirectory() as tempdir:
|
||||||
expected = os.path.realpath(os.path.join(tempdir, '.wakatime.db'))
|
expected = os.path.realpath(os.path.join(tempdir, '.wakatime.db'))
|
||||||
|
|
||||||
with utils.mock.patch('os.environ.get') as mock_env:
|
with mock.patch('os.environ.get') as mock_env:
|
||||||
mock_env.return_value = os.path.realpath(tempdir)
|
mock_env.return_value = os.path.realpath(tempdir)
|
||||||
|
|
||||||
actual = queue._get_db_file()
|
actual = queue._get_db_file()
|
||||||
|
@ -548,8 +584,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_heartbeat_saved_when_requests_raises_exception(self, logs):
|
def test_heartbeat_saved_when_requests_raises_exception(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
exception_msg = u("Oops, requests raised an exception. This is a test.")
|
exception_msg = u("Oops, requests raised an exception. This is a test.")
|
||||||
|
@ -579,15 +615,15 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_nonascii_heartbeat_saved(self, logs):
|
def test_nonascii_heartbeat_saved(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
response.status_code = 500
|
response.status_code = 500
|
||||||
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
with utils.TemporaryDirectory() as tempdir:
|
with TemporaryDirectory() as tempdir:
|
||||||
filename = list(filter(lambda x: x.endswith('.txt'), os.listdir(u('tests/samples/codefiles/unicode'))))[0]
|
filename = list(filter(lambda x: x.endswith('.txt'), os.listdir(u('tests/samples/codefiles/unicode'))))[0]
|
||||||
entity = os.path.join('tests/samples/codefiles/unicode', filename)
|
entity = os.path.join('tests/samples/codefiles/unicode', filename)
|
||||||
shutil.copy(entity, os.path.join(tempdir, filename))
|
shutil.copy(entity, os.path.join(tempdir, filename))
|
||||||
|
@ -613,10 +649,10 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
|
|
||||||
args = ['--file', entity, '--key', key, '--config', config, '--time', now]
|
args = ['--file', entity, '--key', key, '--config', config, '--time', now]
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.stats.standardize_language') as mock_language:
|
with mock.patch('wakatime.stats.standardize_language') as mock_language:
|
||||||
mock_language.return_value = (language, None)
|
mock_language.return_value = (language, None)
|
||||||
|
|
||||||
with utils.mock.patch('wakatime.heartbeat.get_project_info') as mock_project:
|
with mock.patch('wakatime.heartbeat.get_project_info') as mock_project:
|
||||||
mock_project.return_value = (project, branch)
|
mock_project.return_value = (project, branch)
|
||||||
|
|
||||||
execute(args)
|
execute(args)
|
||||||
|
@ -637,8 +673,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_heartbeat_saved_when_bulk_result_json_decode_error(self, logs):
|
def test_heartbeat_saved_when_bulk_result_json_decode_error(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = CustomResponse()
|
response = CustomResponse()
|
||||||
|
@ -665,8 +701,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_heartbeat_saved_from_result_type_error(self, logs):
|
def test_heartbeat_saved_from_result_type_error(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = CustomResponse()
|
response = CustomResponse()
|
||||||
|
@ -693,8 +729,8 @@ class OfflineQueueTestCase(utils.TestCase):
|
||||||
def test_heartbeat_saved_from_result_index_error(self, logs):
|
def test_heartbeat_saved_from_result_index_error(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
with utils.NamedTemporaryFile() as fh:
|
with NamedTemporaryFile() as fh:
|
||||||
with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
|
||||||
mock_db_file.return_value = fh.name
|
mock_db_file.return_value = fh.name
|
||||||
|
|
||||||
response = CustomResponse()
|
response = CustomResponse()
|
||||||
|
|
|
@ -96,5 +96,5 @@ except ImportError: # pragma: nocover
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .packages import simplejson as json
|
from .packages import simplejson as json
|
||||||
except (ImportError, SyntaxError):
|
except (ImportError, SyntaxError): # pragma: nocover
|
||||||
import json
|
import json
|
||||||
|
|
|
@ -21,7 +21,7 @@ from .constants import CONFIG_FILE_PARSE_ERROR
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import configparser
|
import configparser
|
||||||
except ImportError:
|
except ImportError: # pragma: nocover
|
||||||
from .packages import configparser
|
from .packages import configparser
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,10 @@ class Heartbeat(object):
|
||||||
user_agent = None
|
user_agent = None
|
||||||
|
|
||||||
def __init__(self, data, args, configs, _clone=None):
|
def __init__(self, data, args, configs, _clone=None):
|
||||||
|
if not data:
|
||||||
|
self.skip = u('Skipping because heartbeat data is missing.')
|
||||||
|
return
|
||||||
|
|
||||||
self.args = args
|
self.args = args
|
||||||
self.configs = configs
|
self.configs = configs
|
||||||
|
|
||||||
|
@ -91,7 +95,6 @@ class Heartbeat(object):
|
||||||
data = self.dict()
|
data = self.dict()
|
||||||
data.update(attrs)
|
data.update(attrs)
|
||||||
heartbeat = Heartbeat(data, self.args, self.configs, _clone=True)
|
heartbeat = Heartbeat(data, self.args, self.configs, _clone=True)
|
||||||
heartbeat.skip = self.skip
|
|
||||||
return heartbeat
|
return heartbeat
|
||||||
|
|
||||||
def sanitize(self):
|
def sanitize(self):
|
||||||
|
|
Loading…
Reference in a new issue