specter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ {
2
+ "STATUS": [
3
+ {
4
+ "STATUS": "S",
5
+ "When": 1397042303,
6
+ "Code": 22,
7
+ "Msg": "SGMiner versions",
8
+ "Description": "specter 0.1.0"
9
+ }
10
+ ],
11
+ "VERSION": [
12
+ {
13
+ "SGMiner": "4.1.0",
14
+ "API": "1.32"
15
+ }
16
+ ],
17
+ "id": 1
18
+ }
@@ -0,0 +1,22 @@
1
+ require 'middleware'
2
+
3
+ require 'specter/middleware/base'
4
+ require 'specter/middleware/fixture'
5
+ require 'specter/middleware/missing'
6
+ require 'specter/middleware/proxy'
7
+
8
+ module Specter
9
+ module Middleware
10
+
11
+ def self.new(server)
12
+ ::Middleware::Builder.new do
13
+ use Fixture, server
14
+ use Proxy, server if server.options[:proxy]
15
+
16
+ yield if block_given?
17
+
18
+ use Missing, server
19
+ end
20
+ end
21
+ end # Middleware
22
+ end # Specter
@@ -0,0 +1,14 @@
1
+ module Specter
2
+ module Middleware
3
+ class Base
4
+ extend Forwardable
5
+
6
+ def initialize(app, server)
7
+ @app = app
8
+ @server = server
9
+ end
10
+
11
+ def_delegators :@server, :logger, :options
12
+ end # Base
13
+ end # Middleware
14
+ end # Specter
@@ -0,0 +1,32 @@
1
+ require 'pathname'
2
+
3
+ module Specter
4
+ module Middleware
5
+ class Fixture < Base
6
+
7
+ ROOT = Pathname.new(File.expand_path('../../fixtures', __FILE__))
8
+
9
+ def call(env)
10
+ data = load_fixture(env)
11
+
12
+ if data
13
+ env.merge!(data)
14
+ else
15
+ @app.call(env)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def load_fixture(env)
22
+ fixture = ROOT.join("#{env.command}.json")
23
+ return unless fixture.exist?
24
+ logger.debug "loading fixture for #{env.command.inspect}"
25
+ JSON.load(File.read(fixture))
26
+ rescue JSON::ParserError
27
+ logger.debug "failed to parse fixture for #{env.command.inspect}"
28
+ nil
29
+ end
30
+ end # Fixture
31
+ end # Middleware
32
+ end # Specter
@@ -0,0 +1,25 @@
1
+ module Specter
2
+ module Middleware
3
+ class Missing < Base
4
+
5
+ def call(env)
6
+ @app.call(env)
7
+
8
+ if env.empty?
9
+ env.merge!(
10
+ 'STATUS' => [
11
+ {
12
+ 'STATUS' => 'E',
13
+ 'When' => Time.now.to_i,
14
+ 'Code' => 14,
15
+ 'Msg' => 'Invalid command',
16
+ 'Description' => "specter #{VERSION}"
17
+ }
18
+ ],
19
+ 'id' => 1
20
+ )
21
+ end
22
+ end
23
+ end # Missing
24
+ end # Middleware
25
+ end # Specter
@@ -0,0 +1,25 @@
1
+ require 'expedition'
2
+
3
+ module Specter
4
+ module Middleware
5
+ class Proxy < Base
6
+
7
+ def initialize(app, server)
8
+ super
9
+ @miner = Expedition::Client.new(*options[:proxy])
10
+ end
11
+
12
+ def call(env)
13
+ env.merge!(proxy_command(env))
14
+ @app.call(env)
15
+ end
16
+
17
+ private
18
+
19
+ def proxy_command(env)
20
+ logger.debug "proxying #{env.command}, #{env.args.inspect}"
21
+ @miner.send(env.command, *env.args).raw
22
+ end
23
+ end # Proxy
24
+ end # Middleware
25
+ end # Specter
@@ -0,0 +1,40 @@
1
+ require 'json'
2
+
3
+ module Specter
4
+ class Request
5
+
6
+ def self.parse(raw)
7
+ begin
8
+ message = JSON.parse(raw)
9
+ rescue JSON::ParserError
10
+ raise RequestError, $!
11
+ end
12
+
13
+ command = message['command']
14
+ args = message['parameter'].to_s.split(',')
15
+
16
+ new(command, args)
17
+ end
18
+
19
+ attr_reader :command
20
+
21
+ attr_reader :args
22
+
23
+ def initialize(command, args)
24
+ if command.nil? || command.empty?
25
+ raise RequestError, 'command not supplied'
26
+ end
27
+
28
+ @command = command.to_sym
29
+ @args = args
30
+ end
31
+
32
+ def execute(client)
33
+ client.send(command, *args)
34
+ end
35
+
36
+ def inspect
37
+ "#<#{self.class} command:#{command}, args:#{args.inspect}>"
38
+ end
39
+ end # Request
40
+ end # Specer
@@ -0,0 +1,77 @@
1
+ require 'socket'
2
+ require 'logger'
3
+
4
+ require 'specter/middleware'
5
+ require 'specter/request'
6
+ require 'specter/env'
7
+
8
+ module Specter
9
+ class Server
10
+
11
+ attr_reader :cli
12
+
13
+ attr_reader :options
14
+
15
+ attr_reader :logger
16
+
17
+ attr_reader :socket
18
+
19
+ attr_reader :stack
20
+
21
+ def initialize(cli)
22
+ @cli = cli
23
+ @options = cli.options
24
+
25
+ @logger = Logger.new(STDOUT)
26
+ @socket = TCPServer.new(options[:host], options[:port])
27
+ @stack = Middleware.new(self)
28
+ end
29
+
30
+ def run
31
+ BasicSocket.do_not_reverse_lookup = true
32
+ return @thread = Thread.new { handle_requests }
33
+ end
34
+
35
+ def handle_requests
36
+ loop do
37
+ client = socket.accept
38
+ process_request(client)
39
+ end
40
+ end
41
+
42
+ def process_request(client)
43
+ Timeout.timeout(5) do
44
+ req = Request.parse(client.gets)
45
+ env = Env.new(client, req)
46
+ log_request(env)
47
+ @stack.call(env)
48
+ client.write env.to_str
49
+ end
50
+ rescue Timeout::Error
51
+ log_timeout(client)
52
+ rescue Object => e
53
+ log_error(client, e)
54
+ ensure
55
+ client.close rescue nil
56
+ end
57
+
58
+ def log_timeout(client)
59
+ logger.warn "%s - timeout" % [
60
+ client.remote_address.ip_address
61
+ ]
62
+ end
63
+
64
+ def log_error(client, e)
65
+ logger.error "%s - %s: %s\n%s" % [
66
+ client.remote_address.ip_address, e.class, e.message,
67
+ e.backtrace.join("\n")
68
+ ]
69
+ end
70
+
71
+ def log_request(env)
72
+ logger.info "%s - %s - %s" % [
73
+ env.client.remote_address.ip_address, env.request.command, env.request.args.inspect
74
+ ]
75
+ end
76
+ end # Server
77
+ end # Specter
@@ -0,0 +1,3 @@
1
+ module Specter
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'specter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'specter'
8
+ spec.version = Specter::VERSION
9
+ spec.authors = ['Gabe Evans']
10
+ spec.email = ['gabe@ga.be']
11
+ spec.summary = %q{Specter stubs a subset of the cgminer client protocol. It allows you to test your programs against a dummy server when writing programs that interact with cgminer and cgminer-compatibile software.}
12
+ spec.description = spec.summary
13
+ spec.homepage = 'https://github.com/gevans/specter'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = %w(lib)
20
+
21
+ spec.add_dependency 'expedition'
22
+ spec.add_dependency 'middleware'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.5'
25
+ spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'rspec'
27
+ spec.add_development_dependency 'pry'
28
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: specter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gabe Evans
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: expedition
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Specter stubs a subset of the cgminer client protocol. It allows you
98
+ to test your programs against a dummy server when writing programs that interact
99
+ with cgminer and cgminer-compatibile software.
100
+ email:
101
+ - gabe@ga.be
102
+ executables:
103
+ - specter
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - ".gitignore"
108
+ - ".rspec"
109
+ - ".travis.yml"
110
+ - CHANGELOG.md
111
+ - Gemfile
112
+ - LICENSE.txt
113
+ - README.md
114
+ - Rakefile
115
+ - bin/specter
116
+ - lib/specter.rb
117
+ - lib/specter/cli.rb
118
+ - lib/specter/env.rb
119
+ - lib/specter/fixtures/coin.json
120
+ - lib/specter/fixtures/config.json
121
+ - lib/specter/fixtures/devdetails.json
122
+ - lib/specter/fixtures/devs.json
123
+ - lib/specter/fixtures/gpu.json
124
+ - lib/specter/fixtures/gpucount.json
125
+ - lib/specter/fixtures/notify.json
126
+ - lib/specter/fixtures/pools.json
127
+ - lib/specter/fixtures/stats.json
128
+ - lib/specter/fixtures/summary.json
129
+ - lib/specter/fixtures/version.json
130
+ - lib/specter/middleware.rb
131
+ - lib/specter/middleware/base.rb
132
+ - lib/specter/middleware/fixture.rb
133
+ - lib/specter/middleware/missing.rb
134
+ - lib/specter/middleware/proxy.rb
135
+ - lib/specter/request.rb
136
+ - lib/specter/server.rb
137
+ - lib/specter/version.rb
138
+ - specter.gemspec
139
+ homepage: https://github.com/gevans/specter
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.2.2
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Specter stubs a subset of the cgminer client protocol. It allows you to test
163
+ your programs against a dummy server when writing programs that interact with cgminer
164
+ and cgminer-compatibile software.
165
+ test_files: []