iLO-manager first main commitgit status
This commit is contained in:
1 parent
e6f4cc04ca
commit
599d8da562
3271 files changed
+550655
No files matched your search
Whitespace-only changes.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,66 @@
|
||||
"""
|
||||
conftest.py is used to set up shared fixtures, plugins, hooks, other config etc.
|
||||
This is the global, root-level conftest.py loaded for all tests.
|
||||
Sub-directories can have their own conftest.py that gets loaded locally for that sub-directory only.
|
||||
http://docs.pytest.org/en/latest/writing_plugins.html#conftest-py-local-per-directory-plugins
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
from importlib import import_module
|
||||
|
||||
import pytest
|
||||
|
||||
# Add the 'src' directory to the module search path so our tests can import from it
|
||||
SRC_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../ilorest'))
|
||||
RDMC_FILE = os.path.join(SRC_DIR, 'rdmc.py')
|
||||
|
||||
sys.path.insert(0, SRC_DIR)
|
||||
|
||||
DisplayHelpers = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.lib.DisplayHelpers')
|
||||
ShowPmemCommand = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.ShowPmemCommand')
|
||||
RestHelpers = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.lib.RestHelpers')
|
||||
Mapper = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.lib.Mapper')
|
||||
MapperRenderers = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.lib.MapperRenderers')
|
||||
PmemHelpers = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.lib.PmemHelpers')
|
||||
ClearPendingConfigCommand = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.ClearPendingConfigCommand')
|
||||
ApplyPmemConfigCommand = import_module('extensions.PERSISTENT_MEMORY_COMMANDS.ApplyPmemConfigCommand')
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--runquix", action="store_true", default=False,
|
||||
help="Run tests associated with an open QuIX (which are skipped by default).")
|
||||
parser.addoption("--skipincremental", action="store_true", default=False,
|
||||
help="Skip incremental configuration tests (run by default).")
|
||||
parser.addoption("--clear-nand-counters", action="store_true", default=False,
|
||||
help="Clear all iLO NAND write counters using the iLO debugger.")
|
||||
|
||||
logging_group = parser.getgroup('logging', description='logging configuration')
|
||||
logging_group.addoption("--ilodebug", metavar='path', help="log iLO debugger output to the specified file.")
|
||||
logging_group.addoption("--vsp", metavar='path', help="log Virtual Serial Port output to the specified file.")
|
||||
logging_group.addoption("--uefi-debug-level", choices=[0, 1, 2, 3], type=int,
|
||||
help="set UEFI serial debug level when capturing Virtual Serial Port output: "
|
||||
"0 (Disabled), 1 (ErrorsOnly), 2 (Medium), 3 (Verbose)")
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
openquix_marker = item.get_marker("openquix")
|
||||
if openquix_marker is not None:
|
||||
if item.config.getoption("--runquix") is False:
|
||||
pytest.skip("skipping test associated with an open QuIX")
|
||||
|
||||
|
||||
def pytest_collection(session):
|
||||
"""
|
||||
Hook to use testpaths for a test root directory passed in as a pytest argument.
|
||||
This allows using testpaths without having to execute pytest from the test root directory.
|
||||
"""
|
||||
args = session.config.args
|
||||
testpaths = session.config.getini('testpaths')
|
||||
currdir = session.startdir
|
||||
rootdir = session.config.rootdir
|
||||
|
||||
if len(args) == 1 and testpaths:
|
||||
testdir = args[0]
|
||||
if currdir.join(testdir) == rootdir:
|
||||
session.config.args = [os.path.join(testdir, testpath) for testpath in testpaths]
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,228 @@
|
||||
"""
|
||||
conftest.py is used to set up shared fixtures, plugins, hooks, other config etc.
|
||||
This is the functional test conftest.py
|
||||
http://docs.pytest.org/en/latest/writing_plugins.html#conftest-py-local-per-directory-plugins
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
|
||||
import pytest
|
||||
|
||||
import redfish
|
||||
|
||||
# For cross-compatibility between Python 2 and Python 3
|
||||
try:
|
||||
from urllib.parse import urlparse
|
||||
except ImportError:
|
||||
from urlparse import urlparse
|
||||
|
||||
from ..conftest import RDMC_FILE
|
||||
from . import utils
|
||||
from .ilomock import MockServer
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def mock_server():
|
||||
with MockServer() as server:
|
||||
yield server
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dl360_large(mock_server):
|
||||
"""Returns a mock server config:
|
||||
|
||||
- DL360 Gen10
|
||||
- 1x AEP DIMM
|
||||
- 1x DRAM DIMM
|
||||
"""
|
||||
data_dir = os.path.join(os.path.dirname(__file__), 'mockdata/dl360-large')
|
||||
mock_server.load(data_dir)
|
||||
return MockServerConfig(mock_server, username='rev', password='hpe123')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dl360_memfast_disabled(dl360_large):
|
||||
"""Returns a dl360_configured config with MemFastTraining disabled
|
||||
"""
|
||||
dl360_large.patch('/redfish/v1/systems/1/bios/settings/', {'Attributes': {'MemFastTraining': 'Disabled'}})
|
||||
|
||||
return dl360_large
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def test_server():
|
||||
"""Returns a server config specified by the TEST_SERVER environment variable.
|
||||
|
||||
TEST_SERVER should be a URL with optional auth, e.g. https://user:password@host:port
|
||||
"""
|
||||
if 'TEST_SERVER' not in os.environ:
|
||||
pytest.skip("TEST_SERVER not set")
|
||||
|
||||
url, username, password = utils.urlparse_auth(os.getenv('TEST_SERVER'))
|
||||
# If no credentials, then populate with hard-coded values. Credentials required by ilorest.
|
||||
username = "orange" if username is None else username
|
||||
password = "password" if password is None else password
|
||||
return ServerConfig(url=url, username=username, password=password)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ilorest(tmpdir):
|
||||
"""Returns an ilorest session (in scripting mode by default).
|
||||
|
||||
Each ilorest session receives its own unique temporary cache directory.
|
||||
"""
|
||||
yield Ilorest(cache_dir=tmpdir.dirname)
|
||||
tmpdir.remove(ignore_errors=True)
|
||||
|
||||
|
||||
class ServerConfig(object):
|
||||
|
||||
def __init__(self, url=None, username=None, password=None):
|
||||
self.url = url
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
@property
|
||||
def config(self):
|
||||
return self.url, self.username, self.password
|
||||
|
||||
@property
|
||||
def hostname(self):
|
||||
parts = urlparse(self.url)
|
||||
hostname = parts.hostname if parts.scheme else self.url
|
||||
return hostname
|
||||
|
||||
|
||||
class MockServerConfig(ServerConfig):
|
||||
|
||||
def __init__(self, server, username=None, password=None):
|
||||
super(MockServerConfig, self).__init__(url=server.url, username=username, password=password)
|
||||
self.server = server
|
||||
|
||||
def patch(self, path, data):
|
||||
"""Patches a resource in the mock server."""
|
||||
self.server.patch(path, data)
|
||||
|
||||
|
||||
class Ilorest(object):
|
||||
"""Wrapper for the iLO RESTful Interface Tool."""
|
||||
|
||||
def __init__(self, cache_dir=None):
|
||||
"""Starts ilorest in scripting mode.
|
||||
|
||||
:param cache_dir: directory to use for caching instead of the default global location
|
||||
"""
|
||||
self.cache_dir = cache_dir
|
||||
self.args = [sys.executable, RDMC_FILE]
|
||||
|
||||
if cache_dir:
|
||||
self.args.append('--cache-dir={}'.format(cache_dir))
|
||||
|
||||
self.interactive = False
|
||||
self.proc = None
|
||||
self.prompt = "iLOrest > "
|
||||
|
||||
def run(self, args, sendline=None):
|
||||
"""Runs an ilorest command.
|
||||
|
||||
:param args: list of command arguments
|
||||
:param sendline: string to send after running (only used in interactive mode)
|
||||
:return: results of the command as a named tuple: (stdout, stderr, retcode)
|
||||
"""
|
||||
if not self.interactive:
|
||||
return utils.run_cmd(self.args + args)
|
||||
|
||||
# interactive mode
|
||||
cmd_line = ' '.join(args)
|
||||
self.proc.sendline(cmd_line)
|
||||
if sendline:
|
||||
self.proc.sendline(sendline)
|
||||
|
||||
stdout, stderr = self.proc.read(expect=self.prompt)
|
||||
|
||||
match = re.search("iLOrest return code: ([0-9]+)\n", stdout)
|
||||
retcode = int(match.group(1)) if match else None
|
||||
|
||||
return utils.CommandResult(stdout=stdout, stderr=stderr, retcode=retcode)
|
||||
|
||||
def login(self, url=None, username=None, password=None):
|
||||
"""Logs in to the server and establishes a secure session.
|
||||
|
||||
:param url: iLO server url if connecting remotely
|
||||
:param username: iLO username. If no username specified, use "orange"
|
||||
:param password: iLO password. If no password specified, use "password"
|
||||
"""
|
||||
args = ['login']
|
||||
if url:
|
||||
args.append(url)
|
||||
if username:
|
||||
args.extend(['-u', username])
|
||||
if password:
|
||||
args.extend(['-p', password])
|
||||
|
||||
results = self.run(args)
|
||||
assert results.retcode == 0, "Failed to connect or log in"
|
||||
|
||||
def logout(self):
|
||||
"""Ends the current session and disconnects from the server."""
|
||||
self.run(['logout'])
|
||||
|
||||
@contextmanager
|
||||
def session(self, url=None, username=None, password=None):
|
||||
"""Establishes a session with an iLO server and logs out afterwards."""
|
||||
self.login(url=url, username=username, password=password)
|
||||
yield self
|
||||
self.logout()
|
||||
|
||||
@contextmanager
|
||||
def interactive_session(self, url=None, username=None, password=None):
|
||||
"""Establishes an interactive session with an iLO server, and logs out and exits afterwards."""
|
||||
with self.interactive_mode(), self.session(url=url, username=username, password=password):
|
||||
yield self
|
||||
|
||||
@contextmanager
|
||||
def interactive_mode(self):
|
||||
"""Enters interactive mode and exits afterwards."""
|
||||
# use --verbose to extract the return code
|
||||
self.proc = utils.InteractivePopen(self.args + ['--verbose'])
|
||||
self.proc.read(expect=self.prompt)
|
||||
self.interactive = True
|
||||
yield self
|
||||
self.proc.communicate('exit')
|
||||
self.interactive = False
|
||||
|
||||
|
||||
class RestClient(object):
|
||||
"""REST client for an iLO server."""
|
||||
|
||||
def __init__(self, url=None, username=None, password=None):
|
||||
"""Initializes an iLO REST client.
|
||||
|
||||
:param url: iLO server url if connecting remotely
|
||||
:param username: iLO username
|
||||
:param password: iLO password
|
||||
"""
|
||||
# if no scheme/protocol defined, try https
|
||||
if "://" not in url:
|
||||
url = "https://" + url
|
||||
self._client = redfish.redfish_client(base_url=url, username=username, password=password)
|
||||
self._client.login(auth=redfish.AuthMethod.BASIC)
|
||||
|
||||
def get(self, path):
|
||||
"""Sends a GET request."""
|
||||
resp = self._client.get(path)
|
||||
return resp.dict
|
||||
|
||||
def patch(self, path, body):
|
||||
"""
|
||||
Sends a PATCH request to the path with the given body
|
||||
:param path: URI path
|
||||
:param body: the body of the patch. For example dict:{ "Attributes": { "Prop1": true } }
|
||||
:return: RestResponse status, RestResponse dictionary
|
||||
"""
|
||||
rest_response = self._client.patch(path=path, body=body)
|
||||
return rest_response.status, rest_response.dict
|
||||
@@ -0,0 +1,97 @@
|
||||
"""ilomock module"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import requests
|
||||
|
||||
JAVA_BIN = os.getenv('JAVA_BIN', 'java')
|
||||
ILOMOCK_JAR = os.getenv('ILOMOCK_JAR')
|
||||
|
||||
os.environ['NO_PROXY'] = 'localhost'
|
||||
|
||||
# ignore SSL warnings
|
||||
# requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
||||
class MockServerError(Exception):
|
||||
"""An error occurred starting the mock server."""
|
||||
|
||||
|
||||
class MockServer(object):
|
||||
"""Wrapper for ilomock."""
|
||||
|
||||
def __init__(self, profile_dir=None, port=0):
|
||||
"""Initializes a mock server.
|
||||
|
||||
:param profile_dir: path to the server profile to use
|
||||
:param port: port to listen on
|
||||
"""
|
||||
self.profile_dir = profile_dir
|
||||
self.port = port
|
||||
self.url = None
|
||||
self.proc = None
|
||||
|
||||
def start(self):
|
||||
"""Starts the mock server.
|
||||
|
||||
:raises MockServerError: if the server failed to start
|
||||
"""
|
||||
if not ILOMOCK_JAR:
|
||||
raise MockServerError("ILOMOCK_JAR must be set")
|
||||
|
||||
sys.stdout.write("Starting mock server on port {} with profile {}".format(self.port, self.profile_dir))
|
||||
|
||||
args = [JAVA_BIN, '-jar', ILOMOCK_JAR, '-p', str(self.port)]
|
||||
if self.profile_dir:
|
||||
args.extend(['-s', self.profile_dir])
|
||||
if not os.path.exists(JAVA_BIN):
|
||||
raise IOError("JAVA_BIN location does not exist: {}".format(JAVA_BIN))
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
# Block until the server starts or fails
|
||||
output = []
|
||||
for line in iter(proc.stdout.readline, ''):
|
||||
output.append(line)
|
||||
prefix = "Listening on port "
|
||||
if line.startswith(prefix):
|
||||
self.proc = proc
|
||||
self.port = int(line[len(prefix):])
|
||||
self.url = "https://localhost:{}".format(self.port)
|
||||
return
|
||||
|
||||
proc.communicate()
|
||||
output = ''.join(output)
|
||||
raise MockServerError("Failed to start ilomock: {}\n{}".format(proc.returncode, output))
|
||||
|
||||
def stop(self):
|
||||
"""Stops the running mock server."""
|
||||
if self.proc:
|
||||
self.proc.kill()
|
||||
self.proc = None
|
||||
self.url = None
|
||||
|
||||
def __enter__(self):
|
||||
"""Starts the mock server and returns it."""
|
||||
self.start()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
"""Ensures the running mock server stops."""
|
||||
self.stop()
|
||||
|
||||
def patch(self, path, data):
|
||||
"""Patches a resource in the mock server."""
|
||||
payload = {'path': path, 'data': data}
|
||||
resp = requests.post(self.url + '/admin/patch', json=payload, verify=False)
|
||||
assert resp.status_code == 200, "Failed to patch mock server: {}\n{}"\
|
||||
.format(resp.status_code, resp.text)
|
||||
|
||||
def load(self, profile_dir):
|
||||
"""Loads a new server profile while the mock server is running."""
|
||||
config = {'serverProfile': profile_dir}
|
||||
resp = requests.post(self.url + '/admin/load', json=config, verify=False)
|
||||
assert resp.status_code == 200, "Failed to load mock server: {}\n{}"\
|
||||
.format(resp.status_code, resp.text)
|
||||
@@ -0,0 +1,37 @@
|
||||
"""Module containing functional tests for the all flag"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="temporarily remove all flag")
|
||||
class TestAllFlag(object):
|
||||
"""Functional Tests for the --all | -a flag"""
|
||||
|
||||
@staticmethod
|
||||
def test_all_flag(ilorest, dl360_large):
|
||||
"""Test for --all flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--all'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_all_flag_with_json(ilorest, dl360_large):
|
||||
"""Test for --all flag with --json flag specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--all', '--json'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
"""Module containing functional tests for the 'applydcpmmconfig' command"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestApplyPmemConfigCommand(object):
|
||||
"""Class for functional tests for the applydcpmmconfig command"""
|
||||
|
||||
@staticmethod
|
||||
def test_show_invalid_flag(ilorest):
|
||||
"""Test function call with invalid flag"""
|
||||
results = ilorest.run(['applydcpmmconfig', '--bad-flag'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_show_help_flag(ilorest):
|
||||
"""Test function call with help flag"""
|
||||
results = ilorest.run(['applydcpmmconfig', '-h'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_no_flag(ilorest):
|
||||
"""Test for the case when `applydcpmmconfig` command is run without any flag"""
|
||||
results = ilorest.run(['applydcpmmconfig'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_force_flag_1(ilorest):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with force flag"""
|
||||
results = ilorest.run(['applydcpmmconfig', '-f'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_force_flag_2(ilorest):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with force flag"""
|
||||
results = ilorest.run(['applydcpmmconfig', '-L', '-f'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
# Cannot test for the positive case - mock server not accepting delete tasks.
|
||||
@staticmethod
|
||||
def test_with_force_flag_3(ilorest, dl360_large):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with force flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['applydcpmmconfig', '-C', 'MemoryMode', '-f'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.NO_CHANGES_MADE_OR_FOUND
|
||||
|
||||
@staticmethod
|
||||
def test_with_config_flag_1(ilorest, dl360_large):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with config flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['applydcpmmconfig', '-C'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_config_flag_2(ilorest, dl360_large):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with config flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['applydcpmmconfig', '-C', 'xyz'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_config_flag_3(ilorest, dl360_large):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with config flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['applydcpmmconfig', '-C', 'AppDirectInterleaved'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.NO_CHANGES_MADE_OR_FOUND
|
||||
|
||||
@staticmethod
|
||||
def test_with_list_flag(ilorest):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with list flag"""
|
||||
results = ilorest.run(['applydcpmmconfig', '-L'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_extra_attributes_1(ilorest):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with extraneous attributes"""
|
||||
results = ilorest.run(['applydcpmmconfig', '-L', '1qazxcsd'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_extra_attributes_2(ilorest, dl360_large):
|
||||
"""Test for the case when `applydcpmmconfig` command is run with extraneous attributes"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['applydcpmmconfig', '-C', 'AppDirectInterleaved', '1qazxcsd'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
"""Module containing functional tests for the 'cleardcpmmpendingconfig' command"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestClearDcpmmPendingConfigCommand(object):
|
||||
"""Class for functional tests for the cleardcpmmpendingconfig command"""
|
||||
|
||||
@staticmethod
|
||||
def test_show_invalid_flag(ilorest):
|
||||
"""Test function call with invalid flag"""
|
||||
results = ilorest.run(['cleardcpmmpendingconfig', '--bad-flag'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_show_help_flag(ilorest):
|
||||
"""Test function call with help flag"""
|
||||
results = ilorest.run(['cleardcpmmpendingconfig', '-h'])
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_without_flag(ilorest, dl360_large):
|
||||
"""Test for the case when `cleardcpmmpendingconfig` command is run without any flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['cleardcpmmpendingconfig'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_extraneous_attributes(ilorest):
|
||||
"""
|
||||
Test for the case when `cleardcpmmpendingconfig` command is run with extraneous attributes
|
||||
"""
|
||||
results = ilorest.run(['cleardcpmmpendingconfig', 'testargument'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
@@ -0,0 +1,88 @@
|
||||
"""Module containing functional tests for the config flag"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestConfigFlag(object):
|
||||
"""Functional Tests for the --config | -C flag"""
|
||||
|
||||
@staticmethod
|
||||
def test_with_no_dimm_id(ilorest, dl360_large):
|
||||
"""Test for --config flag with no DIMM IDs specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--config'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_valid_dimm_id(ilorest, dl360_large):
|
||||
"""Test for --config flag with valid DIMM IDs specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--config', '--dimm', '1@2,2@3'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_non_pmem_dimm_id(ilorest, dl360_large):
|
||||
"""Test for --config flag with valid non pmem DIMM IDs specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--config', '--dimm', '1@5'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_json_format_1(ilorest, dl360_large):
|
||||
"""Test for --config flag with --json flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--config', '--dimm', '1@2,2@3', '-j'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_json_format_2(ilorest, dl360_large):
|
||||
"""Test for --config flag with --json flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--config', '-j'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_invalid_member_dimm_id(ilorest, dl360_large):
|
||||
"""Test for --config flag with invalid DIMM IDs specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--config', '--dimm', '8@15'])
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_invalid_dimm_id(ilorest):
|
||||
"""Test for --config flag with invalid DIMM IDs specified"""
|
||||
results = ilorest.run(['showdcpmm', '--config', '--dimm', '132,243,xyz'])
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
@@ -0,0 +1,111 @@
|
||||
"""Module containing functional tests for the device flag"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestDeviceFlag(object):
|
||||
"""Functional Tests for the --device | -D flag"""
|
||||
@staticmethod
|
||||
def test_with_no_dimm_id(ilorest, dl360_large):
|
||||
"""Test for --device flag with no DIMM IDs specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--device'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_valid_non_pmem_dimm_id(ilorest, dl360_large):
|
||||
"""
|
||||
Test for --device flag with valid DIMM IDs
|
||||
which are not Persistent Memory Modules specified
|
||||
"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--device', '--dimm', '1@1,2@3'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_invalid_dimm_id_1(ilorest):
|
||||
"""
|
||||
Test for --device flag with invalid DIMM IDs specified.
|
||||
Fails at Validation.
|
||||
"""
|
||||
results = ilorest.run(['showdcpmm', '--device', '--dimm', '132,243,xyz'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_invalid_dimm_id_2(ilorest, dl360_large):
|
||||
"""
|
||||
Test for --device flag with invalid DIMM IDs specified
|
||||
Passes Validation, Fails later when DIMM IDs not found
|
||||
"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--device', '--dimm', '8@2,2@18'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_valid_pmem_dimm_id(ilorest, dl360_large):
|
||||
"""
|
||||
Test for --device flag with valid DIMM IDs
|
||||
which are Persistent Memory Modules specified
|
||||
"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--device', '--dimm', '1@2'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_valid_pmem_dimm_id_json(ilorest, dl360_large):
|
||||
"""
|
||||
Test for --device flag with valid DIMM IDs
|
||||
which are Persistent Memory Modules specified
|
||||
along with the --json flag
|
||||
"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--device', '--dimm', '1@2', '--json'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_json(ilorest, dl360_large):
|
||||
"""
|
||||
Test for --device flag with valid DIMM IDs
|
||||
which are Persistent Memory Modules specified
|
||||
along with the --json flag
|
||||
"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--device', '--json'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
@@ -0,0 +1,62 @@
|
||||
"""Module containing functional tests for the device flag"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="temporarily remove display flag")
|
||||
class TestDisplayFlag(object):
|
||||
"""Functional Tests for the --display | -d flag"""
|
||||
|
||||
@staticmethod
|
||||
def test_with_no_display_attributes(ilorest):
|
||||
"""Test for --display flag with no display attributes"""
|
||||
results = ilorest.run(['showdcpmm', '--display'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_invalid_display_attributes(ilorest, dl360_large):
|
||||
"""Test for --display flag with invalid display attributes"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--display', 'xyz,abc'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_valid_display_attributes(ilorest, dl360_large):
|
||||
"""Test for --display flag with valid display attributes"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--display', 'DeviceLocator'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_valid_display_attributes_json(ilorest, dl360_large):
|
||||
"""
|
||||
Test for --display flag with valid display attributes
|
||||
along with the --json flag
|
||||
"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--display', 'DeviceLocator', '--json'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
@@ -0,0 +1,44 @@
|
||||
"""Module containing functional tests for the logical flag"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestLogicalFlag(object):
|
||||
"""Functional Tests for the --logical | -L flag"""
|
||||
|
||||
@staticmethod
|
||||
def test_with_no_attributes(ilorest, dl360_large):
|
||||
"""Test for --logical flag with no attributes specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--logical'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_dimm_flag(ilorest):
|
||||
"""Test for --logical flag with dimm flag specified"""
|
||||
results = ilorest.run(['showdcpmm', '--logical', '--dimm', '1@2'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_json_flag(ilorest, dl360_large):
|
||||
"""Test for --logical flag with --json flag specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--logical', '--json'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
Functional tests for the command to show the DCPMMs
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
from jsonpointer import resolve_pointer
|
||||
from pmemtests.functional.conftest import RestClient
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestShowDcPmemCommand(object):
|
||||
"""Class for functional tests for the command to enable and disable the scalable pmem feature"""
|
||||
|
||||
@staticmethod
|
||||
def test_show_invalid_flag(ilorest):
|
||||
""" test function call with invalid flag """
|
||||
results = ilorest.run(['showdcpmm', '--bad-flag'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_show_help_flag(ilorest):
|
||||
""" test function call with help flag """
|
||||
results = ilorest.run(['showdcpmm', '-h'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_showdcpmm_no_flag(ilorest, dl360_large):
|
||||
"""Test for the case when `showdcpmm` command is run without any flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_showdcpmm_dimm_flag_1(ilorest):
|
||||
"""Test for the case when `showdcpmm` command is run with dimm flag"""
|
||||
results = ilorest.run(['showdcpmm', '--dimm'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_showdcpmm_dimm_flag_2(ilorest, dl360_large):
|
||||
"""Test for the case when `showdcpmm` command is run with dimm flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--dimm', '1@2'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_showdcpmm_dimm_flag_3(ilorest, dl360_large):
|
||||
"""Test for the case when `showdcpmm` command is run with dimm flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--dimm', '1@2', '2@3'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.skip(reason="temporarily remove display flag")
|
||||
def test_all_and_display_flags(ilorest):
|
||||
"""Test for the case when --all and --display flags are specified together"""
|
||||
results = ilorest.run(['showdcpmm', '--all', '--display', 'xyz'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_device_and_config_flags(ilorest):
|
||||
"""Test for the case when --device and --config flags are specified together"""
|
||||
results = ilorest.run(['showdcpmm', '--device', '--config'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_logical_and_summary_flags(ilorest):
|
||||
"""Test for the case when --summary and --logical flags are specified together"""
|
||||
results = ilorest.run(['showdcpmm', '--logical', '--summary'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_example(ilorest, dl360_large):
|
||||
""" this is just an example to show using the RestClient """
|
||||
url, username, password = dl360_large.config
|
||||
|
||||
# run ilorest rawget
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['rawget', '/redfish/v1/systems/1/bios/settings'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
# check REST attributes
|
||||
client = RestClient(url, username, password)
|
||||
bios_settings = client.get('/redfish/v1/systems/1/bios/settings')
|
||||
sys.stdout.write(str(bios_settings))
|
||||
assert resolve_pointer(bios_settings, '/Attributes/MemFastTraining') == "Enabled"
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
"""Module containing functional tests for the showdcpmmpendingconfig command"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestShowDcpmmPendingConfigCommand(object):
|
||||
"""Class for functional tests for the showdcpmmpendingconfig command"""
|
||||
|
||||
@staticmethod
|
||||
def test_show_invalid_flag(ilorest):
|
||||
"""Test function call with invalid flag"""
|
||||
results = ilorest.run(['showdcpmmpendingconfig', '--bad-flag'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_show_help_flag(ilorest):
|
||||
"""Test function call with help flag"""
|
||||
results = ilorest.run(['showdcpmmpendingconfig', '-h'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_no_flag(ilorest, dl360_large):
|
||||
"""Test for the case when `showdcpmmpendingconfig` command is run without any flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmmpendingconfig'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_json_flag(ilorest, dl360_large):
|
||||
"""Test for the case when `showdcpmmpendingconfig` command is run with json flag"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmmpendingconfig', '-j'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_extraneous_attributes(ilorest):
|
||||
"""
|
||||
Test for the case when `showdcpmmpendingconfig` command is run with extraneous attributes
|
||||
"""
|
||||
results = ilorest.run(['showdcpmmpendingconfig', '1qazxcsd'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
@@ -0,0 +1,44 @@
|
||||
"""Module containing functional tests for the summary flag"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from rdmc_helper import ReturnCodes
|
||||
|
||||
|
||||
class TestSummaryFlag(object):
|
||||
"""Functional Tests for the --summary | -M flag"""
|
||||
|
||||
@staticmethod
|
||||
def test_with_no_attributes(ilorest, dl360_large):
|
||||
"""Test for --summary flag with no attributes specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--summary'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
|
||||
@staticmethod
|
||||
def test_with_dimm_flag(ilorest):
|
||||
"""Test for --summary flag with dimm flag specified"""
|
||||
results = ilorest.run(['showdcpmm', '--summary', '--dimm', '1@2'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.INVALID_COMMAND_LINE_ERROR
|
||||
|
||||
@staticmethod
|
||||
def test_with_json_flag(ilorest, dl360_large):
|
||||
"""Test for --summary flag with --json flag specified"""
|
||||
url, username, password = dl360_large.config
|
||||
with ilorest.session(url, username, password):
|
||||
results = ilorest.run(['showdcpmm', '--summary', '--json'])
|
||||
sys.stdout.write("results.stdout: ")
|
||||
sys.stdout.write(results.stdout)
|
||||
sys.stdout.write("results.stderr: ")
|
||||
sys.stdout.write(results.stderr)
|
||||
assert results.retcode == ReturnCodes.SUCCESS
|
||||
@@ -0,0 +1,110 @@
|
||||
"""Utilities for functional tests"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
from collections import namedtuple
|
||||
|
||||
# For cross-compatibility between Python 2 and Python 3
|
||||
try:
|
||||
from urllib.parse import urlparse
|
||||
except ImportError:
|
||||
from urlparse import urlparse
|
||||
|
||||
CommandResult = namedtuple('CommandResult', ('stdout', 'stderr', 'retcode'))
|
||||
|
||||
|
||||
def run_cmd(args):
|
||||
"""Runs a shell command.
|
||||
|
||||
:param args: list of command arguments
|
||||
:return: results of the command as a named tuple: (stdout, stderr, retcode)
|
||||
"""
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = proc.communicate()
|
||||
retcode = proc.returncode
|
||||
return CommandResult(stdout=stdout, stderr=stderr, retcode=retcode)
|
||||
|
||||
|
||||
def urlparse_auth(url):
|
||||
"""Extracts the auth section from a URL (e.g. https://user:password@host)."""
|
||||
parts = urlparse(url)
|
||||
username = parts.username
|
||||
password = parts.password
|
||||
netloc = parts.netloc.split('@')[-1]
|
||||
url = parts._replace(netloc=netloc).geturl()
|
||||
return url, username, password
|
||||
|
||||
|
||||
class InteractivePopen(object):
|
||||
"""Interactive subprocess Popen."""
|
||||
|
||||
def __init__(self, args):
|
||||
"""Launches an interactive shell as a subprocess.
|
||||
|
||||
:param args: sequence of command arguments or a single string
|
||||
"""
|
||||
fout = tempfile.NamedTemporaryFile('wb', delete=False)
|
||||
ferr = tempfile.NamedTemporaryFile('wb', delete=False)
|
||||
self.fout = open(fout.name, 'r')
|
||||
self.ferr = open(ferr.name, 'r')
|
||||
self.proc = subprocess.Popen(args, stdout=fout, stderr=ferr, stdin=subprocess.PIPE)
|
||||
|
||||
def communicate(self, input=None):
|
||||
"""Interacts with the process and waits for it to terminate.
|
||||
|
||||
:param input: data to send to stdin
|
||||
:return: named tuple of (stdout, stderr, retcode)
|
||||
"""
|
||||
self.proc.communicate(input)
|
||||
stdout, stderr = self.read()
|
||||
retcode = self.proc.returncode
|
||||
|
||||
# clean up
|
||||
self.fout.close()
|
||||
self.ferr.close()
|
||||
os.remove(self.fout.name)
|
||||
os.remove(self.ferr.name)
|
||||
|
||||
return CommandResult(stdout=stdout, stderr=stderr, retcode=retcode)
|
||||
|
||||
def send(self, str):
|
||||
"""Sends data to stdin."""
|
||||
self.proc.stdin.write(str)
|
||||
|
||||
def sendline(self, line=""):
|
||||
"""Sends a newline-terminated string to stdin."""
|
||||
self.send(line + '\n')
|
||||
|
||||
def read(self, expect=None, timeout=60, poll_interval=0.1):
|
||||
"""Reads from stdout and stderr.
|
||||
|
||||
The read is non-blocking unless 'expect' is specified.
|
||||
|
||||
:param expect: string to match in stdout before finishing the read
|
||||
:param timeout: time to wait for the expected string, in seconds
|
||||
:param poll_interval: poll interval, in seconds
|
||||
:return: tuple of (stdout, stderr)
|
||||
"""
|
||||
stdout = ""
|
||||
stderr = ""
|
||||
time_timeout = time.time() + timeout
|
||||
while True:
|
||||
out = self.fout.read()
|
||||
err = self.ferr.read()
|
||||
if out:
|
||||
stdout += out
|
||||
if err:
|
||||
stderr += err
|
||||
|
||||
if expect is None or expect in stdout:
|
||||
break
|
||||
|
||||
if time.time() > time_timeout:
|
||||
break
|
||||
|
||||
time.sleep(poll_interval)
|
||||
|
||||
return stdout, stderr
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,139 @@
|
||||
"""
|
||||
conftest.py is used to set up shared fixtures, plugins, hooks, other config etc.
|
||||
This is the conftest.py for integration tests
|
||||
http://docs.pytest.org/en/latest/writing_plugins.html#conftest-py-local-per-directory-plugins
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from ..functional.conftest import RestClient, ilorest, test_server
|
||||
from .ilocli import IloCli
|
||||
from .ilodebug import IloDebugger
|
||||
|
||||
ilo_debug_logger = logging.getLogger('ilodebug')
|
||||
vsp_logger = logging.getLogger('vsp')
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
# configure logging
|
||||
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
|
||||
|
||||
ilo_debug_file = config.getoption('--ilodebug')
|
||||
if ilo_debug_file:
|
||||
sys.stdout.write("logging iLO debugger output to: {}".format(ilo_debug_file))
|
||||
ilo_debug_logger.setLevel(logging.DEBUG)
|
||||
fh = logging.FileHandler(ilo_debug_file, mode='wb+')
|
||||
fh.setLevel(logging.DEBUG)
|
||||
fh.setFormatter(formatter)
|
||||
ilo_debug_logger.addHandler(fh)
|
||||
|
||||
vsp_file = config.getoption('--vsp')
|
||||
if vsp_file:
|
||||
sys.stdout.write("logging iLO Virtual Serial Port output to: {}".format(vsp_file))
|
||||
vsp_logger.setLevel(logging.DEBUG)
|
||||
fh = logging.FileHandler(vsp_file, mode='wb+')
|
||||
fh.setLevel(logging.DEBUG)
|
||||
fh.setFormatter(formatter)
|
||||
vsp_logger.addHandler(fh)
|
||||
|
||||
|
||||
def pytest_runtest_makereport(item, call):
|
||||
# incremental testing marker
|
||||
if "incremental" in item.keywords:
|
||||
if call.excinfo is not None:
|
||||
parent = item.parent
|
||||
parent._previousfailed = item
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
# incremental testing marker
|
||||
if "incremental" in item.keywords:
|
||||
previousfailed = getattr(item.parent, "_previousfailed", None)
|
||||
if previousfailed is not None:
|
||||
pytest.xfail("previous test failed (%s)" % previousfailed.name)
|
||||
|
||||
|
||||
@pytest.fixture(scope='session', autouse=True)
|
||||
def clear_nand_counters(test_server, request):
|
||||
"""Clear all iLO NAND write counters using the iLO debugger."""
|
||||
if request.config.getoption('--clear-nand-counters'):
|
||||
with IloDebugger(test_server.hostname) as ilo_debugger:
|
||||
sys.stdout.write("Clearing all iLO NAND write counters (setting timers to max)")
|
||||
output = ilo_debugger.run("otmax all")
|
||||
assert "Set daily timer to MAX value" in output, \
|
||||
"Failed to clear NAND write counters:\n {}".format(output)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ilodebug(test_server, request):
|
||||
"""Start an iLO debugger session and log all output."""
|
||||
if request.config.getoption('--ilodebug'):
|
||||
test_path = request.node.nodeid.replace('::()::', '::')
|
||||
ilo_debug_logger.info(test_path)
|
||||
|
||||
with IloDebugger(test_server.hostname) as ilo_debugger:
|
||||
# get current system time
|
||||
output = ilo_debugger.run('id')
|
||||
ilo_debug_logger.debug(output)
|
||||
yield ilo_debugger
|
||||
output = ilo_debugger.read()
|
||||
if output:
|
||||
ilo_debug_logger.debug('\n' + output)
|
||||
else:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def vsp(test_server, request, set_uefi_debug):
|
||||
"""Start an iLO Virtual Serial Port session and log all output."""
|
||||
if request.config.getoption('--vsp'):
|
||||
test_path = request.node.nodeid.replace('::()::', '::')
|
||||
vsp_logger.info(test_path)
|
||||
|
||||
hostname = test_server.hostname
|
||||
username, password = test_server.username, test_server.password
|
||||
|
||||
with IloCli(hostname, username, password) as cli:
|
||||
if cli is None:
|
||||
yield
|
||||
else:
|
||||
# get current system time
|
||||
cli.sendline("time")
|
||||
with cli.vsp_session():
|
||||
yield cli
|
||||
output = cli.read()
|
||||
if output:
|
||||
vsp_logger.debug('\n' + output)
|
||||
else:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def set_uefi_debug(test_server, request):
|
||||
"""Temporarily set the UEFI serial debug level using the iLO debugger.
|
||||
|
||||
The debug levels are: 0 (Disabled), 1 (ErrorsOnly), 2 (Medium), 3 (Verbose).
|
||||
"""
|
||||
new_dbg = request.config.getoption('--uefi-debug-level')
|
||||
if new_dbg is not None:
|
||||
with IloDebugger(test_server.hostname) as debugger:
|
||||
# save the current debug level
|
||||
output = debugger.run("evs name cqhdbg")
|
||||
match = re.search('EVS NAME "CQHDBG".+\n.+([0-9]{2})', output)
|
||||
current_dbg = "0x{}".format(match.group(1)) if match else None
|
||||
|
||||
sys.stdout.write("setting UEFI serial debug level to {} (current {})".format(new_dbg, current_dbg))
|
||||
debugger.run("evs xset cqhdbg {}".format(new_dbg))
|
||||
|
||||
yield
|
||||
# restore previous debug level
|
||||
if current_dbg:
|
||||
with IloDebugger(test_server.hostname) as debugger:
|
||||
debugger.run("evs xset cqhdbg {}".format(current_dbg))
|
||||
else:
|
||||
yield
|
||||
@@ -0,0 +1,82 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
|
||||
import paramiko
|
||||
|
||||
|
||||
class IloCli(object):
|
||||
"""Wrapper for the iLO CLI (SMASH CLP)."""
|
||||
|
||||
def __init__(self, hostname, username=None, password=None, port=22, timeout=10, window_size=None):
|
||||
"""Initialize an iLO CLI instance.
|
||||
|
||||
:param hostname: iLO hostname
|
||||
:param username: iLO username
|
||||
:param password: iLO password
|
||||
:param port: SSH port
|
||||
:param window_size: window size for the SSH session (max is used if not specified)
|
||||
:param timeout: connection timeout, in seconds
|
||||
"""
|
||||
self.hostname = hostname
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.port = port
|
||||
self.timeout = timeout
|
||||
self.window_size = window_size if window_size else paramiko.common.MAX_WINDOW_SIZE
|
||||
self.ssh = paramiko.SSHClient()
|
||||
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
self.channel = None
|
||||
|
||||
def open(self):
|
||||
"""Start an interactive iLO CLI session."""
|
||||
self.ssh.connect(self.hostname, username=self.username, password=self.password,
|
||||
port=self.port, timeout=self.timeout, look_for_keys=False)
|
||||
transport = self.ssh.get_transport()
|
||||
self.channel = transport.open_session(window_size=self.window_size)
|
||||
self.channel.get_pty()
|
||||
self.channel.invoke_shell()
|
||||
|
||||
def close(self):
|
||||
"""End the iLO CLI session."""
|
||||
if self.channel:
|
||||
self.channel.close()
|
||||
self.ssh.close()
|
||||
|
||||
def __enter__(self):
|
||||
for _ in range(5):
|
||||
try:
|
||||
self.open()
|
||||
return self
|
||||
except paramiko.SSHException:
|
||||
sys.stdout.write("SSHException: retrying connection")
|
||||
time.sleep(30)
|
||||
|
||||
sys.stdout.write("SSH: Max retries attempted. No vsp will be captured.")
|
||||
return None
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.close()
|
||||
|
||||
def read(self):
|
||||
"""Read all available output without blocking I/O."""
|
||||
buf = []
|
||||
while self.channel.recv_ready():
|
||||
data = self.channel.recv(1024)
|
||||
buf.append(data)
|
||||
return "".join(buf)
|
||||
|
||||
def send(self, data):
|
||||
self.channel.send(data)
|
||||
|
||||
def sendline(self, data):
|
||||
self.send(data + '\n')
|
||||
|
||||
@contextmanager
|
||||
def vsp_session(self):
|
||||
"""Start a Virtual Serial Port session, returning to the CLI afterward."""
|
||||
self.sendline("vsp")
|
||||
yield self
|
||||
self.send("\x1B(") # press 'ESC ('
|
||||
@@ -0,0 +1,61 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from telnetlib import Telnet
|
||||
|
||||
|
||||
class IloDebugger(object):
|
||||
DEBUG_PORT = 8
|
||||
|
||||
def __init__(self, hostname, timeout=10):
|
||||
"""Initialize an iLO debugger instance.
|
||||
|
||||
:param hostname: hostname of the iLO server
|
||||
:param timeout: connection timeout, in seconds
|
||||
"""
|
||||
self.hostname = hostname
|
||||
self.timeout = timeout
|
||||
self.tn = None
|
||||
self.prompt = '\r\n>'
|
||||
|
||||
def open(self):
|
||||
"""Connect to the iLO debugger."""
|
||||
self.tn = Telnet(self.hostname, self.DEBUG_PORT, self.timeout)
|
||||
# wait until the debugger is ready and clear initial output
|
||||
self.read_until(self.prompt)
|
||||
|
||||
def close(self):
|
||||
"""Close the connection."""
|
||||
if self.tn:
|
||||
self.tn.close()
|
||||
self.tn = None
|
||||
|
||||
def __enter__(self):
|
||||
self.open()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.close()
|
||||
|
||||
def read(self):
|
||||
"""Read all available output without blocking I/O."""
|
||||
output = self.tn.read_very_eager()
|
||||
# debugger occasionally outputs CRLFs with double CRs - just convert all to LFs
|
||||
output = output.replace('\r', '')
|
||||
return output
|
||||
|
||||
def read_until(self, expected, timeout=10):
|
||||
"""Read until an expected string is encountered or the timeout, in seconds, has been reached."""
|
||||
output = self.tn.read_until(expected, timeout)
|
||||
output = output.replace('\r', '')
|
||||
return output
|
||||
|
||||
def writeline(self, line):
|
||||
"""Write a line to the iLO debugger."""
|
||||
self.tn.write(line + '\n')
|
||||
|
||||
def run(self, cmd_line):
|
||||
"""Run an iLO debugger command and capture output."""
|
||||
self.read() # clear any previous output
|
||||
self.writeline(cmd_line)
|
||||
output = self.read_until(self.prompt)
|
||||
return output
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
conftest.py is used to set up shared fixtures, plugins, hooks, other config etc.
|
||||
This is the unit test conftest.py
|
||||
http://docs.pytest.org/en/latest/writing_plugins.html#conftest-py-local-per-directory-plugins
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from ..conftest import (
|
||||
ClearPendingConfigCommand,
|
||||
DisplayHelpers,
|
||||
MapperRenderers,
|
||||
RestHelpers,
|
||||
ShowPmemCommand,
|
||||
)
|
||||
@@ -0,0 +1,511 @@
|
||||
"""Module to Test the 'applydcpmmconfig' command"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from rdmc_base_classes import RdmcCommandBase
|
||||
from rdmc_helper import (
|
||||
InvalidCommandLineError,
|
||||
NoChangesFoundOrMadeError,
|
||||
NoContentsFoundForOperationError,
|
||||
)
|
||||
|
||||
from ..conftest import ApplyPmemConfigCommand, RestHelpers
|
||||
|
||||
|
||||
class MockData(object):
|
||||
"""
|
||||
Mock Data for 'applydcpmmconfig' command
|
||||
"""
|
||||
mock_tasks = [{
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 1",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm12/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/"
|
||||
"MemoryChunks/?$expand=."
|
||||
},
|
||||
"TaskState": "New"
|
||||
}, {
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 2",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm10/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/"
|
||||
"MemoryChunks/?$expand=."
|
||||
},
|
||||
"TaskState": "Old"
|
||||
}]
|
||||
|
||||
other_mock_tasks = [{
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 1",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm12/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/?$expand=."
|
||||
},
|
||||
"TaskState": "New"
|
||||
}, {
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 2",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm10/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/?$expand=."
|
||||
},
|
||||
"TaskState": "Old"
|
||||
}]
|
||||
|
||||
mock_chunks = [
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#MemoryChunks.MemoryChunks",
|
||||
"@odata.etag": "W/\"89E7F7C3\"",
|
||||
"@odata.id": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/MemoryChunks/2/",
|
||||
"@odata.type": "#MemoryChunks.v1_2_2.MemoryChunks",
|
||||
"Id": "2",
|
||||
"AddressRangeType": "PMEM",
|
||||
"Description": "Memory Chunk",
|
||||
"InterleaveSets": [
|
||||
{
|
||||
"Memory": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc1dimm7/"
|
||||
},
|
||||
"RegionId": "3",
|
||||
"SizeMiB": 131072
|
||||
}
|
||||
],
|
||||
"IsMirrorEnabled": False,
|
||||
"IsSpare": False,
|
||||
"MemoryChunkSizeMiB": 131072,
|
||||
"Name": "MemoryChunk",
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"@odata.context": "/redfish/v1/$metadata#HpeMemoryChunksExt.HpeMemoryChunksExt",
|
||||
"@odata.type": "#HpeMemoryChunksExt.v2_1_0.HpeMemoryChunksExt",
|
||||
"MemoryChunkSizePercentage": 50
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#MemoryChunks.MemoryChunks",
|
||||
"@odata.etag": "W/\"89E7F7C3\"",
|
||||
"@odata.id": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/MemoryChunks/1/",
|
||||
"@odata.type": "#MemoryChunks.v1_2_2.MemoryChunks",
|
||||
"Id": "1",
|
||||
"AddressRangeType": "PMEM",
|
||||
"Description": "Memory Chunk",
|
||||
"InterleaveSets": [
|
||||
{
|
||||
"Memory": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc1dimm6/"
|
||||
},
|
||||
"RegionId": "1",
|
||||
"SizeMiB": 131072
|
||||
}
|
||||
],
|
||||
"IsMirrorEnabled": False,
|
||||
"IsSpare": False,
|
||||
"MemoryChunkSizeMiB": 131072,
|
||||
"Name": "MemoryChunk",
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"@odata.context": "/redfish/v1/$metadata#HpeMemoryChunksExt.HpeMemoryChunksExt",
|
||||
"@odata.type": "#HpeMemoryChunksExt.v2_1_0.HpeMemoryChunksExt",
|
||||
"MemoryChunkSizePercentage": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
mock_interleavable_set = [
|
||||
{
|
||||
"MemorySet": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc2dimm6/"
|
||||
},
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc2dimm7/"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"MemorySet": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc2dimm6/"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"MemorySet": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc2dimm7/"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
expect_post_bodies_app_direct_interleaved = [
|
||||
{
|
||||
'AddressRangeType': 'PMEM',
|
||||
'Oem': {
|
||||
'Hpe': {
|
||||
'MemoryChunkSizePercentage': 100
|
||||
}
|
||||
},
|
||||
'InterleaveSets': [
|
||||
{
|
||||
'Memory': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'
|
||||
}
|
||||
},
|
||||
{
|
||||
'Memory': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
expected_post_bodies_app_direct_not_interleaved = [
|
||||
{
|
||||
'AddressRangeType': 'PMEM',
|
||||
'Oem': {
|
||||
'Hpe': {
|
||||
'MemoryChunkSizePercentage': 100
|
||||
}
|
||||
},
|
||||
'InterleaveSets': [
|
||||
{
|
||||
'Memory': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'AddressRangeType': 'PMEM',
|
||||
'Oem': {
|
||||
'Hpe': {
|
||||
'MemoryChunkSizePercentage': 100
|
||||
}
|
||||
},
|
||||
'InterleaveSets': [
|
||||
{
|
||||
'Memory': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
expected_post_bodies_memory_mode = [
|
||||
{
|
||||
'AddressRangeType': 'PMEM',
|
||||
'Oem': {
|
||||
'Hpe': {
|
||||
'MemoryChunkSizePercentage': 0
|
||||
}
|
||||
},
|
||||
'InterleaveSets': [
|
||||
{
|
||||
'Memory': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'
|
||||
}
|
||||
},
|
||||
{
|
||||
'Memory': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
def retrieve_memory_domains(self):
|
||||
"""
|
||||
Function to retrive memory domains
|
||||
"""
|
||||
memory_domains = [{
|
||||
'Name': 'PROC1 Memory Domain',
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain',
|
||||
'@odata.context': '/redfish/v1/$metadata#MemoryDomain.MemoryDomain',
|
||||
'Id': 'PROC1MemoryDomain',
|
||||
"InterleavableMemorySets":[{
|
||||
"MemorySet":[
|
||||
{
|
||||
"@odata.id":"/redfish/v1/Systems/1/Memory/proc2dimm6/"
|
||||
},
|
||||
{
|
||||
"@odata.id":"/redfish/v1/Systems/1/Memory/proc2dimm7/"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"MemorySet":[
|
||||
{
|
||||
"@odata.id":"/redfish/v1/Systems/1/Memory/proc2dimm6/"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"MemorySet":[
|
||||
{
|
||||
"@odata.id":"/redfish/v1/Systems/1/Memory/proc2dimm7/"
|
||||
}
|
||||
]
|
||||
}],
|
||||
"MemoryChunks":{
|
||||
"@odata.id":"/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/MemoryChunks"}
|
||||
}]
|
||||
return [], memory_domains, []
|
||||
|
||||
class TestApplyPmemConfigCommand(object):
|
||||
"""
|
||||
Class for unit tests of 'applydcpmmconfig' command
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('customparser, expected_result', [
|
||||
('', None)
|
||||
])
|
||||
def test_define_arguments(customparser, expected_result):
|
||||
"""
|
||||
Branch Test for 'define_arguments()' when parser is not customparser
|
||||
"""
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(
|
||||
RdmcCommandBase)
|
||||
result = pmem_command.define_arguments(customparser)
|
||||
assert result == expected_result
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('memory_chunk_tasks, memory_chunks', [
|
||||
([MockData.mock_tasks[0]], list()),
|
||||
(list(), MockData.mock_chunks),
|
||||
([MockData.mock_tasks[1]], MockData.mock_chunks),
|
||||
([MockData.other_mock_tasks[0]], MockData.mock_chunks)
|
||||
])
|
||||
def test_warn_existing_chunks_and_tasks_fail(memory_chunk_tasks, memory_chunks):
|
||||
"""
|
||||
Tests for 'delete_existing_chunks_and_tasks' with invalid data
|
||||
"""
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
with pytest.raises(NoChangesFoundOrMadeError):
|
||||
pmem_command.warn_existing_chunks_and_tasks(memory_chunk_tasks, memory_chunks)
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('memory_chunk_tasks, memory_chunks, expected_result', [
|
||||
(list(), list(), None),
|
||||
(None, list(), None)
|
||||
])
|
||||
def test_warn_existing_chunks_and_tasks_pass(memory_chunk_tasks,
|
||||
memory_chunks, expected_result):
|
||||
"""
|
||||
Tests for 'delete_existing_chunks_and_tasks' with valid data
|
||||
"""
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
result = pmem_command.warn_existing_chunks_and_tasks(memory_chunk_tasks, memory_chunks)
|
||||
assert result == expected_result
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('memory_chunk_tasks, memory_chunks, response, expected_result', [
|
||||
([MockData.mock_tasks[0]], list(), 200, None),
|
||||
([MockData.mock_tasks[0]], MockData.mock_chunks, 202, None),
|
||||
(None, None, None, None),
|
||||
(list(), list(), None, None)
|
||||
])
|
||||
def test_delete_existing_chunks_and_tasks_pass(memory_chunk_tasks, memory_chunks,
|
||||
response, expected_result, monkeypatch):
|
||||
"""
|
||||
Tests for 'delete_existing_chunks_and_tasks' with valid data
|
||||
"""
|
||||
def get_response(*argv):
|
||||
"""
|
||||
Returns response codes
|
||||
"""
|
||||
#pylint: disable=unused-argument
|
||||
return response
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "delete_resource", get_response)
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
result = pmem_command.delete_existing_chunks_and_tasks(memory_chunk_tasks, memory_chunks)
|
||||
assert result == expected_result
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('memory_chunk_tasks, memory_chunks', [
|
||||
([MockData.mock_tasks[0]], MockData.mock_chunks),
|
||||
(None, MockData.mock_chunks),
|
||||
])
|
||||
def test_delete_existing_chunks_and_tasks_fail(memory_chunk_tasks, memory_chunks, monkeypatch):
|
||||
"""
|
||||
Tests for 'delete_existing_chunks_and_tasks' with invalid data
|
||||
"""
|
||||
def get_response(*argv):
|
||||
"""
|
||||
Returns none
|
||||
"""
|
||||
#pylint: disable=unused-argument
|
||||
return None
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "delete_resource", get_response)
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
with pytest.raises(NoChangesFoundOrMadeError):
|
||||
pmem_command.delete_existing_chunks_and_tasks(memory_chunk_tasks, memory_chunks)
|
||||
|
||||
|
||||
class MockOptions(object):
|
||||
"""
|
||||
Class containing mock options for validation tests
|
||||
"""
|
||||
list = False
|
||||
config = ""
|
||||
force = False
|
||||
|
||||
@staticmethod
|
||||
def set_options(list, config, force):
|
||||
"""
|
||||
Setter function for options
|
||||
"""
|
||||
MockOptions.list = list
|
||||
MockOptions.config = config
|
||||
MockOptions.force = force
|
||||
|
||||
|
||||
class TestValidation(object):
|
||||
"""
|
||||
Class containing test for validation based on mock options
|
||||
"""
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("list, config, force, expected_result", [
|
||||
(True, False, False, None),
|
||||
(False, "memorymode", False, None),
|
||||
(False, "appdirectnotinterleaved", True, None),
|
||||
(False, "appdirectinterleaved", True, None),
|
||||
(False, "AppdirecTinterLeaveD", False, None),
|
||||
(False, "APPDIRECTNOTINTERLEAVED", False, None),
|
||||
])
|
||||
def test_validate_options_pass(list, config, force, expected_result):
|
||||
"""
|
||||
Tests for 'validate_options' with valid options
|
||||
"""
|
||||
MockOptions.set_options(list, config, force)
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
result = pmem_command.validate_options(MockOptions)
|
||||
assert result == expected_result
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("list_flag, config, force", [
|
||||
(False, "", False),
|
||||
(True, "AppDirectInterleaved", False),
|
||||
(False, "qwerty", True),
|
||||
(True, "MemoryMode", True),
|
||||
(False, None, True),
|
||||
(True, None, True)
|
||||
])
|
||||
def test_validate_options_fail(list_flag, config, force):
|
||||
"""
|
||||
Tests for 'validate_options' with invalid options
|
||||
"""
|
||||
MockOptions.set_options(list_flag, config, force)
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
with pytest.raises(InvalidCommandLineError):
|
||||
pmem_command.validate_options(MockOptions)
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("list_flag, config, force", [
|
||||
(False, "False", False),
|
||||
(False, None, True),
|
||||
(True, "args", True)
|
||||
])
|
||||
def test_validate_args(list_flag, config, force):
|
||||
"""
|
||||
Tests for 'validate_args'
|
||||
"""
|
||||
MockOptions.set_options(list_flag, config, force)
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
with pytest.raises(InvalidCommandLineError):
|
||||
pmem_command.validate_args(MockOptions)
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('mock_config_data, mock_interleavable_set, expected_result', [
|
||||
(ApplyPmemConfigCommand.ApplyPmemConfigCommand.config_ids[0],
|
||||
MockData.mock_interleavable_set,
|
||||
MockData.expected_post_bodies_memory_mode),
|
||||
(ApplyPmemConfigCommand.ApplyPmemConfigCommand.config_ids[1],
|
||||
MockData.mock_interleavable_set,
|
||||
MockData.expect_post_bodies_app_direct_interleaved),
|
||||
(ApplyPmemConfigCommand.ApplyPmemConfigCommand.config_ids[2],
|
||||
MockData.mock_interleavable_set,
|
||||
MockData.expected_post_bodies_app_direct_not_interleaved)
|
||||
])
|
||||
|
||||
def test_get_post_data(mock_config_data, mock_interleavable_set, expected_result):
|
||||
"""
|
||||
Test for get_post_data with MemoryMode, AppDirectInterleaved and AppDirectNotInterleaved
|
||||
"""
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(
|
||||
RdmcCommandBase)
|
||||
result = pmem_command.get_post_data(mock_config_data, mock_interleavable_set)
|
||||
assert result == expected_result
|
||||
|
||||
@staticmethod
|
||||
def test_apply_predefined_err(monkeypatch):
|
||||
"""
|
||||
Test for apply_predefined_config with empty memory domains list
|
||||
"""
|
||||
def retrive_empty_mem_domains(*argv):
|
||||
"""
|
||||
returns empty list
|
||||
"""
|
||||
#pylint: disable=unused-argument
|
||||
return [], [], []
|
||||
|
||||
MockOptions.set_options(False, "memorymode", True)
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "retrieve_task_members_and_mem_domains",
|
||||
retrive_empty_mem_domains)
|
||||
with pytest.raises(NoContentsFoundForOperationError):
|
||||
pmem_command.apply_predefined_config(MockOptions)
|
||||
|
||||
def test_apply_predefined_err3(self, monkeypatch):
|
||||
"""
|
||||
Test for apply_predefined_config with invalid post request
|
||||
"""
|
||||
def get_failure_resp(*argv):
|
||||
"""
|
||||
returns None
|
||||
"""
|
||||
#pylint: disable=unused-argument
|
||||
return None
|
||||
MockOptions.set_options(False, "appdirectinterleaved", True)
|
||||
pmem_command = ApplyPmemConfigCommand.ApplyPmemConfigCommand(RdmcCommandBase)
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "retrieve_task_members_and_mem_domains",
|
||||
MockData().retrieve_memory_domains)
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "post_resource", get_failure_resp)
|
||||
with pytest.raises(NoChangesFoundOrMadeError):
|
||||
pmem_command.apply_predefined_config(MockOptions)
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
"""Module to Test the 'cleardcpmmpendingconfig' command"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from rdmc_base_classes import RdmcCommandBase
|
||||
from rdmc_helper import NoChangesFoundOrMadeError, NoContentsFoundForOperationError
|
||||
|
||||
from .conftest import ClearPendingConfigCommand, RestHelpers
|
||||
|
||||
|
||||
class MockData(object):
|
||||
"""
|
||||
Mock Data for 'cleardcpmmpendingconfig' command
|
||||
"""
|
||||
task = None
|
||||
resp = None
|
||||
|
||||
mock_tasks_1 = [{
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 1",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm12/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/"
|
||||
"MemoryChunks/?$expand=."
|
||||
},
|
||||
"TaskState": "New"
|
||||
}, {
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 2",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm10/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/"
|
||||
"MemoryChunks/?$expand=."
|
||||
},
|
||||
"TaskState": "Old"
|
||||
}]
|
||||
|
||||
mock_tasks_2 = [{
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 1",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm12/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/"
|
||||
"MemoryChunks/?$expand=."
|
||||
},
|
||||
"TaskState": "New"
|
||||
}]
|
||||
|
||||
mock_tasks_3 = [{
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 1",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm12/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/?$expand=."
|
||||
},
|
||||
"TaskState": "New"
|
||||
}, {
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 2",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm10/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/?$expand=."
|
||||
},
|
||||
"TaskState": "Old"
|
||||
}]
|
||||
|
||||
@staticmethod
|
||||
def get_resource_tasks(*argv):
|
||||
"""
|
||||
Returns mock tasks
|
||||
"""
|
||||
return MockData.task
|
||||
|
||||
@staticmethod
|
||||
def get_response_code(*argv):
|
||||
"""
|
||||
Returns mock response codes
|
||||
"""
|
||||
return MockData.resp
|
||||
|
||||
class TestDeleteTasks(object):
|
||||
"""
|
||||
Class for unit tests of 'cleardcpmmpendingconfig' command
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("tasks, expected_result", [
|
||||
(MockData.mock_tasks_1, [MockData.mock_tasks_1[0]]),
|
||||
([MockData.mock_tasks_2[0]], [MockData.mock_tasks_2[0]])
|
||||
])
|
||||
def test_get_memory_chunk_tasks_pass(tasks, expected_result, monkeypatch):
|
||||
"""
|
||||
Tests for 'get_memory_chunk_tasks' with valid data
|
||||
"""
|
||||
MockData.task = tasks
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers,
|
||||
"retrieve_task_members", MockData.get_resource_tasks)
|
||||
pmem_command = ClearPendingConfigCommand.ClearPendingConfigCommand(RdmcCommandBase)
|
||||
result = pmem_command.get_memory_chunk_tasks()
|
||||
assert result == expected_result
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("tasks", [
|
||||
(MockData.mock_tasks_3),
|
||||
([MockData.mock_tasks_3[0]]),
|
||||
([MockData.mock_tasks_3[1]]),
|
||||
([MockData.mock_tasks_1[1]])
|
||||
])
|
||||
def test_get_memory_chunk_tasks_fail(tasks, monkeypatch):
|
||||
"""
|
||||
Tests for 'get_memory_chunk_tasks' with invalid data
|
||||
"""
|
||||
MockData.task = tasks
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "retrieve_task_members",
|
||||
MockData.get_resource_tasks)
|
||||
pmem_command = ClearPendingConfigCommand.ClearPendingConfigCommand(RdmcCommandBase)
|
||||
with pytest.raises(NoContentsFoundForOperationError):
|
||||
pmem_command.get_memory_chunk_tasks()
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("resp, verbose", [
|
||||
(200, False),
|
||||
(200, True)
|
||||
])
|
||||
def test_delete_tasks_pass(resp, verbose, monkeypatch):
|
||||
"""
|
||||
Tests for 'delete_tasks' with valid data
|
||||
"""
|
||||
MockData.resp = resp
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "delete_resource",
|
||||
MockData.get_response_code)
|
||||
pmem_command = ClearPendingConfigCommand.ClearPendingConfigCommand(RdmcCommandBase)
|
||||
result = pmem_command.delete_tasks(MockData.mock_tasks_3, verbose)
|
||||
assert result is None
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("resp, verbose", [
|
||||
(None, False),
|
||||
(None, True)
|
||||
])
|
||||
def test_delete_tasks_fail(resp, verbose, monkeypatch):
|
||||
"""
|
||||
Tests for 'delete_tasks' with invalid data
|
||||
"""
|
||||
MockData.resp = resp
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "delete_resource",
|
||||
MockData.get_response_code)
|
||||
pmem_command = ClearPendingConfigCommand.ClearPendingConfigCommand(RdmcCommandBase)
|
||||
with pytest.raises(NoChangesFoundOrMadeError):
|
||||
pmem_command.delete_tasks(MockData.mock_tasks_3, verbose)
|
||||
@@ -0,0 +1,165 @@
|
||||
"""Module to test the DisplayHelpers Class"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import ast
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# For cross-compatibility between Python 2 and Python 3
|
||||
from six import StringIO
|
||||
|
||||
from .conftest import DisplayHelpers
|
||||
|
||||
|
||||
class TestDisplayHelpers(object):
|
||||
"""
|
||||
Class to test methods from the DisplayHelpers class
|
||||
"""
|
||||
output_format = DisplayHelpers.OutputFormats
|
||||
|
||||
@staticmethod
|
||||
def capture_stdout(func, data, out_format, prop_id=None):
|
||||
"""
|
||||
Function to capture the standard output stream
|
||||
"""
|
||||
old_stdout = sys.stdout
|
||||
capturer = StringIO()
|
||||
sys.stdout = capturer
|
||||
func(data, out_format, prop_id)
|
||||
sys.stdout = old_stdout
|
||||
output = capturer.getvalue()
|
||||
return output
|
||||
|
||||
@pytest.mark.parametrize('table_data, expected_output', [
|
||||
# Tests with empty input
|
||||
(None, ""),
|
||||
([], ""),
|
||||
# Single object test
|
||||
(["ItemId:ID1\nProperty1:Value1"], "ItemId Property1 ID1 Value1"),
|
||||
# Test to check truncation of string
|
||||
(["ItemId:ID1\nProp2:Value of property2\nProp1:Value1"],
|
||||
"ItemId Prop2 Prop1 ID1 Value of.. Value1"),
|
||||
# Multiple objects test
|
||||
(["ItemId:ID1\nProperty1: ", "ItemId:ID2\nProperty1:LongPropertyValue"],
|
||||
"ItemId Property1 ID1 ID2 LongProp..")
|
||||
])
|
||||
def test_printtable_withwidth(self, table_data, expected_output):
|
||||
"""
|
||||
Test for printtable with a custom specified width
|
||||
"""
|
||||
display_helpers = DisplayHelpers.DisplayHelpers(10)
|
||||
out = TestDisplayHelpers.capture_stdout(
|
||||
display_helpers.display_data, table_data, self.output_format.table, None)
|
||||
assert [str(x) for x in out.split()] == expected_output.split()
|
||||
|
||||
@pytest.mark.parametrize('table_data, expected_output', [
|
||||
# Tests with empty input
|
||||
(None, ""),
|
||||
([], ""),
|
||||
# Single object test
|
||||
(["ItemId:ID1\nProperty1:Value1"], "ItemId Property1 ID1 Value1"),
|
||||
# Test to check truncation of string
|
||||
(["ItemId:ID1\nProp2:Value of property2\nProp1:Value1"],
|
||||
"ItemId Prop2 Prop1 ID1 Value of property2 Value1"),
|
||||
# Converting redfish property to friendly name test
|
||||
(["Property2:Value2\nFWVersion:2.1"], " Property2 FWVersion Value2 2.1"),
|
||||
# Multiple objects test
|
||||
(["ItemId:ID1\nProperty1: ", "ItemId:ID2\nProperty1:LongPropertyValue"],
|
||||
"ItemId Property1 ID1 ID2 LongPropertyValue")
|
||||
])
|
||||
def test_printtable(self, table_data, expected_output):
|
||||
"""
|
||||
Test for printtable with the default width
|
||||
"""
|
||||
display_helpers = DisplayHelpers.DisplayHelpers()
|
||||
out = TestDisplayHelpers.capture_stdout(
|
||||
display_helpers.display_data, table_data, self.output_format.table, None)
|
||||
assert out.split() == expected_output.split()
|
||||
|
||||
@pytest.mark.parametrize('table_data, expected_output', [
|
||||
# Tests with empty input
|
||||
(None, ""),
|
||||
([], ""),
|
||||
# Single object test
|
||||
(["ItemId:ID1\nProperty1:Value1"],
|
||||
"--- 1 ---\nItemId: ID1\nProperty1: Value1"),
|
||||
# Converting redfish property to friendly name test
|
||||
(["FWVersion:2.1\nItemId:ID1"], "--- 1 ---\nFWVersion: 2.1\nItemId: ID1"),
|
||||
# Multiple objects test
|
||||
(["ItemId:ID1\nProperty1:", "ItemId:ID2\nProperty1:Value1"],
|
||||
"--- 1 ---\nItemId: ID1\nProperty1: \n\n--- 2 ---\nItemId: ID2\nProperty1: Value1")
|
||||
])
|
||||
def test_printlist(self, table_data, expected_output):
|
||||
"""
|
||||
Test for the printlist function that produces output in list form
|
||||
"""
|
||||
display_helpers = DisplayHelpers.DisplayHelpers()
|
||||
out = TestDisplayHelpers.capture_stdout(
|
||||
display_helpers.display_data, table_data, self.output_format.list, None)
|
||||
assert out.strip() == expected_output.strip()
|
||||
|
||||
@pytest.mark.parametrize('table_data, expected_output', [
|
||||
# Tests with empty input
|
||||
(None, ""),
|
||||
([], ""),
|
||||
# Single object test
|
||||
(["ItemId:ID1\nProperty1:Value1"],
|
||||
"--- ItemId: ID1 ---\nProperty1: Value1"),
|
||||
# Converting redfish property to friendly name test
|
||||
(["ItemId:ID1\nFWVersion:2.1"], "--- ItemId: ID1 ---\nFWVersion: 2.1"),
|
||||
# Multiple objects test
|
||||
(["ItemId:ID1\nProperty1:", "ItemId:ID2\nProperty1:Value1"],
|
||||
"--- ItemId: ID1 ---\nProperty1: \n\n--- ItemId: ID2 ---\nProperty1: Value1")
|
||||
])
|
||||
def test_printlist_withid(self, table_data, expected_output):
|
||||
"""
|
||||
Test for the printlist function that produces output in list form with custom ID
|
||||
"""
|
||||
display_helpers = DisplayHelpers.DisplayHelpers()
|
||||
out = TestDisplayHelpers.capture_stdout(
|
||||
display_helpers.display_data, table_data, self.output_format.list, "ItemId")
|
||||
assert out.strip() == expected_output.strip()
|
||||
|
||||
@pytest.mark.parametrize('table_data, expected_output', [
|
||||
# Tests with empty input
|
||||
(None, ""),
|
||||
([], ""),
|
||||
# Single object test
|
||||
([{"ItemId": "ID1", "Property1": "Value1"}],
|
||||
[{"ItemId": "ID1", "Property1": "Value1"}]),
|
||||
# Converting redfish property to friendly name test
|
||||
([{"FWVersion": 2.1, "Property2": "Value2"}],
|
||||
[{"Property2": "Value2", "FWVersion": 2.1}]),
|
||||
# Multiple objects test
|
||||
([{"ItemId": "ID1", "Property1": ""}, {"ItemId": "ID2", "Property1": "LongPropertyValue"}],
|
||||
[{"ItemId": "ID1", "Property1": ""}, {"ItemId": "ID2", "Property1": "LongPropertyValue"}])
|
||||
])
|
||||
def test_printjson(self, table_data, expected_output):
|
||||
"""
|
||||
Test for the printjson function that produces output in json form
|
||||
"""
|
||||
display_helpers = DisplayHelpers.DisplayHelpers()
|
||||
out = TestDisplayHelpers.capture_stdout(
|
||||
display_helpers.display_data, table_data, self.output_format.json, None)
|
||||
if expected_output == "":
|
||||
assert out == expected_output
|
||||
else:
|
||||
out = ast.literal_eval("".join(out.split()))
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('string, maxlen, expected_output', [
|
||||
("Banana", 10, "Banana"),
|
||||
("Hot Tamale", 10, "Hot Tamale"),
|
||||
("Antidisestablishmentarianism", 10, "Antidise.."),
|
||||
("hippopotomonstrosesquipedaliophobia", 18, "hippopotomonstro.."),
|
||||
(None, 10, "")
|
||||
])
|
||||
def test_truncate_lengthy(string, maxlen, expected_output):
|
||||
"""
|
||||
Test for the truncate_lengthy method
|
||||
"""
|
||||
display_helpers = DisplayHelpers.DisplayHelpers()
|
||||
out = display_helpers.truncate_lengthy(string, maxlen)
|
||||
assert out == expected_output
|
||||
@@ -0,0 +1,297 @@
|
||||
"""
|
||||
This module contains tests for MapperRenderers
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from .conftest import MapperRenderers
|
||||
|
||||
|
||||
class TestMapperRenderes(object):
|
||||
"""
|
||||
class to test functions in MapperRenderers
|
||||
"""
|
||||
mock_data = [
|
||||
{
|
||||
"DeviceLocator": "PROC 1 DIMM 1",
|
||||
"CapacityMiB": 123456,
|
||||
"PersistentRegionSizeLimitMiB": 24680,
|
||||
"SizeMiB": "xyz",
|
||||
"VolatileRegionSizeLimitMiB": 45678,
|
||||
},
|
||||
{
|
||||
"DeviceLocator": "PROC 2 DIMM 12",
|
||||
"CapacityMiB": 987654,
|
||||
"PersistentRegionSizeLimitMiB": 13579,
|
||||
"SizeMiB": "abc@123",
|
||||
"VolatileRegionSizeLimitMiB": 90123,
|
||||
}]
|
||||
|
||||
tasks = [
|
||||
{
|
||||
"Payload": {
|
||||
"JsonBody": {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Payload": {
|
||||
"JsonBody": {
|
||||
"MemoryChunkSizeMiB": 250
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Payload": {
|
||||
"JsonBody": {
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"MemoryChunkSizePercentage": 40
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Payload": {
|
||||
"JsonBody": {
|
||||
"MemoryChunkSizeMiB": 700,
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"MemoryChunkSizePercentage": 25
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Payload": {
|
||||
"JsonBody": {
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"MemoryChunkSizePercentage": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Payload": {
|
||||
"JsonBody": {
|
||||
"MemoryChunkSizeMiB": 0,
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"MemoryChunkSizePercentage": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("num, expected_output", [
|
||||
(0, "0.0 GiB"),
|
||||
(20, "0.02 GiB"),
|
||||
(400, "0.39 GiB"),
|
||||
(1024, "1.0 GiB"),
|
||||
(2000, "1.95 GiB"),
|
||||
(18499, "18.07 GiB")
|
||||
])
|
||||
def test_format_num(num, expected_output):
|
||||
"""
|
||||
Test for format_num()
|
||||
:param num: any number
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.format_num(num)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("num, expected_output", [
|
||||
(0, {"Units": "GiB", "Value": 0.0}),
|
||||
(20, {"Units": "GiB", "Value": 0.02}),
|
||||
(400, {"Units": "GiB", "Value": 0.39}),
|
||||
(1024, {"Units": "GiB", "Value": 1.0}),
|
||||
(2000, {"Units": "GiB", "Value": 1.95}),
|
||||
(18499, {"Units": "GiB", "Value": 18.07})
|
||||
])
|
||||
def test_format_num_json(num, expected_output):
|
||||
"""
|
||||
Test for format_num_json()
|
||||
:param num: any number
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.format_num_json(num)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("members, expected_output", [
|
||||
([], "0.0 GiB"),
|
||||
([mock_data[0]], "120.56 GiB"),
|
||||
([mock_data[1]], "964.51 GiB"),
|
||||
(mock_data, "1085.07 GiB")
|
||||
])
|
||||
def test_calculate_total_capacity(members, expected_output):
|
||||
"""
|
||||
Test for calculate_total_capacity()
|
||||
:param members: members for which total capacity needs to be calculated
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_total_capacity(members)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("members, expected_output", [
|
||||
([], {"Units": "GiB", "Value": 0.0}),
|
||||
([mock_data[0]], {"Units": "GiB", "Value": 120.56}),
|
||||
([mock_data[1]], {"Units": "GiB", "Value": 964.51}),
|
||||
(mock_data, {"Units": "GiB", "Value": 1085.07})
|
||||
])
|
||||
def test_calculate_total_capacity_json(members, expected_output):
|
||||
"""
|
||||
Test for calculate_total_capacity_json()
|
||||
:param members: members for which total capacity needs to be calculated
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_total_capacity_json(members)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("members, expected_output", [
|
||||
([], "0.0 GiB"),
|
||||
([mock_data[0]], "44.61 GiB"),
|
||||
([mock_data[1]], "88.01 GiB"),
|
||||
(mock_data, "132.62 GiB")
|
||||
])
|
||||
def test_calculate_total_volatile(members, expected_output):
|
||||
"""
|
||||
Test for calculate_total_volatile()
|
||||
:param members: members for which total volatile size needs to be calculated
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_total_volatile(members)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("members, expected_output", [
|
||||
([], {"Units": "GiB", "Value": 0.0}),
|
||||
([mock_data[0]], {"Units": "GiB", "Value": 44.61}),
|
||||
([mock_data[1]], {"Units": "GiB", "Value": 88.01}),
|
||||
(mock_data, {"Units": "GiB", "Value": 132.62})
|
||||
])
|
||||
def test_calculate_total_volatile_json(members, expected_output):
|
||||
"""
|
||||
Test for calculate_total_volatile_json()
|
||||
:param members: members for which total volatile size needs to be calculated
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_total_volatile_json(members)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("members, expected_output", [
|
||||
([], "0.0 GiB"),
|
||||
([mock_data[0]], "24.1 GiB"),
|
||||
([mock_data[1]], "13.26 GiB"),
|
||||
(mock_data, "37.36 GiB")
|
||||
])
|
||||
def test_calculate_total_appdirect(members, expected_output):
|
||||
"""
|
||||
Test for calculate_total_appdirect()
|
||||
:param members: members for which total appdirect size needs to be calculated
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_total_appdirect(members)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("members, expected_output", [
|
||||
([], {"Units": "GiB", "Value": 0.0}),
|
||||
([mock_data[0]], {"Units": "GiB", "Value": 24.10}),
|
||||
([mock_data[1]], {"Units": "GiB", "Value": 13.26}),
|
||||
(mock_data, {"Units": "GiB", "Value": 37.36})
|
||||
])
|
||||
def test_calculate_total_appdirect_json(members, expected_output):
|
||||
"""
|
||||
Test for calculate_total_appdirect_json()
|
||||
:param members: members for which total appdirect size needs to be calculated
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_total_appdirect_json(members)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("temp, expected_output", [
|
||||
# neither MemoryChunkSizeMiB nor MemoryChunkSizPercentage is present
|
||||
({"Task": tasks[0], "TotalCapacity": 1000}, "1000.0 GiB"),
|
||||
# Only MemoryChunkSizeMiB is present
|
||||
({"Task": tasks[1], "TotalCapacity": 1000}, "250.0 GiB"),
|
||||
# Only MemoryChunkSizePercentage is present
|
||||
({"Task": tasks[2], "TotalCapacity": 1000}, "400.0 GiB"),
|
||||
# Both MemoryChunkSizeMiB and MemoryChunkSizePercentage are present
|
||||
({"Task": tasks[3], "TotalCapacity": 1000}, "700.0 GiB"),
|
||||
# MemoryChunkSizePercentage is 0
|
||||
({"Task": tasks[4], "TotalCapacity": 1000}, "0.0 GiB"),
|
||||
# MemoryChunkSizeMiB is 0
|
||||
({"Task": tasks[4], "TotalCapacity": 1000}, "0.0 GiB")
|
||||
])
|
||||
def test_calculate_task_pmem_size(temp, expected_output):
|
||||
"""
|
||||
Test for calculate_task_pmem_size()
|
||||
:param temp: dictionary with task and total capacity of the task as keys
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_task_pmem_size(temp)
|
||||
assert out == expected_output
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("temp, expected_output", [
|
||||
# neither MemoryChunkSizeMiB nor MemoryChunkSizPercentage is present
|
||||
({"Task": tasks[0], "TotalCapacity": 1000}, "1000.0 GiB"),
|
||||
# Only MemoryChunkSizeMiB is present
|
||||
({"Task": tasks[1], "TotalCapacity": 1000}, "750.0 GiB"),
|
||||
# Only MemoryChunkSizePercentage is present
|
||||
({"Task": tasks[2], "TotalCapacity": 1000}, "600.0 GiB"),
|
||||
# Both MemoryChunkSizeMiB and MemoryChunkSizePercentage are present
|
||||
({"Task": tasks[3], "TotalCapacity": 1000}, "300.0 GiB"),
|
||||
# MemoryChunkSizePercentage is 0
|
||||
({"Task": tasks[4], "TotalCapacity": 1000}, "1000.0 GiB"),
|
||||
# MemoryChunkSizeMiB is 0
|
||||
({"Task": tasks[4], "TotalCapacity": 1000}, "1000.0 GiB")
|
||||
])
|
||||
def test_calculate_task_volatile_size(temp, expected_output):
|
||||
"""
|
||||
Test for calculate_task_volatile_size()
|
||||
:param temp: dictionary with task and total capacity of the task as keys
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.calculate_task_volatile_size(temp)
|
||||
assert out == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("operation, expected_output", [
|
||||
("post", "post"),
|
||||
("POST", "CREATE"),
|
||||
("GET", "GET"),
|
||||
("get", "get")
|
||||
])
|
||||
def test_map_operation(operation, expected_output):
|
||||
"""
|
||||
Test for map_operation()
|
||||
:param operation: HTTP operation
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
renderers = MapperRenderers.MapperRenderers()
|
||||
out = renderers.map_operation(operation)
|
||||
assert out == expected_output
|
||||
@@ -0,0 +1,179 @@
|
||||
"""
|
||||
This module contains tests for PmemHelpers
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from ..conftest import PmemHelpers
|
||||
|
||||
|
||||
class TestPmemHelpers(object):
|
||||
"""
|
||||
Class to test functions in PmemHelpers
|
||||
"""
|
||||
mem_members = [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc1dimm1/",
|
||||
"DeviceLocator": "PROC 1 DIMM 1",
|
||||
"MemoryType": "NVDIMM_P",
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"@odata.context": "/redfish/v1/$metadata#HpeMemoryExt.HpeMemoryExt",
|
||||
"@odata.type": "#HpeMemoryExt.v2_1_0.HpeMemoryExt",
|
||||
"ProductName": "Intel Optane Memory"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc1dimm2/",
|
||||
"DeviceLocator": "PROC 1 DIMM 2",
|
||||
"MemoryType": "DRAM",
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"@odata.context": "/redfish/v1/$metadata#HpeMemoryExt.HpeMemoryExt",
|
||||
"@odata.type": "#HpeMemoryExt.v2_1_0.HpeMemoryExt",
|
||||
"DIMMStatus": "NotPresent"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
chunks = [
|
||||
{
|
||||
"InterleaveSets": [
|
||||
{
|
||||
"Memory": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc1dimm1/"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"InterleaveSets": [
|
||||
{
|
||||
"Memory": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc1dimm12/"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"InterleaveSets": [
|
||||
{
|
||||
"Memory": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc2dimm1/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Memory": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/Memory/proc2dimm12/"
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('dimm_id_list, expected_output', [
|
||||
(['1@2', '2@3', '3@4'], ['PROC 1 DIMM 2', 'PROC 2 DIMM 3', 'PROC 3 DIMM 4']),
|
||||
(['2@12'], ['PROC 2 DIMM 12'])
|
||||
])
|
||||
def test_parse_dimm_id(dimm_id_list, expected_output):
|
||||
"""
|
||||
Test for parse_dimm_id()
|
||||
:param dimm_id_list: DIMM IDs in the 'X@Y' format
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
result = PmemHelpers.PmemHelpers.parse_dimm_id(dimm_id_list)
|
||||
assert result == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("memory_members, expected_output", [
|
||||
(mem_members, ([{'MemoryType': 'NVDIMM_P',
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm1/',
|
||||
'Oem': {
|
||||
'Hpe':
|
||||
{'@odata.type': '#HpeMemoryExt.v2_1_0.HpeMemoryExt',
|
||||
'@odata.context': '/redfish/v1/$metadata#HpeMemoryExt.'
|
||||
'HpeMemoryExt',
|
||||
'ProductName': 'Intel Optane Memory'}
|
||||
},
|
||||
'DeviceLocator': 'PROC 1 DIMM 1'}],
|
||||
set(['PROC 1 DIMM 1']))),
|
||||
([mem_members[0]], ([{'MemoryType': 'NVDIMM_P',
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm1/',
|
||||
'Oem': {
|
||||
'Hpe':
|
||||
{'@odata.type': '#HpeMemoryExt.v2_1_0.HpeMemoryExt',
|
||||
'@odata.context': '/redfish/v1/$metadata#HpeMemoryExt.'
|
||||
'HpeMemoryExt',
|
||||
'ProductName': 'Intel Optane Memory'}
|
||||
},
|
||||
'DeviceLocator': 'PROC 1 DIMM 1'}],
|
||||
set(['PROC 1 DIMM 1']))),
|
||||
([mem_members[1]], ([], set([]))),
|
||||
([], ([], set([])))
|
||||
])
|
||||
def test_get_pmem_members(memory_members, expected_output):
|
||||
"""
|
||||
Test for get_pmem_members()
|
||||
:param memory_members: members of memory collection resource
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
result = PmemHelpers.PmemHelpers.get_pmem_members(memory_members)
|
||||
assert result == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("data_id, chunks, expected_output", [
|
||||
("/redfish/v1/Systems/1/Memory/proc1dimm1/", chunks, False),
|
||||
("/redfish/v1/Systems/1/Memory/proc2dimm1/", chunks, True),
|
||||
("/redfish/v1/Systems/1/Memory/proc2dimm1/", [], None),
|
||||
("/redfish/v1/Systems/1/Memory/proc1dimm4/", chunks, None)])
|
||||
def test_is_interleave_set(data_id, chunks, expected_output):
|
||||
"""
|
||||
Test for is_interleave_set()
|
||||
:param data_id: @odata.id of the memory to be checked
|
||||
:param chunks: list of chunks
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
result = PmemHelpers.PmemHelpers.is_interleave_set(data_id, chunks)
|
||||
assert result == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('location_list, expected_output', [
|
||||
(['PROC X DIMM Y'], ('X@Y', 'PROC X')),
|
||||
(['PROC A DIMM B', 'PROC A DIMM C', 'PROC A DIMM D'], ('A@B, A@C, A@D', 'PROC A'))
|
||||
])
|
||||
def test_location_format_converter(location_list, expected_output):
|
||||
"""
|
||||
Test for location_format_converter()
|
||||
:param location_list: list of locations of the format 'PROC X DIMM Y'
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
result = PmemHelpers.PmemHelpers.location_format_converter(location_list)
|
||||
assert result == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("id1, id2, expected_output", [
|
||||
("/redfish/v1/Systems/1/Memory/proc1dimm1", "/redfish/v1/Systems/1/Memory/proc1dimm1",
|
||||
True),
|
||||
("/redfish/v1/Systems/1/Memory/proc1dimm1/", "/redfish/v1/Systems/1/Memory/proc1dimm1",
|
||||
True),
|
||||
("/redfish/v1/Systems/1/Memory/proc1dimm1", "/redfish/v1/Systems/1/Memory/proc1dimm1/",
|
||||
True),
|
||||
("/redfish/v1/Systems/1/Memory/proc1dimm1/", "/redfish/v1/Systems/1/Memory/proc1dimm1/",
|
||||
True),
|
||||
("/redfish/v1/Systems/1/Memory/proc1dimm2/", "/redfish/v1/Systems/1/Memory/proc1dimm1/",
|
||||
False)
|
||||
])
|
||||
def test_compare_id(id1, id2, expected_output):
|
||||
"""
|
||||
Test for compare_id()
|
||||
:param id1: first id to be compared
|
||||
:param id2: second id to be compared
|
||||
:param expected_output:
|
||||
:return: expected output of the test
|
||||
"""
|
||||
result = PmemHelpers.PmemHelpers.compare_id(id1, id2)
|
||||
assert result == expected_output
|
||||
@@ -0,0 +1,409 @@
|
||||
"""Module to Test the Rest Helpers Class"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from rdmc_base_classes import RdmcCommandBase
|
||||
|
||||
from .conftest import RestHelpers
|
||||
|
||||
|
||||
class MockMemoryDomainResource(object):
|
||||
"""
|
||||
Class to mock Memory Domain Resources
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.status = 200
|
||||
self.dict = {"@odata.context": "/redfish/v1/$metadata#MemoryDomainCollection"
|
||||
".MemoryDomainCollection",
|
||||
"@odata.etag": "W\"92240A75\"",
|
||||
"@odata.id": "/redfish/v1/Systems/1/MemoryDomains/",
|
||||
"@odata.type": "#MemoryDomainCollection.MemoryDomainCollection",
|
||||
"Description": "Memory Domains Collection",
|
||||
"Members": [{"@odata.context": "/redfish/v1/$metadata#MemoryDomain."
|
||||
"MemoryDomain",
|
||||
"@odata.id": "/redfish/v1/Systems/1/MemoryDomains/"
|
||||
"PROC1MemoryDomain/",
|
||||
"@odata.type": "#MemoryDomain.v1_0_0.MemoryDomain",
|
||||
"Id": "PROC1MemoryDomain",
|
||||
"InterleavableMemorySets": [
|
||||
{"MemorySet": [{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc1dimm6/"},
|
||||
{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc1dimm7/"}]},
|
||||
{"MemorySet": [{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc1dimm6/"}]},
|
||||
{"MemorySet": [{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc1dimm7/"}]}],
|
||||
"MemoryChunks": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/MemoryDomains/"
|
||||
"PROC1MemoryDomain/MemoryChunks/"},
|
||||
"Name": "PROC1 Memory Domain"},
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#MemoryDomain"
|
||||
".MemoryDomain",
|
||||
"@odata.id": "/redfish/v1/Systems/1/MemoryDomains"
|
||||
"/PROC2MemoryDomain/",
|
||||
"@odata.type": "#MemoryDomain.v1_0_0.MemoryDomain",
|
||||
"Id": "PROC2MemoryDomain",
|
||||
"InterleavableMemorySets": [
|
||||
{"MemorySet": [
|
||||
{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc2dimm6/"},
|
||||
{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc2dimm7/"}]},
|
||||
{"MemorySet": [
|
||||
{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc2dimm6/"}]},
|
||||
{"MemorySet": [
|
||||
{"@odata.id": "/redfish/v1/Systems/1/Memory/"
|
||||
"proc2dimm7/"}]}],
|
||||
"MemoryChunks": {
|
||||
"@odata.id": "/redfish/v1/Systems/1/MemoryDomains/"
|
||||
"PROC2MemoryDomain/MemoryChunks/"},
|
||||
"Name": "PROC2 Memory Domain"}],
|
||||
"Members@odata.count": 2,
|
||||
"Name": "Memory Domains Collection"}
|
||||
|
||||
def get_obj(self, *argv):
|
||||
"""
|
||||
Returns dict
|
||||
"""
|
||||
return self.dict
|
||||
|
||||
|
||||
class MockTaskResources(object):
|
||||
"""
|
||||
Class to mock Task Resources
|
||||
"""
|
||||
Tasks = [{
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 1",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm12/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/"
|
||||
"MemoryChunks/?$expand=."
|
||||
},
|
||||
"TaskState": "New"
|
||||
}, {
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 2",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm10/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/"
|
||||
"MemoryChunks/?$expand=."
|
||||
},
|
||||
"TaskState": "Old"
|
||||
}]
|
||||
|
||||
Other_Tasks = [{
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 1",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc1dimm12/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/?$expand=."
|
||||
},
|
||||
"TaskState": "New"
|
||||
}, {
|
||||
"@odata.context": "/redfish/v1/$metadata#Task.Task",
|
||||
"Name": "Task 2",
|
||||
"Payload": {
|
||||
"HttpOperation": "POST",
|
||||
"JsonBody": "{\"AddressRangeType\": \"PMEM\","
|
||||
"\"InterleaveSets\": "
|
||||
"[{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm1/\"}},"
|
||||
"{\"Memory\": "
|
||||
"{\"@odata.id\": \"/redfish/v1/Systems/1/Memory/proc2dimm10/\"}}],"
|
||||
"\"Oem\": {\"Hpe\": {\"MemoryChunkSizePercentage\": 0}}}",
|
||||
"TargetUri": "/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/?$expand=."
|
||||
},
|
||||
"TaskState": "Old"
|
||||
}]
|
||||
|
||||
@staticmethod
|
||||
def get_resource_tasks(*argv):
|
||||
"""
|
||||
Returns valid Task resources
|
||||
"""
|
||||
return {"Members": MockTaskResources.Tasks}
|
||||
|
||||
@staticmethod
|
||||
def get_resource_empty(*argv):
|
||||
"""
|
||||
Returns empty Task Resources
|
||||
"""
|
||||
return {"Members": []}
|
||||
|
||||
@staticmethod
|
||||
def get_resource_none(*argv):
|
||||
"""
|
||||
returns None
|
||||
"""
|
||||
return None
|
||||
|
||||
|
||||
class TestRestHelpers(object):
|
||||
"""
|
||||
Class to test methods from the RestHelpers class
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def test_retrieve_mem_domain_resources(monkeypatch):
|
||||
"""
|
||||
Test for retrieving Memory Domain Resources
|
||||
"""
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers,
|
||||
"get_resource", MockMemoryDomainResource().get_obj)
|
||||
rest_helpers = RestHelpers.RestHelpers(RdmcCommandBase)
|
||||
resp = rest_helpers.retrieve_mem_domain_resources()
|
||||
assert resp == ([{'@odata.context': '/redfish/v1/$metadata#MemoryDomain.MemoryDomain',
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/',
|
||||
'@odata.type': '#MemoryDomain.v1_0_0.MemoryDomain',
|
||||
'Id': 'PROC1MemoryDomain',
|
||||
'InterleavableMemorySets': [
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm6/'},
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm7/'}]},
|
||||
{'MemorySet': [{
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm6/'}]},
|
||||
{'MemorySet': [{
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm7/'}]}],
|
||||
'MemoryChunks': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain'
|
||||
'/MemoryChunks/'},
|
||||
'Name': 'PROC1 Memory Domain'},
|
||||
{'@odata.context': '/redfish/v1/$metadata#MemoryDomain.MemoryDomain',
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/',
|
||||
'@odata.type': '#MemoryDomain.v1_0_0.MemoryDomain',
|
||||
'Id': 'PROC2MemoryDomain',
|
||||
'InterleavableMemorySets': [
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'},
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'}]},
|
||||
{'MemorySet': [{
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'}]},
|
||||
{'MemorySet': [{
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'}]}],
|
||||
'MemoryChunks': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain'
|
||||
'/MemoryChunks/'},
|
||||
'Name': 'PROC2 Memory Domain'}],
|
||||
[{'@odata.context': '/redfish/v1/$metadata#MemoryDomain.MemoryDomain',
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/',
|
||||
'@odata.type': '#MemoryDomain.v1_0_0.MemoryDomain',
|
||||
'Id': 'PROC1MemoryDomain',
|
||||
'InterleavableMemorySets': [
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm6/'},
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm7/'}]},
|
||||
{'MemorySet': [
|
||||
{
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm6/'}]},
|
||||
{'MemorySet': [
|
||||
{
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm7/'}]}],
|
||||
'MemoryChunks': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain'
|
||||
'/MemoryChunks/'},
|
||||
'Name': 'PROC1 Memory Domain'},
|
||||
{'@odata.context': '/redfish/v1/$metadata#MemoryDomain.MemoryDomain',
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/',
|
||||
'@odata.type': '#MemoryDomain.v1_0_0.MemoryDomain',
|
||||
'Id': 'PROC2MemoryDomain',
|
||||
'InterleavableMemorySets': [
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'},
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'}]},
|
||||
{'MemorySet': [
|
||||
{
|
||||
'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'}]},
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'}]}],
|
||||
'MemoryChunks': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain'
|
||||
'/MemoryChunks/'},
|
||||
'Name': 'PROC2 Memory Domain'},
|
||||
{'@odata.context': '/redfish/v1/$metadata#MemoryDomain.MemoryDomain',
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain/',
|
||||
'@odata.type': '#MemoryDomain.v1_0_0.MemoryDomain',
|
||||
'Id': 'PROC1MemoryDomain',
|
||||
'InterleavableMemorySets': [
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm6/'},
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm7/'}]},
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm6/'}]},
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc1dimm7/'}]}],
|
||||
'MemoryChunks': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC1MemoryDomain'
|
||||
'/MemoryChunks/'},
|
||||
'Name': 'PROC1 Memory Domain'},
|
||||
{'@odata.context': '/redfish/v1/$metadata#MemoryDomain.MemoryDomain',
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain/',
|
||||
'@odata.type': '#MemoryDomain.v1_0_0.MemoryDomain',
|
||||
'Id': 'PROC2MemoryDomain',
|
||||
'InterleavableMemorySets': [
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'},
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'}]},
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm6/'}]},
|
||||
{'MemorySet': [
|
||||
{'@odata.id': '/redfish/v1/Systems/1/Memory/proc2dimm7/'}]}],
|
||||
'MemoryChunks': {
|
||||
'@odata.id': '/redfish/v1/Systems/1/MemoryDomains/PROC2MemoryDomain'
|
||||
'/MemoryChunks/'},
|
||||
'Name': 'PROC2 Memory Domain'}])
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('mock_get_resource, expected_output', [
|
||||
(MockTaskResources.get_resource_tasks, MockTaskResources.Tasks),
|
||||
(MockTaskResources.get_resource_empty, []),
|
||||
(MockTaskResources.get_resource_none, [])
|
||||
])
|
||||
def test_retrieve_task_members(mock_get_resource, expected_output, monkeypatch):
|
||||
"""
|
||||
Tests for retrieving task members
|
||||
"""
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers,
|
||||
"get_resource", mock_get_resource)
|
||||
rest_helpers = RestHelpers.RestHelpers(RdmcCommandBase)
|
||||
resp = rest_helpers.retrieve_task_members()
|
||||
assert resp == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("task_members, expected_output", [
|
||||
(MockTaskResources.Tasks, [MockTaskResources.Tasks[0]]),
|
||||
([MockTaskResources.Tasks[1]], []),
|
||||
(MockTaskResources.Other_Tasks, []),
|
||||
([MockTaskResources.Other_Tasks[0]], []),
|
||||
([MockTaskResources.Other_Tasks[1]], []),
|
||||
([], [])
|
||||
])
|
||||
def test_filter_task_members(task_members, expected_output):
|
||||
"""
|
||||
Tests for filtering task members
|
||||
"""
|
||||
rest_helpers = RestHelpers.RestHelpers(RdmcCommandBase)
|
||||
resp = rest_helpers.filter_task_members(task_members)
|
||||
assert resp == expected_output
|
||||
|
||||
|
||||
class MockDeleteResponse(object):
|
||||
"""
|
||||
Class to Mock Delete Response
|
||||
"""
|
||||
@staticmethod
|
||||
def get_success_resp(*argv):
|
||||
"""
|
||||
Returns a success response code (200)
|
||||
"""
|
||||
return 200
|
||||
|
||||
@staticmethod
|
||||
def get_failure_resp(*argv):
|
||||
"""
|
||||
Returns a failure response code (200)
|
||||
"""
|
||||
return 400
|
||||
|
||||
|
||||
class TestDeleteResponse(object):
|
||||
"""
|
||||
Class to Test Delete Response
|
||||
"""
|
||||
@staticmethod
|
||||
def test_delete_success(monkeypatch):
|
||||
"""
|
||||
Test where deletion is successful
|
||||
"""
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "delete_resource",
|
||||
MockDeleteResponse().get_success_resp)
|
||||
rest_helpers = RestHelpers.RestHelpers(RdmcCommandBase)
|
||||
resp = rest_helpers.delete_resource("/redfish/v1/TaskService/Tasks/1")
|
||||
assert resp == 200
|
||||
|
||||
@staticmethod
|
||||
def test_delete_failure(monkeypatch):
|
||||
"""
|
||||
Test where deletion fails
|
||||
"""
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers, "delete_resource",
|
||||
MockDeleteResponse().get_failure_resp)
|
||||
rest_helpers = RestHelpers.RestHelpers(RdmcCommandBase)
|
||||
resp = rest_helpers.delete_resource("/redfish/v1/TaskService/Tasks/1")
|
||||
assert resp == 400
|
||||
|
||||
|
||||
class MockPostResponse(object):
|
||||
"""
|
||||
Class to Mock Post Response
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def get_success_resp(*argv):
|
||||
"""
|
||||
Returns a success response code (202)
|
||||
"""
|
||||
return 202
|
||||
|
||||
@staticmethod
|
||||
def get_failure_resp(*argv):
|
||||
"""
|
||||
Returns a failure response code (402)
|
||||
"""
|
||||
return 402
|
||||
|
||||
|
||||
class TestPostResponse(object):
|
||||
"""
|
||||
Class to Test Post Response
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def test_post_success(monkeypatch):
|
||||
"""
|
||||
Test where POST succeds
|
||||
"""
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers,
|
||||
"post_resource", MockPostResponse().get_success_resp)
|
||||
rest_helpers = RestHelpers.RestHelpers(RdmcCommandBase)
|
||||
resp = rest_helpers.post_resource(
|
||||
"/redfish/v1/TaskService/Tasks/1", {"default": "testing"})
|
||||
assert resp == 202
|
||||
|
||||
@staticmethod
|
||||
def test_post_failure(monkeypatch):
|
||||
"""
|
||||
Test where POST fails
|
||||
"""
|
||||
monkeypatch.setattr(RestHelpers.RestHelpers,
|
||||
"post_resource", MockPostResponse().get_failure_resp)
|
||||
rest_helpers = RestHelpers.RestHelpers(RdmcCommandBase)
|
||||
resp = rest_helpers.post_resource(
|
||||
"/redfish/v1/TaskService/Tasks/1", {"default": "testing"})
|
||||
assert resp == 402
|
||||
@@ -0,0 +1,332 @@
|
||||
"""
|
||||
This module contains tests for ShowPmemCommand
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import pytest
|
||||
|
||||
from rdmc_base_classes import RdmcCommandBase
|
||||
from rdmc_helper import InvalidCommandLineError
|
||||
|
||||
from ..conftest import ShowPmemCommand
|
||||
|
||||
|
||||
class CustomOptions(object):
|
||||
"""
|
||||
Class to mock different options
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.all = True
|
||||
self.display_attributes = None
|
||||
self.json = False
|
||||
|
||||
def all_flag(self):
|
||||
"""
|
||||
Function to set --all flag to true
|
||||
:return: CustomOptions object
|
||||
"""
|
||||
self.all = True
|
||||
return self
|
||||
|
||||
def no_flag(self):
|
||||
"""
|
||||
Function to reset flags
|
||||
:return: CustomOptions object
|
||||
"""
|
||||
self.all = False
|
||||
self.display_attributes = None
|
||||
return self
|
||||
|
||||
def display_flag(self):
|
||||
"""
|
||||
Function to set --display flag
|
||||
:return: CustomOptions object
|
||||
"""
|
||||
self.all = False
|
||||
self.display_attributes = ["RandomNestedKey1"]
|
||||
return self
|
||||
|
||||
def wrong_display_flag(self):
|
||||
"""
|
||||
Function to set --display flag with wrong attributes
|
||||
:return: CustomOptions object
|
||||
"""
|
||||
self.all = False
|
||||
self.display_attributes = ["aBc", "xYz"]
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def get_default(flag):
|
||||
"""
|
||||
Function to return default attributes
|
||||
:return: list of attributes
|
||||
"""
|
||||
if flag == "device":
|
||||
return ["Location", "SizeMiB"]
|
||||
if flag == "config":
|
||||
return ["Location", "Capacity"]
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def get_all(flag):
|
||||
"""
|
||||
Function to return attributes for --all flag
|
||||
:return: list of attributes
|
||||
"""
|
||||
if flag == "device":
|
||||
return ["Location", "SizeMiB", "RandomNestedKey1"]
|
||||
if flag == "config":
|
||||
return ["Location", "Capacity", "RandomNestedKey1"]
|
||||
return []
|
||||
|
||||
|
||||
class MockMappingTable(object):
|
||||
"""
|
||||
class to mock mapping table
|
||||
"""
|
||||
memory = {'Capacity': {'path': '/CapacityMiB', 'redfishName': 'CapacityMiB'},
|
||||
'Location': {'path': '/DeviceLocator', 'redfishName': 'DeviceLocator'},
|
||||
'RandomAttribute': {'path': "/RandomAttribute",
|
||||
'redfishName': 'RandomAttribute'},
|
||||
'RandomNestedKey1': {'path': "/RandomAttribute/RandomNestedKey1",
|
||||
'redfishName': 'RandomNestedKey1'},
|
||||
'SizeMiB': {'path': '/Regions/SizeMiB', 'redfishName': 'SizeMiB'}}
|
||||
memorychunk = {'Capacity': {'path': '/CapacityMiB', 'redfishName': 'CapacityMiB'},
|
||||
'Location': {'path': '/DeviceLocator', 'redfishName': 'DeviceLocator'},
|
||||
'RandomAttribute': {'path': "/RandomAttribute",
|
||||
'redfishName': 'RandomAttribute'},
|
||||
'RandomNestedKey1': {'path': "/RandomAttribute/RandomNestedKey1",
|
||||
'redfishName': 'RandomNestedKey1'},
|
||||
'SizeMiB': {'path': '/Regions/SizeMiB', 'redfishName': 'SizeMiB'}}
|
||||
|
||||
|
||||
class TestShowPmemCommands(object):
|
||||
"""
|
||||
Class to test functions in ShowPmemCommands
|
||||
"""
|
||||
mock_data = [
|
||||
{
|
||||
'DeviceLocator': 'PROC 1 DIMM 1',
|
||||
'CapacityMiB': 123456,
|
||||
'SizeMiB': 'xyz',
|
||||
'RandomAttribute': {
|
||||
'RandomNestedKey1': 'RandomNestedValue1.1',
|
||||
'RandomNestedKey2': [
|
||||
'RandomNestedValue2.1',
|
||||
'RandomNestedValue2.2'
|
||||
],
|
||||
'RandomNestedKey4': [
|
||||
{
|
||||
'RandomNestedKey5': 'RandomNestedValue5.1'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'DeviceLocator': 'PROC 2 DIMM 12',
|
||||
'CapacityMiB': 987654,
|
||||
'SizeMiB': 'abc@123',
|
||||
'RandomAttribute': {
|
||||
'RandomNestedKey1': 'RandomNestedValue1.2',
|
||||
'RandomNestedKey2': [
|
||||
'RandomNestedValue2.3',
|
||||
'RandomNestedValue2.4'
|
||||
],
|
||||
'RandomNestedKey4': [
|
||||
{
|
||||
'RandomNestedKey5': 'RandomNestedValue5.2'
|
||||
}
|
||||
]
|
||||
}
|
||||
}]
|
||||
|
||||
custom_options_obj = CustomOptions()
|
||||
|
||||
@pytest.mark.parametrize('members, options, flag, expected_output', [
|
||||
# display flag
|
||||
(mock_data, CustomOptions().display_flag(), "device",
|
||||
['\nRandomNestedKey1: RandomNestedValue1.1', '\nRandomNestedKey1: RandomNestedValue1.2']),
|
||||
(mock_data, CustomOptions().display_flag(), "config",
|
||||
['\nRandomNestedKey1: RandomNestedValue1.1', '\nRandomNestedKey1: RandomNestedValue1.2']),
|
||||
# no flag
|
||||
([mock_data[1]], CustomOptions().no_flag(), "device",
|
||||
['\nLocation: PROC 2 DIMM 12\nSizeMiB: None']),
|
||||
([mock_data[0]], CustomOptions().no_flag(), "config",
|
||||
['\nLocation: PROC 1 DIMM 1\nCapacity: 123456'])
|
||||
])
|
||||
@pytest.mark.skip(reason="temporarily remove display flag")
|
||||
def test_generate_display_output_pass(self, members, options, flag, expected_output,
|
||||
monkeypatch):
|
||||
"""
|
||||
Tests for generate_display_output() with valid input
|
||||
:param members: list of members returned as a result of GET request
|
||||
:param options: command options
|
||||
:param flag: name of flag
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
monkeypatch.setattr(ShowPmemCommand, "get_default_attributes",
|
||||
self.custom_options_obj.get_default)
|
||||
pmem_command = ShowPmemCommand.ShowPmemCommand(RdmcCommandBase)
|
||||
result = pmem_command.generate_display_output(members, options, flag,
|
||||
MockMappingTable.memory)
|
||||
assert result == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('members, options, flag, expected_output', [
|
||||
([mock_data[0]], CustomOptions().wrong_display_flag(), "device",
|
||||
["\nNo match found for 'aBc'\nNo match found for 'xYz'"]),
|
||||
([mock_data[1]], CustomOptions().wrong_display_flag(), "config",
|
||||
["\nNo match found for 'aBc'\nNo match found for 'xYz'"]),
|
||||
(mock_data, CustomOptions().wrong_display_flag(), "config",
|
||||
["\nNo match found for 'aBc'\nNo match found for 'xYz'",
|
||||
"\nNo match found for 'aBc'\nNo match found for 'xYz'"]),
|
||||
])
|
||||
@pytest.mark.skip(reason="temporarily remove display flag")
|
||||
def test_generate_display_output_fail(members, options, flag, expected_output):
|
||||
"""
|
||||
Tests for generate_display_output() with invalid input
|
||||
:param members: list of members returned as a result of GET request
|
||||
:param options: command options
|
||||
:param flag: name of flag
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
pmem_command = ShowPmemCommand.ShowPmemCommand(RdmcCommandBase)
|
||||
result = pmem_command.generate_display_output(members, options, flag,
|
||||
MockMappingTable.memory)
|
||||
assert result == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize('customparser, expected_output', [
|
||||
('', None)
|
||||
])
|
||||
def test_define_arguments(customparser, expected_output):
|
||||
"""
|
||||
Branch Test for definearguments() when parser is not customparser
|
||||
:param customparser: command line input
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
pmem_command = ShowPmemCommand.ShowPmemCommand(RdmcCommandBase)
|
||||
result = pmem_command.definearguments(customparser)
|
||||
assert result == expected_output
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("flag, expected_output", [
|
||||
("device", ShowPmemCommand.DefaultAttributes.device.value),
|
||||
("config", ShowPmemCommand.DefaultAttributes.config.value),
|
||||
("summary", None),
|
||||
("abc", None)])
|
||||
def test_get_default_attributes(flag, expected_output):
|
||||
"""
|
||||
Test for get_default_attributes()
|
||||
:param flag: name of flag
|
||||
:param expected_output: expected output of the test
|
||||
"""
|
||||
result = ShowPmemCommand.get_default_attributes(flag)
|
||||
assert result == expected_output
|
||||
|
||||
|
||||
class MockOptions(object):
|
||||
"""
|
||||
Class containing mock options for validation tests
|
||||
"""
|
||||
device = False
|
||||
config = False
|
||||
summary = False
|
||||
logical = False
|
||||
dimm = None
|
||||
|
||||
@staticmethod
|
||||
def set_options(device, config, logical, summary, dimm):
|
||||
"""
|
||||
Setter method for Mock options
|
||||
"""
|
||||
MockOptions.device = device
|
||||
MockOptions.config = config
|
||||
MockOptions.logical = logical
|
||||
MockOptions.summary = summary
|
||||
MockOptions.dimm = dimm
|
||||
|
||||
|
||||
class TestValidation(object):
|
||||
"""
|
||||
Class containing validation tests
|
||||
"""
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("device, config, logical, summary, dimm, expected_result", [
|
||||
(False, False, False, False, None, None),
|
||||
(False, False, False, False, ["1@1", "2@10"], None),
|
||||
(True, False, False, False, None, None),
|
||||
(True, False, False, False, ["3@12", "4@8"], None),
|
||||
(False, True, False, False, None, None),
|
||||
(True, False, False, False, ["4@4", "3@3"], None),
|
||||
(True, False, False, False, ["9@19"], None),
|
||||
(False, False, True, False, None, None),
|
||||
(False, False, False, True, None, None)
|
||||
])
|
||||
def test_validate_show_pmem_options_pass(device, config, logical,
|
||||
summary, dimm, expected_result):
|
||||
"""
|
||||
Tests for 'validate_options' with valid options
|
||||
"""
|
||||
MockOptions.set_options(device, config, logical, summary, dimm)
|
||||
pmem_command = ShowPmemCommand.ShowPmemCommand(RdmcCommandBase)
|
||||
result = pmem_command.validate_show_pmem_options(MockOptions)
|
||||
assert result == expected_result
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("device, config, logical, summary, dimm", [
|
||||
(True, True, True, True, None),
|
||||
(True, True, True, False, None),
|
||||
(True, True, False, True, None),
|
||||
(True, False, True, True, None),
|
||||
(False, True, True, True, None),
|
||||
(True, True, False, False, None),
|
||||
(True, False, True, False, None),
|
||||
(True, False, False, True, None),
|
||||
(False, False, True, True, None),
|
||||
(False, True, False, True, None),
|
||||
(False, True, True, False, None),
|
||||
(True, False, False, False, ["0@0"]),
|
||||
(True, False, False, False, ["0@8"]),
|
||||
(True, False, False, False, ["4@0"]),
|
||||
(True, False, False, False, ["4@20"]),
|
||||
(True, False, False, False, ["10@20"]),
|
||||
(True, False, False, False, ["10@2"]),
|
||||
(True, False, False, False, ["3)12", "438"]),
|
||||
(True, False, False, False, ["4#4", "3!3"]),
|
||||
(True, False, False, False, ["3)12", "438"]),
|
||||
(False, False, False, False, ["1@1", "2@=10"]),
|
||||
(False, False, True, False, ["3@12", "4@8"]),
|
||||
(False, False, False, True, ["4@4", "3@3"])
|
||||
])
|
||||
def test_validate_show_pmem_options_fail(device, config, logical, summary, dimm):
|
||||
"""
|
||||
Tests for 'validate_options' with invalid options
|
||||
"""
|
||||
MockOptions.set_options(device, config, logical, summary, dimm)
|
||||
pmem_command = ShowPmemCommand.ShowPmemCommand(RdmcCommandBase)
|
||||
with pytest.raises(InvalidCommandLineError):
|
||||
pmem_command.validate_show_pmem_options(MockOptions)
|
||||
|
||||
@staticmethod
|
||||
@pytest.mark.parametrize("device, config, logical, summary, dimm", [
|
||||
(False, False, False, False, None),
|
||||
(False, False, False, False, ["1@2"]),
|
||||
(True, False, False, False, None),
|
||||
(True, False, False, False, ["4#4", "3!3"]),
|
||||
(False, True, False, False, None),
|
||||
(False, True, False, False, ["4@4", "3@3"]),
|
||||
(False, False, True, False, None),
|
||||
(False, False, True, False, ["1@1", "2@=10"]),
|
||||
(False, False, False, True, None),
|
||||
(False, False, False, True, ["1@1", "2@10"])
|
||||
])
|
||||
def test_validate_args(device, config, logical, summary, dimm):
|
||||
"""
|
||||
Tests for 'validate_args'
|
||||
"""
|
||||
MockOptions.set_options(device, config, logical, summary, dimm)
|
||||
pmem_command = ShowPmemCommand.ShowPmemCommand(RdmcCommandBase)
|
||||
with pytest.raises(InvalidCommandLineError):
|
||||
pmem_command.validate_args(MockOptions)
|
||||
Reference in new issue
Block a user