mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-03-27 05:43:22 +00:00
363 lines
9.7 KiB
Python
363 lines
9.7 KiB
Python
# Copyright (c) Ansible Project
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
import pytest
|
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import (
|
|
MagicMock,
|
|
)
|
|
|
|
from ansible_collections.community.crypto.plugins.module_utils.acme.errors import (
|
|
ACMEProtocolException,
|
|
format_error_problem,
|
|
)
|
|
|
|
|
|
TEST_FORMAT_ERROR_PROBLEM = [
|
|
(
|
|
{
|
|
"type": "foo",
|
|
},
|
|
"",
|
|
"Error foo",
|
|
),
|
|
({"type": "foo", "title": "bar"}, "", 'Error "bar" (foo)'),
|
|
({"type": "foo", "detail": "bar baz"}, "", 'Error foo: "bar baz"'),
|
|
({"type": "foo", "subproblems": []}, "", "Error foo Subproblems:"),
|
|
(
|
|
{
|
|
"type": "foo",
|
|
"subproblems": [
|
|
{
|
|
"type": "bar",
|
|
},
|
|
],
|
|
},
|
|
"",
|
|
"Error foo Subproblems:\n(0) Error bar",
|
|
),
|
|
(
|
|
{
|
|
"type": "foo",
|
|
"subproblems": [
|
|
{
|
|
"type": "bar",
|
|
"subproblems": [
|
|
{
|
|
"type": "baz",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
"",
|
|
"Error foo Subproblems:\n(0) Error bar Subproblems:\n(0.0) Error baz",
|
|
),
|
|
(
|
|
{
|
|
"type": "foo",
|
|
"title": "Foo Error",
|
|
"detail": "Foo went wrong",
|
|
"subproblems": [
|
|
{
|
|
"type": "bar",
|
|
"detail": "Bar went wrong",
|
|
"subproblems": [
|
|
{
|
|
"type": "baz",
|
|
"title": "Baz Error",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
"type": "bar2",
|
|
"title": "Bar 2 Error",
|
|
"detail": "Bar really went wrong",
|
|
},
|
|
],
|
|
},
|
|
"X.",
|
|
'Error "Foo Error" (foo): "Foo went wrong" Subproblems:\n'
|
|
'(X.0) Error bar: "Bar went wrong" Subproblems:\n'
|
|
'(X.0.0) Error "Baz Error" (baz)\n'
|
|
'(X.1) Error "Bar 2 Error" (bar2): "Bar really went wrong"',
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"problem, subproblem_prefix, result", TEST_FORMAT_ERROR_PROBLEM
|
|
)
|
|
def test_format_error_problem(problem, subproblem_prefix, result):
|
|
res = format_error_problem(problem, subproblem_prefix)
|
|
assert res == result
|
|
|
|
|
|
def create_regular_response(response_text):
|
|
response = MagicMock()
|
|
response.read = MagicMock(return_value=response_text.encode("utf-8"))
|
|
response.closed = False
|
|
return response
|
|
|
|
|
|
def create_error_response():
|
|
response = MagicMock()
|
|
response.read = MagicMock(side_effect=AttributeError("read"))
|
|
response.closed = True
|
|
return response
|
|
|
|
|
|
def create_decode_error(msg):
|
|
def f(content):
|
|
raise Exception(msg)
|
|
|
|
return f
|
|
|
|
|
|
TEST_ACME_PROTOCOL_EXCEPTION = [
|
|
(
|
|
{},
|
|
None,
|
|
"ACME request failed.",
|
|
{},
|
|
),
|
|
(
|
|
{
|
|
"msg": "Foo",
|
|
"extras": {
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
None,
|
|
"Foo.",
|
|
{
|
|
"foo": "bar",
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
},
|
|
},
|
|
None,
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created.",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
},
|
|
"response": create_regular_response("xxx"),
|
|
},
|
|
None,
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created. The raw error result: xxx",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
},
|
|
"response": create_regular_response("xxx"),
|
|
},
|
|
create_decode_error("yyy"),
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created. The raw error result: xxx",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
},
|
|
"response": create_regular_response("xxx"),
|
|
},
|
|
lambda content: dict(foo="bar"),
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created. The JSON error result: {'foo': 'bar'}",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
},
|
|
"response": create_error_response(),
|
|
},
|
|
None,
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created.",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
"body": "xxx",
|
|
},
|
|
"response": create_error_response(),
|
|
},
|
|
lambda content: dict(foo="bar"),
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created. The JSON error result: {'foo': 'bar'}",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
},
|
|
"content": "xxx",
|
|
},
|
|
None,
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created. The raw error result: xxx",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 400,
|
|
},
|
|
"content_json": {
|
|
"foo": "bar",
|
|
},
|
|
"extras": {
|
|
"bar": "baz",
|
|
},
|
|
},
|
|
None,
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 400 Bad Request. The JSON error result: {'foo': 'bar'}",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 400,
|
|
"bar": "baz",
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 201,
|
|
},
|
|
"content_json": {
|
|
"type": "foo",
|
|
},
|
|
},
|
|
None,
|
|
"ACME request failed for https://ca.example.com/foo with HTTP status 201 Created. The JSON error result: {'type': 'foo'}",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 201,
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 400,
|
|
},
|
|
"content_json": {
|
|
"type": "foo",
|
|
},
|
|
},
|
|
None,
|
|
"ACME request failed for https://ca.example.com/foo with status 400 Bad Request. Error foo.",
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 400,
|
|
"problem": {
|
|
"type": "foo",
|
|
},
|
|
"subproblems": [],
|
|
},
|
|
),
|
|
(
|
|
{
|
|
"info": {
|
|
"url": "https://ca.example.com/foo",
|
|
"status": 400,
|
|
},
|
|
"content_json": {
|
|
"type": "foo",
|
|
"title": "Foo Error",
|
|
"subproblems": [
|
|
{
|
|
"type": "bar",
|
|
"detail": "This is a bar error",
|
|
"details": "Details.",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
None,
|
|
'ACME request failed for https://ca.example.com/foo with status 400 Bad Request. Error "Foo Error" (foo). Subproblems:\n'
|
|
'(0) Error bar: "This is a bar error".',
|
|
{
|
|
"http_url": "https://ca.example.com/foo",
|
|
"http_status": 400,
|
|
"problem": {
|
|
"type": "foo",
|
|
"title": "Foo Error",
|
|
},
|
|
"subproblems": [
|
|
{
|
|
"type": "bar",
|
|
"detail": "This is a bar error",
|
|
"details": "Details.",
|
|
},
|
|
],
|
|
},
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("input, from_json, msg, args", TEST_ACME_PROTOCOL_EXCEPTION)
|
|
def test_acme_protocol_exception(input, from_json, msg, args):
|
|
if from_json is None:
|
|
module = None
|
|
else:
|
|
module = MagicMock()
|
|
module.from_json = from_json
|
|
with pytest.raises(ACMEProtocolException) as exc:
|
|
raise ACMEProtocolException(module, **input)
|
|
|
|
print(exc.value.msg)
|
|
print(exc.value.module_fail_args)
|
|
print(msg)
|
|
print(args)
|
|
assert exc.value.msg == msg
|
|
assert exc.value.module_fail_args == args
|