update/software-client/software_client/tests/test_software_client.py

163 lines
5.2 KiB
Python

#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023-2024 Wind River Systems, Inc.
#
import json
import os
import sys
import testtools
from unittest import mock
from software_client import software_client
API_PORT = "5493"
URL_PREFIX = "http://127.0.0.1:" + API_PORT + "/software"
FAKE_SW_VERSION = "1.2.3"
PATCH_FLAG_NO = "N"
PATCH_FLAG_YES = "Y"
STATE_APPLIED = "Applied"
STATE_AVAILABLE = "Available"
STATE_NA = "n/a"
STATUS_DEV = "DEV"
FAKE_PATCH_ID_1 = "PATCH_1"
FAKE_PATCH_1_META = {
"apply_active_release_only": "",
"description": "Patch 1 description",
"install_instructions": "Patch 1 instructions",
"reboot_required": PATCH_FLAG_YES,
"state": STATE_APPLIED,
"requires": [],
"status": STATUS_DEV,
"summary": "Patch 1 summary",
"sw_version": FAKE_SW_VERSION,
"unremovable": PATCH_FLAG_NO,
"warnings": "Patch 1 warnings",
}
FAKE_PATCH_ID_2 = "PATCH_2"
FAKE_PATCH_2_META = {
"apply_active_release_only": "",
"description": "Patch 2 description",
"install_instructions": "Patch 2 instructions",
"reboot_required": PATCH_FLAG_NO,
"state": STATE_AVAILABLE,
"requires": [FAKE_PATCH_ID_1],
"status": STATUS_DEV,
"summary": "Patch 2 summary",
"sw_version": FAKE_SW_VERSION,
"unremovable": PATCH_FLAG_NO,
"warnings": "Patch 2 warnings",
}
class FakeResponse(object):
"""This is used to mock a requests.get result"""
def __init__(self, json_data, status_code):
self.json_data = json_data
self.status_code = status_code
self.text = json.dumps(json_data)
def json(self):
return self.json_data
class SoftwareClientTestCase(testtools.TestCase):
PROG = "software"
MOCK_ENV = {
'OS_AUTH_URL': 'FAKE_OS_AUTH_URL',
'OS_PROJECT_NAME': 'FAKE_OS_PROJECT_NAME',
'OS_PROJECT_DOMAIN_NAME': 'FAKE_OS_PROJECT_DOMAIN_NAME',
'OS_USERNAME': 'FAKE_OS_USERNAME',
'OS_PASSWORD': 'FAKE_OS_PASSWORD',
'OS_USER_DOMAIN_NAME': 'FAKE_OS_USER_DOMAIN_NAME',
'OS_REGION_NAME': 'FAKE_OS_REGION_NAME',
'OS_INTERFACE': 'FAKE_OS_INTERFACE'
}
# mock_map is populated by the setUp method
mock_map = {}
def setUp(self):
super(SoftwareClientTestCase, self).setUp()
def _mock_requests_get(*args, **kwargs):
key = args[0]
_ = kwargs # kwargs is unused
# if the key is not found in the mock_map
# we return a 404 (not found)
return self.mock_map.get(key,
FakeResponse(None, 404))
patcher = mock.patch(
'requests.get',
side_effect=_mock_requests_get)
self.mock_requests_get = patcher.start()
self.addCleanup(patcher.stop)
class SoftwareClientNonRootMixin(object):
"""
This Mixin Requires self.MOCK_ENV
Disable printing to stdout
Every client call invokes exit which raises SystemExit
This asserts that happens.
"""
def _test_method(self, shell_args=None):
with mock.patch.dict(os.environ, self.MOCK_ENV):
with mock.patch.object(sys, 'argv', shell_args):
# mock 'print' so running unit tests will
# not print to the tox output
with mock.patch('builtins.print'):
# Every client invocation invokes exit
# which raises SystemExit
self.assertRaises(SystemExit,
software_client.main)
class SoftwareClientHelpTestCase(SoftwareClientTestCase, SoftwareClientNonRootMixin):
"""Test the sw-patch CLI calls that invoke 'help'
'check_for_os_region_name' is the first method called
after args are parsed
print_help is invoked when there is a failure.
"""
@mock.patch('software_client.software_client.check_for_os_region_name')
@mock.patch('argparse.ArgumentParser.print_help')
@mock.patch('argparse.ArgumentParser.print_usage')
def test_main_no_args(self, mock_usage, mock_help, mock_check):
"""When no arguments are called, it should call print_usage"""
shell_args = [self.PROG, ]
self._test_method(shell_args=shell_args)
mock_help.assert_called()
mock_check.assert_not_called()
@mock.patch('software_client.software_client.check_for_os_region_name')
@mock.patch('argparse.ArgumentParser.print_help')
@mock.patch('argparse.ArgumentParser.print_usage')
def test_main_help(self, mock_usage, mock_help, mock_check):
"""When -h is passed in, this should invoke print_help"""
shell_args = [self.PROG, "-h"]
self._test_method(shell_args=shell_args)
mock_help.assert_called()
mock_check.assert_not_called()
@mock.patch('software_client.software_client.check_for_os_region_name')
@mock.patch('argparse.ArgumentParser.print_help')
@mock.patch('argparse.ArgumentParser.print_usage')
def test_main_invalid_action_calls_help(self, mock_usage, mock_help, mock_check):
"""invalid args should invoke print_usage"""
shell_args = [self.PROG, "invalid_arg"]
self._test_method(shell_args=shell_args)
mock_help.assert_not_called()
mock_check.assert_not_called()