bixby-common 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab49bbeea61a049b16a3052cf226339fe4ac645a
4
- data.tar.gz: 80ed512df18cbce6fe9f90e57fab0f1a315de3f1
3
+ metadata.gz: 35c3c23073295651e3c85e8e1c6e874890cd0cf2
4
+ data.tar.gz: 82f4b7036f6ac6b98162dd7c77aed1fec5a66841
5
5
  SHA512:
6
- metadata.gz: 59e70fb49c063504490f264c1a7cd50db08a2b3da32795150faf4d9458b8f8d36a6fa710bf90a029214129218b79ce57beb2dcb35e13bb250afc9d21b72c2593
7
- data.tar.gz: 45766f490d69f003c228f37a88357d1941b3ebbc3c3ce16894fd545702b8f05ddca9e4e03ed5ccdf712b2f6b5530d5ab0e7623788ed912747aa73e0b2da2e3f4
6
+ metadata.gz: 2bbfc1cdbda553922468d37fbc7ad96a3ab709dd1634efcdb972b5e22abda26c8105ff54944be50f1f0c3d40aaaa8547ad5e80d71003dc8ecaeb471b6b2e2387
7
+ data.tar.gz: d7b1596b8a5cac4d7ab3bf1bc6078ec5bb9a9ad2cf5b825bdbb09c2bed3632d7b472b83176e6d5ac9ae545e82bce43ad4c057d241175cf14b28efa9ed98a855a
data/Gemfile CHANGED
@@ -8,6 +8,10 @@ gem "logging"
8
8
  gem "api-auth", :git => "https://github.com/chetan/api_auth.git", :branch => "bixby"
9
9
 
10
10
  group :development do
11
+
12
+ # for some tests
13
+ gem "mixlib-shellout"
14
+
11
15
  gem "yard", "~> 0.8"
12
16
  gem "bundler", "~> 1.1"
13
17
  gem "jeweler", :git => "https://github.com/chetan/jeweler.git", :branch => "bixby"
data/Gemfile.lock CHANGED
@@ -31,12 +31,10 @@ GIT
31
31
 
32
32
  GIT
33
33
  remote: https://github.com/chetan/test_guard.git
34
- revision: 7d069b2d7e46fcbecd7a52966fda7d2d1945e2c9
34
+ revision: b60ce3e2cc47746142f0eba0cff5bcf3b550a88c
35
35
  specs:
36
36
  test_guard (0.2.1)
37
37
  awesome_print
38
- debugger
39
- debugger-pry
40
38
  growl
41
39
  listen
42
40
  simplecov
@@ -54,19 +52,9 @@ GEM
54
52
  builder (3.2.2)
55
53
  coderay (1.0.9)
56
54
  colorize (0.5.8)
57
- columnize (0.3.6)
58
55
  crack (0.4.1)
59
56
  safe_yaml (~> 0.9.0)
60
57
  curb (0.8.4)
61
- debugger (1.6.1)
62
- columnize (>= 0.3.1)
63
- debugger-linecache (~> 1.2.0)
64
- debugger-ruby_core_source (~> 1.2.3)
65
- debugger-linecache (1.2.0)
66
- debugger-pry (0.1.1)
67
- debugger (~> 1)
68
- pry (>= 0.9.9)
69
- debugger-ruby_core_source (1.2.3)
70
58
  eventmachine (1.0.3)
71
59
  eventmachine (1.0.3-java)
72
60
  faraday (0.8.8)
@@ -99,7 +87,7 @@ GEM
99
87
  json (1.8.0-java)
100
88
  jwt (0.1.8)
101
89
  multi_json (>= 1.5)
102
- listen (1.3.0)
90
+ listen (1.3.1)
103
91
  rb-fsevent (>= 0.9.3)
104
92
  rb-inotify (>= 0.9)
105
93
  rb-kqueue (>= 0.2)
@@ -110,9 +98,10 @@ GEM
110
98
  metaclass (0.0.1)
111
99
  method_source (0.8.2)
112
100
  minitest (4.7.5)
101
+ mixlib-shellout (1.2.0)
113
102
  mocha (0.14.0)
114
103
  metaclass (~> 0.0.1)
115
- multi_json (1.7.9)
104
+ multi_json (1.8.0)
116
105
  multi_xml (0.5.5)
117
106
  multipart-post (1.2.0)
118
107
  nokogiri (1.5.10)
@@ -139,7 +128,7 @@ GEM
139
128
  rb-fchange (0.0.6)
140
129
  ffi
141
130
  rb-fsevent (0.9.3)
142
- rb-inotify (0.9.1)
131
+ rb-inotify (0.9.2)
143
132
  ffi (>= 0.5.0)
144
133
  rb-kqueue (0.2.0)
145
134
  ffi (>= 0.5.0)
@@ -184,6 +173,7 @@ DEPENDENCIES
184
173
  json
185
174
  logging
186
175
  minitest (~> 4.0)
