{"action":"created","comment":{"url":"https://api.github.com/repos/autotest/tp-qemu/pulls/comments/242413668","pull_request_review_id":185915104,"id":242413668,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MjQxMzY2OA==","diff_hunk":"@@ -19,167 +21,127 @@ def run(test, params, env):\n     :param params: Dictionary with the test parameters\n     :param env: Dictionary with test environmen.\n     \"\"\"\n-    def check_result(qmp_o, output=None, exception_list=\"\"):\n+\n+    def check_list(qmp_o, key, val=None, check_item_in_pair=True):\n+        \"\"\"\n+        Check if the expect key, val are contained in QMP output qmp_o.\n+\n+        :param qmp_o: output of QMP command\n+        :type qmp_o: list\n+        :param key: expect result\n+        :type key: str\n+        :param val: expect result\n+        :type val: str or None(if check_item_in_pair=False)\n+        :param check_item_in_pair: If expect result is dict (True) or str (False)\n+        :type check_item_in_pair: bool.\n+\n+        :return check result\n+        :rtype: bool\n+        \"\"\"\n+        for element in qmp_o:\n+            if isinstance(element, dict):\n+                if _check_dict(element, key, val, check_item_in_pair):\n+                    return True\n+            elif isinstance(element, list):\n+                if check_list(element, key, val, check_item_in_pair):\n+                    return True\n+            elif element != '' and not check_item_in_pair:\n+                if strict_match:\n+                    if operator.eq(key, element):\n+                        return True\n+                else:\n+                    if key in str(element):\n+                        return True\n+        return False\n+\n+    def _check_dict(dic, key, val, check_item_in_pair=True):\n+        \"\"\"\n+        Check if the expect key, val are contained in QMP output dic.\n+\n+        :param dic: content of QMP command return value\n+        :type dic: dict\n+        :param key: expect result\n+        :type key: str\n+        :param val: expect result\n+        :type val: str or None(if check_item_in_pair=False)\n+        :param check_item_in_pair: If expect result is dict or str\n+        :type check_item_in_pair: bool. Means expect result is dict or str.\n+\n+        :return check result\n+        :rtype: bool\n+        \"\"\"\n+        if key in dic and not check_item_in_pair:\n+            return True\n+        elif key in dic and val == dic[key]:\n+            return True\n+        else:\n+            for value in dic.values():\n+                if isinstance(value, dict):\n+                    if _check_dict(value, key, val, check_item_in_pair):\n+                        return True\n+                elif isinstance(value, list):\n+                    if check_list(value, key, val, check_item_in_pair):\n+                        return True\n+                elif value != '' and not check_item_in_pair:\n+                    if strict_match:\n+                        if operator.eq(key, value):\n+                            return True\n+                    else:\n+                        if key in str(value):\n+                            return True\n+            return False\n+\n+    def check_result(qmp_o, expect_o=None, exception_list=\"\"):\n         \"\"\"\n-        Check test result with difference way accoriding to\n-        result_check.\n-        result_check = equal, will compare cmd_return_value with qmp\n-                       command output.\n-        result_check = contain, will try to find cmd_return_value in qmp\n-                       command output.\n-        result_check = m_equal_q, will compare key value in monitor command\n-                       output and qmp command output.\n-        result_check = m_in_q, will try to find monitor command output's key\n-                       value in qmp command output.\n-        result_check = m_format_q, will try to match the output's format with\n-                       check pattern.\n+        Check test result with difference way according to result_check.\n+        result_check = equal, expect_o should equal to qmp_o.\n+        result_check = contain, expect_o should be contained in qmp_o\n+        result_check = not_contain, expect_o should not be contained in qmp_o.\n \n         :param qmp_o: output from pre_cmd, qmp_cmd or post_cmd.\n-        :param o: output from pre_cmd, qmp_cmd or post_cmd or an execpt\n-        :param exception_list: element no need check.\n-        result set in config file.\n+        :type qmp_o: list\n+        :param expect_o: the expect result.\n+        :type expect_o: list\n+        :param exception_list: element no need to check.\n+        :type exception_list: list\n         \"\"\"\n+        logging.info(\"Expect result is %s\" % expect_o)\n+        logging.info(\"Actual result that get from qmp command is %s\" % qmp_o)\n         if result_check == \"equal\":\n-            value = output\n-            if value != str(qmp_o):\n-                test.fail(\"QMP command return value does not match \"\n-                          \"the expect result. Expect result: '%s'\\n\"\n-                          \"Actual result: '%s'\" % (value, qmp_o))\n+            if not operator.eq(qmp_o, expect_o):\n+                test.fail(\"QMP output does not equal to the expect result.\\n \"\n+                          \"Expect result: '%s'\\n\"\n+                          \"Actual result: '%s'\" % (expect_o, qmp_o))\n         elif result_check == \"contain\":\n-            values = output.split(';')\n-            for value in values:\n-                if value in exception_list:\n-                    continue\n-                if value.strip() not in str(qmp_o):\n-                    test.fail(\"QMP command output does not contain \"\n-                              \"expect result. Expect result: '%s'\\n\"\n-                              \"Actual result: '%s'\" % (value, qmp_o))\n-        elif result_check == \"not_contain\":\n-            values = output.split(';')\n-            for value in values:\n-                if value in exception_list:\n-                    continue\n-                if value in str(qmp_o):\n-                    test.fail(\"QMP command output contains unexpect\"\n-                              \" result. Unexpect result: '%s'\\n\"\n-                              \"Actual result: '%s'\" % (value, qmp_o))\n-        elif result_check == \"m_equal_q\":\n-            msg = \"QMP command ouput is not equal to in human monitor command.\"\n-            msg += \"\\nQMP command output: '%s'\" % qmp_o\n-            msg += \"\\nHuman command output: '%s'\" % output\n-            res = output.splitlines(True)\n-            if type(qmp_o) != type(res):\n-                len_o = 1\n-            else:\n-                len_o = len(qmp_o)\n-            if len(res) != len_o:\n-                if res[0].startswith(' '):\n-                    test.fail(\"Human command starts with ' ', \"\n-                              \"there is probably some garbage in \"\n-                              \"the output.\\n\" + msg)\n-                res_tmp = []\n-                #(qemu)info block in RHEL7 divided into 3 lines\n-                for line in res:\n-                    if not line.startswith(' '):\n-                        res_tmp.append(line)\n-                    else:\n-                        res_tmp[-1] += line\n-                res = res_tmp\n-                if len(res) != len_o:\n-                    test.fail(msg)\n-            re_str = r'([^ \\t\\n\\r\\f\\v=]*)=([^ \\t\\n\\r\\f\\v=]*)'\n-            for i in range(len(res)):\n-                if qmp_cmd == \"query-version\":\n-                    version = qmp_o['qemu']\n-                    version = \"%s.%s.%s\" % (version['major'], version['minor'],\n-                                            version['micro'])\n-                    package = qmp_o['package']\n-                    re_str = r\"([0-9]+\\.[0-9]+\\.[0-9]+)\\s*(\\(\\S*\\))?\"\n-                    hmp_version, hmp_package = re.findall(re_str, res[i])[0]\n-                    if not hmp_package:\n-                        hmp_package = package\n-                    hmp_package = hmp_package.strip()\n-                    package = package.strip()\n-                    hmp_version = hmp_version.strip()\n-                    if version != hmp_version or package != hmp_package:\n-                        test.fail(msg)\n+            for o in expect_o:\n+                if isinstance(o, dict):\n+                    for key, val in o.items():\n+                        result = check_list(qmp_o, key, val)\n+                        if not result:\n+                            break\n+                elif isinstance(o, str):\n+                    result = check_list(qmp_o, o, check_item_in_pair=False)\n+\n+                if result:\n+                    logging.info(\"QMP output contain the expect value %s\" % o)\n                 else:\n-                    matches = re.findall(re_str, res[i])\n-                    for key, val in matches:\n-                        if key in exception_list:\n-                            continue\n-                        if '0x' in val:\n-                            val = int(val, 16)\n-                            val_str = str(bin(val))\n-                            com_str = \"\"\n-                            for p in range(3, len(val_str)):\n-                                if val_str[p] == '1':\n-                                    com_str += '0'\n-                                else:\n-                                    com_str += '1'\n-                            com_str = \"0b\" + com_str\n-                            value = eval(com_str) + 1\n-                            if val_str[2] == '1':\n-                                value = -value\n-                            if value != qmp_o[i][key]:\n-                                msg += \"\\nValue in human monitor: '%s'\" % value\n-                                msg += \"\\nValue in qmp: '%s'\" % qmp_o[i][key]\n-                                test.fail(msg)\n-                        elif qmp_cmd == \"query-block\":\n-                            cmp_str = \"u'%s': u'%s'\" % (key, val)\n-                            cmp_s = \"u'%s': %s\" % (key, val)\n-                            if '0' == val:\n-                                cmp_str_b = \"u'%s': False\" % key\n-                            elif '1' == val:\n-                                cmp_str_b = \"u'%s': True\" % key\n-                            else:\n-                                cmp_str_b = cmp_str\n-                            if (cmp_str not in str(qmp_o[i]) and\n-                                    cmp_str_b not in str(qmp_o[i]) and\n-                                    cmp_s not in str(qmp_o[i])):\n-                                msg += (\"\\nCan not find '%s', '%s' or '%s' in \"\n-                                        \" QMP command output.\"\n-                                        % (cmp_s, cmp_str_b, cmp_str))\n-                                test.fail(msg)\n-                        elif qmp_cmd == \"query-balloon\":\n-                            if (int(val) * 1024 * 1024 != qmp_o[key] and\n-                                    val not in str(qmp_o[key])):\n-                                msg += (\"\\n'%s' is not in QMP command output\"\n-                                        % val)\n-                                test.fail(msg)\n-                        else:\n-                            if (val not in str(qmp_o[i][key]) and\n-                                    str(bool(int(val))) not in str(qmp_o[i][key])):\n-                                msg += (\"\\n'%s' is not in QMP command output\"\n-                                        % val)\n-                                test.fail(msg)\n-        elif result_check == \"m_in_q\":\n-            res = output.splitlines(True)\n-            msg = \"Key value from human monitor command is not in\"\n-            msg += \"QMP command output.\\nQMP command output: '%s'\" % qmp_o\n-            msg += \"\\nHuman monitor command output '%s'\" % output\n-            for i in range(len(res)):\n-                params = res[i].rstrip().split()\n-                for param in params:\n-                    if param.rstrip() in exception_list:\n-                        continue\n-                    try:\n-                        str_o = str(qmp_o.values())\n-                    except AttributeError:\n-                        str_o = qmp_o\n-                    if param.rstrip() not in str(str_o):\n-                        msg += \"\\nKey value is '%s'\" % param.rstrip()\n-                        test.fail(msg)\n-        elif result_check == \"m_format_q\":\n-            match_flag = True\n-            for i in qmp_o:\n-                if output is None:\n-                    test.error(\"QMP output pattern is missing\")\n-                if re.match(output.strip(), str(i)) is None:\n-                    match_flag = False\n-            if not match_flag:\n-                msg = \"Output does not match the pattern: '%s'\" % output\n-                test.fail(msg)\n+                    test.fail(\"QMP output does not contain the expect value.\\n\"\n+                              \"Missed expect value: '%s'\\n\"\n+                              \"Actual result: '%s'\\n\" % (o, qmp_o))\n+        elif result_check == \"not_contain\":\n+            for o in expect_o:\n+                if isinstance(o, dict):\n+                    for key, val in o.items():\n+                        result = check_list(qmp_o, key, val)\n+                        if result:","path":"qemu/tests/qmp_command.py","position":279,"original_position":279,"commit_id":"2116e3451e1bd1fb46df37c289466ac720421544","original_commit_id":"2116e3451e1bd1fb46df37c289466ac720421544","user":{"login":"yanan-fu","id":14147258,"node_id":"MDQ6VXNlcjE0MTQ3MjU4","avatar_url":"https://avatars1.githubusercontent.com/u/14147258?v=4","gravatar_id":"","url":"https://api.github.com/users/yanan-fu","html_url":"https://github.com/yanan-fu","followers_url":"https://api.github.com/users/yanan-fu/followers","following_url":"https://api.github.com/users/yanan-fu/following{/other_user}","gists_url":"https://api.github.com/users/yanan-fu/gists{/gist_id}","starred_url":"https://api.github.com/users/yanan-fu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yanan-fu/subscriptions","organizations_url":"https://api.github.com/users/yanan-fu/orgs","repos_url":"https://api.github.com/users/yanan-fu/repos","events_url":"https://api.github.com/users/yanan-fu/events{/privacy}","received_events_url":"https://api.github.com/users/yanan-fu/received_events","type":"User","site_admin":false},"body":"No, this method can not work,  since `alter=False` for `contain`,  `result and alter` always get `False`, this is not the expect result.","created_at":"2018-12-18T05:52:06Z","updated_at":"2018-12-18T05:52:07Z","html_url":"https://github.com/autotest/tp-qemu/pull/1568#discussion_r242413668","pull_request_url":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/autotest/tp-qemu/pulls/comments/242413668"},"html":{"href":"https://github.com/autotest/tp-qemu/pull/1568#discussion_r242413668"},"pull_request":{"href":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568"}},"in_reply_to_id":242399649},"pull_request":{"url":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568","id":232571195,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMyNTcxMTk1","html_url":"https://github.com/autotest/tp-qemu/pull/1568","diff_url":"https://github.com/autotest/tp-qemu/pull/1568.diff","patch_url":"https://github.com/autotest/tp-qemu/pull/1568.patch","issue_url":"https://api.github.com/repos/autotest/tp-qemu/issues/1568","number":1568,"state":"open","locked":false,"title":"qmp_command: Improve the test","user":{"login":"yanan-fu","id":14147258,"node_id":"MDQ6VXNlcjE0MTQ3MjU4","avatar_url":"https://avatars1.githubusercontent.com/u/14147258?v=4","gravatar_id":"","url":"https://api.github.com/users/yanan-fu","html_url":"https://github.com/yanan-fu","followers_url":"https://api.github.com/users/yanan-fu/followers","following_url":"https://api.github.com/users/yanan-fu/following{/other_user}","gists_url":"https://api.github.com/users/yanan-fu/gists{/gist_id}","starred_url":"https://api.github.com/users/yanan-fu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yanan-fu/subscriptions","organizations_url":"https://api.github.com/users/yanan-fu/orgs","repos_url":"https://api.github.com/users/yanan-fu/repos","events_url":"https://api.github.com/users/yanan-fu/events{/privacy}","received_events_url":"https://api.github.com/users/yanan-fu/received_events","type":"User","site_admin":false},"body":"1. Replace hmp command with qmp, as hmp is deprecated.\r\n2. Remove three meaningless cases that compare the output of hmp\r\n   and qmp:  qmp_query-chardev, qmp_query-cpus, qmp_query-balloon\r\n\r\nid: 1611123\r\nSigned-off-by: Yanan Fu <yfu@redhat.com>","created_at":"2018-11-21T08:08:28Z","updated_at":"2018-12-18T05:52:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"709b213881168578f302982b6145295c6d92f50a","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568/commits","review_comments_url":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568/comments","review_comment_url":"https://api.github.com/repos/autotest/tp-qemu/pulls/comments{/number}","comments_url":"https://api.github.com/repos/autotest/tp-qemu/issues/1568/comments","statuses_url":"https://api.github.com/repos/autotest/tp-qemu/statuses/2116e3451e1bd1fb46df37c289466ac720421544","head":{"label":"yanan-fu:qmp_command","ref":"qmp_command","sha":"2116e3451e1bd1fb46df37c289466ac720421544","user":{"login":"yanan-fu","id":14147258,"node_id":"MDQ6VXNlcjE0MTQ3MjU4","avatar_url":"https://avatars1.githubusercontent.com/u/14147258?v=4","gravatar_id":"","url":"https://api.github.com/users/yanan-fu","html_url":"https://github.com/yanan-fu","followers_url":"https://api.github.com/users/yanan-fu/followers","following_url":"https://api.github.com/users/yanan-fu/following{/other_user}","gists_url":"https://api.github.com/users/yanan-fu/gists{/gist_id}","starred_url":"https://api.github.com/users/yanan-fu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yanan-fu/subscriptions","organizations_url":"https://api.github.com/users/yanan-fu/orgs","repos_url":"https://api.github.com/users/yanan-fu/repos","events_url":"https://api.github.com/users/yanan-fu/events{/privacy}","received_events_url":"https://api.github.com/users/yanan-fu/received_events","type":"User","site_admin":false},"repo":{"id":62797814,"node_id":"MDEwOlJlcG9zaXRvcnk2Mjc5NzgxNA==","name":"tp-qemu","full_name":"yanan-fu/tp-qemu","private":false,"owner":{"login":"yanan-fu","id":14147258,"node_id":"MDQ6VXNlcjE0MTQ3MjU4","avatar_url":"https://avatars1.githubusercontent.com/u/14147258?v=4","gravatar_id":"","url":"https://api.github.com/users/yanan-fu","html_url":"https://github.com/yanan-fu","followers_url":"https://api.github.com/users/yanan-fu/followers","following_url":"https://api.github.com/users/yanan-fu/following{/other_user}","gists_url":"https://api.github.com/users/yanan-fu/gists{/gist_id}","starred_url":"https://api.github.com/users/yanan-fu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yanan-fu/subscriptions","organizations_url":"https://api.github.com/users/yanan-fu/orgs","repos_url":"https://api.github.com/users/yanan-fu/repos","events_url":"https://api.github.com/users/yanan-fu/events{/privacy}","received_events_url":"https://api.github.com/users/yanan-fu/received_events","type":"User","site_admin":false},"html_url":"https://github.com/yanan-fu/tp-qemu","description":"Virt Test Provider for qemu and other related virtualization backends","fork":true,"url":"https://api.github.com/repos/yanan-fu/tp-qemu","forks_url":"https://api.github.com/repos/yanan-fu/tp-qemu/forks","keys_url":"https://api.github.com/repos/yanan-fu/tp-qemu/keys{/key_id}","collaborators_url":"https://api.github.com/repos/yanan-fu/tp-qemu/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/yanan-fu/tp-qemu/teams","hooks_url":"https://api.github.com/repos/yanan-fu/tp-qemu/hooks","issue_events_url":"https://api.github.com/repos/yanan-fu/tp-qemu/issues/events{/number}","events_url":"https://api.github.com/repos/yanan-fu/tp-qemu/events","assignees_url":"https://api.github.com/repos/yanan-fu/tp-qemu/assignees{/user}","branches_url":"https://api.github.com/repos/yanan-fu/tp-qemu/branches{/branch}","tags_url":"https://api.github.com/repos/yanan-fu/tp-qemu/tags","blobs_url":"https://api.github.com/repos/yanan-fu/tp-qemu/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/yanan-fu/tp-qemu/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/yanan-fu/tp-qemu/git/refs{/sha}","trees_url":"https://api.github.com/repos/yanan-fu/tp-qemu/git/trees{/sha}","statuses_url":"https://api.github.com/repos/yanan-fu/tp-qemu/statuses/{sha}","languages_url":"https://api.github.com/repos/yanan-fu/tp-qemu/languages","stargazers_url":"https://api.github.com/repos/yanan-fu/tp-qemu/stargazers","contributors_url":"https://api.github.com/repos/yanan-fu/tp-qemu/contributors","subscribers_url":"https://api.github.com/repos/yanan-fu/tp-qemu/subscribers","subscription_url":"https://api.github.com/repos/yanan-fu/tp-qemu/subscription","commits_url":"https://api.github.com/repos/yanan-fu/tp-qemu/commits{/sha}","git_commits_url":"https://api.github.com/repos/yanan-fu/tp-qemu/git/commits{/sha}","comments_url":"https://api.github.com/repos/yanan-fu/tp-qemu/comments{/number}","issue_comment_url":"https://api.github.com/repos/yanan-fu/tp-qemu/issues/comments{/number}","contents_url":"https://api.github.com/repos/yanan-fu/tp-qemu/contents/{+path}","compare_url":"https://api.github.com/repos/yanan-fu/tp-qemu/compare/{base}...{head}","merges_url":"https://api.github.com/repos/yanan-fu/tp-qemu/merges","archive_url":"https://api.github.com/repos/yanan-fu/tp-qemu/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/yanan-fu/tp-qemu/downloads","issues_url":"https://api.github.com/repos/yanan-fu/tp-qemu/issues{/number}","pulls_url":"https://api.github.com/repos/yanan-fu/tp-qemu/pulls{/number}","milestones_url":"https://api.github.com/repos/yanan-fu/tp-qemu/milestones{/number}","notifications_url":"https://api.github.com/repos/yanan-fu/tp-qemu/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/yanan-fu/tp-qemu/labels{/name}","releases_url":"https://api.github.com/repos/yanan-fu/tp-qemu/releases{/id}","deployments_url":"https://api.github.com/repos/yanan-fu/tp-qemu/deployments","created_at":"2016-07-07T10:18:42Z","updated_at":"2018-11-21T09:43:23Z","pushed_at":"2018-12-13T11:33:57Z","git_url":"git://github.com/yanan-fu/tp-qemu.git","ssh_url":"git@github.com:yanan-fu/tp-qemu.git","clone_url":"https://github.com/yanan-fu/tp-qemu.git","svn_url":"https://github.com/yanan-fu/tp-qemu","homepage":null,"size":35454,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"autotest:master","ref":"master","sha":"fcd34de5c8c814bb5002fca6712aaaed597e66c5","user":{"login":"autotest","id":472856,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQ3Mjg1Ng==","avatar_url":"https://avatars1.githubusercontent.com/u/472856?v=4","gravatar_id":"","url":"https://api.github.com/users/autotest","html_url":"https://github.com/autotest","followers_url":"https://api.github.com/users/autotest/followers","following_url":"https://api.github.com/users/autotest/following{/other_user}","gists_url":"https://api.github.com/users/autotest/gists{/gist_id}","starred_url":"https://api.github.com/users/autotest/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/autotest/subscriptions","organizations_url":"https://api.github.com/users/autotest/orgs","repos_url":"https://api.github.com/users/autotest/repos","events_url":"https://api.github.com/users/autotest/events{/privacy}","received_events_url":"https://api.github.com/users/autotest/received_events","type":"Organization","site_admin":false},"repo":{"id":16180304,"node_id":"MDEwOlJlcG9zaXRvcnkxNjE4MDMwNA==","name":"tp-qemu","full_name":"autotest/tp-qemu","private":false,"owner":{"login":"autotest","id":472856,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQ3Mjg1Ng==","avatar_url":"https://avatars1.githubusercontent.com/u/472856?v=4","gravatar_id":"","url":"https://api.github.com/users/autotest","html_url":"https://github.com/autotest","followers_url":"https://api.github.com/users/autotest/followers","following_url":"https://api.github.com/users/autotest/following{/other_user}","gists_url":"https://api.github.com/users/autotest/gists{/gist_id}","starred_url":"https://api.github.com/users/autotest/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/autotest/subscriptions","organizations_url":"https://api.github.com/users/autotest/orgs","repos_url":"https://api.github.com/users/autotest/repos","events_url":"https://api.github.com/users/autotest/events{/privacy}","received_events_url":"https://api.github.com/users/autotest/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/autotest/tp-qemu","description":"Virt Test Provider for qemu and other related virtualization backends","fork":false,"url":"https://api.github.com/repos/autotest/tp-qemu","forks_url":"https://api.github.com/repos/autotest/tp-qemu/forks","keys_url":"https://api.github.com/repos/autotest/tp-qemu/keys{/key_id}","collaborators_url":"https://api.github.com/repos/autotest/tp-qemu/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/autotest/tp-qemu/teams","hooks_url":"https://api.github.com/repos/autotest/tp-qemu/hooks","issue_events_url":"https://api.github.com/repos/autotest/tp-qemu/issues/events{/number}","events_url":"https://api.github.com/repos/autotest/tp-qemu/events","assignees_url":"https://api.github.com/repos/autotest/tp-qemu/assignees{/user}","branches_url":"https://api.github.com/repos/autotest/tp-qemu/branches{/branch}","tags_url":"https://api.github.com/repos/autotest/tp-qemu/tags","blobs_url":"https://api.github.com/repos/autotest/tp-qemu/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/autotest/tp-qemu/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/autotest/tp-qemu/git/refs{/sha}","trees_url":"https://api.github.com/repos/autotest/tp-qemu/git/trees{/sha}","statuses_url":"https://api.github.com/repos/autotest/tp-qemu/statuses/{sha}","languages_url":"https://api.github.com/repos/autotest/tp-qemu/languages","stargazers_url":"https://api.github.com/repos/autotest/tp-qemu/stargazers","contributors_url":"https://api.github.com/repos/autotest/tp-qemu/contributors","subscribers_url":"https://api.github.com/repos/autotest/tp-qemu/subscribers","subscription_url":"https://api.github.com/repos/autotest/tp-qemu/subscription","commits_url":"https://api.github.com/repos/autotest/tp-qemu/commits{/sha}","git_commits_url":"https://api.github.com/repos/autotest/tp-qemu/git/commits{/sha}","comments_url":"https://api.github.com/repos/autotest/tp-qemu/comments{/number}","issue_comment_url":"https://api.github.com/repos/autotest/tp-qemu/issues/comments{/number}","contents_url":"https://api.github.com/repos/autotest/tp-qemu/contents/{+path}","compare_url":"https://api.github.com/repos/autotest/tp-qemu/compare/{base}...{head}","merges_url":"https://api.github.com/repos/autotest/tp-qemu/merges","archive_url":"https://api.github.com/repos/autotest/tp-qemu/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/autotest/tp-qemu/downloads","issues_url":"https://api.github.com/repos/autotest/tp-qemu/issues{/number}","pulls_url":"https://api.github.com/repos/autotest/tp-qemu/pulls{/number}","milestones_url":"https://api.github.com/repos/autotest/tp-qemu/milestones{/number}","notifications_url":"https://api.github.com/repos/autotest/tp-qemu/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/autotest/tp-qemu/labels{/name}","releases_url":"https://api.github.com/repos/autotest/tp-qemu/releases{/id}","deployments_url":"https://api.github.com/repos/autotest/tp-qemu/deployments","created_at":"2014-01-23T17:51:34Z","updated_at":"2018-12-18T05:12:55Z","pushed_at":"2018-12-18T05:48:36Z","git_url":"git://github.com/autotest/tp-qemu.git","ssh_url":"git@github.com:autotest/tp-qemu.git","clone_url":"https://github.com/autotest/tp-qemu.git","svn_url":"https://github.com/autotest/tp-qemu","homepage":null,"size":35552,"stargazers_count":21,"watchers_count":21,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":124,"mirror_url":null,"archived":false,"open_issues_count":64,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":124,"open_issues":64,"watchers":21,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568"},"html":{"href":"https://github.com/autotest/tp-qemu/pull/1568"},"issue":{"href":"https://api.github.com/repos/autotest/tp-qemu/issues/1568"},"comments":{"href":"https://api.github.com/repos/autotest/tp-qemu/issues/1568/comments"},"review_comments":{"href":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568/comments"},"review_comment":{"href":"https://api.github.com/repos/autotest/tp-qemu/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/autotest/tp-qemu/pulls/1568/commits"},"statuses":{"href":"https://api.github.com/repos/autotest/tp-qemu/statuses/2116e3451e1bd1fb46df37c289466ac720421544"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"yanan-fu"}}