turd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+ ### turd
2
+
3
+ Turd is a little wrapper around typhoeus which is a wrapper around curb which is a wrapper around libcurl which is a wrapper around tcp which is a wrapper around electrons and shit. You can use turd to test http requests and responses. We use it at GitHub to validate responses from various services and alert us if they do not conform to the expected responses. http integration tests if you will. It can be also used for basic telnet-like plain text request validations. Lastly, it also produces some basic diagnostic data like various timings from libcurl.
4
+
5
+ It is called "turd" because my cat pooped on the floor while I was writing it.
6
+
7
+ #### Usage
8
+
9
+ Check out the examples directory for usage details. The basic idea is you define a request and response. turd performs the request and compares the actual response with the expected response. You can use any data that a typhoeus response object supplies to validate responses (header and body substrings, status codes, etc).
10
+
11
+ #### License
12
+
13
+ turd is open source software available under the MIT License
data/lib/turd.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+
3
+ require 'typhoeus'
4
+ require 'socket'
5
+ require 'timeout'
6
+
7
+ __DIR__ = File.dirname(__FILE__)
8
+
9
+ $LOAD_PATH.unshift __DIR__ unless
10
+ $LOAD_PATH.include?(__DIR__) ||
11
+ $LOAD_PATH.include?(File.expand_path(__DIR__))
12
+
13
+ require 'turd/assert'
14
+ require 'turd/http'
15
+ require 'turd/tcp'
16
+ require 'turd/version'
17
+
18
+ module Turd
19
+ class << self
20
+
21
+ def run(request_definition, response_definition)
22
+
23
+ case request_definition[:type]
24
+ when "http"
25
+ response = Turd::Http.request(request_definition)
26
+ when "tcp"
27
+ response = Turd::Tcp.connect(request_definition)
28
+ else
29
+ raise "No request type defined!"
30
+ end
31
+
32
+ Turd::Assert.assert(request_definition, response, response_definition)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,69 @@
1
+ module Turd
2
+ class Assert
3
+
4
+ def self.assert(request_definition, response, response_definition)
5
+
6
+ case request_definition[:type]
7
+
8
+ when "tcp"
9
+ response_definition.each do |option, value|
10
+ if option == :response
11
+ value.each do |v|
12
+ if response[:response].include?(v)
13
+ return response
14
+ else
15
+ raise AssertionFailure.new(response), "#{option} substring failure. expected #{v}, got #{response}"
16
+ end
17
+ end
18
+ elsif option == :total_time
19
+ if response[:total_time] > value
20
+ raise AssertionFailure.new(response), "#{option} timing value was greater than allowed. expected #{value}, got #{response[:total_time]}"
21
+ else
22
+ return response
23
+ end
24
+ end
25
+ end
26
+
27
+ when "http"
28
+ response_definition.each do |option, value|
29
+
30
+ if option == :response_headers || option == :response_body
31
+ value.each do |v|
32
+ if response.options[option].include?(v)
33
+ return return_http_response(response)
34
+ else
35
+ raise AssertionFailure.new(return_http_response(response)), "#{option} substring failure. expected #{v}, got #{response.options[option]}"
36
+ end
37
+ end
38
+ elsif option.to_s.include?("_time")
39
+ if response.options[option] > value
40
+ raise AssertionFailure.new(return_http_response(response)), "#{option} timing value was greater than allowed. expected #{value}, got #{response.options[option]}"
41
+ else
42
+ return return_http_response(response)
43
+ end
44
+ else
45
+ if response.options[option] == value
46
+ return return_http_response(response)
47
+ else
48
+ raise AssertionFailure.new(return_http_response(response)), "#{option} did not match response definition. expected #{value}, got #{response.options[option]}"
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ def self.return_http_response(response)
57
+ response.options.delete(:debug_info)
58
+ response.options
59
+ end
60
+ end
61
+
62
+ class AssertionFailure < RuntimeError
63
+ attr :response
64
+
65
+ def initialize(response)
66
+ @response = response
67
+ end
68
+ end
69
+ end
data/lib/turd/http.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Turd
2
+ class Http
3
+
4
+ def self.request(request_definition)
5
+
6
+ request = Typhoeus::Request.new(
7
+ request_definition[:url],
8
+ request_definition[:options]
9
+ )
10
+
11
+ request.run
12
+
13
+ end
14
+
15
+ end
16
+ end
data/lib/turd/tcp.rb ADDED
@@ -0,0 +1,24 @@
1
+ module Turd
2
+ class Tcp
3
+
4
+ def self.connect(request_definition)
5
+
6
+ response = String.new
7
+ before = Time.now.to_f
8
+
9
+ begin
10
+ TCPSocket.open(request_definition[:options][:host], request_definition[:options][:port]) do |socket|
11
+ response = socket.gets
12
+ end
13
+ rescue Errno::ETIMEDOUT
14
+ # timeout
15
+ end
16
+
17
+ after = Time.now.to_f
18
+
19
+ {:response => response, :total_time => after - before}
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Turd
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: turd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - joe williams
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: typhoeus
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description:
31
+ email: joe@joetify.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files:
35
+ - README.md
36
+ files:
37
+ - lib/turd/assert.rb
38
+ - lib/turd/http.rb
39
+ - lib/turd/tcp.rb
40
+ - lib/turd/version.rb
41
+ - lib/turd.rb
42
+ - README.md
43
+ homepage: http://github.com/joewilliams/turd
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.23
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: a http and tcp testing lib
67
+ test_files: []