176
+ mixlib-shellout
187
177
  mocha
188
178
  multi_json
189
179
  oj
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.4
1
+ 0.4.5
data/bixby-common.gemspec CHANGED
@@ -2,14 +2,15 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: bixby-common 0.4.5 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "bixby-common"
8
- s.version = "0.4.4"
9
+ s.version = "0.4.5"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
12
  s.authors = ["Chetan Sarva"]
12
- s.date = "2013-09-10"
13
+ s.date = "2013-09-13"
13
14
  s.description = "Bixby Common files/libs"
14
15
  s.email = "chetan@pixelcop.net"
15
16
  s.extra_rdoc_files = [
@@ -48,27 +49,35 @@ Gem::Specification.new do |s|
48
49
  "lib/bixby-common/util/log/logger.rb",
49
50
  "lib/bixby-common/websocket/api_channel.rb",
50
51
  "lib/bixby-common/websocket/async_response.rb",
51
- "lib/bixby-common/websocket/client.rb",
52
52
  "lib/bixby-common/websocket/message.rb",
53
53
  "lib/bixby-common/websocket/request.rb",
54
54
  "lib/bixby-common/websocket/response.rb",
55
+ "test/api/http_channel_test.rb",
56
+ "test/base.rb",
55
57
  "test/bixby_common_test.rb",
56
58
  "test/command_response_test.rb",
57
59
  "test/command_spec_test.rb",
58
60
  "test/helper.rb",
61
+ "test/side_effect.rb",
59
62
  "test/support/repo/vendor/test_bundle/bin/cat",
60
63
  "test/support/repo/vendor/test_bundle/bin/cat.json",
61
64
  "test/support/repo/vendor/test_bundle/bin/echo",
62
65
  "test/support/repo/vendor/test_bundle/digest",
63
66
  "test/support/repo/vendor/test_bundle/manifest.json",
67
+ "test/test_handler.rb",
68
+ "test/util/crypto_util_test.rb",
64
69
  "test/util/http_client_test.rb",
65
70
  "test/util/jsonify_test.rb",
66
- "test/util/log_test.rb"
71
+ "test/util/log_test.rb",
72
+ "test/websocket/api_channel_test.rb",
73
+ "test/websocket/async_response_test.rb",
74
+ "test/websocket/request_test.rb",
75
+ "test/websocket/response_test.rb"
67
76
  ]
68
77
  s.homepage = "http://github.com/chetan/bixby-common"
69
78
  s.licenses = ["MIT"]
70
79
  s.require_paths = ["lib"]
71
- s.rubygems_version = "2.0.3"
80
+ s.rubygems_version = "2.1.0"
72
81
  s.summary = "Bixby Common"
73
82
 
74
83
  if s.respond_to? :specification_version then
@@ -80,6 +89,7 @@ Gem::Specification.new do |s|
80
89
  s.add_runtime_dependency(%q<httpi>, [">= 0"])
81
90
  s.add_runtime_dependency(%q<logging>, [">= 0"])
82
91
  s.add_runtime_dependency(%q<api-auth>, [">= 0"])
92
+ s.add_development_dependency(%q<mixlib-shellout>, [">= 0"])
83
93
  s.add_development_dependency(%q<yard>, ["~> 0.8"])
84
94
  s.add_development_dependency(%q<bundler>, ["~> 1.1"])
85
95
  s.add_development_dependency(%q<jeweler>, [">= 0"])
@@ -106,6 +116,7 @@ Gem::Specification.new do |s|
106
116
  s.add_dependency(%q<httpi>, [">= 0"])
107
117
  s.add_dependency(%q<logging>, [">= 0"])
108
118
  s.add_dependency(%q<api-auth>, [">= 0"])
119
+ s.add_dependency(%q<mixlib-shellout>, [">= 0"])
109
120
  s.add_dependency(%q<yard>, ["~> 0.8"])
110
121
  s.add_dependency(%q<bundler>, ["~> 1.1"])
111
122
  s.add_dependency(%q<jeweler>, [">= 0"])
@@ -133,6 +144,7 @@ Gem::Specification.new do |s|
133
144
  s.add_dependency(%q<httpi>, [">= 0"])
134
145
  s.add_dependency(%q<logging>, [">= 0"])
135
146
  s.add_dependency(%q<api-auth>, [">= 0"])
147
+ s.add_dependency(%q<mixlib-shellout>, [">= 0"])
136
148
  s.add_dependency(%q<yard>, ["~> 0.8"])
137
149
  s.add_dependency(%q<bundler>, ["~> 1.1"])
138
150
  s.add_dependency(%q<jeweler>, [">= 0"])
data/lib/bixby-common.rb CHANGED
@@ -17,7 +17,6 @@ module Bixby
17
17
  module WebSocket
18
18
  autoload :APIChannel, "bixby-common/websocket/api_channel"
19
19
  autoload :AsyncResponse, "bixby-common/websocket/async_response"
