Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9343789
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Subscribers
None
View Options
diff --git a/swh/icinga_plugins/tests/test_vault.py b/swh/icinga_plugins/tests/test_vault.py
index ed45c46..ee99db4 100644
--- a/swh/icinga_plugins/tests/test_vault.py
+++ b/swh/icinga_plugins/tests/test_vault.py
@@ -1,168 +1,256 @@
# Copyright (C) 2019 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import time
from click.testing import CliRunner
from swh.icinga_plugins.cli import cli
from .web_scenario import WebScenario
dir_id = 'ab'*20
response_pending = {
"obj_id": dir_id,
"obj_type": "directory",
"progress_message": "foo",
"status": "pending"
}
response_done = {
"fetch_url": f"/api/1/vault/directory/{dir_id}/raw/",
"id": 9,
"obj_id": dir_id,
"obj_type": "directory",
"status": "done"
}
response_failed = {
"obj_id": dir_id,
"obj_type": "directory",
"progress_message": "foobar",
"status": "failed"
}
+response_unknown_status = {
+ "obj_id": dir_id,
+ "obj_type": "directory",
+ "progress_message": "what",
+ "status": "boo"
+}
+
class FakeStorage:
def __init__(self, foo, **kwargs):
pass
def directory_get_random(self):
return bytes.fromhex(dir_id)
def invoke(args, catch_exceptions=False):
runner = CliRunner()
result = runner.invoke(cli, args)
if not catch_exceptions and result.exception:
print(result.output)
raise result.exception
return result
def test_vault_immediate_success(requests_mock, mocker, mocked_time):
scenario = WebScenario()
url = f'mock://swh-web.example.org/api/1/vault/directory/{dir_id}/'
scenario.add_step('get', url, {}, status_code=404)
scenario.add_step('post', url, response_pending)
scenario.add_step('get', url, response_done)
scenario.install_mock(requests_mock)
get_storage_mock = mocker.patch('swh.icinga_plugins.vault.get_storage')
get_storage_mock.side_effect = FakeStorage
result = invoke([
'check-vault',
'--swh-web-url', 'mock://swh-web.example.org',
'--swh-storage-url', 'foo://example.org',
'directory',
])
assert result.output == (
f"VAULT OK - cooking directory {dir_id} took "
f"10.00s and succeeded.\n"
f"| 'total_time' = 10.00s\n")
assert result.exit_code == 0, result.output
def test_vault_delayed_success(requests_mock, mocker, mocked_time):
scenario = WebScenario()
url = f'mock://swh-web.example.org/api/1/vault/directory/{dir_id}/'
scenario.add_step('get', url, {}, status_code=404)
scenario.add_step('post', url, response_pending)
scenario.add_step('get', url, response_pending)
scenario.add_step('get', url, response_done)
scenario.install_mock(requests_mock)
get_storage_mock = mocker.patch('swh.icinga_plugins.vault.get_storage')
get_storage_mock.side_effect = FakeStorage
result = invoke([
'check-vault',
'--swh-web-url', 'mock://swh-web.example.org',
'--swh-storage-url', 'foo://example.org',
'directory',
])
assert result.output == (
f"VAULT OK - cooking directory {dir_id} took "
f"20.00s and succeeded.\n"
f"| 'total_time' = 20.00s\n")
assert result.exit_code == 0, result.output
def test_vault_failure(requests_mock, mocker, mocked_time):
scenario = WebScenario()
url = f'mock://swh-web.example.org/api/1/vault/directory/{dir_id}/'
scenario.add_step('get', url, {}, status_code=404)
scenario.add_step('post', url, response_pending)
scenario.add_step('get', url, response_failed)
scenario.install_mock(requests_mock)
get_storage_mock = mocker.patch('swh.icinga_plugins.vault.get_storage')
get_storage_mock.side_effect = FakeStorage
result = invoke([
'check-vault',
'--swh-web-url', 'mock://swh-web.example.org',
'--swh-storage-url', 'foo://example.org',
'directory',
], catch_exceptions=True)
assert result.output == (
f"VAULT CRITICAL - cooking directory {dir_id} took "
f"10.00s and failed with: foobar\n"
f"| 'total_time' = 10.00s\n")
assert result.exit_code == 2, result.output
+def test_vault_unknown_status(requests_mock, mocker, mocked_time):
+ scenario = WebScenario()
+
+ url = f'mock://swh-web.example.org/api/1/vault/directory/{dir_id}/'
+
+ scenario.add_step('get', url, {}, status_code=404)
+ scenario.add_step('post', url, response_pending)
+ scenario.add_step('get', url, response_unknown_status)
+
+ scenario.install_mock(requests_mock)
+
+ get_storage_mock = mocker.patch('swh.icinga_plugins.vault.get_storage')
+ get_storage_mock.side_effect = FakeStorage
+
+ result = invoke([
+ 'check-vault',
+ '--swh-web-url', 'mock://swh-web.example.org',
+ '--swh-storage-url', 'foo://example.org',
+ 'directory',
+ ], catch_exceptions=True)
+
+ assert result.output == (
+ f"VAULT CRITICAL - cooking directory {dir_id} took "
+ f"10.00s and resulted in unknown status: boo\n"
+ f"| 'total_time' = 10.00s\n")
+ assert result.exit_code == 2, result.output
+
+
def test_vault_timeout(requests_mock, mocker, mocked_time):
scenario = WebScenario()
url = f'mock://swh-web.example.org/api/1/vault/directory/{dir_id}/'
scenario.add_step('get', url, {}, status_code=404)
scenario.add_step('post', url, response_pending)
scenario.add_step('get', url, response_pending)
scenario.add_step('get', url, response_pending,
callback=lambda: time.sleep(4000))
scenario.install_mock(requests_mock)
get_storage_mock = mocker.patch('swh.icinga_plugins.vault.get_storage')
get_storage_mock.side_effect = FakeStorage
result = invoke([
'check-vault',
'--swh-web-url', 'mock://swh-web.example.org',
'--swh-storage-url', 'foo://example.org',
'directory',
], catch_exceptions=True)
assert result.output == (
f"VAULT CRITICAL - cooking directory {dir_id} took more than "
f"4020.00s and has status: foo\n"
f"| 'total_time' = 4020.00s\n")
assert result.exit_code == 2, result.output
+
+
+def test_vault_cached_directory(requests_mock, mocker, mocked_time):
+ """First serves a directory that's already in the cache, to
+ test that vault_check requests another one."""
+ scenario = WebScenario()
+
+ url = f'mock://swh-web.example.org/api/1/vault/directory/{dir_id}/'
+
+ scenario.add_step('get', url, {}, status_code=200)
+ scenario.add_step('get', url, {}, status_code=404)
+ scenario.add_step('post', url, response_pending)
+ scenario.add_step('get', url, response_done)
+
+ scenario.install_mock(requests_mock)
+
+ get_storage_mock = mocker.patch('swh.icinga_plugins.vault.get_storage')
+ get_storage_mock.side_effect = FakeStorage
+
+ result = invoke([
+ 'check-vault',
+ '--swh-web-url', 'mock://swh-web.example.org',
+ '--swh-storage-url', 'foo://example.org',
+ 'directory',
+ ])
+
+ assert result.output == (
+ f"VAULT OK - cooking directory {dir_id} took "
+ f"10.00s and succeeded.\n"
+ f"| 'total_time' = 10.00s\n")
+ assert result.exit_code == 0, result.output
+
+
+def test_vault_no_directory(requests_mock, mocker, mocked_time):
+ """Tests with an empty storage"""
+ scenario = WebScenario()
+ scenario.install_mock(requests_mock)
+
+ get_storage_mock = mocker.patch('swh.icinga_plugins.vault.get_storage')
+ get_storage_mock.side_effect = FakeStorage
+ mocker.patch(
+ f'{__name__}.FakeStorage.directory_get_random', return_value=None)
+
+ result = invoke([
+ 'check-vault',
+ '--swh-web-url', 'mock://swh-web.example.org',
+ '--swh-storage-url', 'foo://example.org',
+ 'directory',
+ ], catch_exceptions=True)
+
+ assert result.output == (
+ "VAULT CRITICAL - No directory exists in the archive.\n")
+ assert result.exit_code == 2, result.output
diff --git a/swh/icinga_plugins/vault.py b/swh/icinga_plugins/vault.py
index 3df0ad5..95c1883 100644
--- a/swh/icinga_plugins/vault.py
+++ b/swh/icinga_plugins/vault.py
@@ -1,98 +1,98 @@
# Copyright (C) 2019 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import time
import requests
from swh.storage import get_storage
from .base_check import BaseCheck
class NoDirectory(Exception):
pass
class VaultCheck(BaseCheck):
TYPE = 'VAULT'
DEFAULT_WARNING_THRESHOLD = 0
DEFAULT_CRITICAL_THRESHOLD = 3600
def __init__(self, obj):
super().__init__(obj)
self._swh_storage = get_storage('remote', url=obj['swh_storage_url'])
self._swh_web_url = obj['swh_web_url']
self._poll_interval = obj['poll_interval']
def _url_for_dir(self, dir_id):
return self._swh_web_url + f'/api/1/vault/directory/{dir_id.hex()}/'
def _pick_directory(self):
dir_ = self._swh_storage.directory_get_random()
if dir_ is None:
raise NoDirectory()
return dir_
def _pick_uncached_directory(self):
while True:
dir_id = self._pick_directory()
response = requests.get(self._url_for_dir(dir_id))
if response.status_code == 404:
return dir_id
def main(self):
try:
dir_id = self._pick_uncached_directory()
except NoDirectory:
self.print_result(
'CRITICAL',
- 'No directory exists in the archive')
+ 'No directory exists in the archive.')
return 2
start_time = time.time()
total_time = 0
response = requests.post(self._url_for_dir(dir_id))
assert response.status_code == 200, (response, response.text)
result = response.json()
while result['status'] in ('new', 'pending'):
time.sleep(self._poll_interval)
response = requests.get(self._url_for_dir(dir_id))
assert response.status_code == 200, (response, response.text)
result = response.json()
total_time = time.time() - start_time
if total_time > self.critical_threshold:
self.print_result(
'CRITICAL',
f'cooking directory {dir_id.hex()} took more than '
f'{total_time:.2f}s and has status: '
f'{result["progress_message"]}',
total_time=total_time)
return 2
if result['status'] == 'done':
(status_code, status) = self.get_status(total_time)
self.print_result(
status,
f'cooking directory {dir_id.hex()} took {total_time:.2f}s '
f'and succeeded.',
total_time=total_time)
return status_code
elif result['status'] == 'failed':
self.print_result(
'CRITICAL',
f'cooking directory {dir_id.hex()} took {total_time:.2f}s '
f'and failed with: {result["progress_message"]}',
total_time=total_time)
return 2
else:
self.print_result(
'CRITICAL',
f'cooking directory {dir_id.hex()} took {total_time:.2f}s '
f'and resulted in unknown status: {result["status"]}',
total_time=total_time)
return 2
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Jul 4, 1:51 PM (3 d, 21 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3273569
Attached To
rDICP Icinga plugins
Event Timeline
Log In to Comment