rookout 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@ module Rookout
14
14
  def initialize labels
15
15
  @agent_id = nil
16
16
  @labels = labels.clone
17
- @labels["rookout_debug"] = "on"
17
+ @labels["rookout_debug"] = "on" if Config.debug
18
18
 
19
19
  @ip_addr = local_ip
20
20
 
@@ -0,0 +1,36 @@
1
+ module Rookout
2
+ module ComWs
3
+ require_relative "../logger"
4
+
5
+ class Pinger
6
+ def initialize connection, interval, timeout
7
+ @interval = interval
8
+ @timeout = timeout
9
+ @connection = connection
10
+
11
+ @last_pong = Time.now
12
+ @last_ping = Time.now
13
+ end
14
+
15
+ def repeat
16
+ loop do
17
+ if Time.now - @last_ping > @interval
18
+ Logger.instance.debug "Sending Ping"
19
+ @last_ping = Time.now
20
+ @connection.ping Time.now.to_s do
21
+ Logger.instance.debug "Got Ping reply"
22
+ @last_pong = Time.now
23
+ end
24
+ end
25
+
26
+ if Time.now - @last_pong > @timeout
27
+ Logger.instance.debug "Ping timeout"
28
+ break
29
+ end
30
+
31
+ yield
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,143 @@
1
+ module Rookout
2
+ module ComWs
3
+ require "openssl"
4
+ require "websocket/driver"
5
+
6
+ require_relative "../config"
7
+ require_relative "../logger"
8
+ require_relative "../exceptions"
9
+
10
+ class WebsocketClient
11
+ def initialize url, proxy, token
12
+ @token = token
13
+ @connection = WebsocketConnection.new url, proxy
14
+ @driver = nil
15
+ @error = nil
16
+ @last_ping = nil
17
+ end
18
+
19
+ def connect
20
+ # TODO: add proxy support
21
+ @connection.connect
22
+ @driver = WebSocket::Driver.client @connection
23
+
24
+ headers.each do |key, value|
25
+ @driver.set_header key, value
26
+ end
27
+
28
+ @driver.on :error do |error|
29
+ @error = error
30
+ end
31
+
32
+ # Connect to the remote server
33
+ @driver.start
34
+ # TODO: ADD CONNECT TIMEOUT
35
+ while @driver.state == :connecting
36
+ recv_data = @connection.read_char
37
+ @driver.parse recv_data
38
+ end
39
+
40
+ raise Exceptions::RookWebsocketException, @error if @driver.state != :open
41
+ end
42
+
43
+ def connection_pump message_handler
44
+ @driver.on :message do |e|
45
+ message_handler.call e.data
46
+ end
47
+
48
+ until @driver.state == :closed
49
+ recv_data = @connection.read_char
50
+ @driver.parse recv_data
51
+ end
52
+ end
53
+
54
+ def send_frame msg
55
+ @driver.binary msg
56
+ end
57
+
58
+ def ping message, &callback
59
+ @driver.ping message, &callback
60
+ end
61
+
62
+ def close
63
+ return if @driver.nil?
64
+
65
+ @driver.close
66
+ @connection.close
67
+ end
68
+
69
+ private
70
+
71
+ def headers
72
+ result = {
73
+ "User-Agent" => "RookoutAgent/#{Config.rookout_version}+#{Config.rookout_commit}"
74
+ }
75
+
76
+ result["X-Rookout-Token"] = @token unless @token.nil?
77
+
78
+ result
79
+ end
80
+ end
81
+
82
+ class WebsocketConnection
83
+ def initialize url, proxy
84
+ @url = url
85
+ @proxy = proxy
86
+
87
+ @uri = URI.parse @url
88
+ @secure = %w[https wss].include? @uri.scheme
89
+
90
+ @socket = nil
91
+ end
92
+
93
+ def connect
94
+ if @secure
95
+ @socket = ssl_connect
96
+ else
97
+ @socket = tcp_connect
98
+ end
99
+ end
100
+
101
+ attr_reader :url
102
+
103
+ def read_char
104
+ @socket.getc
105
+ end
106
+
107
+ def write buffer
108
+ @socket << buffer
109
+ end
110
+
111
+ def close
112
+ return if @socket.nil?
113
+
114
+ @socket.close
115
+ @socket = nil
116
+ end
117
+
118
+ private
119
+
120
+ def tcp_connect
121
+ TCPSocket.new @uri.host,
122
+ @uri.port || (@secure ? 443 : 80)
123
+ end
124
+
125
+ def ssl_connect
126
+ tcp_socket = tcp_connect
127
+
128
+ ctx = ::OpenSSL::SSL::SSLContext.new
129
+ ctx.min_version = ::OpenSSL::SSL::TLS1_2_VERSION
130
+ cert_store = ::OpenSSL::X509::Store.new
131
+ cert_store.set_default_paths
132
+ ctx.cert_store = cert_store
133
+
134
+ ssl_socket = ::OpenSSL::SSL::SSLSocket.new tcp_socket, ctx
135
+ ssl_socket.hostname = @uri.host
136
+ ssl_socket.sync_close = true
137
+ ssl_socket.connect
138
+
139
+ ssl_socket
140
+ end
141
+ end
142
+ end
143
+ end
@@ -1,5 +1,6 @@
1
1
  module Rookout