20
- autoload :Client, "bixby-common/websocket/client"
21
20
  autoload :Message, "bixby-common/websocket/message"
22
21
  autoload :Request, "bixby-common/websocket/request"
23
22
  autoload :Response, "bixby-common/websocket/response"
@@ -36,5 +36,14 @@ class JsonRequest
36
36
  MultiJson.dump(self)
37
37
  end
38
38
 
39
+ # Test if this object is equal to some other object
40
+ #
41
+ # @param [JsonRequest] other
42
+ #
43
+ # @return [Boolean]
44
+ def ==(other)
45
+ operation == other.operation && params == other.params
46
+ end
47
+
39
48
  end # JsonRequest
40
49
  end # Bixby
@@ -2,6 +2,9 @@
2
2
  module Bixby
3
3
  class RpcHandler
4
4
 
5
+ def initialize(*args)
6
+ end
7
+
5
8
  # Handle a request
6
9
  #
7
10
  # @param [JsonRequest] request
@@ -66,13 +66,30 @@ module Bixby
66
66
  return data.read
67
67
  end
68
68
 
69
+ # Generate a new 2048-bit RSA keypair
70
+ #
71
+ # @return [OpenSSL::PKey::RSA]
72
+ def generate_keypair
73
+ OpenSSL::PKey::RSA.generate(2048)
74
+ end
75
+
76
+ # Generate a new access key
77
+ #
78
+ # @return [String]
79
+ # :nocov:
69
80
  def generate_access_key
70
81
  Digest.hexencode(Digest::MD5.new.digest(OpenSSL::Random.random_bytes(512)))
71
82
  end
83
+ # :nocov:
72
84
 
85
+ # Generate a new secret key
86
+ #
87
+ # @return [String]
88
+ # :nocov:
73
89
  def generate_secret_key
74
90
  Digest.hexencode(Digest::SHA2.new(512).digest(OpenSSL::Random.random_bytes(512)))
75
91
  end
92
+ # :nocov:
76
93
 
77
94
 
78
95
  private
@@ -2,8 +2,10 @@
2
2
  module Bixby
3
3
  module Debug
4
4
 
5
+ # :nocov:
6
+
5
7
  # Simple helper for use in to_s methods
6
- def self.pretty_str(str) # :nocov:
8
+ def self.pretty_str(str)
7
9
  if str.nil? then
8
10
  "nil"
9
11
  elsif str.empty? then
@@ -13,7 +15,7 @@ module Bixby
13
15
  else
14
16
  '"' + str + '"'
15
17
  end
16
- end # :nocov:
18
+ end
17
19
 
18
20
  # Pretty print a hash
19
21
  #
@@ -41,5 +43,7 @@ module Bixby
41
43
  str.gsub(/\n/, "\n#{indent}")
42
44
  end
43
45
 
46
+ # :nocov:
47
+
44
48
  end # Debug
45
49
  end # Bixby
@@ -22,9 +22,11 @@ module HttpClient
22
22
  #
23
23
  # @param [String] url
24
24
  # @return [Object] Result of calling JSON.parse() on the response body
25
+ # :nocov:
25
26
  def http_get_json(url)
26
27
  MultiJson.load(http_get(url))
27
28
  end
29
+ # :nocov:
28
30
 
29
31
  # Execute an HTTP POST request to the given URL
30
32
  #
@@ -41,9 +43,11 @@ module HttpClient
41
43
  # @param [String] url
42
44
  # @param [Hash] data Key/Value pairs to POST
43
45
  # @return [Object] Result of calling JSON.parse() on the response body
46
+ # :nocov:
44
47
  def http_post_json(url, data)
45
48
  MultiJson.load(http_post(url, data))
46
49
  end
50
+ # :nocov:
47
51
 
48
52
  # Execute an HTTP post request and save the response body
49
53
  #
@@ -3,6 +3,7 @@
3
3
 
4
4
  module Logging
5
5
  class Logger
6
+ # :nocov:
6
7
 
7
8
  # Override to pass trace flag from parent to child
8
9
  def initialize( name )
@@ -16,6 +17,7 @@ module Logging
16
17
  _setup(name, :parent => parent, :trace => parent.trace)
17
18
  end
18
19
 
20
+ # :nocov:
19
21
  end
20
22
  end
21
23
 
@@ -1,6 +1,8 @@
1
1
 
2
2
  require "bixby-common/websocket/async_response"
3
+
3
4
  require "api-auth"
5
+ require "eventmachine"
4
6
 
5
7
  module Bixby
6
8
  module WebSocket
@@ -32,8 +32,8 @@ module Bixby
32
32
  # @param [Object] obj result of request, usually a JsonResponse
33
33
  def response=(obj)
34
34
  @mutex.synchronize {
35
- @completed = true
36
35
  @response = obj
36
+ @completed = true
37
37
  @cond.signal
38
38
  }
39
39
 
