1e0493a4af57c1a73376a7bafaed542c01f588196Eric Lifrom autotest_lib.client.common_lib import error 222434d4311581dde7a3bb51eef03a27d757aa263Eric Lifrom autotest_lib.client.virt import kvm_monitor 3861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li 4e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 5e0493a4af57c1a73376a7bafaed542c01f588196Eric Lidef run_qmp_basic(test, params, env): 6e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 7e0493a4af57c1a73376a7bafaed542c01f588196Eric Li QMP Specification test-suite: this checks if the *basic* protocol conforms 8e0493a4af57c1a73376a7bafaed542c01f588196Eric Li to its specification, which is file QMP/qmp-spec.txt in QEMU's source tree. 9e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 10e0493a4af57c1a73376a7bafaed542c01f588196Eric Li IMPORTANT NOTES: 11e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 12e0493a4af57c1a73376a7bafaed542c01f588196Eric Li o Most tests depend heavily on QMP's error information (eg. classes), 13e0493a4af57c1a73376a7bafaed542c01f588196Eric Li this might have bad implications as the error interface is going to 14e0493a4af57c1a73376a7bafaed542c01f588196Eric Li change in QMP 15e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 16e0493a4af57c1a73376a7bafaed542c01f588196Eric Li o Command testing is *not* covered in this suite. Each command has its 17e0493a4af57c1a73376a7bafaed542c01f588196Eric Li own specification and should be tested separately 18e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 19e0493a4af57c1a73376a7bafaed542c01f588196Eric Li o We use the same terminology as used by the QMP specification, 20e0493a4af57c1a73376a7bafaed542c01f588196Eric Li specially with regard to JSON types (eg. a Python dict is called 21e0493a4af57c1a73376a7bafaed542c01f588196Eric Li a json-object) 22e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 23e0493a4af57c1a73376a7bafaed542c01f588196Eric Li o This is divided in sub test-suites, please check the bottom of this 24e0493a4af57c1a73376a7bafaed542c01f588196Eric Li file to check the order in which they are run 25e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 26e0493a4af57c1a73376a7bafaed542c01f588196Eric Li TODO: 27e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 28e0493a4af57c1a73376a7bafaed542c01f588196Eric Li o Finding which test failed is not as easy as it should be 29e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 30e0493a4af57c1a73376a7bafaed542c01f588196Eric Li o Are all those check_*() functions really needed? Wouldn't a 31e0493a4af57c1a73376a7bafaed542c01f588196Eric Li specialized class (eg. a Response class) do better? 32e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 33e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def fail_no_key(qmp_dict, key): 34e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if not isinstance(qmp_dict, dict): 35e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("qmp_dict is not a dict (it's '%s')" % 36e0493a4af57c1a73376a7bafaed542c01f588196Eric Li type(qmp_dict)) 37e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if not key in qmp_dict: 38e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("'%s' key doesn't exist in dict ('%s')" % 39e0493a4af57c1a73376a7bafaed542c01f588196Eric Li (key, str(qmp_dict))) 40e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 41e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 42e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_dict_key(qmp_dict, key, keytype): 43e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 44e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Performs the following checks on a QMP dict key: 45e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 46e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 1. qmp_dict is a dict 47e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 2. key exists in qmp_dict 48e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 3. key is of type keytype 49e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 50e0493a4af57c1a73376a7bafaed542c01f588196Eric Li If any of these checks fails, error.TestFail is raised. 51e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 52e0493a4af57c1a73376a7bafaed542c01f588196Eric Li fail_no_key(qmp_dict, key) 53e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if not isinstance(qmp_dict[key], keytype): 54e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("'%s' key is not of type '%s', it's '%s'" % 55e0493a4af57c1a73376a7bafaed542c01f588196Eric Li (key, keytype, type(qmp_dict[key]))) 56e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 57e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 58e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_key_is_dict(qmp_dict, key): 59e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_dict_key(qmp_dict, key, dict) 60e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 61e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 62e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_key_is_list(qmp_dict, key): 63e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_dict_key(qmp_dict, key, list) 64e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 65e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 66e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_key_is_str(qmp_dict, key): 67e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_dict_key(qmp_dict, key, unicode) 68e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 69e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 70e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_str_key(qmp_dict, keyname, value=None): 71e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_dict_key(qmp_dict, keyname, unicode) 72e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if value and value != qmp_dict[keyname]: 73e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("'%s' key value '%s' should be '%s'" % 74e0493a4af57c1a73376a7bafaed542c01f588196Eric Li (keyname, str(qmp_dict[keyname]), str(value))) 75e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 76e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 77e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_key_is_int(qmp_dict, key): 78e0493a4af57c1a73376a7bafaed542c01f588196Eric Li fail_no_key(qmp_dict, key) 79e0493a4af57c1a73376a7bafaed542c01f588196Eric Li try: 80e0493a4af57c1a73376a7bafaed542c01f588196Eric Li value = int(qmp_dict[key]) 81e0493a4af57c1a73376a7bafaed542c01f588196Eric Li except: 82e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("'%s' key is not of type int, it's '%s'" % 83e0493a4af57c1a73376a7bafaed542c01f588196Eric Li (key, type(qmp_dict[key]))) 84e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 85e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 86e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_bool_key(qmp_dict, keyname, value=None): 87e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_dict_key(qmp_dict, keyname, bool) 88e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if value and value != qmp_dict[keyname]: 89e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("'%s' key value '%s' should be '%s'" % 90e0493a4af57c1a73376a7bafaed542c01f588196Eric Li (keyname, str(qmp_dict[keyname]), str(value))) 91e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 92e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 93e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_success_resp(resp, empty=False): 94e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 95e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check QMP OK response. 96e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 97e0493a4af57c1a73376a7bafaed542c01f588196Eric Li @param resp: QMP response 98e0493a4af57c1a73376a7bafaed542c01f588196Eric Li @param empty: if True, response should not contain data to return 99e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 100e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_dict(resp, "return") 101e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if empty and len(resp["return"]) > 0: 102e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("success response is not empty ('%s')" % 103e0493a4af57c1a73376a7bafaed542c01f588196Eric Li str(resp)) 104e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 105e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 106e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def check_error_resp(resp, classname=None, datadict=None): 107e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 108e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check QMP error response. 109e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 110e0493a4af57c1a73376a7bafaed542c01f588196Eric Li @param resp: QMP response 111e0493a4af57c1a73376a7bafaed542c01f588196Eric Li @param classname: Expected error class name 112e0493a4af57c1a73376a7bafaed542c01f588196Eric Li @param datadict: Expected error data dictionary 113e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 114e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_dict(resp, "error") 115e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_str(resp["error"], "class") 116e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if classname and resp["error"]["class"] != classname: 117e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("got error class '%s' expected '%s'" % 118e0493a4af57c1a73376a7bafaed542c01f588196Eric Li (resp["error"]["class"], classname)) 119e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_dict(resp["error"], "data") 120e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if datadict and resp["error"]["data"] != datadict: 121e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("got data dict '%s' expected '%s'" % 122e0493a4af57c1a73376a7bafaed542c01f588196Eric Li (resp["error"]["data"], datadict)) 123e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 124e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 125e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_version(version): 126e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 127e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check the QMP greeting message version key which, according to QMP's 128e0493a4af57c1a73376a7bafaed542c01f588196Eric Li documentation, should be: 129e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 130e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "qemu": { "major": json-int, "minor": json-int, "micro": json-int } 131e0493a4af57c1a73376a7bafaed542c01f588196Eric Li "package": json-string } 132e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 133e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_dict(version, "qemu") 134e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for key in [ "major", "minor", "micro" ]: 135e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_int(version["qemu"], key) 136e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_str(version, "package") 137e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 138e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 139e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_greeting(greeting): 140e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_dict(greeting, "QMP") 141e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_dict(greeting["QMP"], "version") 142e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_key_is_list(greeting["QMP"], "capabilities") 143e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 144e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 145e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def greeting_suite(monitor): 146e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 147e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check the greeting message format, as described in the QMP 148e0493a4af57c1a73376a7bafaed542c01f588196Eric Li specfication section '2.2 Server Greeting'. 149e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 150e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "QMP": { "version": json-object, "capabilities": json-array } } 151e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 152e0493a4af57c1a73376a7bafaed542c01f588196Eric Li greeting = monitor.get_greeting() 153e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_greeting(greeting) 154e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_version(greeting["QMP"]["version"]) 155e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 156e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 157e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def json_parsing_errors_suite(monitor): 158e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 159e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check that QMP's parser is able to recover from parsing errors, please 160e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check the JSON spec for more info on the JSON syntax (RFC 4627). 161e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 162e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # We're quite simple right now and the focus is on parsing errors that 163e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # have already biten us in the past. 164e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # 165e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # TODO: The following test-cases are missing: 166e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # 167e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # - JSON numbers, strings and arrays 168e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # - More invalid characters or malformed structures 169e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # - Valid, but not obvious syntax, like zillion of spaces or 170e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # strings with unicode chars (different suite maybe?) 171e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json = [] 172e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 173e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # A JSON value MUST be an object, array, number, string, true, false, 174e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # or null 175e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # 176e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # NOTE: QMP seems to ignore a number of chars, like: | and ? 177e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append(":") 178e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append(",") 179e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 180e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # Malformed json-objects 181e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # 182e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # NOTE: sending only "}" seems to break QMP 183e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # NOTE: Duplicate keys are accepted (should it?) 184e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append("{ \"execute\" }") 185e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append("{ \"execute\": \"query-version\", }") 186e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append("{ 1: \"query-version\" }") 187e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append("{ true: \"query-version\" }") 188e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append("{ []: \"query-version\" }") 189e0493a4af57c1a73376a7bafaed542c01f588196Eric Li bad_json.append("{ {}: \"query-version\" }") 190e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 191e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for cmd in bad_json: 192e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_raw(cmd) 193e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "JSONParsing") 194e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 195e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 196e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_id_key(monitor): 197e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 198e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check that QMP's "id" key is correctly handled. 199e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 200e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # The "id" key must be echoed back in error responses 201861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li id_key = "kvm-autotest" 202861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li resp = monitor.cmd_qmp("eject", { "foobar": True }, id=id_key) 203e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp) 204861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li check_str_key(resp, "id", id_key) 205e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 206e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # The "id" key must be echoed back in success responses 207861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li resp = monitor.cmd_qmp("query-status", id=id_key) 208e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_success_resp(resp) 209861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li check_str_key(resp, "id", id_key) 210e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 211e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # The "id" key can be any json-object 212861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li for id_key in [ True, 1234, "string again!", [1, [], {}, True, "foo"], 213e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "key": {} } ]: 214861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li resp = monitor.cmd_qmp("query-status", id=id_key) 215e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_success_resp(resp) 216861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li if resp["id"] != id_key: 217e0493a4af57c1a73376a7bafaed542c01f588196Eric Li raise error.TestFail("expected id '%s' but got '%s'" % 218861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li (str(id_key), str(resp["id"]))) 219e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 220e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 221e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_invalid_arg_key(monitor): 222e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 223e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Currently, the only supported keys in the input object are: "execute", 224e0493a4af57c1a73376a7bafaed542c01f588196Eric Li "arguments" and "id". Although expansion is supported, invalid key 225e0493a4af57c1a73376a7bafaed542c01f588196Eric Li names must be detected. 226e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 227e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj({ "execute": "eject", "foobar": True }) 228e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "QMPExtraInputObjectMember", 229e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "member": "foobar" }) 230e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 231e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 232e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_bad_arguments_key_type(monitor): 233e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 234e0493a4af57c1a73376a7bafaed542c01f588196Eric Li The "arguments" key must be an json-object. 235e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 236e0493a4af57c1a73376a7bafaed542c01f588196Eric Li We use the eject command to perform the tests, but that's a random 237e0493a4af57c1a73376a7bafaed542c01f588196Eric Li choice, any command that accepts arguments will do, as the command 238e0493a4af57c1a73376a7bafaed542c01f588196Eric Li doesn't get called. 239e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 240e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for item in [ True, [], 1, "foo" ]: 241e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj({ "execute": "eject", "arguments": item }) 242e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "QMPBadInputObjectMember", 243e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "member": "arguments", "expected": "object" }) 244e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 245e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 246e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_bad_execute_key_type(monitor): 247e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 248e0493a4af57c1a73376a7bafaed542c01f588196Eric Li The "execute" key must be a json-string. 249e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 250e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for item in [ False, 1, {}, [] ]: 251e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj({ "execute": item }) 252e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "QMPBadInputObjectMember", 253e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "member": "execute", "expected": "string" }) 254e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 255e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 256e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_no_execute_key(monitor): 257e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 258e0493a4af57c1a73376a7bafaed542c01f588196Eric Li The "execute" key must exist, we also test for some stupid parsing 259e0493a4af57c1a73376a7bafaed542c01f588196Eric Li errors. 260e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 261e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for cmd in [ {}, { "execut": "qmp_capabilities" }, 262e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "executee": "qmp_capabilities" }, { "foo": "bar" }]: 263e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj(cmd) 264e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp) # XXX: check class and data dict? 265e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 266e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 267e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_bad_input_obj_type(monitor): 268e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 269e0493a4af57c1a73376a7bafaed542c01f588196Eric Li The input object must be... an json-object. 270e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 271e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for cmd in [ "foo", [], True, 1 ]: 272e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj(cmd) 273e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "QMPBadInputObject", { "expected":"object" }) 274e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 275e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 276e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def test_good_input_obj(monitor): 277e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 278e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Basic success tests for issuing QMP commands. 279e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 280e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # NOTE: We don't use the cmd_qmp() method here because the command 281e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # object is in a 'random' order 282e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj({ "execute": "query-version" }) 283e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_success_resp(resp) 284e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 285e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj({ "arguments": {}, "execute": "query-version" }) 286e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_success_resp(resp) 287e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 288e0493a4af57c1a73376a7bafaed542c01f588196Eric Li id = "1234foo" 289e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_obj({ "id": id, "execute": "query-version", 290e0493a4af57c1a73376a7bafaed542c01f588196Eric Li "arguments": {} }) 291e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_success_resp(resp) 292e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_str_key(resp, "id", id) 293e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 294e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # TODO: would be good to test simple argument usage, but we don't have 295e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # a read-only command that accepts arguments. 296e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 297e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 298e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def input_object_suite(monitor): 299e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 300e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check the input object format, as described in the QMP specfication 301e0493a4af57c1a73376a7bafaed542c01f588196Eric Li section '2.3 Issuing Commands'. 302e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 303e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "execute": json-string, "arguments": json-object, "id": json-value } 304e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 305e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_good_input_obj(monitor) 306e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_bad_input_obj_type(monitor) 307e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_no_execute_key(monitor) 308e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_bad_execute_key_type(monitor) 309e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_bad_arguments_key_type(monitor) 310e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_id_key(monitor) 311e0493a4af57c1a73376a7bafaed542c01f588196Eric Li test_invalid_arg_key(monitor) 312e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 313e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 314e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def argument_checker_suite(monitor): 315e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 316e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check that QMP's argument checker is detecting all possible errors. 317e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 318e0493a4af57c1a73376a7bafaed542c01f588196Eric Li We use a number of different commands to perform the checks, but the 319e0493a4af57c1a73376a7bafaed542c01f588196Eric Li command used doesn't matter much as QMP performs argument checking 320e0493a4af57c1a73376a7bafaed542c01f588196Eric Li _before_ calling the command. 321e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 322e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # stop doesn't take arguments 323e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("stop", { "foo": 1 }) 324e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "InvalidParameter", { "name": "foo" }) 325e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 326e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # required argument omitted 327e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("screendump") 328e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "MissingParameter", { "name": "filename" }) 329e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 330e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # 'bar' is not a valid argument 331e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("screendump", { "filename": "outfile", 332e0493a4af57c1a73376a7bafaed542c01f588196Eric Li "bar": "bar" }) 333e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "InvalidParameter", { "name": "bar"}) 334e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 335e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # test optional argument: 'force' is omitted, but it's optional, so 336e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # the handler has to be called. Test this happens by checking an 337e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # error that is generated by the handler itself. 338e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("eject", { "device": "foobar" }) 339e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "DeviceNotFound") 340e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 341e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # filename argument must be a json-string 342e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for arg in [ {}, [], 1, True ]: 343e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("screendump", { "filename": arg }) 344e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "InvalidParameterType", 345e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "name": "filename", "expected": "string" }) 346e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 347e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # force argument must be a json-bool 348e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for arg in [ {}, [], 1, "foo" ]: 349e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("eject", { "force": arg, "device": "foo" }) 350e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "InvalidParameterType", 351e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "name": "force", "expected": "bool" }) 352e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 353e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # val argument must be a json-int 354e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for arg in [ {}, [], True, "foo" ]: 355e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("memsave", { "val": arg, "filename": "foo", 356e0493a4af57c1a73376a7bafaed542c01f588196Eric Li "size": 10 }) 357e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "InvalidParameterType", 358e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "name": "val", "expected": "int" }) 359e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 360e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # value argument must be a json-number 361e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for arg in [ {}, [], True, "foo" ]: 362e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp("migrate_set_speed", { "value": arg }) 363e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "InvalidParameterType", 364e0493a4af57c1a73376a7bafaed542c01f588196Eric Li { "name": "value", "expected": "number" }) 365e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 366e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # qdev-type commands have their own argument checker, all QMP does 367e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # is to skip its checking and pass arguments through. Check this 368e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # works by providing invalid options to device_add and expecting 369e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # an error message from qdev 370861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li resp = monitor.cmd_qmp("device_add", { "driver": "e1000", 371861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li "foo": "bar" }) 372e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "PropertyNotFound", 373e0493a4af57c1a73376a7bafaed542c01f588196Eric Li {"device": "e1000", "property": "foo"}) 374e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 375e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 376e0493a4af57c1a73376a7bafaed542c01f588196Eric Li def unknown_commands_suite(monitor): 377e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 378e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Check that QMP handles unknown commands correctly. 379e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 380e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # We also call a HMP-only command, to be sure it will fail as expected 381e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for cmd in [ "bar", "query-", "query-foo", "q", "help" ]: 382e0493a4af57c1a73376a7bafaed542c01f588196Eric Li resp = monitor.cmd_qmp(cmd) 383e0493a4af57c1a73376a7bafaed542c01f588196Eric Li check_error_resp(resp, "CommandNotFound", { "name": cmd }) 384e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 385e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 386861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li vm = env.get_vm(params["main_vm"]) 387861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li vm.verify_alive() 388861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li 389861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li # Look for the first qmp monitor available, otherwise, fail the test 390861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li qmp_monitor = None 391861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li for m in vm.monitors: 392861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li if isinstance(m, kvm_monitor.QMPMonitor): 393861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li qmp_monitor = m 394861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li 395861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li if qmp_monitor is None: 396861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li raise error.TestError('Could not find a QMP monitor, aborting test') 397e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 398e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # Run all suites 399861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li greeting_suite(qmp_monitor) 400861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li input_object_suite(qmp_monitor) 401861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li argument_checker_suite(qmp_monitor) 402861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li unknown_commands_suite(qmp_monitor) 403861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li json_parsing_errors_suite(qmp_monitor) 404e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 405e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # check if QMP is still alive 406861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li if not qmp_monitor.is_responsive(): 407861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li raise error.TestFail('QMP monitor is not responsive after testing') 408