Add more unit tests for ligo.gracedb.rest.GraceDb

parent 99651820
......@@ -287,3 +287,74 @@ def test_force_noauth_and_fail_if_noauth():
'constructor: fail_if_noauth=True and force_noauth=True.')
with pytest.raises(ValueError, match=err_str):
GraceDb(force_noauth=True, fail_if_noauth=True)
@pytest.mark.parametrize(
"resource,key",
[
('api_versions', 'api-versions'),
('server_version', 'server-version'),
('links', 'links'),
('templates', 'templates'),
('groups', 'groups'),
('pipelines', 'pipelines'),
('searches', 'searches'),
('allowed_labels', 'labels'),
('superevent_categories', 'superevent-categories'),
('em_groups', 'em-groups'),
('voevent_types', 'voevent-types'),
('signoff_types', 'signoff-types'),
('signoff_statuses', 'signoff-statuses'),
('instruments', 'instruments'),
]
)
def test_properties_from_api_root(safe_client, resource, key):
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
with mock.patch(si_prop, new_callable=mock.PropertyMock()) as mock_si:
getattr(safe_client, resource)
call_args, call_kwargs = mock_si.get.call_args
assert mock_si.get.call_count == 1
assert len(call_args) == 1
assert call_kwargs == {}
assert call_args[0] == key
@pytest.mark.parametrize("api_version", [1, 1.2, [], (), {}])
def test_bad_api_version(api_version):
err_msg = 'api_version should be a string'
with pytest.raises(TypeError, match=err_msg):
GraceDb(api_version=api_version)
@pytest.mark.parametrize(
"service_url,api_version",
[
('test', None),
('test/', None),
('test', 'v1'),
('test/', 'v2'),
('test/', 'default'),
],
)
def test_set_service_url(safe_client, service_url, api_version):
safe_client._set_service_url(service_url, api_version)
# Construct expected service urls
expected_service_url = service_url.rstrip('/') + '/'
expected_versioned_service_url = expected_service_url
if api_version and api_version != 'default':
expected_versioned_service_url += api_version + '/'
assert safe_client._service_url == expected_service_url
assert safe_client._versioned_service_url == expected_versioned_service_url
def test_legacy_service_url(safe_client, capsys):
service_url = 'fake-service-url'
safe_client._service_url = service_url
assert safe_client.service_url == service_url
stdout = capsys.readouterr().out
assert stdout.strip() == \
"DEPRECATED: this attribute has been moved to '_service_url'"
try:
from unittest import mock
except ImportError: # python < 3
import mock
import pytest
@pytest.mark.parametrize("emo_number", [None, 12])
def test_superevent_emobservations(safe_client, emo_number):
superevent_id = 'TS190302abc'
# Set up templates mock
mock_template = mock.MagicMock()
if emo_number:
template_key = 'superevent-emobservation-detail-template'
else:
template_key = 'superevent-emobservation-list-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
with mock.patch('ligo.gracedb.rest.GraceDb.get') as mock_get, \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.emobservations(superevent_id,
emobservation_num=emo_number)
get_call_args, get_call_kwargs = mock_get.call_args
assert len(get_call_args) == 1
assert get_call_kwargs == {}
# Test template call kwargs
num_kwargs = 1
if emo_number:
num_kwargs += 1
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
assert len(template_call_kwargs) == num_kwargs
assert template_call_kwargs['superevent_id'] == superevent_id
if emo_number:
assert template_call_kwargs['N'] == emo_number
@pytest.mark.parametrize("emo_number", [None, 12])
def test_event_logs(safe_client, emo_number):
graceid = 'T123456'
# Set up templates mock
mock_template = mock.MagicMock()
if emo_number:
template_key = 'emobservation-detail-template'
else:
template_key = 'emobservation-list-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
with mock.patch('ligo.gracedb.rest.GraceDb.get') as mock_get, \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.emobservations(graceid, emobservation_num=emo_number)
get_call_args, get_call_kwargs = mock_get.call_args
assert len(get_call_args) == 1
assert get_call_kwargs == {}
# Test template call kwargs
num_kwargs = 1
if emo_number:
num_kwargs += 1
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
assert len(template_call_kwargs) == num_kwargs
assert template_call_kwargs['graceid'] == graceid
if emo_number:
assert template_call_kwargs['N'] == emo_number
@pytest.mark.parametrize(
"is_event,obj_id",
[
(True, "T123456"),
(False, "TS121212abc"),
]
)
def test_write_emobservations(safe_client, is_event, obj_id):
# Generate data
emgroup = 'FAKE_EMGROUP'
ra_list = [1] * 4
ra_width_list = [2] * 4
dec_list = [3] * 4
dec_width_list = [4] * 4
start_time_list = [5] * 4
duration_list = [6] * 4
comment = 'test'
# Set up templates mock
mock_template = mock.MagicMock()
if is_event:
template_key = 'emobservation-list-template'
else:
template_key = 'superevent-emobservation-list-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
# Set up emgroup mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'em-groups': [emgroup]}
with mock.patch('ligo.gracedb.rest.GraceDb.post') as mock_post, \
mock.patch(si_prop, mock_si_dict), \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.writeEMObservation(
obj_id, emgroup, ra_list, ra_width_list, dec_list, dec_width_list,
start_time_list, duration_list, comment=comment
)
# Test call to self.post
post_call_args, post_call_kwargs = mock_post.call_args
assert len(post_call_args) == 1
assert len(post_call_kwargs) == 1
assert 'body' in post_call_kwargs
request_body = post_call_kwargs['body']
assert request_body['group'] == emgroup
assert request_body['ra_list'] == ra_list
assert request_body['ra_width_list'] == ra_width_list
assert request_body['dec_list'] == dec_list
assert request_body['dec_width_list'] == dec_width_list
assert request_body['start_time_list'] == start_time_list
assert request_body['duration_list'] == duration_list
assert request_body['comment'] == comment
# Test template call kwargs
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
assert len(template_call_kwargs) == 1
if is_event:
call_key = 'graceid'
else:
call_key = 'superevent_id'
assert template_call_kwargs[call_key] == obj_id
@pytest.mark.parametrize(
"ras,ra_widths,decs,dec_widths,start_times,durations",
[
([1] * 4, [1] * 4, [1] * 4, [1] * 4, [1] * 4, [1] * 5),
([1] * 4, [1] * 4, [1] * 4, [1] * 4, [1] * 5, [1] * 4),
([1] * 4, [1] * 4, [1] * 4, [1] * 5, [1] * 4, [1] * 4),
([1] * 4, [1] * 4, [1] * 5, [1] * 4, [1] * 4, [1] * 4),
([1] * 4, [1] * 5, [1] * 4, [1] * 4, [1] * 4, [1] * 4),
([1] * 5, [1] * 4, [1] * 4, [1] * 4, [1] * 4, [1] * 4),
([1] * 1, [1] * 2, [1] * 3, [1] * 4, [1] * 5, [1] * 6),
]
)
def test_write_emobservation_different_list_lengths(
safe_client, ras, ra_widths, decs, dec_widths, start_times, durations
):
# Set up emgroup mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'em-groups': ['emgroup1']}
err_msg = ("raList, decList, startTimeList, raWidthList, decWidthList, "
"and durationList should be the same length")
with mock.patch(si_prop, mock_si_dict):
with pytest.raises(ValueError, match=err_msg):
safe_client.writeEMObservation(
'TS121212a', 'emgroup1', ras, ra_widths, decs, dec_widths,
start_times, durations, comment="test"
)
def test_write_emobservation_bad_emgroup(safe_client):
# Set up emgroup mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'em-groups': ['emgroup1']}
err_msg = "group must be one of {groups}".format(
groups=", ".join(mock_si_dict['em-groups']))
with mock.patch(si_prop, mock_si_dict):
with pytest.raises(ValueError, match=err_msg):
safe_client.writeEMObservation(
'TS121212a', 'emgroup20', 1, 1, 1, 1, 1, 1, comment="test"
)
This diff is collapsed.
try:
from unittest import mock
except ImportError: # python < 3
import mock
import os
import pytest
@pytest.mark.parametrize("filename", ['file.txt', "", None])
def test_superevent_files(safe_client, filename):
superevent_id = 'S190302abc'
# Set up templates mock
mock_template = mock.MagicMock()
if filename:
template_key = 'superevent-file-detail-template'
else:
template_key = 'superevent-file-list-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
with mock.patch('ligo.gracedb.rest.GraceDb.get') as mock_get, \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.files(superevent_id, filename=filename)
get_call_args, get_call_kwargs = mock_get.call_args
assert len(get_call_args) == 1
assert get_call_kwargs == {}
# Test template call kwargs
num_kwargs = 1
if filename:
num_kwargs += 1
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
assert len(template_call_kwargs) == num_kwargs
assert template_call_kwargs['superevent_id'] == superevent_id
if filename:
assert template_call_kwargs['file_name'] == filename
@pytest.mark.parametrize("filename", ['file.txt', "", None])
def test_event_files(safe_client, filename):
graceid = 'T123456'
# Set up templates mock
mock_template = mock.MagicMock()
template_key = 'files-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
with mock.patch('ligo.gracedb.rest.GraceDb.get') as mock_get, \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.files(graceid, filename=filename)
get_call_args, get_call_kwargs = mock_get.call_args
assert len(get_call_args) == 1
assert get_call_kwargs == {}
# Test template call kwargs
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
assert len(template_call_kwargs) == 2
assert template_call_kwargs['graceid'] == graceid
if not filename:
filename = ""
assert template_call_kwargs['filename'] == filename
def test_legacy_writefile(safe_client, capsys):
obj_id = 'TS121212abc'
filename = 'test_file.txt'
filecontents = 'fake filecontents'
expected_stdout = ("WARNING: the writeFile() method is deprecated in "
"favor of writeLog() and will be removed in a future "
"release.")
with mock.patch('ligo.gracedb.rest.GraceDb.writeLog') as mock_writelog:
safe_client.writeFile(obj_id, filename, filecontents=filecontents)
# Check call
call_args, call_kwargs = mock_writelog.call_args
assert mock_writelog.call_count == 1
assert len(call_args) == 2
assert obj_id in call_args
assert "FILE UPLOAD" in call_args
assert len(call_kwargs) == 2
assert call_kwargs['filename'] == filename
assert call_kwargs['filecontents'] == filecontents
# Check output
stdout = capsys.readouterr().out
assert stdout.strip() == expected_stdout.strip()
@pytest.mark.parametrize(
"filename,filecontents",
[
('file.txt', None),
('subdir1/subdir2/file.txt', None),
('-', None),
('file.txt', 'fc1'),
('subdir1/subdir2/file.txt', 'fc2'),
('-', 'fc3'),
]
)
def test_write_log_with_file(safe_client, filename, filecontents):
# Set up templates mock
mock_template = mock.MagicMock()
mock_template_dict = {'superevent-log-list-template': mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
# Set up mock open
open_func = 'ligo.gracedb.rest.open'
mock_data = 'fake data'
open_mocker = mock.mock_open(read_data=mock_data)
# Set up mock sys.stdin.read
stdin_obj = 'ligo.gracedb.rest.sys.stdin'
mock_stdin_data = 'fake stdin data'
with mock.patch('ligo.gracedb.rest.GraceDb.post') as mock_post, \
mock.patch(open_func, open_mocker), \
mock.patch(stdin_obj) as mock_stdin, \
mock.patch(template_prop, mock_template_dict): # noqa: E127
mock_stdin.read.return_value = mock_stdin_data
safe_client.writeLog('TS121212a', 'test', filename=filename,
filecontents=filecontents)
# Test call to self.post
post_call_args, post_call_kwargs = mock_post.call_args
assert len(post_call_args) == 1
assert len(post_call_kwargs) == 2
assert 'body' in post_call_kwargs
assert 'files' in post_call_kwargs
# Test file contents
post_files = post_call_kwargs['files']
assert len(post_files) == 1
assert post_files[0][0] == 'upload'
if filecontents is None:
if filename == '-':
assert post_files[0][1] == 'stdin'
assert post_files[0][2] == mock_stdin_data
else:
assert post_files[0][1] == os.path.basename(filename)
assert post_files[0][2] == mock_data
else:
assert post_files[0][1] == os.path.basename(filename)
assert post_files[0][2] == filecontents
def test_write_log_with_filecontents_handler(safe_client):
# Set up templates mock
mock_template = mock.MagicMock()
mock_template_dict = {'superevent-log-list-template': mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
# Set up mock filecontents
filename = 'file.txt'
filecontents = mock.MagicMock()
mock_data = 'more fake data'
filecontents.read.return_value = mock_data
with mock.patch('ligo.gracedb.rest.GraceDb.post') as mock_post, \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.writeLog('TS121212a', 'test', filename=filename,
filecontents=filecontents)
# Test call to self.post
post_call_args, post_call_kwargs = mock_post.call_args
assert len(post_call_args) == 1
assert len(post_call_kwargs) == 2
assert 'body' in post_call_kwargs
assert 'files' in post_call_kwargs
# Test file contents
post_files = post_call_kwargs['files']
assert len(post_files) == 1
assert post_files[0][0] == 'upload'
assert post_files[0][1] == os.path.basename(filename)
assert post_files[0][2] == mock_data
try:
from unittest import mock
except ImportError: # python < 3
import mock
import pytest
@pytest.mark.parametrize(
"is_event,label_name",
[
(True, ""),
(False, ""),
(True, 'LABEL_NAME'),
(False, 'LABEL_NAME'),
]
)
def test_get_labels(safe_client, is_event, label_name):
if is_event:
obj_id = 'T123456'
else:
obj_id = 'TS190302abc'
# Set up templates mock
mock_template = mock.MagicMock()
if is_event:
template_key = 'event-label-template'
else:
if label_name:
template_key = 'superevent-label-detail-template'
else:
template_key = 'superevent-label-list-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
# Set up allowed_labels mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'labels': ['LABEL_NAME']}
with mock.patch('ligo.gracedb.rest.GraceDb.get') as mock_get, \
mock.patch(si_prop, mock_si_dict), \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.labels(obj_id, label=label_name)
get_call_args, get_call_kwargs = mock_get.call_args
assert len(get_call_args) == 1
assert get_call_kwargs == {}
# Test template call kwargs
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
if is_event:
assert len(template_call_kwargs) == 2
assert template_call_kwargs['graceid'] == obj_id
assert template_call_kwargs['label'] == label_name
else:
if label_name:
assert len(template_call_kwargs) == 2
assert template_call_kwargs['superevent_id'] == obj_id
assert template_call_kwargs['label_name'] == label_name
else:
assert len(template_call_kwargs) == 1
assert template_call_kwargs['superevent_id'] == obj_id
def test_get_label_bad_label_name(safe_client):
# Set up allowed_labels mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'labels': ['LABEL_NAME']}
label = 'bad_label'
err_msg = "Label '{label}' does not exist in the database".format(
label=label)
with mock.patch(si_prop, mock_si_dict):
with pytest.raises(NameError, match=err_msg):
safe_client.labels('T123456', label=label)
@pytest.mark.parametrize("is_event", [True, False])
def test_write_label(safe_client, is_event):
label = 'TEST_LABEL'
if is_event:
obj_id = 'T123456'
else:
obj_id = 'TS190302abc'
request_func = 'ligo.gracedb.rest.GraceDb.post_or_put_or_patch'
# Set up templates mock
mock_template = mock.MagicMock()
if is_event:
template_key = 'event-label-template'
else:
template_key = 'superevent-label-list-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
# Set up allowed_labels mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'labels': [label]}
with mock.patch(request_func) as mock_rf, \
mock.patch(si_prop, mock_si_dict), \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.writeLabel(obj_id, label)
rf_call_args, rf_call_kwargs = mock_rf.call_args
assert len(rf_call_args) == 2
assert len(rf_call_kwargs) == 1
assert 'body' in rf_call_kwargs
if is_event:
assert rf_call_args[0] == 'PUT'
assert rf_call_kwargs['body'] == {}
else:
assert rf_call_args[0] == 'POST'
assert rf_call_kwargs['body'] == {'name': label}
# Test template call kwargs
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
if is_event:
assert len(template_call_kwargs) == 2
assert template_call_kwargs['graceid'] == obj_id
assert template_call_kwargs['label'] == label
else:
assert len(template_call_kwargs) == 1
assert template_call_kwargs['superevent_id'] == obj_id
def test_write_label_bad_label_name(safe_client):
# Set up allowed_labels mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'labels': ['LABEL_NAME']}
label = 'bad_label'
err_msg = "Label '{label}' does not exist in the database".format(
label=label)
with mock.patch(si_prop, mock_si_dict):
with pytest.raises(NameError, match=err_msg):
safe_client.writeLabel('T123456', label)
@pytest.mark.parametrize("is_event", [True, False])
def test_remove_label(safe_client, is_event):
label = 'TEST_LABEL'
if is_event:
obj_id = 'T123456'
else:
obj_id = 'TS190302abc'
# Set up templates mock
mock_template = mock.MagicMock()
if is_event:
template_key = 'event-label-template'
else:
template_key = 'superevent-label-detail-template'
mock_template_dict = {template_key: mock_template}
template_prop = 'ligo.gracedb.rest.GraceDb.templates'
# Set up allowed_labels mock
si_prop = 'ligo.gracedb.rest.GraceDb.service_info'
mock_si_dict = {'labels': [label]}
with mock.patch('ligo.gracedb.rest.GraceDb.delete') as mock_delete, \
mock.patch(si_prop, mock_si_dict), \
mock.patch(template_prop, mock_template_dict): # noqa: E127
safe_client.removeLabel(obj_id, label)
delete_call_args, delete_call_kwargs = mock_delete.call_args
assert len(delete_call_args) == 1
assert len(delete_call_kwargs) == 0
# Test template call kwargs
template_call_args, template_call_kwargs = mock_template.format.call_args
assert template_call_args == ()
assert len(template_call_kwargs) == 2
if is_event:
assert template_call_kwargs['graceid'] == obj_id
assert template_call_kwargs['label'] == label
else:
assert template_call_kwargs['superevent_id'] == obj_id