2
2
  require_relative "version"
3
+ require_relative "commit"
3
4
 
4
5
  module Config
5
6
  # Magic to allow for module variables to be easily accessible
@@ -136,5 +136,45 @@ module Rookout
136
136
  super "No Rookout token was supplied. Make sure to pass the Rookout Token when starting the rook"
137
137
  end
138
138
  end
139
+
140
+ class RookInvalidOptions < ToolException
141
+ def initialize description
142
+ super description
143
+ end
144
+ end
145
+
146
+ class RookCrcMismatchException < ToolException
147
+ def initialize filepath, expected, calculated
148
+ super "Line CRC32s do not match! path: #{filepath}, expected: #{expected}, calculated:#{calculated}",
149
+ {
150
+ "filepath" => filepath,
151
+ "expected" => expected,
152
+ "calculated" => calculated
153
+ }
154
+ end
155
+ end
156
+
157
+ class RookLineMoved < ToolException
158
+ def initialize filepath, old_line_no, new_line_no
159
+ super "Line has moved! path: #{filepath}, original line no: #{old_line_no}, new line no: #{new_line_no}",
160
+ {
161
+ "filepath" => filepath,
162
+ "old_line_no" => old_line_no,
163
+ "new_line_no" => new_line_no
164
+ }
165
+ end
166
+ end
167
+
168
+ class RookCommunicationException < ToolException
169
+ def initialize
170
+ super "Failed to connect to the controller - will continue attempting in the background"
171
+ end
172
+ end
173
+
174
+ class RookWebsocketException < ToolException
175
+ def initialize error
176
+ super "Error from Websocket #{error}", { "error" => error }
177
+ end
178
+ end
139
179
  end
140
180
  end
@@ -5,6 +5,7 @@ module Rookout
5
5
 
6
6
  require_relative "config"
7
7
  require_relative "exceptions"
8
+ include Exceptions
8
9
 
9
10
  def initialize
10
11
  @rook = nil
@@ -19,24 +20,21 @@ module Rookout
19
20
  require_relative "rookout_singleton"
20
21
 
21
22
  configure_logging options
22
- labels = options[:labels] || parse_labels(ENV["ROOKOUT_LABELS"])
23
- validate_labels labels
24
-
25
23
  configure_git options
26
24
 
27
- com = configure_com options
28
-
29
- async_start = true? ENV["ROOKOUT_ASYNC_START"]
30
- fork = evaluate_flag options[:fork], "ROOKOUT_ENABLE_FORK"
31
-
32
- print_config com, labels: labels, async_start: async_start, fork: fork if Config.debug
25
+ start_options = configure_start_options options
26
+ print_config start_options
33
27
 
34
28
  rook = RookoutSingleton.instance
