{"action":"created","comment":{"url":"https://api.github.com/repos/Shopify/semian/pulls/comments/43559315","id":43559315,"diff_hunk":"@@ -0,0 +1,318 @@\n+require 'test_helper'\n+require 'semian/net_http'\n+require 'thin'\n+\n+class TestNetHTTP < MiniTest::Unit::TestCase\n+  class RackServer\n+    def self.call(env)\n+      response_code = env['REQUEST_URI'].delete(\"/\")\n+      response_code = '200' if response_code == \"\"\n+      [response_code, {'Content-Type' => 'text/html'}, ['Success']]\n+    end\n+  end\n+\n+  PORT = 31_050\n+  TOXIC_PORT = PORT + 1\n+\n+  def test_semian_identifier\n+    with_server do\n+      Net::HTTP.start(\"localhost\", TOXIC_PORT) do |http|\n+        assert_equal \"http_localhost_31051\", http.semian_identifier\n+      end\n+    end\n+  end\n+\n+  def test_trigger_open\n+    with_server do\n+      open_circuit!\n+      uri = URI('http://localhost:31051/200')\n+      assert_raises Net::CircuitOpenError do\n+        Net::HTTP.get(uri)\n+      end\n+    end\n+  end\n+\n+  def test_trigger_close_after_open\n+    with_server do\n+      open_circuit!\n+      close_circuit!\n+    end\n+  end\n+\n+  def test_bulkheads_tickets_are_working\n+    with_server do\n+      threads = []\n+      ticket_count = Net::HTTP.new(\"localhost\", TOXIC_PORT).raw_semian_options[:tickets]\n+\n+      @proxy.downstream(:latency, latency: 500).apply do\n+        uri = URI('http://localhost:31051/200')\n+        (ticket_count + 1).times do\n+          threads << Thread.new do\n+            Net::HTTP.get(uri)\n+          end\n+        end\n+        assert_raises Net::ResourceBusyError do","path":"test/net_http_test.rb","position":54,"original_position":54,"commit_id":"b96839b2a0e37940819d5e3dcba46d9120274eff","original_commit_id":"b96839b2a0e37940819d5e3dcba46d9120274eff","user":{"login":"Sirupsen","id":97400,"avatar_url":"https://avatars.githubusercontent.com/u/97400?v=3","gravatar_id":"","url":"https://api.github.com/users/Sirupsen","html_url":"https://github.com/Sirupsen","followers_url":"https://api.github.com/users/Sirupsen/followers","following_url":"https://api.github.com/users/Sirupsen/following{/other_user}","gists_url":"https://api.github.com/users/Sirupsen/gists{/gist_id}","starred_url":"https://api.github.com/users/Sirupsen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sirupsen/subscriptions","organizations_url":"https://api.github.com/users/Sirupsen/orgs","repos_url":"https://api.github.com/users/Sirupsen/repos","events_url":"https://api.github.com/users/Sirupsen/events{/privacy}","received_events_url":"https://api.github.com/users/Sirupsen/received_events","type":"User","site_admin":false},"body":"Similarly you could have a situation where none of them raise.. that's up to the scheduler. This test is fundamentally racy","created_at":"2015-10-30T22:32:08Z","updated_at":"2015-10-30T22:32:08Z","html_url":"https://github.com/Shopify/semian/pull/58#discussion_r43559315","pull_request_url":"https://api.github.com/repos/Shopify/semian/pulls/58","_links":{"self":{"href":"https://api.github.com/repos/Shopify/semian/pulls/comments/43559315"},"html":{"href":"https://github.com/Shopify/semian/pull/58#discussion_r43559315"},"pull_request":{"href":"https://api.github.com/repos/Shopify/semian/pulls/58"}}},"pull_request":{"url":"https://api.github.com/repos/Shopify/semian/pulls/58","id":49065215,"html_url":"https://github.com/Shopify/semian/pull/58","diff_url":"https://github.com/Shopify/semian/pull/58.diff","patch_url":"https://github.com/Shopify/semian/pull/58.patch","issue_url":"https://api.github.com/repos/Shopify/semian/issues/58","number":58,"state":"open","locked":false,"title":"Net::HTTP Semian Adapter","user":{"login":"kyewei","id":4326799,"avatar_url":"https://avatars.githubusercontent.com/u/4326799?v=3","gravatar_id":"","url":"https://api.github.com/users/kyewei","html_url":"https://github.com/kyewei","followers_url":"https://api.github.com/users/kyewei/followers","following_url":"https://api.github.com/users/kyewei/following{/other_user}","gists_url":"https://api.github.com/users/kyewei/gists{/gist_id}","starred_url":"https://api.github.com/users/kyewei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kyewei/subscriptions","organizations_url":"https://api.github.com/users/kyewei/orgs","repos_url":"https://api.github.com/users/kyewei/repos","events_url":"https://api.github.com/users/kyewei/events{/privacy}","received_events_url":"https://api.github.com/users/kyewei/received_events","type":"User","site_admin":false},"body":"^ What the title says. \r\n\r\nIf `semian/net_http` is included in a rails server instance, then some sort of initialization like this has to occur:\r\nIn `http.yml`:\r\n```\r\ndevelopment:\r\n  default:\r\n    tickets: 1\r\n    success_threshold: 1\r\n    error_threshold: 3\r\n    error_timeout: 10\r\n...\r\n```\r\nIn an initialization file somewhere:\r\n```\r\nhttp_config = YAML.load_file(\"#{Rails.root}/path_to_file/http.yml\")\r\nSemian::NetHTTP.raw_semian_options = proc do |semian_identifier|\r\n  if !http_config[Rails.env].key?(semian_identifier)\r\n    http_config[Rails.env][\"http_default\"]\r\n  else\r\n    http_config[Rails.env][semian_identifier]\r\n  end\r\nend\r\n# If we need extra errors, concat more onto array\r\n# assert_equal(Semian::NetHTTP.exceptions, Semian::NetHTTP::DEFAULT_ERRORS)\r\nSemian::NetHTTP.exceptions.concat([::Resolv::ResolvError, ::OpenURI::HTTPError, ::OpenSSL::SSL::SSLError])\r\n```\r\n\r\nReview? @Sirupsen @byroot ","created_at":"2015-10-28T20:52:21Z","updated_at":"2015-10-30T22:32:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c354deffef9a1a5e25562c122de0cac410050d40","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Shopify/semian/pulls/58/commits","review_comments_url":"https://api.github.com/repos/Shopify/semian/pulls/58/comments","review_comment_url":"https://api.github.com/repos/Shopify/semian/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Shopify/semian/issues/58/comments","statuses_url":"https://api.github.com/repos/Shopify/semian/statuses/b96839b2a0e37940819d5e3dcba46d9120274eff","head":{"label":"Shopify:net_http_adapter","ref":"net_http_adapter","sha":"b96839b2a0e37940819d5e3dcba46d9120274eff","user":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"repo":{"id":24375548,"name":"semian","full_name":"Shopify/semian","owner":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Shopify/semian","description":":monkey: Resiliency toolkit for Ruby for failing fast","fork":false,"url":"https://api.github.com/repos/Shopify/semian","forks_url":"https://api.github.com/repos/Shopify/semian/forks","keys_url":"https://api.github.com/repos/Shopify/semian/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Shopify/semian/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Shopify/semian/teams","hooks_url":"https://api.github.com/repos/Shopify/semian/hooks","issue_events_url":"https://api.github.com/repos/Shopify/semian/issues/events{/number}","events_url":"https://api.github.com/repos/Shopify/semian/events","assignees_url":"https://api.github.com/repos/Shopify/semian/assignees{/user}","branches_url":"https://api.github.com/repos/Shopify/semian/branches{/branch}","tags_url":"https://api.github.com/repos/Shopify/semian/tags","blobs_url":"https://api.github.com/repos/Shopify/semian/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Shopify/semian/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Shopify/semian/git/refs{/sha}","trees_url":"https://api.github.com/repos/Shopify/semian/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Shopify/semian/statuses/{sha}","languages_url":"https://api.github.com/repos/Shopify/semian/languages","stargazers_url":"https://api.github.com/repos/Shopify/semian/stargazers","contributors_url":"https://api.github.com/repos/Shopify/semian/contributors","subscribers_url":"https://api.github.com/repos/Shopify/semian/subscribers","subscription_url":"https://api.github.com/repos/Shopify/semian/subscription","commits_url":"https://api.github.com/repos/Shopify/semian/commits{/sha}","git_commits_url":"https://api.github.com/repos/Shopify/semian/git/commits{/sha}","comments_url":"https://api.github.com/repos/Shopify/semian/comments{/number}","issue_comment_url":"https://api.github.com/repos/Shopify/semian/issues/comments{/number}","contents_url":"https://api.github.com/repos/Shopify/semian/contents/{+path}","compare_url":"https://api.github.com/repos/Shopify/semian/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Shopify/semian/merges","archive_url":"https://api.github.com/repos/Shopify/semian/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Shopify/semian/downloads","issues_url":"https://api.github.com/repos/Shopify/semian/issues{/number}","pulls_url":"https://api.github.com/repos/Shopify/semian/pulls{/number}","milestones_url":"https://api.github.com/repos/Shopify/semian/milestones{/number}","notifications_url":"https://api.github.com/repos/Shopify/semian/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Shopify/semian/labels{/name}","releases_url":"https://api.github.com/repos/Shopify/semian/releases{/id}","created_at":"2014-09-23T14:47:19Z","updated_at":"2015-10-28T16:59:34Z","pushed_at":"2015-10-30T19:46:11Z","git_url":"git://github.com/Shopify/semian.git","ssh_url":"git@github.com:Shopify/semian.git","clone_url":"https://github.com/Shopify/semian.git","svn_url":"https://github.com/Shopify/semian","homepage":"","size":897,"stargazers_count":165,"watchers_count":165,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"open_issues_count":14,"forks":6,"open_issues":14,"watchers":165,"default_branch":"master"}},"base":{"label":"Shopify:master","ref":"master","sha":"332e0003d8d1a710b1fa39dfce6c8fb0357708b3","user":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"repo":{"id":24375548,"name":"semian","full_name":"Shopify/semian","owner":{"login":"Shopify","id":8085,"avatar_url":"https://avatars.githubusercontent.com/u/8085?v=3","gravatar_id":"","url":"https://api.github.com/users/Shopify","html_url":"https://github.com/Shopify","followers_url":"https://api.github.com/users/Shopify/followers","following_url":"https://api.github.com/users/Shopify/following{/other_user}","gists_url":"https://api.github.com/users/Shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/Shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Shopify/subscriptions","organizations_url":"https://api.github.com/users/Shopify/orgs","repos_url":"https://api.github.com/users/Shopify/repos","events_url":"https://api.github.com/users/Shopify/events{/privacy}","received_events_url":"https://api.github.com/users/Shopify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Shopify/semian","description":":monkey: Resiliency toolkit for Ruby for failing fast","fork":false,"url":"https://api.github.com/repos/Shopify/semian","forks_url":"https://api.github.com/repos/Shopify/semian/forks","keys_url":"https://api.github.com/repos/Shopify/semian/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Shopify/semian/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Shopify/semian/teams","hooks_url":"https://api.github.com/repos/Shopify/semian/hooks","issue_events_url":"https://api.github.com/repos/Shopify/semian/issues/events{/number}","events_url":"https://api.github.com/repos/Shopify/semian/events","assignees_url":"https://api.github.com/repos/Shopify/semian/assignees{/user}","branches_url":"https://api.github.com/repos/Shopify/semian/branches{/branch}","tags_url":"https://api.github.com/repos/Shopify/semian/tags","blobs_url":"https://api.github.com/repos/Shopify/semian/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Shopify/semian/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Shopify/semian/git/refs{/sha}","trees_url":"https://api.github.com/repos/Shopify/semian/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Shopify/semian/statuses/{sha}","languages_url":"https://api.github.com/repos/Shopify/semian/languages","stargazers_url":"https://api.github.com/repos/Shopify/semian/stargazers","contributors_url":"https://api.github.com/repos/Shopify/semian/contributors","subscribers_url":"https://api.github.com/repos/Shopify/semian/subscribers","subscription_url":"https://api.github.com/repos/Shopify/semian/subscription","commits_url":"https://api.github.com/repos/Shopify/semian/commits{/sha}","git_commits_url":"https://api.github.com/repos/Shopify/semian/git/commits{/sha}","comments_url":"https://api.github.com/repos/Shopify/semian/comments{/number}","issue_comment_url":"https://api.github.com/repos/Shopify/semian/issues/comments{/number}","contents_url":"https://api.github.com/repos/Shopify/semian/contents/{+path}","compare_url":"https://api.github.com/repos/Shopify/semian/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Shopify/semian/merges","archive_url":"https://api.github.com/repos/Shopify/semian/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Shopify/semian/downloads","issues_url":"https://api.github.com/repos/Shopify/semian/issues{/number}","pulls_url":"https://api.github.com/repos/Shopify/semian/pulls{/number}","milestones_url":"https://api.github.com/repos/Shopify/semian/milestones{/number}","notifications_url":"https://api.github.com/repos/Shopify/semian/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Shopify/semian/labels{/name}","releases_url":"https://api.github.com/repos/Shopify/semian/releases{/id}","created_at":"2014-09-23T14:47:19Z","updated_at":"2015-10-28T16:59:34Z","pushed_at":"2015-10-30T19:46:11Z","git_url":"git://github.com/Shopify/semian.git","ssh_url":"git@github.com:Shopify/semian.git","clone_url":"https://github.com/Shopify/semian.git","svn_url":"https://github.com/Shopify/semian","homepage":"","size":897,"stargazers_count":165,"watchers_count":165,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"open_issues_count":14,"forks":6,"open_issues":14,"watchers":165,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Shopify/semian/pulls/58"},"html":{"href":"https://github.com/Shopify/semian/pull/58"},"issue":{"href":"https://api.github.com/repos/Shopify/semian/issues/58"},"comments":{"href":"https://api.github.com/repos/Shopify/semian/issues/58/comments"},"review_comments":{"href":"https://api.github.com/repos/Shopify/semian/pulls/58/comments"},"review_comment":{"href":"https://api.github.com/repos/Shopify/semian/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Shopify/semian/pulls/58/commits"},"statuses":{"href":"https://api.github.com/repos/Shopify/semian/statuses/b96839b2a0e37940819d5e3dcba46d9120274eff"}}}}