{"action":"created","comment":{"url":"https://api.github.com/repos/rancherio/validation-tests/pulls/comments/28079575","id":28079575,"diff_hunk":"@@ -0,0 +1,277 @@\n+from common_fixtures import *  # NOQA\n+import traceback\n+import logging\n+\n+DEFAULT_TIMEOUT = 450\n+\n+# Digital Ocean configurations\n+access_key = os.environ.get('DIGITALOCEAN_KEY')\n+image_name = \"ubuntu-14-10-x64\"\n+region = \"sfo1\"\n+size = \"2gb\"\n+\n+# Digital Ocean default configurations\n+default_size = \"512mb\"\n+default_image_name = \"ubuntu-14-04-x64\"\n+default_region = \"nyc3\"\n+\n+\n+# Digital Ocean Error Messages\n+error_msg_auth_failure = \"401\"\n+\n+error_msg_invalid_region = \"Error creating machine: \" \\\n+                           \"digitalocean requires a valid region\"\n+\n+\n+if_machine_digocean = pytest.mark.skipif(\n+    os.environ.get('DIGITALOCEAN_KEY') is None,\n+    reason='DIGITALOCEAN_KEY is not set')\n+\n+# Get logger\n+logger = logging.getLogger(__name__)\n+\n+\n+@if_machine_digocean\n+def test_digital_ocean_machine_all_params(client):\n+\n+    name = random_str()\n+    create_args = {\"name\": name,\n+                   \"digitaloceanConfig\": {\"accessToken\": access_key,\n+                                          \"image\": image_name,\n+                                          \"region\": region,\n+                                          \"size\": size\n+                                          }\n+                   }\n+\n+    expected_values = {\"image\": image_name,\n+                       \"region\": region,\n+                       \"size\": size\n+                       }\n+    try:\n+        digital_ocean_machine_life_cycle(client, create_args, expected_values)\n+    finally:\n+        delete_host_in_digital_ocean(name)\n+\n+\n+@if_machine_digocean\n+def test_digital_ocean_machine_accesstoken(client):\n+\n+    name = random_str()\n+    create_args = {\"name\": random_str(),\n+                   \"digitaloceanConfig\": {\"accessToken\": access_key,\n+                                          }\n+                   }\n+\n+    expected_values = {\"image\": default_image_name,\n+                       \"region\": default_region,\n+                       \"size\": default_size\n+                       }\n+    try:\n+        digital_ocean_machine_life_cycle(client, create_args, expected_values)\n+    finally:\n+        delete_host_in_digital_ocean(name)\n+\n+\n+@if_machine_digocean\n+def test_digital_ocean_machine_parallel(client):\n+    create_args = {\"name\": random_str(),\n+                   \"digitaloceanConfig\": {\"accessToken\": access_key,\n+                                          \"image\": image_name,\n+                                          \"region\": region,\n+                                          \"size\": size\n+                                          }\n+                   }\n+    machines = []\n+    try:\n+        # Create 2 Digital Ocean Machines in parallel\n+        for n in range(0, 2):\n+            name = random_str() + \"-parallel-\" + str(n)\n+            create_args[\"name\"] = name\n+            machine = client.create_machine(**create_args)\n+            machines.append(machine)\n+\n+        # Check if both the machine and host get to \"active\" state\n+\n+        for machine in machines:\n+            machine = client.wait_success(machine, timeout=DEFAULT_TIMEOUT)\n+            assert machine.state == 'active'\n+            machine = wait_for_host(client, machine)\n+            host = machine.hosts()[0]\n+            assert host.state == 'active'\n+\n+        for machine in machines:\n+            machine = client.wait_success(machine.remove())\n+            assert machine.state == 'removed'\n+\n+            host = machine.hosts()[0]\n+            assert host.state == 'removed'\n+            wait_for_host_destroy_in_digital_ocean(\n+                host.ipAddresses()[0].address)\n+    finally:\n+        for machine in machines:\n+            delete_host_in_digital_ocean(machine.name)\n+\n+\n+@if_machine_digocean\n+def test_digital_ocean_machine_invalid_access_token(client):\n+\n+    name = random_str()\n+    create_args = {\"name\": name,\n+                   \"digitaloceanConfig\": {\"accessToken\": \"1234abcdefg\",\n+                                          \"image\": image_name,\n+                                          \"region\": region,\n+                                          \"size\": size\n+                                          }\n+                   }\n+    # Create a Digital Ocean Machine with invalid access token\n+    machine = client.create_machine(**create_args)\n+    machine = wait_for_condition(client,\n+                                 machine,\n+                                 lambda x: x.state == 'error',\n+                                 lambda x: 'Machine state is ' + x.state\n+                                 )\n+    assert error_msg_auth_failure in machine.transitioningMessage\n+\n+    hosts = machine.hosts()\n+    assert len(hosts) == 0\n+\n+    machine = client.wait_success(machine.remove())\n+    assert machine.state == 'removed'\n+\n+\n+@if_machine_digocean\n+def test_digital_ocean_machine_invalid_region(client):\n+\n+    name = random_str()\n+    create_args = {\"name\": name,\n+                   \"digitaloceanConfig\": {\"accessToken\": access_key,\n+                                          \"image\": image_name,\n+                                          \"region\": \"abc\",\n+                                          \"size\": size\n+                                          }\n+                   }\n+    # Create a Digital Ocean Machine with invalid access token\n+    machine = client.create_machine(**create_args)\n+\n+    machine = wait_for_condition(client,\n+                                 machine,\n+                                 lambda x: x.state == 'error',\n+                                 lambda x: 'Machine state is ' + x.state\n+                                 )\n+\n+    assert error_msg_invalid_region in machine.transitioningMessage\n+\n+    hosts = machine.hosts()\n+    assert len(hosts) == 0\n+\n+    machine = client.wait_success(machine.remove())\n+    assert machine.state == 'removed'\n+\n+\n+def digital_ocean_machine_life_cycle(client, configs, expected_values):\n+\n+    # Create a Digital Ocean Machine\n+    machine = client.create_machine(**configs)\n+\n+    machine = client.wait_success(machine, timeout=DEFAULT_TIMEOUT)\n+    assert machine.state == 'active'\n+\n+    # Wait until host shows up with some physicalHostId\n+    machine = wait_for_host(client, machine)\n+    host = machine.hosts()[0]\n+    assert host.state == 'active'\n+    assert machine.accountId == host.accountId\n+\n+    # Check that the droplet that is being created in Digital Ocean has the\n+    # correct configurations\n+\n+    droplet = check_host_in_digital_ocean(host.ipAddresses()[0].address)\n+\n+    assert droplet is not None\n+    assert droplet[\"name\"] == machine.name\n+    assert droplet[\"image\"][\"slug\"] == expected_values[\"image\"]\n+    assert droplet[\"size_slug\"] == expected_values[\"size\"]\n+    assert droplet[\"region\"][\"slug\"] == expected_values[\"region\"]\n+\n+    # Remove the machine and make sure that the host\n+    # and the machine get removed\n+\n+    machine = client.wait_success(machine.remove())\n+    assert machine.state == 'removed'\n+\n+    host = client.reload(machine.hosts()[0])\n+    assert host.state == 'removed'\n+\n+    wait_for_host_destroy_in_digital_ocean(host.ipAddresses()[0].address)\n+\n+\n+def wait_for_host(client, machine):\n+    wait_for_condition(client,\n+                       machine,\n+                       lambda x: len(x.hosts()) == 1,\n+                       lambda x: 'Number of hosts associated with machine ' +\n+                                 str(len(x.hosts())),\n+                       DEFAULT_TIMEOUT)\n+\n+    host = machine.hosts()[0]\n+    host = wait_for_condition(client,\n+                              host,\n+                              lambda x: x.state == 'active',\n+                              lambda x: 'Host state is ' + x.state\n+                              )\n+    return machine\n+\n+\n+def check_host_in_digital_ocean(ipaddress):\n+    url = 'https://api.digitalocean.com/v2/droplets'\n+    headers = {'Authorization': \"Bearer \" + access_key}\n+    r = requests.get(url, headers=headers)\n+    response = r.json()\n+    r.close()\n+    droplet_list = response[\"droplets\"]\n+    matched_droplet = None\n+\n+    for droplet in droplet_list:\n+        if droplet[\"networks\"][\"v4\"][0][\"ip_address\"] == ipaddress:\n+            matched_droplet = droplet\n+            break\n+\n+    return matched_droplet\n+\n+\n+def delete_host_in_digital_ocean(name):\n+    try:\n+        url = 'https://api.digitalocean.com/v2/droplets'\n+        headers = {'Authorization': \"Bearer \" + access_key}\n+        r = requests.get(url, headers=headers)\n+        response = r.json()\n+        r.close()\n+        droplet_list = response[\"droplets\"]\n+\n+        for droplet in droplet_list:\n+            if droplet[\"name\"] == name:\n+                url = 'https://api.digitalocean.com/v2/droplets/' + \\\n+                      str(droplet[\"id\"])\n+                headers = {'Authorization': \"Bearer \" + access_key}\n+                r = requests.delete(url, headers=headers)\n+                r.close()\n+    except Exception:\n+        error_msg = \"Error encountered when trying to delete machine - \" + name\n+        logger.error(msg=error_msg)\n+        logger.error(msg=traceback.format_exc())\n+\n+\n+def wait_for_host_destroy_in_digital_ocean(ipaddress, timeout=300):\n+    start = time.time()\n+    time_elapsed = 0\n+    host = check_host_in_digital_ocean(ipaddress)\n+    while host is not None:\n+        assert host[\"locked\"] is True\n+        time.sleep(1)","path":"tests/validation/cattlevalidationtest/core/test_machine.py","position":279,"original_position":270,"commit_id":"dc3c50763ea5a2e2068602bc694bb19c025a6a28","original_commit_id":"407d5c79d6c0af2778db9ab2f25101173066edbd","user":{"login":"sonchang","id":8651231,"avatar_url":"https://avatars.githubusercontent.com/u/8651231?v=3","gravatar_id":"","url":"https://api.github.com/users/sonchang","html_url":"https://github.com/sonchang","followers_url":"https://api.github.com/users/sonchang/followers","following_url":"https://api.github.com/users/sonchang/following{/other_user}","gists_url":"https://api.github.com/users/sonchang/gists{/gist_id}","starred_url":"https://api.github.com/users/sonchang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sonchang/subscriptions","organizations_url":"https://api.github.com/users/sonchang/orgs","repos_url":"https://api.github.com/users/sonchang/repos","events_url":"https://api.github.com/users/sonchang/events{/privacy}","received_events_url":"https://api.github.com/users/sonchang/received_events","type":"User","site_admin":false},"body":"I wonder should we increase this sleep to even 2 seconds or maybe even more.  Pinging Digital Ocean every second seems a bit aggressive.","created_at":"2015-04-09T16:48:37Z","updated_at":"2015-04-09T16:48:37Z","html_url":"https://github.com/rancherio/validation-tests/pull/33#discussion_r28079575","pull_request_url":"https://api.github.com/repos/rancherio/validation-tests/pulls/33","_links":{"self":{"href":"https://api.github.com/repos/rancherio/validation-tests/pulls/comments/28079575"},"html":{"href":"https://github.com/rancherio/validation-tests/pull/33#discussion_r28079575"},"pull_request":{"href":"https://api.github.com/repos/rancherio/validation-tests/pulls/33"}}},"pull_request":{"url":"https://api.github.com/repos/rancherio/validation-tests/pulls/33","id":32476012,"html_url":"https://github.com/rancherio/validation-tests/pull/33","diff_url":"https://github.com/rancherio/validation-tests/pull/33.diff","patch_url":"https://github.com/rancherio/validation-tests/pull/33.patch","issue_url":"https://api.github.com/repos/rancherio/validation-tests/issues/33","number":33,"state":"open","locked":false,"title":"Test cases for validating lifecyle of Digitial Ocean hosts","user":{"login":"sangeethah","id":4266958,"avatar_url":"https://avatars.githubusercontent.com/u/4266958?v=3","gravatar_id":"","url":"https://api.github.com/users/sangeethah","html_url":"https://github.com/sangeethah","followers_url":"https://api.github.com/users/sangeethah/followers","following_url":"https://api.github.com/users/sangeethah/following{/other_user}","gists_url":"https://api.github.com/users/sangeethah/gists{/gist_id}","starred_url":"https://api.github.com/users/sangeethah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sangeethah/subscriptions","organizations_url":"https://api.github.com/users/sangeethah/orgs","repos_url":"https://api.github.com/users/sangeethah/repos","events_url":"https://api.github.com/users/sangeethah/events{/privacy}","received_events_url":"https://api.github.com/users/sangeethah/received_events","type":"User","site_admin":false},"body":"@will-chan , @cloudnautique - please review ","created_at":"2015-04-02T01:20:02Z","updated_at":"2015-04-09T16:48:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0dbbe791501d14c2c836ca707019823856bda1fb","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rancherio/validation-tests/pulls/33/commits","review_comments_url":"https://api.github.com/repos/rancherio/validation-tests/pulls/33/comments","review_comment_url":"https://api.github.com/repos/rancherio/validation-tests/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rancherio/validation-tests/issues/33/comments","statuses_url":"https://api.github.com/repos/rancherio/validation-tests/statuses/dc3c50763ea5a2e2068602bc694bb19c025a6a28","head":{"label":"sangeethah:machinetest","ref":"machinetest","sha":"dc3c50763ea5a2e2068602bc694bb19c025a6a28","user":{"login":"sangeethah","id":4266958,"avatar_url":"https://avatars.githubusercontent.com/u/4266958?v=3","gravatar_id":"","url":"https://api.github.com/users/sangeethah","html_url":"https://github.com/sangeethah","followers_url":"https://api.github.com/users/sangeethah/followers","following_url":"https://api.github.com/users/sangeethah/following{/other_user}","gists_url":"https://api.github.com/users/sangeethah/gists{/gist_id}","starred_url":"https://api.github.com/users/sangeethah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sangeethah/subscriptions","organizations_url":"https://api.github.com/users/sangeethah/orgs","repos_url":"https://api.github.com/users/sangeethah/repos","events_url":"https://api.github.com/users/sangeethah/events{/privacy}","received_events_url":"https://api.github.com/users/sangeethah/received_events","type":"User","site_admin":false},"repo":{"id":32605013,"name":"validation-tests","full_name":"sangeethah/validation-tests","owner":{"login":"sangeethah","id":4266958,"avatar_url":"https://avatars.githubusercontent.com/u/4266958?v=3","gravatar_id":"","url":"https://api.github.com/users/sangeethah","html_url":"https://github.com/sangeethah","followers_url":"https://api.github.com/users/sangeethah/followers","following_url":"https://api.github.com/users/sangeethah/following{/other_user}","gists_url":"https://api.github.com/users/sangeethah/gists{/gist_id}","starred_url":"https://api.github.com/users/sangeethah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sangeethah/subscriptions","organizations_url":"https://api.github.com/users/sangeethah/orgs","repos_url":"https://api.github.com/users/sangeethah/repos","events_url":"https://api.github.com/users/sangeethah/events{/privacy}","received_events_url":"https://api.github.com/users/sangeethah/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sangeethah/validation-tests","description":"Repository for validation tests","fork":true,"url":"https://api.github.com/repos/sangeethah/validation-tests","forks_url":"https://api.github.com/repos/sangeethah/validation-tests/forks","keys_url":"https://api.github.com/repos/sangeethah/validation-tests/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sangeethah/validation-tests/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sangeethah/validation-tests/teams","hooks_url":"https://api.github.com/repos/sangeethah/validation-tests/hooks","issue_events_url":"https://api.github.com/repos/sangeethah/validation-tests/issues/events{/number}","events_url":"https://api.github.com/repos/sangeethah/validation-tests/events","assignees_url":"https://api.github.com/repos/sangeethah/validation-tests/assignees{/user}","branches_url":"https://api.github.com/repos/sangeethah/validation-tests/branches{/branch}","tags_url":"https://api.github.com/repos/sangeethah/validation-tests/tags","blobs_url":"https://api.github.com/repos/sangeethah/validation-tests/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sangeethah/validation-tests/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sangeethah/validation-tests/git/refs{/sha}","trees_url":"https://api.github.com/repos/sangeethah/validation-tests/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sangeethah/validation-tests/statuses/{sha}","languages_url":"https://api.github.com/repos/sangeethah/validation-tests/languages","stargazers_url":"https://api.github.com/repos/sangeethah/validation-tests/stargazers","contributors_url":"https://api.github.com/repos/sangeethah/validation-tests/contributors","subscribers_url":"https://api.github.com/repos/sangeethah/validation-tests/subscribers","subscription_url":"https://api.github.com/repos/sangeethah/validation-tests/subscription","commits_url":"https://api.github.com/repos/sangeethah/validation-tests/commits{/sha}","git_commits_url":"https://api.github.com/repos/sangeethah/validation-tests/git/commits{/sha}","comments_url":"https://api.github.com/repos/sangeethah/validation-tests/comments{/number}","issue_comment_url":"https://api.github.com/repos/sangeethah/validation-tests/issues/comments{/number}","contents_url":"https://api.github.com/repos/sangeethah/validation-tests/contents/{+path}","compare_url":"https://api.github.com/repos/sangeethah/validation-tests/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sangeethah/validation-tests/merges","archive_url":"https://api.github.com/repos/sangeethah/validation-tests/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sangeethah/validation-tests/downloads","issues_url":"https://api.github.com/repos/sangeethah/validation-tests/issues{/number}","pulls_url":"https://api.github.com/repos/sangeethah/validation-tests/pulls{/number}","milestones_url":"https://api.github.com/repos/sangeethah/validation-tests/milestones{/number}","notifications_url":"https://api.github.com/repos/sangeethah/validation-tests/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sangeethah/validation-tests/labels{/name}","releases_url":"https://api.github.com/repos/sangeethah/validation-tests/releases{/id}","created_at":"2015-03-20T20:21:04Z","updated_at":"2015-04-02T01:10:39Z","pushed_at":"2015-04-09T16:40:19Z","git_url":"git://github.com/sangeethah/validation-tests.git","ssh_url":"git@github.com:sangeethah/validation-tests.git","clone_url":"https://github.com/sangeethah/validation-tests.git","svn_url":"https://github.com/sangeethah/validation-tests","homepage":null,"size":175,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"rancherio:master","ref":"master","sha":"36e45d518cd74162e5857acde26517b7f8f04933","user":{"login":"rancherio","id":9343010,"avatar_url":"https://avatars.githubusercontent.com/u/9343010?v=3","gravatar_id":"","url":"https://api.github.com/users/rancherio","html_url":"https://github.com/rancherio","followers_url":"https://api.github.com/users/rancherio/followers","following_url":"https://api.github.com/users/rancherio/following{/other_user}","gists_url":"https://api.github.com/users/rancherio/gists{/gist_id}","starred_url":"https://api.github.com/users/rancherio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rancherio/subscriptions","organizations_url":"https://api.github.com/users/rancherio/orgs","repos_url":"https://api.github.com/users/rancherio/repos","events_url":"https://api.github.com/users/rancherio/events{/privacy}","received_events_url":"https://api.github.com/users/rancherio/received_events","type":"Organization","site_admin":false},"repo":{"id":27966032,"name":"validation-tests","full_name":"rancherio/validation-tests","owner":{"login":"rancherio","id":9343010,"avatar_url":"https://avatars.githubusercontent.com/u/9343010?v=3","gravatar_id":"","url":"https://api.github.com/users/rancherio","html_url":"https://github.com/rancherio","followers_url":"https://api.github.com/users/rancherio/followers","following_url":"https://api.github.com/users/rancherio/following{/other_user}","gists_url":"https://api.github.com/users/rancherio/gists{/gist_id}","starred_url":"https://api.github.com/users/rancherio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rancherio/subscriptions","organizations_url":"https://api.github.com/users/rancherio/orgs","repos_url":"https://api.github.com/users/rancherio/repos","events_url":"https://api.github.com/users/rancherio/events{/privacy}","received_events_url":"https://api.github.com/users/rancherio/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rancherio/validation-tests","description":"Repository for validation tests","fork":false,"url":"https://api.github.com/repos/rancherio/validation-tests","forks_url":"https://api.github.com/repos/rancherio/validation-tests/forks","keys_url":"https://api.github.com/repos/rancherio/validation-tests/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rancherio/validation-tests/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rancherio/validation-tests/teams","hooks_url":"https://api.github.com/repos/rancherio/validation-tests/hooks","issue_events_url":"https://api.github.com/repos/rancherio/validation-tests/issues/events{/number}","events_url":"https://api.github.com/repos/rancherio/validation-tests/events","assignees_url":"https://api.github.com/repos/rancherio/validation-tests/assignees{/user}","branches_url":"https://api.github.com/repos/rancherio/validation-tests/branches{/branch}","tags_url":"https://api.github.com/repos/rancherio/validation-tests/tags","blobs_url":"https://api.github.com/repos/rancherio/validation-tests/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rancherio/validation-tests/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rancherio/validation-tests/git/refs{/sha}","trees_url":"https://api.github.com/repos/rancherio/validation-tests/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rancherio/validation-tests/statuses/{sha}","languages_url":"https://api.github.com/repos/rancherio/validation-tests/languages","stargazers_url":"https://api.github.com/repos/rancherio/validation-tests/stargazers","contributors_url":"https://api.github.com/repos/rancherio/validation-tests/contributors","subscribers_url":"https://api.github.com/repos/rancherio/validation-tests/subscribers","subscription_url":"https://api.github.com/repos/rancherio/validation-tests/subscription","commits_url":"https://api.github.com/repos/rancherio/validation-tests/commits{/sha}","git_commits_url":"https://api.github.com/repos/rancherio/validation-tests/git/commits{/sha}","comments_url":"https://api.github.com/repos/rancherio/validation-tests/comments{/number}","issue_comment_url":"https://api.github.com/repos/rancherio/validation-tests/issues/comments{/number}","contents_url":"https://api.github.com/repos/rancherio/validation-tests/contents/{+path}","compare_url":"https://api.github.com/repos/rancherio/validation-tests/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rancherio/validation-tests/merges","archive_url":"https://api.github.com/repos/rancherio/validation-tests/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rancherio/validation-tests/downloads","issues_url":"https://api.github.com/repos/rancherio/validation-tests/issues{/number}","pulls_url":"https://api.github.com/repos/rancherio/validation-tests/pulls{/number}","milestones_url":"https://api.github.com/repos/rancherio/validation-tests/milestones{/number}","notifications_url":"https://api.github.com/repos/rancherio/validation-tests/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rancherio/validation-tests/labels{/name}","releases_url":"https://api.github.com/repos/rancherio/validation-tests/releases{/id}","created_at":"2014-12-13T16:17:26Z","updated_at":"2015-04-01T20:57:22Z","pushed_at":"2015-04-09T16:40:20Z","git_url":"git://github.com/rancherio/validation-tests.git","ssh_url":"git@github.com:rancherio/validation-tests.git","clone_url":"https://github.com/rancherio/validation-tests.git","svn_url":"https://github.com/rancherio/validation-tests","homepage":null,"size":783,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":2,"forks":8,"open_issues":2,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rancherio/validation-tests/pulls/33"},"html":{"href":"https://github.com/rancherio/validation-tests/pull/33"},"issue":{"href":"https://api.github.com/repos/rancherio/validation-tests/issues/33"},"comments":{"href":"https://api.github.com/repos/rancherio/validation-tests/issues/33/comments"},"review_comments":{"href":"https://api.github.com/repos/rancherio/validation-tests/pulls/33/comments"},"review_comment":{"href":"https://api.github.com/repos/rancherio/validation-tests/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rancherio/validation-tests/pulls/33/commits"},"statuses":{"href":"https://api.github.com/repos/rancherio/validation-tests/statuses/dc3c50763ea5a2e2068602bc694bb19c025a6a28"}}}}