35
- rook.connect com[:token], com[:host], com[:port], com[:proxy], labels, async_start, fork
36
-
37
- # TODO: ADD DETAILED PROCESSING FOR SPECIFIC ERRORS
29
+ rook.connect(**start_options)
30
+ rescue RookMissingToken, RookInvalidToken, RookInvalidOptions, RookVersionNotSupported => e
31
+ raise if throw_errors
32
+ STDERR.puts "[Rookout] Failed to start Rookout: #{e.message}"
33
+ rescue RookCommunicationException => e
34
+ raise if throw_errors
35
+ STDERR.puts "[Rookout] " + e.message
38
36
  rescue Exception => e
39
- puts e.full_message if Config.debug
37
+ STDERR.puts e.full_message if Config.debug
40
38
  raise if throw_errors
41
39
  end
42
40
  end
@@ -59,7 +57,7 @@ module Rookout
59
57
  def configure_logging options
60
58
  if Config.debug
61
59
  log_to_stderr = true
62
- log_level = "DEBUG"
60
+ log_level = :DEBUG
63
61
  else
64
62
  log_to_stderr = evaluate_flag options[:log_to_stderr], "ROOKOUT_LOG_TO_STDERR"
65
63
  log_level = options[:log_level] || ENV["ROOKOUT_LOG_FILE"]
@@ -77,16 +75,22 @@ module Rookout
77
75
  Config.user_git_commit = options[:git_commit] if options[:git_commit]
78
76
  end
79
77
 
80
- def configure_com options
78
+ def configure_start_options options
81
79
  host = evaluate_config options[:host], "ROOKOUT_CONTROLLER_HOST", "wss://control.rookout.com"
82
80
  port = evaluate_config options[:port], "ROOKOUT_CONTROLLER_PORT", 443
83
81
  proxy = evaluate_config options[:proxy], "ROOKOUT_PROXY"
84
82
  token = evaluate_config options[:token], "ROOKOUT_TOKEN"
85
83
 
86
- raise Exceptions::RookMissingToken if token.nil? && host == "wss://control.rookout.com"
84
+ raise RookMissingToken if token.nil? && host == "wss://control.rookout.com"
87
85
  verify_token token if token
88
86
 
89
- { host: host, port: port, proxy: proxy, token: token }
87
+ labels = options[:labels] || parse_labels(ENV["ROOKOUT_LABELS"])
88
+ validate_labels labels
89
+
90
+ async_start = true? ENV["ROOKOUT_ASYNC_START"]
91
+ fork = evaluate_flag options[:fork], "ROOKOUT_ENABLE_FORK"
92
+
93
+ { host: host, port: port, proxy: proxy, token: token, labels: labels, async_start: async_start, fork: fork }
90
94
  end
91
95
 
92
96
  def evaluate_flag argument, env_var_name
@@ -120,21 +124,22 @@ module Rookout
120
124
  def validate_labels labels
121
125
  labels.each do |label_name, _|
122
126
  if label_name.start_with? "$"
123
- raise Exceptions::RookInvalidLabel, label_name
127
+ raise RookInvalidLabel, label_name
124
128
  end
125
129
  end
126
130
  end
127
131
 
128
132
  def verify_token token
129
- raise Exceptions::RookInvalidOptions, "Rookout token should be a String" unless token.is_a? String
130
- raise Exceptions::RookInvalidOptions, "Rookout token should be 64 characters" unless token.length == 64
131
- raise Exceptions::RookInvalidOptions, "Rookout token must consist of only hexadecimal characters" unless
133
+ raise RookInvalidOptions, "Rookout token should be a String" unless token.is_a? String
134
+ raise RookInvalidOptions, "Rookout token should be 64 characters" unless token.length == 64
135
+ raise RookInvalidOptions, "Rookout token must consist of only hexadecimal characters" unless
132
136
  token.match(/^[0-9a-zA-Z]{0,64}$/)
133
137
  end
134
138
 
135
- def print_config com, options
136
- puts "[Rookout] Communication Options: #{com}"
137
- puts "[Rookout] Other Options #{options}"
139
+ def print_config options
140
+ return unless Config.debug
141
+
142
+ puts "[Rookout] Start Options: #{options}"
138
143
  end
139
144
  end
140
145
  end
