From 932181692ef69bddf2d2709ec309911613cf6d03 Mon Sep 17 00:00:00 2001 From: Gil Bregman Date: Wed, 29 Nov 2023 17:44:09 +0200 Subject: [PATCH] Use enum and not string for some GRPC fields. Fixes #253 Signed-off-by: Gil Bregman --- control/cli.py | 98 +++++++++++++++++++--------- control/grpc.py | 74 +++++++++++++++------ control/proto/gateway.proto | 45 ++++++++++--- tests/test_cli.py | 126 ++++++++++++++++++++++++++++++------ 4 files changed, 264 insertions(+), 79 deletions(-) diff --git a/control/cli.py b/control/cli.py index 7dffeab2f..f5c73ae61 100644 --- a/control/cli.py +++ b/control/cli.py @@ -296,45 +296,73 @@ def remove_host(self, args): argument("-n", "--subnqn", help="Subsystem NQN", required=True), argument("-g", "--gateway-name", help="Gateway name", required=True), argument("-t", "--trtype", help="Transport type", default="TCP"), - argument("-f", "--adrfam", help="Address family", default="ipv4"), + argument("-f", "--adrfam", help="Address family", default="IPV4"), argument("-a", "--traddr", help="NVMe host IP", required=True), argument("-s", "--trsvcid", help="Port number", default="4420", required=False), ]) def create_listener(self, args): """Creates a listener for a subsystem at a given IP/Port.""" traddr = GatewayConfig.escape_address_if_ipv6(args.traddr) - req = pb2.create_listener_req( - nqn=args.subnqn, - gateway_name=args.gateway_name, - trtype=args.trtype, - adrfam=args.adrfam, - traddr=traddr, - trsvcid=args.trsvcid, - ) - ret = self.stub.create_listener(req) - self.logger.info(f"Created {args.subnqn} listener at {traddr}:{args.trsvcid}: {ret.status}") + trtype = None + adrfam = None + if args.trtype: + trtype = args.trtype.upper() + if args.adrfam: + adrfam = args.adrfam.lower() + try: + req = pb2.create_listener_req( + nqn=args.subnqn, + gateway_name=args.gateway_name, + trtype=trtype, + adrfam=adrfam, + traddr=traddr, + trsvcid=args.trsvcid, + ) + ret = self.stub.create_listener(req) + self.logger.info(f"Created {args.subnqn} listener at {traddr}:{args.trsvcid}: {ret.status}") + except ValueError as err: + self.logger.error(f"{err}") + self.logger.info(f"Created {args.subnqn} listener at {traddr}:{args.trsvcid}: {False}") + raise + except Exception as ex: + self.logger.info(f"Created {args.subnqn} listener at {traddr}:{args.trsvcid}: {False}") + raise @cli.cmd([ argument("-n", "--subnqn", help="Subsystem NQN", required=True), argument("-g", "--gateway-name", help="Gateway name", required=True), argument("-t", "--trtype", help="Transport type", default="TCP"), - argument("-f", "--adrfam", help="Address family", default="ipv4"), + argument("-f", "--adrfam", help="Address family", default="IPV4"), argument("-a", "--traddr", help="NVMe host IP", required=True), argument("-s", "--trsvcid", help="Port number", default="4420", required=False), ]) def delete_listener(self, args): """Deletes a listener from a subsystem at a given IP/Port.""" traddr = GatewayConfig.escape_address_if_ipv6(args.traddr) - req = pb2.delete_listener_req( - nqn=args.subnqn, - gateway_name=args.gateway_name, - trtype=args.trtype, - adrfam=args.adrfam, - traddr=traddr, - trsvcid=args.trsvcid, - ) - ret = self.stub.delete_listener(req) - self.logger.info(f"Deleted {traddr}:{args.trsvcid} from {args.subnqn}: {ret.status}") + trtype = None + adrfam = None + if args.trtype: + trtype = args.trtype.upper() + if args.adrfam: + adrfam = args.adrfam.lower() + try: + req = pb2.delete_listener_req( + nqn=args.subnqn, + gateway_name=args.gateway_name, + trtype=trtype, + adrfam=adrfam, + traddr=traddr, + trsvcid=args.trsvcid, + ) + ret = self.stub.delete_listener(req) + self.logger.info(f"Deleted {traddr}:{args.trsvcid} from {args.subnqn}: {ret.status}") + except ValueError as err: + self.logger.error(f"{err}") + self.logger.info(f"Deleted {traddr}:{args.trsvcid} from {args.subnqn}: {False}") + raise + except Exception as ex: + self.logger.info(f"Deleted {traddr}:{args.trsvcid} from {args.subnqn}: {False}") + raise @cli.cmd() def get_subsystems(self, args): @@ -363,8 +391,6 @@ def disable_spdk_nvmf_logs(self, args): f"Disable SPDK nvmf logs: {ret.status}") @cli.cmd([ - argument("-f", "--flags", help="SPDK nvmf enable flags", \ - action='store_true', required=True), argument("-l", "--log_level", \ help="SPDK nvmf log level (ERROR, WARNING, NOTICE, INFO, DEBUG)", required=False), argument("-p", "--log_print_level", \ @@ -372,12 +398,24 @@ def disable_spdk_nvmf_logs(self, args): required=False), ]) def set_spdk_nvmf_logs(self, args): - """Set spdk nvmf log and flags""" - req = pb2.set_spdk_nvmf_logs_req(flags=args.flags, log_level=args.log_level, \ - print_level=args.log_print_level) - ret = self.stub.set_spdk_nvmf_logs(req) - self.logger.info( - f"Set SPDK nvmf logs : {ret.status}") + """Set spdk nvmf log and print levels""" + log_level = None + print_level = None + if args.log_level: + log_level = args.log_level.upper() + if args.log_print_level: + print_level = args.log_print_level.upper() + try: + req = pb2.set_spdk_nvmf_logs_req(log_level=log_level, print_level=print_level) + ret = self.stub.set_spdk_nvmf_logs(req) + self.logger.info(f"Set SPDK nvmf logs: {ret.status}") + except ValueError as err: + self.logger.error(f"{err}") + self.logger.info(f"Set SPDK nvmf logs: {False}") + raise + except Exception as ex: + self.logger.info(f"Set SPDK nvmf logs: {False}") + raise @cli.cmd() def get_gateway_info(self, args): diff --git a/control/grpc.py b/control/grpc.py index a6b994b08..d3cd9b1e4 100644 --- a/control/grpc.py +++ b/control/grpc.py @@ -642,8 +642,18 @@ def create_listener_safe(self, request, context=None): """Creates a listener for a subsystem at a given IP/Port.""" ret = True traddr = GatewayConfig.escape_address_if_ipv6(request.traddr) + try: + trtype = pb2.TransportType.keys()[request.trtype] + except Exception: + raise Exception(f"Unknown transport type {request.trtype}") + + try: + adrfam = pb2.AddressFamily.keys()[request.adrfam] + except Exception: + raise Exception(f"Unknown address family {request.adrfam}") + self.logger.info(f"Received request to create {request.gateway_name}" - f" {request.trtype} {request.adrfam} listener for {request.nqn} at" + f" {trtype} {adrfam} listener for {request.nqn} at" f" {traddr}:{request.trsvcid}., context: {context}") if self.is_discovery_nqn(request.nqn): @@ -653,12 +663,12 @@ def create_listener_safe(self, request, context=None): try: if request.gateway_name == self.gateway_name: listener_already_exist = self.matching_listener_exists( - context, request.nqn, request.gateway_name, request.trtype, request.traddr, request.trsvcid) + context, request.nqn, request.gateway_name, trtype, request.traddr, request.trsvcid) if listener_already_exist: self.logger.error(f"{request.nqn} already listens on address {request.traddr} port {request.trsvcid}") - req = {"nqn": request.nqn, "trtype": request.trtype, "traddr": request.traddr, + req = {"nqn": request.nqn, "trtype": trtype, "traddr": request.traddr, "gateway_name": request.gateway_name, - "trsvcid": request.trsvcid, "adrfam": request.adrfam, + "trsvcid": request.trsvcid, "adrfam": adrfam, "method": "nvmf_subsystem_add_listener", "req_id": 0} ret = {"code": -errno.EEXIST, "message": f"{request.nqn} already listens on address {request.traddr} port {request.trsvcid}"} msg = "\n".join(["request:", "%s" % json.dumps(req, indent=2), @@ -669,10 +679,10 @@ def create_listener_safe(self, request, context=None): ret = rpc_nvmf.nvmf_subsystem_add_listener( self.spdk_rpc_client, nqn=request.nqn, - trtype=request.trtype, + trtype=trtype, traddr=request.traddr, trsvcid=request.trsvcid, - adrfam=request.adrfam, + adrfam=adrfam, ) self.logger.info(f"create_listener: {ret}") else: @@ -710,10 +720,10 @@ def create_listener_safe(self, request, context=None): self.spdk_rpc_client, nqn=request.nqn, ana_state="inaccessible", - trtype=request.trtype, + trtype=trtype, traddr=request.traddr, trsvcid=request.trsvcid, - adrfam=request.adrfam, + adrfam=adrfam, anagrpid=(x+1) ) except Exception as ex: self.logger.error(f" set_listener_ana_state failed with: \n {ex}") @@ -726,7 +736,7 @@ def create_listener_safe(self, request, context=None): request, preserving_proto_field_name=True) self.gateway_state.add_listener(request.nqn, request.gateway_name, - request.trtype, request.traddr, + trtype, request.traddr, request.trsvcid, json_req) except Exception as ex: self.logger.error( @@ -743,8 +753,18 @@ def delete_listener_safe(self, request, context=None): ret = True traddr = GatewayConfig.escape_address_if_ipv6(request.traddr) + try: + trtype = pb2.TransportType.keys()[request.trtype] + except Exception: + raise Exception(f"Unknown transport type {request.trtype}") + + try: + adrfam = pb2.AddressFamily.keys()[request.adrfam] + except Exception: + raise Exception(f"Unknown address family {request.adrfam}") + self.logger.info(f"Received request to delete {request.gateway_name}" - f" {request.trtype} listener for {request.nqn} at" + f" {trtype} listener for {request.nqn} at" f" {traddr}:{request.trsvcid}., context: {context}") if self.is_discovery_nqn(request.nqn): @@ -756,10 +776,10 @@ def delete_listener_safe(self, request, context=None): ret = rpc_nvmf.nvmf_subsystem_remove_listener( self.spdk_rpc_client, nqn=request.nqn, - trtype=request.trtype, + trtype=trtype, traddr=request.traddr, trsvcid=request.trsvcid, - adrfam=request.adrfam, + adrfam=adrfam, ) self.logger.info(f"delete_listener: {ret}") else: @@ -777,7 +797,7 @@ def delete_listener_safe(self, request, context=None): try: self.gateway_state.remove_listener(request.nqn, request.gateway_name, - request.trtype, + trtype, request.traddr, request.trsvcid) except Exception as ex: @@ -849,23 +869,37 @@ def get_spdk_nvmf_log_flags_and_level(self, request, context): def set_spdk_nvmf_logs_safe(self, request, context): """Enables spdk nvmf logs""" self.logger.info(f"Received request to set SPDK nvmf logs") + log_level = None + print_level = None + if request.log_level: + try: + log_level = pb2.LogLevel.keys()[request.log_level] + except Exception: + raise Exception(f"Unknown log level {request.log_level}") + + if request.print_level: + try: + print_level = pb2.LogLevel.keys()[request.print_level] + except Exception: + raise Exception(f"Unknown print level {request.print_level}") + try: nvmf_log_flags = [key for key in rpc_log.log_get_flags(self.spdk_rpc_client).keys() \ if key.startswith('nvmf')] ret = [rpc_log.log_set_flag( self.spdk_rpc_client, flag=flag) for flag in nvmf_log_flags] self.logger.info(f"Set SPDK log flags {nvmf_log_flags} to TRUE") - if request.log_level: - ret_log = rpc_log.log_set_level(self.spdk_rpc_client, level=request.log_level) - self.logger.info(f"Set log level to: {request.log_level}") + if log_level: + ret_log = rpc_log.log_set_level(self.spdk_rpc_client, level=log_level) + self.logger.info(f"Set log level to: {log_level}") ret.append(ret_log) - if request.print_level: + if print_level: ret_print = rpc_log.log_set_print_level( - self.spdk_rpc_client, level=request.print_level) - self.logger.info(f"Set log print level to: {request.print_level}") + self.spdk_rpc_client, level=print_level) + self.logger.info(f"Set log print level to: {print_level}") ret.append(ret_print) except Exception as ex: - self.logger.error(f"set_spdk_nvmf_logs failed with: \n {ex}") + self.logger.error(f"set_spdk_nvmf_logs failed with:\n{ex}") context.set_code(grpc.StatusCode.INTERNAL) context.set_details(f"{ex}") for flag in nvmf_log_flags: diff --git a/control/proto/gateway.proto b/control/proto/gateway.proto index 7a43348a2..f29b1abd2 100644 --- a/control/proto/gateway.proto +++ b/control/proto/gateway.proto @@ -10,6 +10,34 @@ syntax = "proto3"; +enum TransportType { + TCP = 0; + RDMA = 1; + FC = 2; + INTRA_HOST = 3; + PCIE = 4; + VFIOUSER = 5; + CUSTOM = 6; + CUSTOM_FABRICS = 7; +} + +enum AddressFamily { + ipv4 = 0; + ipv6 = 1; + ib = 2; + fc = 3; + intra_host = 4; +} + +enum LogLevel { + DISABLED = 0; + ERROR = 1; + WARN = 2; + NOTICE = 3; + INFO = 4; + DEBUG = 5; +} + service Gateway { // Creates a bdev from an RBD image rpc create_bdev(create_bdev_req) returns (bdev) {} @@ -117,8 +145,8 @@ message remove_host_req { message create_listener_req { string nqn = 1; string gateway_name = 2; - string trtype = 3; - string adrfam = 4; + TransportType trtype = 3; + AddressFamily adrfam = 4; string traddr = 5; string trsvcid = 6; } @@ -126,8 +154,8 @@ message create_listener_req { message delete_listener_req { string nqn = 1; string gateway_name = 2; - string trtype = 3; - string adrfam = 4; + TransportType trtype = 3; + AddressFamily adrfam = 4; string traddr = 5; string trsvcid = 6; } @@ -142,9 +170,8 @@ message disable_spdk_nvmf_logs_req { } message set_spdk_nvmf_logs_req { - bool flags = 1; - optional string log_level = 2; - optional string print_level = 3; + optional LogLevel log_level = 1; + optional LogLevel print_level = 2; } message get_gateway_info_req { @@ -197,8 +224,8 @@ message gateway_info { message listen_address { string transport = 1; - string trtype = 2; - string adrfam = 3; + TransportType trtype = 2; + AddressFamily adrfam = 3; string traddr = 4; string trsvcid = 5; } diff --git a/tests/test_cli.py b/tests/test_cli.py index d1ca6b584..140487281 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -21,14 +21,18 @@ nsid = "1" nsid_ipv6 = "3" anagrpid = "2" -trtype = "TCP" gateway_name = socket.gethostname() addr = "127.0.0.1" addr_ipv6 = "::1" server_addr_ipv6 = "2001:db8::3" -listener_list = [["-g", gateway_name, "-a", addr, "-s", "5001"], ["-g", gateway_name, "-a", addr,"-s", "5002"]] +listener_list = [["-g", gateway_name, "-a", addr, "-s", "5001", "-t", "tCp", "-f", "ipV4"], ["-g", gateway_name, "-a", addr, "-s", "5002"]] listener_list_no_port = [["-g", gateway_name, "-a", addr]] -listener_list_ipv6 = [["-g", gateway_name, "-a", addr_ipv6, "-s", "5003"], ["-g", gateway_name, "-a", addr_ipv6, "-s", "5004"]] +listener_list_fc_trtype = [["-g", gateway_name, "-a", addr, "-s", "5010", "--trtype", "FC"]] +listener_list_invalid_trtype = [["-g", gateway_name, "-a", addr, "-s", "5011", "--trtype", "JUNK"]] +listener_list_invalid_adrfam = [["-g", gateway_name, "-a", addr, "-s", "5013", "--adrfam", "JUNK"]] +listener_list_ib_adrfam = [["-g", gateway_name, "-a", addr, "-s", "5014", "--adrfam", "ib"]] +listener_list_ipv6 = [["-g", gateway_name, "-a", addr_ipv6, "-s", "5003", "--adrfam", "ipv6"], ["-g", gateway_name, "-a", addr_ipv6, "-s", "5004", "--adrfam", "IPV6"]] +listener_list_discovery = [["-n", "nqn.2014-08.org.nvmexpress.discovery", "-g", gateway_name, "-a", addr, "-s", "5012"]] config = "ceph-nvmeof.conf" @pytest.fixture(scope="module") @@ -191,15 +195,15 @@ def test_create_listener(self, caplog, listener, gateway): caplog.clear() cli(["create_listener", "-n", subsystem] + listener) assert "enable_ha: False" in caplog.text - assert "ipv4" in caplog.text + assert "ipv4" in caplog.text.lower() assert f"Created {subsystem} listener at {listener[3]}:{listener[5]}: True" in caplog.text @pytest.mark.parametrize("listener_ipv6", listener_list_ipv6) def test_create_listener_ipv6(self, caplog, listener_ipv6, gateway): caplog.clear() - cli(["--server-address", server_addr_ipv6, "create_listener", "-n", subsystem, "--adrfam", "IPV6"] + listener_ipv6) + cli(["--server-address", server_addr_ipv6, "create_listener", "-n", subsystem] + listener_ipv6) assert "enable_ha: False" in caplog.text - assert "IPV6" in caplog.text + assert "ipv6" in caplog.text.lower() assert f"Created {subsystem} listener at [{listener_ipv6[3]}]:{listener_ipv6[5]}: True" in caplog.text @pytest.mark.parametrize("listener", listener_list_no_port) @@ -207,9 +211,79 @@ def test_create_listener_no_port(self, caplog, listener, gateway): caplog.clear() cli(["create_listener", "-n", subsystem] + listener) assert "enable_ha: False" in caplog.text - assert "ipv4" in caplog.text + assert "ipv4" in caplog.text.lower() assert f"Created {subsystem} listener at {listener[3]}:4420: True" in caplog.text + @pytest.mark.parametrize("listener", listener_list_fc_trtype) + def test_create_listener_fc_trtype(self, caplog, listener, gateway): + caplog.clear() + rc = 0 + with pytest.raises(Exception) as ex: + try: + cli(["create_listener", "-n", subsystem] + listener) + except SystemExit as sysex: + rc = sysex + pass + assert "create_listener failed" in str(ex.value) + assert rc != 0 + assert "create_listener failed" in caplog.text + assert "Invalid parameters" in caplog.text + assert '"trtype": "FC"' in caplog.text + + @pytest.mark.parametrize("listener", listener_list_invalid_trtype) + def test_create_listener_invalid_trtype(self, caplog, listener, gateway): + caplog.clear() + with pytest.raises(Exception) as ex: + try: + cli(["create_listener", "-n", subsystem] + listener) + except SystemExit as sysex: + pass + assert "unknown enum label" in str(ex.value) + assert "unknown enum label" in caplog.text + assert f"Created {subsystem} listener at {listener[3]}:{listener[5]}: False" in caplog.text + + @pytest.mark.parametrize("listener", listener_list_invalid_adrfam) + def test_create_listener_invalid_adrfam(self, caplog, listener, gateway): + caplog.clear() + with pytest.raises(Exception) as ex: + try: + cli(["create_listener", "-n", subsystem] + listener) + except SystemExit as sysex: + pass + assert "unknown enum label" in str(ex.value) + assert "unknown enum label" in caplog.text + assert f"Created {subsystem} listener at {listener[3]}:{listener[5]}: False" in caplog.text + + @pytest.mark.parametrize("listener", listener_list_ib_adrfam) + def test_create_listener_ib_adrfam(self, caplog, listener, gateway): + caplog.clear() + rc = 0 + with pytest.raises(Exception) as ex: + try: + cli(["create_listener", "-n", subsystem] + listener) + except SystemExit as sysex: + rc = sysex + pass + assert "create_listener failed" in str(ex.value) + assert rc != 0 + assert "create_listener failed" in caplog.text + assert "Invalid parameters" in caplog.text + assert '"adrfam": "ib"' in caplog.text + + @pytest.mark.parametrize("listener", listener_list_discovery) + def test_create_listener_on_discovery(self, caplog, listener, gateway): + caplog.clear() + rc = 0 + with pytest.raises(Exception) as ex: + try: + cli(["create_listener"] + listener) + except SystemExit as sysex: + rc = sysex + pass + assert "Can't create a listener for a discovery subsystem" in str(ex.value) + assert rc != 0 + assert "Can't create a listener for a discovery subsystem" in caplog.text + class TestDelete: @pytest.mark.parametrize("host", host_list) def test_remove_host(self, caplog, host, gateway): @@ -229,7 +303,7 @@ def test_delete_listener(self, caplog, listener, gateway): @pytest.mark.parametrize("listener_ipv6", listener_list_ipv6) def test_delete_listener_ipv6(self, caplog, listener_ipv6, gateway): caplog.clear() - cli(["--server-address", server_addr_ipv6, "delete_listener", "-n", subsystem, "--adrfam", "IPV6"] + listener_ipv6) + cli(["--server-address", server_addr_ipv6, "delete_listener", "-n", subsystem] + listener_ipv6) assert f"Deleted [{listener_ipv6[3]}]:{listener_ipv6[5]} from {subsystem}: True" in caplog.text @pytest.mark.parametrize("listener", listener_list_no_port) @@ -252,14 +326,16 @@ def test_delete_bdev(self, caplog, gateway): assert "Will remove namespace" not in caplog.text caplog.clear() # Should fail as there is a namespace using the bdev + rc = 0 with pytest.raises(Exception) as ex: try: cli(["delete_bdev", "-b", bdev1]) except SystemExit as sysex: # should fail with non-zero return code - assert sysex != 0 - pass + rc = sysex assert "Device or resource busy" in str(ex.value) + assert rc != 0 + assert "Device or resource busy" in caplog.text assert f"Namespace 2 from {subsystem} is still using bdev {bdev1}" in caplog.text caplog.clear() cli(["delete_bdev", "-b", bdev1, "--force"]) @@ -295,14 +371,16 @@ def test_create_bdev_ana_ipv6(self, caplog, gateway): def test_create_subsystem_ana(self, caplog, gateway): caplog.clear() + rc = 0 with pytest.raises(Exception) as ex: try: cli(["create_subsystem", "-n", subsystem, "-t"]) except SystemExit as sysex: # should fail with non-zero return code - assert sysex != 0 - pass + rc = sysex assert "HA enabled but ANA-reporting is disabled" in str(ex.value) + assert rc != 0 + assert "HA enabled but ANA-reporting is disabled" in caplog.text caplog.clear() cli(["create_subsystem", "-n", subsystem, "-a", "-t"]) assert f"Created subsystem {subsystem}: True" in caplog.text @@ -324,7 +402,7 @@ def test_create_listener_ana(self, caplog, listener, gateway): caplog.clear() cli(["create_listener", "-n", subsystem] + listener) assert "enable_ha: True" in caplog.text - assert "ipv4" in caplog.text + assert "ipv4" in caplog.text.lower() assert f"Created {subsystem} listener at {listener[3]}:{listener[5]}: True" in caplog.text @@ -356,7 +434,7 @@ def test_delete_subsystem_ana(self, caplog, gateway): cli(["delete_subsystem", "-n", subsystem]) assert f"Deleted subsystem {subsystem}: True" in caplog.text -class TestSDKLOg: +class TestSPDKLOg: def test_log_flags(self, caplog, gateway): caplog.clear() cli(["get_spdk_nvmf_log_flags_and_level"]) @@ -365,8 +443,8 @@ def test_log_flags(self, caplog, gateway): assert '"log_level": "NOTICE"' in caplog.text assert '"log_print_level": "INFO"' in caplog.text caplog.clear() - cli(["set_spdk_nvmf_logs", "-f"]) - assert "Set SPDK nvmf logs : True" in caplog.text + cli(["set_spdk_nvmf_logs"]) + assert "Set SPDK nvmf logs: True" in caplog.text caplog.clear() cli(["get_spdk_nvmf_log_flags_and_level"]) assert '"nvmf": true' in caplog.text @@ -374,8 +452,8 @@ def test_log_flags(self, caplog, gateway): assert '"log_level": "NOTICE"' in caplog.text assert '"log_print_level": "INFO"' in caplog.text caplog.clear() - cli(["set_spdk_nvmf_logs", "-f", "-l", "DEBUG"]) - assert "Set SPDK nvmf logs : True" in caplog.text + cli(["set_spdk_nvmf_logs", "-l", "DebuG"]) + assert "Set SPDK nvmf logs: True" in caplog.text caplog.clear() cli(["get_spdk_nvmf_log_flags_and_level"]) assert '"nvmf": true' in caplog.text @@ -383,8 +461,8 @@ def test_log_flags(self, caplog, gateway): assert '"log_level": "DEBUG"' in caplog.text assert '"log_print_level": "INFO"' in caplog.text caplog.clear() - cli(["set_spdk_nvmf_logs", "-f", "-p", "ERROR"]) - assert "Set SPDK nvmf logs : True" in caplog.text + cli(["set_spdk_nvmf_logs", "-p", "eRRor"]) + assert "Set SPDK nvmf logs: True" in caplog.text caplog.clear() cli(["get_spdk_nvmf_log_flags_and_level"]) assert '"nvmf": true' in caplog.text @@ -400,3 +478,11 @@ def test_log_flags(self, caplog, gateway): assert '"nvmf_tcp": false' in caplog.text assert '"log_level": "NOTICE"' in caplog.text assert '"log_print_level": "INFO"' in caplog.text + caplog.clear() + with pytest.raises(Exception) as ex: + try: + cli(["set_spdk_nvmf_logs", "-l", "JUNK"]) + except SystemExit as sysex: + pass + assert "Set SPDK nvmf logs: False" in str(ex.value) + assert "Set SPDK nvmf logs: False" in caplog.text