tcell_agent 0.2.21 → 0.2.22

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tcell_agent.rb +1 -0
  3. data/lib/tcell_agent/api.rb +3 -2
  4. data/lib/tcell_agent/appsensor/injections_matcher.rb +137 -0
  5. data/lib/tcell_agent/appsensor/injections_reporter.rb +67 -0
  6. data/lib/tcell_agent/appsensor/meta_data.rb +71 -0
  7. data/lib/tcell_agent/appsensor/rules/appsensor_rule_manager.rb +5 -2
  8. data/lib/tcell_agent/appsensor/rules/appsensor_rule_set.rb +1 -1
  9. data/lib/tcell_agent/appsensor/sensor.rb +48 -0
  10. data/lib/tcell_agent/configuration.rb +15 -2
  11. data/lib/tcell_agent/instrumentation.rb +3 -2
  12. data/lib/tcell_agent/logger.rb +19 -3
  13. data/lib/tcell_agent/patches.rb +26 -0
  14. data/lib/tcell_agent/patches/block_rule.rb +58 -0
  15. data/lib/tcell_agent/patches/meta_data.rb +54 -0
  16. data/lib/tcell_agent/patches/sensors_matcher.rb +30 -0
  17. data/lib/tcell_agent/policies/appsensor/cmdi_sensor.rb +4 -0
  18. data/lib/tcell_agent/policies/appsensor/database_sensor.rb +7 -3
  19. data/lib/tcell_agent/policies/appsensor/fpt_sensor.rb +4 -0
  20. data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +32 -38
  21. data/lib/tcell_agent/policies/appsensor/misc_sensor.rb +4 -4
  22. data/lib/tcell_agent/policies/appsensor/nullbyte_sensor.rb +4 -0
  23. data/lib/tcell_agent/policies/appsensor/payloads_policy.rb +3 -1
  24. data/lib/tcell_agent/policies/appsensor/response_codes_sensor.rb +3 -3
  25. data/lib/tcell_agent/policies/appsensor/retr_sensor.rb +4 -0
  26. data/lib/tcell_agent/policies/appsensor/size_sensor.rb +9 -3
  27. data/lib/tcell_agent/policies/appsensor/user_agent_sensor.rb +3 -3
  28. data/lib/tcell_agent/policies/appsensor_policy.rb +55 -131
  29. data/lib/tcell_agent/policies/content_security_policy.rb +148 -137
  30. data/lib/tcell_agent/policies/patches_policy.rb +41 -13
  31. data/lib/tcell_agent/rails.rb +11 -109
  32. data/lib/tcell_agent/rails/auth/devise.rb +5 -1
  33. data/lib/tcell_agent/rails/dlp.rb +5 -2
  34. data/lib/tcell_agent/rails/dlp/process_request.rb +88 -0
  35. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +1 -1
  36. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +3 -13
  37. data/lib/tcell_agent/rails/on_start.rb +5 -101
  38. data/lib/tcell_agent/rails/routes.rb +240 -81
  39. data/lib/tcell_agent/rails/routes/grape.rb +113 -0
  40. data/lib/tcell_agent/rails/routes/route_id.rb +29 -0
  41. data/lib/tcell_agent/sensor_events/app_config.rb +21 -13
  42. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +7 -26
  43. data/lib/tcell_agent/servers/passenger.rb +10 -0
  44. data/lib/tcell_agent/start_background_thread.rb +82 -0
  45. data/lib/tcell_agent/utils/params.rb +1 -1
  46. data/lib/tcell_agent/version.rb +1 -1
  47. data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +504 -0
  48. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +222 -0
  49. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +7 -13
  50. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_set_spec.rb +18 -18
  51. data/spec/lib/tcell_agent/patches/block_rule_spec.rb +381 -0
  52. data/spec/lib/tcell_agent/patches/sensors_matcher_spec.rb +35 -0
  53. data/spec/lib/tcell_agent/patches_spec.rb +156 -0
  54. data/spec/lib/tcell_agent/policies/appsensor/cmdi_sensor_spec.rb +21 -10
  55. data/spec/lib/tcell_agent/policies/appsensor/fpt_sensor_spec.rb +20 -9
  56. data/spec/lib/tcell_agent/policies/appsensor/nullbyte_sensor_spec.rb +44 -9
  57. data/spec/lib/tcell_agent/policies/appsensor/request_size_sensor_spec.rb +4 -4
  58. data/spec/lib/tcell_agent/policies/appsensor/response_codes_sensor_spec.rb +13 -13
  59. data/spec/lib/tcell_agent/policies/appsensor/response_size_sensor_spec.rb +5 -5
  60. data/spec/lib/tcell_agent/policies/appsensor/retr_sensor_spec.rb +20 -9
  61. data/spec/lib/tcell_agent/policies/appsensor/sqli_sensor_spec.rb +24 -14
  62. data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +243 -241
  63. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +128 -200
  64. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +126 -55
  65. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +485 -24
  66. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +5 -0
  67. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +4 -2
  68. data/spec/lib/tcell_agent/rails/routes/grape_spec.rb +294 -0
  69. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +80 -0
  70. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +182 -0
  71. metadata +30 -7
  72. data/lib/tcell_agent/policies/appsensor/login_sensor.rb +0 -39
  73. data/lib/tcell_agent/policies/appsensor/sensor.rb +0 -46
  74. data/lib/tcell_agent/rails/path_parameters_setter.rb +0 -43
  75. data/spec/lib/tcell_agent/policies/appsensor/login_sensor_spec.rb +0 -104