@@ -9,10 +9,7 @@ module Bixby
9
9
  def initialize(id=nil, type="rpc", headers=nil)
10
10
  @id = id || SecureRandom.uuid
11
11
  @type = type
12
- @hash = { :type => @type, :id => @id }
13
-
14
- headers ||= {}
15
- @headers = @hash[:headers] = headers
12
+ @headers = headers || {}
16
13
  end
17
14
 
18
15
  def self.from_wire(body)
@@ -39,7 +36,12 @@ module Bixby
39
36
  end
40
37
 
41
38
  def to_wire
42
- @body
39
+ hash = { :type => @type,
40
+ :id => @id,
41
+ :headers => @headers,
42
+ :data => @body }
43
+
44
+ MultiJson.dump(hash)
43
45
  end
44
46
 
45
47
  # Convert object to String, useful for debugging
@@ -10,8 +10,7 @@ module Bixby
10
10
  end
11
11
  super(id, type, headers)
12
12
 
13
- @hash[:data] = json_request.to_wire
14
- @body = MultiJson.dump(@hash)
13
+ @body = json_request.to_wire
15
14
  end
16
15
 
17
16
  def json_request
@@ -10,8 +10,7 @@ module Bixby
10
10
  end
11
11
  super(id, "rpc_result", headers)
12
12
 
13
- @hash[:data] = json_response.to_wire
14
- @body = MultiJson.dump(@hash)
13
+ @body = json_response.to_wire
15
14
  end
16
15
 
17
16
  def json_response
@@ -0,0 +1,65 @@
1
+
2
+ require 'helper'
3
+
4
+ module Bixby
5
+ module Test
6
+ module API
7
+ class TestHttpChannel < TestCase
8
+
9
+ def test_exec
10
+ url = "http://google.com/"
11
+
12
+ json_req = JsonRequest.new("exec", {"foo" => "bar"})
13
+ signed_json_req = SignedJsonRequest.new(json_req, "foo", "bar")
14
+
15
+ # setup response stub
16
+ cr = CommandResponse.new(:status => 0, :stdout => "foobar", :stderr => "")
17
+ json_res = JsonResponse.new("success", nil, cr.to_hash)
18
+ res_mock = mock()
19
+ res_mock.expects(:body).once.returns(json_res.to_wire)
20
+ HTTPI.expects(:post).with{ |r| r.kind_of?(HTTPI::Request) && r.url.to_s == url }.returns(res_mock)
21
+
22
+ chan = HttpChannel.new(url)
23
+ res = chan.execute(signed_json_req)
24
+
25
+ # req should have been modified
26
+ assert_includes signed_json_req.headers, "Content-Type"
27
+ assert_equal "application/json", signed_json_req.headers["Content-Type"]
28
+
29
+ assert res
30
+ assert_kind_of JsonResponse, res
31
+ assert res.success?
32
+
33
+ cr = CommandResponse.from_json_response(res)
34
+ assert cr
35
+ assert_equal 0, cr.status
36
+ assert_equal "foobar", cr.stdout
37
+ assert_equal "", cr.stderr
38
+ end
39
+
40
+ def test_exec_download
41
+ url = "http://google.com/"
42
+
43
+ json_req = JsonRequest.new("exec", {"foo" => "bar"})
44
+ signed_json_req = SignedJsonRequest.new(json_req, "foo", "bar")
45
+
46
+ # setup response stub
47
+ HTTPI.expects(:post).with{ |r| r.kind_of?(HTTPI::Request) && r.url.to_s == url }
48
+
49
+ chan = HttpChannel.new(url)
50
+ res = chan.execute_download(signed_json_req) do
51
+ end
52
+
53
+ # req should have been modified
54
+ assert_includes signed_json_req.headers, "Content-Type"
55
+ assert_equal "application/json", signed_json_req.headers["Content-Type"]
56
+
57
+ assert res
58
+ assert_kind_of JsonResponse, res
59
+ assert res.success?
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
data/test/base.rb ADDED
@@ -0,0 +1,16 @@
1
+
2
+ module Bixby
3
+ module Test
4
+ class TestCase < MiniTest::Unit::TestCase
5
+
6
+ def setup
7
+ ENV["BIXBY_HOME"] = File.join(File.expand_path(File.dirname(__FILE__)), "support")
8
+ end
9
+
10
+ def teardown
11
+ EM.stop_event_loop if EM.reactor_running?
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -1,10 +1,11 @@
1
1
 
2
2
  require 'helper'
3
+ require 'mixlib/shellout'
3
4
 
4
5
  module Bixby
5
6
  module Test
6
7
 
7
- class TestCommandResponse < MiniTest::Unit::TestCase
8
+ class TestCommandResponse < TestCase
8
9
 
9
10
  def test_from_json_response
10
11
  res = JsonResponse.new("fail", "unknown")
@@ -30,6 +31,36 @@ class TestCommandResponse < MiniTest::Unit::TestCase
30
31
  assert_nil cr.stderr
