Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ venv/
*.pyc
.vscode
dev_tools.py
.idea/
.eggs/
build/
dist/
3 changes: 3 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pytest]
log_print = True
python_paths = src/
2 changes: 1 addition & 1 deletion src/logsearch/logsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def __init__(self, resp, progress, parent):
self.__progress = None

def poll_query(self):
while True:
while self.__resp.status_code == 202:
res = self.__resp.json()
continue_url = res['links'][0]['href']
percentage = res['progress']
Expand Down
198 changes: 177 additions & 21 deletions test/basic_test.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,198 @@
"""
tests
"""
import pytest
import requests_mock
from logsearch.logsearch import LogSearch

__API_KEY = 'DUMMY_API_KEY'
__API_KEY_HEADER = {'x-api-key': __API_KEY}

__API_KEY_URL = 'https://eu.rest.logs.insight.rapid7.com/management/organizations/apikeys'

__SEARCH_QUERY_URL = "https://eu.rest.logs.insight.rapid7.com/query/logs?limit=1"

__LOG_ID ='a96d464b-acf7-43c8-b133-4df8551e718d'

__SEARCH_QUERY_RESULTS_URL = 'https://eu.rest.logs.insight.rapid7.com/query/' \
'f9eab513-2b74-49e9-8a60-421880324294:1:43e3ccb9c280164eeb5b1167164975c094a21f2b' \
'::ff9470943e7ae1b73c9f4067560a769f7007b544:' \
'?log_keys=%s&query=where(main)+calculate(count)&time_range=Last+24+Hours' % __LOG_ID

__SEARCH_QUERY_RESPONSE_JSON = {
"logs": ["a96d464b-acf7-43c8-b133-4df8551e718d"],
"progress": 0,
"events": [],
"partial": {
"cardinality": 0,
"granularity": 8640000,
"from": 1549383619380,
"to": 1549470019380,
"type": "count",
"stats": {
"global_timeseries": {
"count": 0
}
},
"groups": [],
"status": 200,
"timeseries": {
"global_timeseries": [
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0}
]
},
"count": 0
},
"links": [
{
"rel": "Self",
"href": "https://eu.rest.logs.insight.rapid7.com/query/f9eab513-2b74-49e9-8a60-421880324294:1:43e3ccb9c280164eeb5b1167164975c094a21f2b::ff9470943e7ae1b73c9f4067560a769f7007b544:?log_keys=a96d464b-acf7-43c8-b133-4df8551e718d&query=where(main)+calculate(count)&time_range=Last+24+Hours"
}
],
"id": "f9eab513-2b74-49e9-8a60-421880324294:1:43e3ccb9c280164eeb5b1167164975c094a21f2b::ff9470943e7ae1b73c9f4067560a769f7007b544:",
"leql": {
"statement": "where(main) calculate(count)",
"during": {
"from": 1549383619380,
"to": 1549470019380,
"time_range": "Last 24 Hours"
}
}
}

__SEARCH_QUERY_RESULTS_RESPONSE_JSON = {
"logs": ["a96d464b-acf7-43c8-b133-4df8551e718d"],
"statistics": {
"cardinality": 0,
"granularity": 8640000,
"from": 1549383619380,
"to": 1549470019380,
"type": "count",
"stats": {
"global_timeseries": {
"count": 143
}
},
"groups": [],
"status": 200,
"timeseries": {
"global_timeseries": [
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 0},
{"count": 59},
{"count": 84},
{"count": 0}
]
},
"count": 143
},
"leql": {
"statement": "where(main) calculate(count)",
"during": {
"from": 1549383619380,
"to": 1549470019380,
"time_range": "Last 24 Hours"
}
}
}

__REGIONS = ['US', 'EU', 'AU', 'CA']