@@ -41,6 +41,11 @@ module TCellAgent
41
41
  subject { withTCellMiddleware( app ) }
42
42
 
43
43
  context "Appsensor Middleware" do
44
+ before(:all) do
45
+ # need to ensure default rules file is loaded
46
+ AppSensorRuleManager.instance.load_default_rules_file
47
+ end
48
+
44
49
  before(:each) do
45
50
  TCellAgent.configuration = TCellAgent::Configuration.new
46
51
  TCellAgent.configuration.read_config_from_file(get_test_resource_path("normal_config.json"))
@@ -2,6 +2,8 @@ require 'spec_helper'
2
2
  require 'rack/test'
3
3
  require 'rack'
4
4
 
5
+ require 'tcell_agent/rails/dlp/process_request'
6
+
5
7
  module TCellAgent
6
8
  module Instrumentation
7
9
  module Rails
@@ -58,7 +60,7 @@ module TCellAgent
58
60
  tcell_context.add_response_db_filter("secretvalue", action_obj, "databx", "*", "tablex", "columnb")
59
61
  end
60
62
  end
61
- TCellAgent::AroundFilters.handle_request_dlp_parameters(rack_request)
63
+ TCellAgent::DLP.handle_request_dlp_parameters(rack_request)
62
64
  #if tcell_context && dlp_policy && dlp_policy.has_actions_for_form_parameter?
63
65
  # for_params(rack_request) { |method, param_name, param_value|
64
66
  # actions = dlp_policy.get_actions_for_form_parameter(param_name, tcell_context.route_id)
@@ -167,4 +169,4 @@ module TCellAgent
167
169
  end
168
170
  end
169
171
  end