31
32
  end
32
33
 
34
+ def test_to_json_response
35
+ cr = CommandResponse.new(:status => 50, :stdout => "foobar", :stderr => "baz")
36
+ js = cr.to_json_response
37
+
38
+ assert js
39
+ assert_kind_of JsonResponse, js
40
+
41
+ refute js.success?
42
+ assert js.fail?
43
+
44
+ assert_nil js.message
45
+ assert js.data
46
+
47
+ assert_equal 50, js.data[:status]
48
+ assert_equal "foobar", js.data[:stdout]
49
+ assert_equal "baz", js.data[:stderr]
50
+ end
51
+
52
+ def test_from_shellout
53
+ cmd = Mixlib::ShellOut.new("uname")
54
+ cmd.run_command
55
+
56
+ cr = CommandResponse.new(cmd)
57
+ assert cr
58
+
59
+ assert_equal 0, cr.status
60
+ assert cr.stdout =~ /^Darwin|Linux$/
61
+ assert_empty cr.stderr
62
+ end
63
+
33
64
  def test_status
34
65
  cr = CommandResponse.new
35
66
  cr.status = 0
@@ -5,10 +5,10 @@ require 'helper'
5
5
  module Bixby
6
6
  module Test
7
7
 
8
- class TestCommandSpec < MiniTest::Unit::TestCase
8
+ class TestCommandSpec < TestCase
9
9
 
10
10
  def setup
11
- ENV["BIXBY_HOME"] = File.join(File.expand_path(File.dirname(__FILE__)), "support")
11
+ super
12
12
  h = { :repo => "vendor", :bundle => "test_bundle", 'command' => "echo", :foobar => "baz" }
13
13
  @c = CommandSpec.new(h)
14
14
  @expected_digest = "2bb6900420c87d5a7cbd8acc9dd1978593670f4e31bfa9218bb9c7c31d4472dd"
data/test/helper.rb CHANGED
@@ -29,6 +29,10 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
29
29
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
30
30
  require 'bixby-common'
31
31
 
32
+ require "base"
33
+ require "test_handler"
34
+ require "side_effect"
35
+
32
36
  Dir.glob(File.dirname(__FILE__) + "/../lib/**/*.rb").each{ |f| require f }
33
37
 
34
38
  MiniTest::Unit.autorun
@@ -0,0 +1,15 @@
1
+
2
+ module Bixby
3
+ module Test
4
+
5
+ class SideEffect
6
+ def initialize(&block)
7
+ @block = block
8
+ end
9
+ def perform
10
+ @block.call
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+
2
+ module Bixby
3
+ module Test
4
+ class TestHandler < Bixby::RpcHandler
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+
2
+ require 'helper'
3
+
4
+ module Bixby
5
+ module Test
6
+
7
+ class TestCryptoUtil < TestCase
8
+
9
+ def test_crypto_cycle
10
+
11
+ key1 = CryptoUtil.generate_keypair
12
+ key2 = CryptoUtil.generate_keypair
13
+
14
+ data = {"foo" => "bar"}
15
+ uuid = "123456"
16
+
17
+ encrypted = CryptoUtil.encrypt(MultiJson.dump(data), uuid, key1, key2)
18
+ assert encrypted
19
+ encrypted_io = StringIO.new(encrypted)
20
+ assert_equal uuid, encrypted_io.readline.strip
21
+
22
+ decrypted = CryptoUtil.decrypt(encrypted_io, key1, key2)
23
+ assert decrypted
24
+ data_out = MultiJson.load(decrypted)
25
+ assert data_out
26
+ assert_kind_of Hash, data_out
27
+ assert_equal "bar", data_out["foo"]
28
+ end
29
+
30
+
31
+ end # TestCryptoUtil
32
+
33
+ end # Test
34
+ end # Bixby
@@ -4,11 +4,12 @@ require 'helper'
4
4
  module Bixby
5
5
  module Test
6
6
 
7
- class TestHttpClient < MiniTest::Unit::TestCase
7
+ class TestHttpClient < TestCase
8
8
 
9
9
  include WebMock::API
10
10
 
11
11
  def teardown
12
+ super
12
13
  WebMock.reset!
13
14
  end
14
15
 
@@ -4,7 +4,7 @@ require 'helper'
4
4
  module Bixby
5
5
  module Test
6
6
 
7
- class TestLog < MiniTest::Unit::TestCase
7
+ class TestLog < TestCase
8
8
 
9
9
  def test_setup_logger
10
10
  ENV["BIXBY_DEBUG"] = "1"
@@ -20,6 +20,29 @@ class TestLog < MiniTest::Unit::TestCase
20
20
  assert_equal 1, Logging::Logger.root.level # info
21
21
  end
22
22
 
