Page MenuHomeSoftware Heritage

No OneTemporary

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

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

Event Timeline