@@ -11,6 +11,14 @@ module Rookout
11
11
  LOG_LEVELS = [:DEBUG, :INFO, :WARNING, :ERROR].freeze
12
12
 
13
13
  def initialize
14
+ # Detect unit tests
15
+ if ($PROGRAM_NAME.end_with?("minitest_runner.rb") ||
16
+ $PROGRAM_NAME.end_with?("tunit_or_minitest_in_folder_runner.rb")) &&
17
+ Dir.pwd.end_with?("ruby-sdk")
18
+ Config.logger_log_level = :DEBUG
19
+ Config.logger_log_to_stderr = true
20
+ end
21
+
14
22
  @verbosity = LOG_LEVELS.index(Config.logger_log_level) || LOG_LEVELS.index(:INFO)
15
23
 
16
24
  @output = nil
@@ -43,7 +51,6 @@ module Rookout
43
51
  end
44
52
 
45
53
  def exception message, exc
46
- # TODO: REVIEW HOW TO REPORT EXCEPTIONS
47
54
  error message, exc
48
55
  end
49
56
 
@@ -54,7 +61,14 @@ module Rookout
54
61
  @level = level
55
62
  @time = Time.new
56
63
  @message = message
57
- @formatted_message = message % arguments
64
+ @formatted_message = @message % arguments
65
+
66
+ arguments.each do |argument|
67
+ if argument.is_a? Exception
68
+ @formatted_message += "\n" + argument.message + "\n" + argument.backtrace.join("\n\t")
69
+ end
70
+ end
71
+
58
72
  @arguments = arguments
59
73
  set_caller
60
74
  end
@@ -17,7 +17,7 @@ module Rookout
17
17
  Logger.instance.exception message, e
18
18
 
19
19
  error = RookError.new e, message
20
- variant = error.dumps
20
+ variant.error_value = error.dumps
21
21
  end
22
22
  variant
23
23
  end
@@ -4,7 +4,7 @@ module Rookout
4
4
  class Namespace
5
5
  require_relative "../../exceptions"
6
6
  def call_method name, _args
7
- raise Exceptions::RookMethodNotFound, self.class.to_s, name
7
+ raise Exceptions::RookMethodNotFound.new(self.class.to_s, name)
8
8
  end
9
9
 
10
10
  def read_attribute name
@@ -12,7 +12,7 @@ module Rookout
12
12
  end
13
13
 
14
14
  def write_attribute name, _value
15
- raise Exceptions::RookWriteAttributeNotSupported, self.class.to_s, name
15
+ raise Exceptions::RookWriteAttributeNotSupported.new(self.class.to_s, name)
16
16
  end
17
17
 
18
18
  def read_key key
@@ -6,7 +6,7 @@ module Rookout
6
6
 
7
7
  require_relative "../../protobuf/variant_pb"
8
8
 
9
- class RubyUtilsNamespace < Namespace
9
+ class NoopNamespace < Namespace
10
10
  def initialize
11
11
  super
12
12
  end
@@ -17,7 +17,7 @@ module Rookout
17
17
  Logger.instance.exception message, e
18
18
 
19
19
  error = RookError.new e, message
20
- variant = error.dumps
20
+ variant.error_value = error.dumps
21
21
  end
22
22
  variant
23
23
  end
@@ -29,7 +29,7 @@ module Rookout
29
29
 
30
30
  if obj.nil?
31
31
  dump_nil variant
32
- elsif obj.is_a?(Numeric) || obj == true || obj == false
32
+ elsif obj.is_a?(Numeric) || obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
33
33
  dump_numeric obj, variant
34
34
  elsif obj.is_a?(String) || obj.is_a?(Symbol)
35
35
  dump_string obj, variant, config
@@ -104,7 +104,7 @@ module Rookout
104
104
  variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
105
105
  imaginary: obj.imaginary.to_f
106
106
  else
107
- raise Exceptions.RookClassCannotBeSerialized, obj.class, "Unknown Numeric Type"
107
+ raise Exceptions::RookClassCannotBeSerialized.new(obj.class, "Unknown Numeric Type")
108
108
  end
109
109
  # TODO: ADD SUPPORT FOR RATIONALS
110
110
  end