23
+ def test_filtering_layout
24
+
25
+ filter = Bixby::Log::FilteringLayout.new
26
+
27
+ f = "foo"
28
+ assert_equal "foo", filter.format_obj(f)
29
+ assert filter.format_obj(nil) =~ /NilClass/
30
+ assert filter.format_obj(3) =~ /Fixnum.*3/
31
+
32
+ begin
33
+ raise "foo"
34
+ rescue => ex
35
+ assert filter.format_obj(ex) =~ /turn/
36
+
37
+ # filter out all turn lines
38
+ filter.set_filter do |ex|
39
+ ex.backtrace.reject{ |s| s =~ /turn/ }
40
+ end
41
+ refute filter.format_obj(ex) =~ /turn/
42
+
43
+ end
44
+ end
45
+
23
46
  end # TestLog
24
47
 
25
48
  end # Test
@@ -0,0 +1,100 @@
1
+
2
+ require 'helper'
3
+
4
+ module Bixby
5
+
6
+
7
+ module WebSocket
8
+ class APIChannel
9
+ def responses
10
+ @responses
11
+ end
12
+ end
13
+ end
14
+
15
+
16
+ module Test
17
+ module WebSocket
18
+ class TestAPIChannel < TestCase
19
+
20
+ attr_reader :api_chan, :ws
21
+
22
+ def setup
23
+ @em_thread = Thread.new { EM.run{} }
24
+ @ws = mock()
25
+ @api_chan = Bixby::WebSocket::APIChannel.new(ws, TestHandler)
26
+ end
27
+
28
+ def test_open
29
+ refute api_chan.connected?
30
+ api_chan.open(nil)
31
+ assert api_chan.connected?
32
+ end
33
+
34
+
35
+ def test_exec
36
+ # test executing a request on the channel
37
+ json_req = JsonRequest.new("exec", {:foo => "bar"})
38
+ ws.expects(:send).once().add_side_effect(SideEffect.new{ api_chan.responses.values.first.response = "hi" })
39
+ assert_equal "hi", api_chan.execute(json_req)
40
+ end
41
+
42
+ def test_message_request
43
+ # test receiving a request on the channel
44
+ json_req = JsonRequest.new("exec", {"foo" => "bar"})
45
+ signed_json_req = SignedJsonRequest.new(json_req, "foo", "bar")
46
+ req = Bixby::WebSocket::Request.new(signed_json_req)
47
+
48
+ cr = CommandResponse.new(:status => 0, :stdout => "foobar", :stderr => "")
49
+ json_res = JsonResponse.new("success", nil, cr.to_hash)
50
+
51
+ event = mock()
52
+ event.expects(:data).once.returns(req.to_wire)
53
+ TestHandler.any_instance.expects(:handle).with{ |r| r == json_req }.returns(json_res)
54
+ ws.expects(:send).once.with { |str|
55
+ res = Bixby::WebSocket::Message.from_wire(str)
56
+ !res.nil? && res.json_response.to_wire == json_res.to_wire
57
+ }
58
+ api_chan.message(event)
59
+ end
60
+
61
+ def test_message_response
62
+ # test receiving a response on the channel
63
+ cr = CommandResponse.new(:status => 0, :stdout => "foobar", :stderr => "")
64
+ json_res = JsonResponse.new("success", nil, cr.to_hash)
65
+ res = Bixby::WebSocket::Response.new(json_res, "1234")
66
+
67
+ event = mock()
68
+ event.expects(:data).once.returns(res.to_wire)
69
+ api_chan.responses["1234"] = Bixby::WebSocket::AsyncResponse.new("1234")
70
+ api_chan.message(event)
71
+ ret = api_chan.fetch_response("1234")
72
+ assert ret
73
+ assert_kind_of JsonResponse, ret
74
+ assert_equal json_res.to_wire, ret.to_wire
75
+ end
76
+
77
+ def test_message_connect
78
+ # test receiving a connect request on the channel
79
+ json_req = JsonRequest.new("", {})
80
+ signed_json_req = SignedJsonRequest.new(json_req, "foo", "bar")
81
+ req = Bixby::WebSocket::Request.new(signed_json_req, nil, "connect")
82
+
83
+ event = mock()
84
+ event.expects(:data).once.returns(req.to_wire)
85
+ TestHandler.any_instance.expects(:connect).with(json_req, api_chan)
86
+ api_chan.message(event)
87
+ end
88
+
89
+ def test_close
90
+ # close
91
+ api_chan.open(nil)
92
+ TestHandler.any_instance.expects(:disconnect).with(api_chan).once()
93
+ api_chan.close(nil)
94
+
95
+ end
96
+
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,43 @@
1
+
2
+ require 'helper'
3
+
4
+ module Bixby
5
+ module Test
6
+ module WebSocket
7
+ class TestAsyncResponse < TestCase
8
+
9
+ def test_block
10
+
11
+ sync_response = nil
12
+ cb_response = nil
13
+
14
+ res = Bixby::WebSocket::AsyncResponse.new("1234") do |r|
15
+ cb_response = r
16
+ end
17
+
18
+ assert res
19
+ assert_equal "1234", res.id
20
+ refute res.completed?
21
+
22
+ # start a thread waiting on the response to be writ ten
23
+ t = Thread.new {
24
+ sync_response = res.response
25
+ }
26
+ assert t.alive?
27
+
28
+ # small sleep here, otherwise execution will continue too quickly, before the thread starts
29
+ assert_nil t.join(0.001)
30
+
31
+ # now write it, thread should complete & callback will fire
32
+ res.response = "hi"
33
+
34
+ t.join
35
+ refute t.alive?
36
+ assert_equal "hi", cb_response
37
+ assert_equal "hi", sync_response
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,65 @@
1
+
2
+ require 'helper'
3
+
4
+ module Bixby
5
+ module Test
6
+ module WebSocket
7
+ class TestRequest < TestCase
8
+
9
+ def test_init
10
+ json_req = JsonRequest.new("exec", {:foo => "bar"})
11
+ req = Bixby::WebSocket::Request.new(json_req)
12
+
13
+ assert req
14
+ assert req.headers
15
+ assert_empty req.headers
16
+
17
+ h = MultiJson.load(req.to_wire)
18
+ test_common_props(h)
19
+ assert_empty h["headers"]
20
+ end
21
+
22
+ def test_signed
23
+ json_req = JsonRequest.new("exec", {:foo => "bar"})
24
+ signed_json_req = SignedJsonRequest.new(json_req, "foo", "bar")
25
+ req = Bixby::WebSocket::Request.new(signed_json_req)
26
+
27
+ assert req
28
+ h = MultiJson.load(req.to_wire)
29
+ test_common_props(h)
30
+ refute_empty h["headers"]
31
+
32
+ assert_includes h["headers"], "Content-MD5"
33
+ assert_includes h["headers"], "Date"
34
+ assert_includes h["headers"], "Authorization"
35
+ assert h["headers"]["Authorization"] =~ /^APIAuth foo:/
36
+ end
37
+
38
+ def test_json_req
39
+ json_req = JsonRequest.new("exec", {"foo" => "bar"})
40
+ req = Bixby::WebSocket::Request.new(json_req)
41
+
42
+ assert req.json_request
43
+ assert_equal json_req, req.json_request
44
+ assert_equal json_req, Bixby::WebSocket::Message.from_wire(req.to_wire).json_request
45
+ end
46
+
47
+
48
+ private
49
+
50
+ def test_common_props(h)
51
+ assert h
52
+ assert_equal "rpc", h["type"]
53
+ assert h["id"]
54
+
55
+ d = MultiJson.load(h["data"])
56
+ assert_equal "exec", d["operation"]
57
+ refute_empty d["params"]
58
+ assert_equal "bar", d["params"]["foo"]
59
+ h
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,45 @@
1
+
2
+ require 'helper'
3
+
4
+ module Bixby
5
+ module Test
6
+ module WebSocket
7
+ class TestResponse < TestCase
8
+
9
+ def test_init
10
+ cr = CommandResponse.new(:status => 0, :stdout => "foobar", :stderr => "")
11
+ json_res = JsonResponse.new("success", nil, cr.to_hash)
12
+ res = Bixby::WebSocket::Response.new(json_res, "1234")
13
+
14
+ assert res
15
+ assert res.headers
16
+ assert_empty res.headers
17
+
18
+ h = MultiJson.load(res.to_wire)
19
+ assert h
20
+ assert_equal "rpc_result", h["type"]
21
+ assert_equal "1234", h["id"]
22
+
23
+ d = MultiJson.load(h["data"])
24
+ assert_equal "success", d["status"]
25
+ refute d["message"]
26
+ refute d["code"]
27
+ assert_equal 0, d["data"]["status"]
28
+ assert_equal "foobar", d["data"]["stdout"]
29
+ assert_equal "", d["data"]["stderr"]
30
+ end
31
+
32
+ def test_json_res
33
+ cr = CommandResponse.new("status" => 0, "stdout" => "foobar", "stderr" => "")
34
+ json_res = JsonResponse.new("success", nil, cr.to_hash)
35
+ res = Bixby::WebSocket::Response.new(json_res, "1234")
36
+
37
+ assert res.json_response
38
+ assert_equal json_res.to_wire, res.json_response.to_wire
39
+ assert_equal json_res.to_wire, Bixby::WebSocket::Message.from_wire(res.to_wire).json_response.to_wire
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bixby-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chetan Sarva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-10 00:00:00.000000000 Z
11
+ date: 2013-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye-websocket
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mixlib-shellout
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'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: yard
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -399,22 +413,30 @@ files:
399
413
  - lib/bixby-common/util/log/logger.rb
