File: test_session.py

package info (click to toggle)
blebox-uniapi 2.5.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 520 kB
  • sloc: python: 4,994; makefile: 85; sh: 5
file content (155 lines) | stat: -rw-r--r-- 5,017 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""Tests for `blebox_uniapi` package."""

import pytest
import logging
import aiohttp

from unittest.mock import patch, Mock, AsyncMock

from blebox_uniapi.session import ApiHost as Session
from blebox_uniapi import error


@pytest.fixture
def mocked_client():
    with patch("aiohttp.ClientSession", spec_set=True, autospec=True) as mocked_session:
        yield mocked_session.return_value


@pytest.fixture
def logger():
    return Mock(spec_set=logging.Logger).return_value


@pytest.fixture
def client():
    return Mock(spec_set=aiohttp.ClientSession)


def valid_response():
    response = Mock(spec_set=aiohttp.ClientResponse)
    response.status = 200
    response.text = AsyncMock(return_value="foobar")
    response.json = AsyncMock(return_value=123)
    return response


def timeout_error(connection, timeout):
    raise aiohttp.ServerTimeoutError


def client_error(connection, timeout):
    raise aiohttp.ClientError("client err")


def os_error(connection, timeout):
    raise aiohttp.ClientOSError("os error")


def bad_http_response(spec_set=aiohttp.ClientResponse):
    response = Mock(spec_set=aiohttp.ClientResponse)
    response.status = 400
    return response


async def test_session_api_get(logger, client):
    client.get = AsyncMock(return_value=valid_response())
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)

    result = await api_session.async_api_get("/api/foo")

    client.get.assert_called_once_with("http://127.0.0.4:88/api/foo", timeout=2)

    assert result == 123


async def test_session_default_client_created(mocked_client, logger):
    mocked_client.get = AsyncMock(return_value=valid_response())
    api_session = Session("127.0.0.4", "88", 2, None, None, logger)

    result = await api_session.async_api_get("/api/foo")

    mocked_client.get.assert_called_once_with("http://127.0.0.4:88/api/foo", timeout=2)
    assert result == 123


async def test_session_default_timeout_used(mocked_client, logger):
    mocked_client.get = AsyncMock(return_value=valid_response())
    api_session = Session("127.0.0.4", "88", None, None, None, logger)

    await api_session.async_api_get("/api/foo")
    expected_timeout = aiohttp.ClientTimeout(
        total=None, connect=None, sock_read=5, sock_connect=5
    )

    mocked_client.get.assert_called_once_with(
        "http://127.0.0.4:88/api/foo", timeout=expected_timeout
    )


async def test_session_api_get_timeout(logger, client):
    client.get = AsyncMock(side_effect=timeout_error)
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)

    with pytest.raises(error.TimeoutError):
        await api_session.async_api_get("/api/foo")


async def test_session_api_post_timeout(logger, client):
    def post_timeout_error(connection, **kwargs):
        timeout_error(connection, timeout=kwargs.get("timeout"))

    client.post = AsyncMock(side_effect=post_timeout_error)
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)

    with pytest.raises(error.TimeoutError):
        await api_session.async_api_post("/api/foo", {})


async def test_session_api_get_client_error(logger, client):
    client.get = AsyncMock(side_effect=client_error)
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)
    with pytest.raises(
        error.ClientError,
        match=r"API request http://127\.0\.0\.4:88/api/foo failed: client err",
    ):
        await api_session.async_api_get("/api/foo")


async def test_session_always_show_address_details(logger, client):
    client.get = AsyncMock(side_effect=os_error)
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)
    with pytest.raises(
        error.ConnectionError, match=r"Failed to connect to 127\.0\.0\.4:88: os error"
    ):
        await api_session.async_api_get("/api/foo")


async def test_session_api_post_client_error(logger, client):
    def post_client_error(connection, **kwargs):
        client_error(connection, timeout=kwargs.get("timeout"))

    client.post = AsyncMock(side_effect=post_client_error)
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)
    with pytest.raises(error.ClientError):
        await api_session.async_api_post("/api/foo", {})


async def test_session_api_get_http_error(logger, client):
    client.get = AsyncMock(return_value=bad_http_response())
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)
    with pytest.raises(error.HttpError):
        await api_session.async_api_get("/api/foo")


async def test_session_api_post_http_error(logger, client):
    client.post = AsyncMock(return_value=bad_http_response())
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)
    with pytest.raises(error.HttpError):
        await api_session.async_api_post("/api/foo", {})


async def test_session_provides_a_logger(logger, client):
    api_session = Session("127.0.0.4", "88", 2, client, None, logger)
    api_session.logger.debug("foobar")
    logger.debug.assert_called_once_with("foobar")