170
- end
172
+ end
@@ -0,0 +1,294 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ module Instrumentation
5
+
6
+ # Fake out grape gem
7
+ module Grape
8
+ class API
9
+ end
10
+ end
11
+
12
+ class GrapeRoute < Grape::API
13
+ end
14
+
15
+ class RegularRoute
16
+ end
17
+
18
+ describe ".grape_route?" do
19
+ context "rails 3" do
20
+ context "with a regular route" do
21
+ it "should return false" do
22
+ stub_const("::Rails::VERSION::MAJOR", 3)
23
+ stub_const("::Rails::VERSION::MINOR", 0)
24
+
25
+ route = double("route", app: RegularRoute.new)
26
+
27
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
28
+
29
+ expect(is_grape_route).to eq(false)
30
+ end
31
+ end
32
+
33
+ context "with a grape route" do
34
+ it "should return false" do
35
+ stub_const("::Rails::VERSION::MAJOR", 3)
36
+ stub_const("::Rails::VERSION::MINOR", 0)
37
+
38
+ route = double("route", app: GrapeRoute)
39
+
40
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
41
+
42
+ expect(is_grape_route).to eq(false)
43
+ end
44
+ end
45
+ end
46
+
47
+ context "rails 4.0" do
48
+ context "with a regular route" do
49
+ it "should return false" do
50
+ stub_const("::Rails::VERSION::MAJOR", 4)
51
+ stub_const("::Rails::VERSION::MINOR", 0)
52
+
53
+ route = double("route", app: RegularRoute.new)
54
+
55
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
56
+
57
+ expect(is_grape_route).to eq(false)
58
+ end
59
+ end
60
+
61
+ context "with a grape route" do
62
+ it "should return true" do
63
+ stub_const("::Rails::VERSION::MAJOR", 4)
64
+ stub_const("::Rails::VERSION::MINOR", 0)
65
+
66
+ route = double("route", app: GrapeRoute)
67
+
68
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
69
+
70
+ expect(is_grape_route).to eq(true)
71
+ end
72
+ end
73
+ end
74
+
75
+ context "rails 4.1" do
76
+ context "with a regular route" do
77
+ it "should return false" do
78
+ stub_const("::Rails::VERSION::MAJOR", 4)
79
+ stub_const("::Rails::VERSION::MINOR", 1)
80
+
81
+ route = double("route", app: RegularRoute.new)
82
+
83
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
84
+
85
+ expect(is_grape_route).to eq(false)
86
+ end
87
+ end
88
+
89
+ context "with a grape route" do
90
+ it "should return true" do
91
+ stub_const("::Rails::VERSION::MAJOR", 4)
92
+ stub_const("::Rails::VERSION::MINOR", 1)
93
+
94
+ route = double("route", app: GrapeRoute)
95
+
96
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
97
+
98
+ expect(is_grape_route).to eq(true)
99
+ end
100
+ end
101
+ end
102
+
103
+ context "rails 4.2" do
104
+ context "with a regular route" do
105
+ it "should return false" do
106
+ stub_const("::Rails::VERSION::MAJOR", 4)
107
+ stub_const("::Rails::VERSION::MINOR", 2)
108
+
109
+ route = double("route", app: double("app", app: RegularRoute.new))
110
+
111
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
112
+
113
+ expect(is_grape_route).to eq(false)
114
+ end
115
+ end
116
+
117
+ context "with a grape route" do
118
+ it "should return true" do
119
+ stub_const("::Rails::VERSION::MAJOR", 4)
120
+ stub_const("::Rails::VERSION::MINOR", 2)
121
+
122
+ route = double("route", app: double("app", app: GrapeRoute))
123
+
124
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
125
+
126
+ expect(is_grape_route).to eq(true)
127
+ end
128
+ end
129
+ end
130
+
131
+ context "rails 5.0" do
132
+ context "with a regular route" do
133
+ it "should return false" do
134
+ stub_const("::Rails::VERSION::MAJOR", 5)
135
+ stub_const("::Rails::VERSION::MINOR", 0)
136
+
137
+ route = double("route", app: double("app", app: RegularRoute.new))
138
+
139
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
140
+
141
+ expect(is_grape_route).to eq(false)
142
+ end
143
+ end
144
+
145
+ context "with a grape route" do
146
+ it "should return true" do
147
+ stub_const("::Rails::VERSION::MAJOR", 5)
148
+ stub_const("::Rails::VERSION::MINOR", 0)
149
+
150
+ route = double("route", app: double("app", app: GrapeRoute))
151
+
152
+ is_grape_route = TCellAgent::Instrumentation.grape_route?(route)
153
+
154
+ expect(is_grape_route).to eq(true)
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ describe ".grape_route_info" do
161
+
162
+ context "with grape version 0.10.1" do
163
+ it "should use route_method and route_path" do
164
+ route = double("route")
165
+ grape_gem = double("grape_gem", version: "0.10.1")
166
+
167
+ expect(Gem).to receive(:loaded_specs).and_return({
168
+ "grape" => grape_gem
169
+ })
170
+ expect(route).to receive(:route_method).and_return("POST")
171
+ expect(route).to receive(:route_path).and_return("/grape_api/endpoint")
172
+
173
+ route_info = TCellAgent::Instrumentation.grape_route_info(route)
174
+
175
+ expect(route_info[:method]).to eq("POST")
176
+ expect(route_info[:path]).to eq("/grape_api/endpoint")
177
+ end
178
+ end
179
+
180
+ context "with grape version 0.16.0" do
181
+ it "should use request_method and path" do
182
+ route = double("route")
183
+ grape_gem = double("grape_gem", version: "0.16.0")
184
+
185
+ expect(Gem).to receive(:loaded_specs).and_return({
186
+ "grape" => grape_gem
187
+ })
188
+ expect(route).to receive(:request_method).and_return("POST")
189
+ expect(route).to receive(:path).and_return("/grape_api/endpoint")
190
+
191
+ route_info = TCellAgent::Instrumentation.grape_route_info(route)
192
+
193
+ expect(route_info[:method]).to eq("POST")
194
+ expect(route_info[:path]).to eq("/grape_api/endpoint")
195
+ end
196
+ end
197
+
198
+ end
199
+
200
+ describe ".instrument_grape_api" do
201
+
202
+ context "with nil routes" do
203
+ it "should not send any events" do
204
+ expect(TCellAgent::SensorEvents::Util).to_not receive(:calculateRouteId)
205
+ TCellAgent::Instrumentation.instrument_grape_api("/api", nil)
206
+ end
207
+ end
208
+
209
+ context "with empty routes" do
210
+ it "should not send any events" do
211
+ expect(TCellAgent::SensorEvents::Util).to_not receive(:calculateRouteId)
212
+ TCellAgent::Instrumentation.instrument_grape_api("/api", [])
213
+ end
214
+ end
215
+
216
+ context "with grape version < 1.16" do
217
+ before(:each) do
218
+ grape_gem = double("grape_gem", version: "0.10.1")
219
+
220
+ expect(Gem).to receive(:loaded_specs).and_return({
221
+ "grape" => grape_gem
222
+ }).at_least(1)
223
+ end
224
+
225
+ context "with one route" do
226
+ it "should send one event" do
227
+ route = double("grape_route", route_method: "GET", route_path: "/users")
228
+
229
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
230
+ "/api/users", "GET", "409553642", nil, nil
231
+ ).and_call_original
232
+
233
+ TCellAgent::Instrumentation.instrument_grape_api("/api", [route])
234
+ end
235
+ end
236
+
237
+ context "with two routes" do
238
+ it "should send two events" do
239
+ route = double("grape_route", route_method: "GET", route_path: "/users")
240
+ route_dos = double("grape_route", route_method: "POST", route_path: "/users")
241
+
242
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
243
+ "/api/users", "GET", "409553642", nil, nil
244
+ ).and_call_original
245
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
246
+ "/api/users", "POST", "-2105512096", nil, nil
247
+ ).and_call_original
248
+
249
+ TCellAgent::Instrumentation.instrument_grape_api("/api", [route, route_dos])
250
+ end
251
+ end
252
+ end
253
+
254
+ context "with grape version >= 1.16" do
255
+ before(:each) do
256
+ grape_gem = double("grape_gem", version: "0.16.0")
257
+
258
+ expect(Gem).to receive(:loaded_specs).and_return({
259
+ "grape" => grape_gem
260
+ }).at_least(1)
261
+ end
262
+
263
+ context "with one route" do
264
+ it "should send one event" do
265
+ route = double("grape_route", request_method: "GET", path: "/users")
266
+
267
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
268
+ "/api/users", "GET", "409553642", nil, nil
269
+ ).and_call_original
270
+
271
+ TCellAgent::Instrumentation.instrument_grape_api("/api", [route])
272
+ end
273
+ end
274
+
275
+ context "with two routes" do
276
+ it "should send two events" do
277
+ route = double("grape_route", request_method: "GET", path: "/users")
278
+ route_dos = double("grape_route", request_method: "POST", path: "/users")
279
+
280
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
281
+ "/api/users", "GET", "409553642", nil, nil
282
+ ).and_call_original
283
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
284
+ "/api/users", "POST", "-2105512096", nil, nil
285
+ ).and_call_original
286
+
287
+ TCellAgent::Instrumentation.instrument_grape_api("/api", [route, route_dos])
288
+ end
289
+ end
290
+ end
291
+ end
292
+
293
+ end
294
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ module Instrumentation
5
+
6
+ describe RouteId do
7
+ TCELL_CONTEXT_KEY = TCellAgent::Instrumentation::TCELL_ID
8
+
9
+ describe ".update_context" do
10
+
11
+ context "with nil route" do
12
+ it "should not set anything" do
13
+ tcell_context = TCellData.new
14
+ tcell_context.route_id = nil
15
+
16
+ RouteId.update_context({TCELL_CONTEXT_KEY => tcell_context}, {}, nil)
17
+
18
+ expect(tcell_context.route_id).to eq(nil)
19
+ expect(tcell_context.grape_mount_endpoint).to eq(nil)
20
+ expect(tcell_context.path_parameters).to eq(nil)
21
+ end
22
+ end
23
+
24
+ context "with nil context" do
25
+ it "should not set anything "do
26
+ route = double("route")
27
+ expect(route).to_not receive(:path)
28
+
29
+ RouteId.update_context({}, {}, route)
30
+ end
31
+ end
32
+
33
+ context "with a regular route and parameters" do
34
+ it "should set the route id" do
35
+ tcell_context = TCellData.new
36
+ tcell_context.route_id = nil
37
+ tcell_context.request_method = "GET"
38
+
39
+ route = double(
40
+ "route",
41
+ path: double("path", spec: "/some/regular/path"))
42
+
43
+ expect(TCellAgent::Instrumentation).to receive(:grape_route?).with(route).and_return(false)
44
+
45
+ RouteId.update_context({TCELL_CONTEXT_KEY => tcell_context}, {id: 1}, route)
46
+
47
+ expect(tcell_context.route_id).to eq(
48
+ TCellAgent::SensorEvents::Util.calculateRouteId("GET", "/some/regular/path")
49
+ )
50
+ expect(tcell_context.grape_mount_endpoint).to eq(nil)
51
+ expect(tcell_context.path_parameters).to eq({id: 1})
52
+ end
53
+ end
54
+
55
+ context "with a grape route and parameters" do
56
+ it "should set the grape mount endpoint" do
57
+ tcell_context = TCellData.new
58
+ tcell_context.route_id = nil
59
+ tcell_context.request_method = "GET"
60
+
61
+ route = double(
62
+ "route",
63
+ path: double("path", spec: "/grape_api"))
64
+
65
+ expect(TCellAgent::Instrumentation).to receive(:grape_route?).with(route).and_return(true)
66
+
67
+ RouteId.update_context({TCELL_CONTEXT_KEY => tcell_context}, {id: 1}, route)
68
+
69
+ expect(tcell_context.route_id).to eq(nil)
70
+ expect(tcell_context.grape_mount_endpoint).to eq("/grape_api")
71
+ expect(tcell_context.path_parameters).to eq({id: 1})
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ module Instrumentation
5
+
6
+ # Fake out grape gem
7
+ module Grape
8
+ class API
9
+ end
10
+ end
11
+
12
+ class GrapeRoute < Grape::API
13
+
14
+ def self.routes
15
+ ["/api/grape/route"]
16
+ end
17
+
18
+ end
19
+
20
+ describe ".instrument_route" do
21
+ context "with a nil route" do
22
+ it "shouldn't be reported" do
23
+ configuration = double("configuration", enabled: true, should_instrument?: true)
24
+
25
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).twice()
26
+ expect(TCellAgent::Instrumentation).to_not receive(:instrument_grape_api)
27
+ expect(TCellAgent::SensorEvents::Util).to_not receive(:calculateRouteId)
28
+
29
+ Rails.instrument_route(nil)
30
+ end
31
+ end
32
+
33
+ context "with rails 5.0" do
34
+ context "with a regular route" do
35
+ it "should report it" do
36
+ stub_const("::Rails::VERSION::MAJOR", 5)
37
+ stub_const("::Rails::VERSION::MINOR", 0)
38
+
39
+ configuration = double("configuration", enabled: true, should_instrument?: true)
40
+ route = double(
41
+ "route",
42
+ path: double("path", spec: "/regular/route"),
43
+ defaults: {},
44
+ app: double("app", app: "some_app"))
45
+
46
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).twice()
47
+ expect(route).to receive(:verb).and_return("GET|POST").twice()
48
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
49
+ "/regular/route", "GET", "-1187510355", nil, "{}"
50
+ ).and_call_original
51
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
52
+ "/regular/route", "POST", "1100742947", nil, "{}"
53
+ ).and_call_original
54
+
55
+ Rails.instrument_route(route)
56
+ end
57
+ end
58
+
59
+ context "with a grape route" do
60
+ it "should instrument the grape endpoint" do
61
+ stub_const("::Rails::VERSION::MAJOR", 5)
62
+ stub_const("::Rails::VERSION::MINOR", 0)
63
+
64
+ configuration = double("configuration", enabled: true, should_instrument?: true)
65
+ route = double(
66
+ "route",
67
+ path: double("path", spec: "/grape"),
68
+ defaults: {},
69
+ app: double("app", app: GrapeRoute))
70
+
71
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).twice()
72
+ expect(route).to receive(:verb).and_return("GET|POST")
73
+ expect(TCellAgent::SensorEvents::Util).to_not receive(:calculateRouteId)
74
+ expect(TCellAgent::Instrumentation).to receive(:instrument_grape_api).with(
75
+ "/grape", ["/api/grape/route"]
76
+ )
77
+
78
+ Rails.instrument_route(route)
79
+ end
80
+ end
81
+ end
82
+
83
+ context "with rails 4.2" do
84
+ context "with a regular route" do
85
+ it "should report it" do
86
+ stub_const("::Rails::VERSION::MAJOR", 4)
87
+ stub_const("::Rails::VERSION::MINOR", 2)
88
+
89
+ configuration = double("configuration", enabled: true, should_instrument?: true)
90
+ route = double(
91
+ "route",
92
+ path: double("path", spec: "/regular/route"),
93
+ defaults: {},
94
+ constraints: {request_method: "DELETE"},
95
+ app: double("app", app: "some_app"))
96
+
97
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).twice()
98
+ expect(TCellAgent::Instrumentation).to_not receive(:instrument_grape_api)
99
+ expect(route).to receive(:verb).and_return(/DELETE/).at_least(9)
100
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
101
+ "/regular/route", "DELETE", "-990446408", nil, "{}"
102
+ ).and_call_original
103
+
104
+ Rails.instrument_route(route)
105
+ end
106
+ end
107
+
108
+ context "with a grape route" do
109
+ it "should instrument the grape endpoint" do
110
+ stub_const("::Rails::VERSION::MAJOR", 4)
111
+ stub_const("::Rails::VERSION::MINOR", 2)
112
+
113
+ configuration = double("configuration", enabled: true, should_instrument?: true)
114
+ route = double(
115
+ "route",
116
+ path: double("path", spec: "/grape"),
117
+ defaults: {},
118
+ constraints: {request_method: "PUT"},
119
+ app: double("app", app: GrapeRoute))
120
+
121
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).twice()
122
+ expect(TCellAgent::Instrumentation).to receive(:instrument_grape_api).with(
123
+ "/grape", ["/api/grape/route"]
124
+ )
125
+ expect(TCellAgent::SensorEvents::Util).to_not receive(:calculateRouteId)
126
+
127
+ Rails.instrument_route(route)
128
+ end
129
+ end
130
+ end
131
+
132
+ context "with rails 4.1" do
133
+ context "with a regular route" do
134
+ it "should report it" do
135
+ stub_const("::Rails::VERSION::MAJOR", 4)
136
+ stub_const("::Rails::VERSION::MINOR", 1)
137
+
138
+ configuration = double("configuration", enabled: true, should_instrument?: true)
139
+ route = double(
140
+ "route",
141
+ path: double("path", spec: "/regular/route"),
142
+ defaults: {},
143
+ constraints: {request_method: "PUT"},
144
+ app: "some_app")
145
+
146
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).twice()
147
+ expect(TCellAgent::Instrumentation).to_not receive(:instrument_grape_api)
148
+ expect(route).to receive(:verb).and_return(/PUT/).at_least(9)
149
+ expect(TCellAgent::SensorEvents::AppRoutesSensorEvent).to receive(:new).with(
150
+ "/regular/route", "PUT", "-1393108268", nil, "{}"
151
+ ).and_call_original
152
+
153
+ Rails.instrument_route(route)
154
+ end
155
+ end
156
+
157
+ context "with a grape route" do
158
+ it "should instrument the grape endpoint" do
159
+ stub_const("::Rails::VERSION::MAJOR", 4)
160
+ stub_const("::Rails::VERSION::MINOR", 1)
161
+ configuration = double("configuration", enabled: true, should_instrument?: true)
162
+ route = double(
163
+ "route",
164
+ path: double("path", spec: "/grape"),
165
+ defaults: {},
166
+ constraints: {request_method: "PUT"},
167
+ app: GrapeRoute)
168
+
169
+ expect(TCellAgent).to receive(:configuration).and_return(configuration).twice()
170
+ expect(TCellAgent::Instrumentation).to receive(:instrument_grape_api).with(
171
+ "/grape", ["/api/grape/route"]
172
+ )
173
+ expect(TCellAgent::SensorEvents::Util).to_not receive(:calculateRouteId)
174
+
175
+ Rails.instrument_route(route)
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ end
182
+ end