400
414
  - lib/bixby-common/websocket/api_channel.rb
401
415
  - lib/bixby-common/websocket/async_response.rb
402
- - lib/bixby-common/websocket/client.rb
403
416
  - lib/bixby-common/websocket/message.rb
404
417
  - lib/bixby-common/websocket/request.rb
405
418
  - lib/bixby-common/websocket/response.rb
419
+ - test/api/http_channel_test.rb
420
+ - test/base.rb
406
421
  - test/bixby_common_test.rb
407
422
  - test/command_response_test.rb
408
423
  - test/command_spec_test.rb
409
424
  - test/helper.rb
425
+ - test/side_effect.rb
410
426
  - test/support/repo/vendor/test_bundle/bin/cat
411
427
  - test/support/repo/vendor/test_bundle/bin/cat.json
412
428
  - test/support/repo/vendor/test_bundle/bin/echo
413
429
  - test/support/repo/vendor/test_bundle/digest
414
430
  - test/support/repo/vendor/test_bundle/manifest.json
431
+ - test/test_handler.rb
432
+ - test/util/crypto_util_test.rb
415
433
  - test/util/http_client_test.rb
416
434
  - test/util/jsonify_test.rb
417
435
  - test/util/log_test.rb
436
+ - test/websocket/api_channel_test.rb
437
+ - test/websocket/async_response_test.rb
438
+ - test/websocket/request_test.rb
439
+ - test/websocket/response_test.rb
418
440
  homepage: http://github.com/chetan/bixby-common