def test_load_logsearch_with_api_key_makes_request_to_rest():
with requests_mock.Mocker() as m:
m.get(
"https://eu.rest.logs.insight.rapid7.com/management/organizations/apikeys",
request_headers={'x-api-key': 'dummy_key'},
text='ok'
)
ls = LogSearch(api_key='dummy_key')
m.get(__API_KEY_URL, request_headers=__API_KEY_HEADER, text='ok')
LogSearch(api_key=__API_KEY)


def test_load_logsearch_with_invalid_api_key_raises_value_error():
with requests_mock.Mocker() as m:
m.get(
"https://eu.rest.logs.insight.rapid7.com/management/organizations/apikeys",
request_headers={'x-api-key': 'dummy_key'},
status_code=404
)
m.get(__API_KEY_URL, request_headers=__API_KEY_HEADER, status_code=404)

with pytest.raises(ValueError) as excinfo:
ls = LogSearch(api_key='dummy_key')
LogSearch(api_key=__API_KEY)

assert str(excinfo.value) == 'API Key is not valid or a readonly key'


def test_load_logsearch_with_region_makes_request_to_correct_region():
for region in ['US', 'EU', 'AU', 'CA']:
for region in __REGIONS:
with requests_mock.Mocker() as m:
m.get(
"https://%s.rest.logs.insight.rapid7.com/management/organizations/apikeys" % region,
request_headers={'x-api-key': 'dummy_key'},
text='ok'
)
ls = LogSearch(api_key='dummy_key', region=region)
url = __API_KEY_URL.replace('eu.', region + '.')
m.get(url, request_headers=__API_KEY_HEADER, text='ok')
LogSearch(api_key=__API_KEY, region=region)


def test_load_logsearch_with_invalid_region():
with pytest.raises(ValueError) as excinfo:
ls = LogSearch(api_key='dummy_key', region='FR')
LogSearch(api_key=__API_KEY, region='FR')

assert str(excinfo.value) == "Unrecognised region 'FR' valid regions are [EU, US, CA, AU]"


def test_simple_query_when_lerest_returns_202_continuation():
with requests_mock.Mocker() as m:
m.get(__API_KEY_URL,
request_headers=__API_KEY_HEADER,
json={'apikeys': [__LOG_ID]},
status_code=200)

dummy_continuation_link_dict = {
'rel': 'Self',
'href': __SEARCH_QUERY_RESULTS_URL
}

resp_body = {
'events': [],
'links': [dummy_continuation_link_dict,],
'progress': 0
}

m.post(__SEARCH_QUERY_URL,
request_headers=__API_KEY_HEADER,
status_code=202,
json=resp_body)

m.get(__SEARCH_QUERY_RESULTS_URL, json=__SEARCH_QUERY_RESULTS_RESPONSE_JSON)

ls = LogSearch(api_key=__API_KEY)
query = ls.search(query='where(main) calculate(count)',
log_ids=[__LOG_ID],
time_range='Last 24 Hours',
limit=1)
assert query.get_resp().json() == __SEARCH_QUERY_RESULTS_RESPONSE_JSON


def test_simple_query_when_lerest_returns_200_no_continuation():
with requests_mock.Mocker() as m:
m.get(__API_KEY_URL,
request_headers=__API_KEY_HEADER,
json={'apikeys': [__LOG_ID]},
status_code=200)

m.post(__SEARCH_QUERY_URL,
request_headers=__API_KEY_HEADER,
status_code=200,
json=__SEARCH_QUERY_RESULTS_RESPONSE_JSON)

ls = LogSearch(api_key=__API_KEY)

assert str(excinfo.value) == "Unrecognised region 'FR' valid regions are [EU, US, CA, AU]"
query = ls.search(query='where(main) calculate(count)',
log_ids=[__LOG_ID],
time_range='Last 24 Hours',
limit=1)
assert query.get_resp().json() == __SEARCH_QUERY_RESULTS_RESPONSE_JSON
1 change: 1 addition & 0 deletions test_requirements.pip
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pytest==4.1.1
pytest-pythonpath==0.7.3
requests-mock==1.5.2
pylint==1.9.2