419
441
  licenses:
420
442
  - MIT
@@ -435,7 +457,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
435
457
  version: '0'
436
458
  requirements: []
437
459
  rubyforge_project:
438
- rubygems_version: 2.0.3
460
+ rubygems_version: 2.1.0
439
461
  signing_key:
440
462
  specification_version: 4
441
463
  summary: Bixby Common
@@ -1,125 +0,0 @@
1
-
2
- require 'faye/websocket'
3
- require 'eventmachine'
4
-
5
- module Bixby
6
- module WebSocket
7
-
8
- # WebSocket Client
9
- class Client
10
-
11
- include Bixby::Log
12
-
13
- attr_reader :ws, :api
14
-
15
- def initialize(url, handler)
16
- @url = url
17
- @handler = handler
18
- @tries = 0
19
- @exiting = false
20
- end
21
-
22
- # Start the Client thread
23
- #
24
- # NOTE: This call never returns!
25
- def start
26
-
27
- @exiting = false
28
-
29
- Kernel.trap("EXIT") do
30
- @exiting = true
31
- end
32
-
33
- logger.debug "connecting to #{@url}"
34
- EM.run {
35
- connect()
36
- }
37
- end
38
-
39
- def stop
40
- @exiting = true
41
- EM.stop_event_loop
42
- end
43
-
44
-
45
- private
46
-
47
- # Connect to the WebSocket endpoint given by @url. Will attempt to keep
48
- # the connection open forever, reconnecting as needed.
49
- def connect
50
-
51
- @ws = Faye::WebSocket::Client.new(@url, nil, :ping => 60)
52
- @api = Bixby::WebSocket::APIChannel.new(@ws, @handler)
53
-
54
- ws.on :open do |e|
55
- begin
56
- logger.info "connected to manager at #{@url}"
57
- api.open(e)
58
- @tries = 0
59
-
60
- # send a connection request
61
- id = SecureRandom.uuid
62
- json_req = JsonRequest.new("", "")
63
- signed_req = SignedJsonRequest.new(json_req, Bixby.agent.access_key, Bixby.agent.secret_key)
64
- connect_req = Request.new(signed_req, id, "connect")
65
- EM.next_tick {
66
- ws.send(connect_req.to_wire)
67
- }
68
-
69
- rescue Exception => ex
70
- logger.error ex
71
- end
72
- end
73
-
74
- ws.on :message do |e|
75
- begin
76
- api.message(e)
77
- rescue Exception => ex
78
- logger.error ex
79
- end
80
- end
81
-
82
- ws.on :close do |e|
83
- begin
84
- if api.connected? then
85
- logger.info "lost connection to manager"
86
- else
87
- logger.debug "failed to connect"
88
- end
89
- api.close(e)
90
- backoff()
91
- connect()
92
- rescue Exception => ex
93
- logger.error ex
94
- end
95
- end
96
- end
97
-
98
- # Delay reconnection by a slowly increasing interval
99
- def backoff
100
-
101
- if @exiting or not EM.reactor_running? then
102
- # shutting down, don't try to reconnect
103
- return
104
- end
105
-
106
- @tries += 1
107
- if @tries == 1 then
108
- logger.debug "retrying immediately"
109
- elsif @tries == 2 then
110
- logger.debug "retrying every 1 sec"
111
- sleep 1
112
- elsif @tries <= 30 then
113
- sleep 1
114
- elsif @tries == 31 then
115
- logger.debug "retrying every 5 sec"
116
- sleep 5
117
- else
118
- sleep 5
119
- end
120
- end
121
-
122
- end
123
-
124
- end
125
- end