appmap 0.31.0 → 0.34.2
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 +4 -4
- data/.gitignore +1 -1
- data/.rbenv-gemsets +1 -0
- data/CHANGELOG.md +22 -0
- data/README.md +38 -4
- data/Rakefile +10 -3
- data/appmap.gemspec +5 -0
- data/ext/appmap/appmap.c +26 -0
- data/ext/appmap/extconf.rb +6 -0
- data/lib/appmap.rb +23 -10
- data/lib/appmap/class_map.rb +13 -7
- data/lib/appmap/config.rb +54 -30
- data/lib/appmap/cucumber.rb +19 -2
- data/lib/appmap/event.rb +25 -16
- data/lib/appmap/hook.rb +52 -77
- data/lib/appmap/hook/method.rb +103 -0
- data/lib/appmap/open.rb +57 -0
- data/lib/appmap/rails/action_handler.rb +7 -7
- data/lib/appmap/rails/sql_handler.rb +10 -8
- data/lib/appmap/rspec.rb +1 -1
- data/lib/appmap/trace.rb +7 -7
- data/lib/appmap/util.rb +19 -0
- data/lib/appmap/version.rb +1 -1
- data/spec/abstract_controller4_base_spec.rb +1 -1
- data/spec/abstract_controller_base_spec.rb +9 -2
- data/spec/fixtures/hook/instance_method.rb +4 -0
- data/spec/fixtures/hook/singleton_method.rb +21 -12
- data/spec/hook_spec.rb +140 -44
- data/spec/open_spec.rb +19 -0
- data/spec/record_sql_rails_pg_spec.rb +56 -33
- data/test/cli_test.rb +12 -2
- data/test/fixtures/openssl_recorder/Gemfile +3 -0
- data/test/fixtures/openssl_recorder/appmap.yml +3 -0
- data/{spec/fixtures/hook/openssl_sign.rb → test/fixtures/openssl_recorder/lib/openssl_cert_sign.rb} +11 -4
- data/test/fixtures/openssl_recorder/lib/openssl_encrypt.rb +34 -0
- data/test/fixtures/openssl_recorder/lib/openssl_key_sign.rb +28 -0
- data/test/openssl_test.rb +203 -0
- data/test/test_helper.rb +1 -0
- metadata +58 -4
@@ -16,11 +16,11 @@ module AppMap
|
|
16
16
|
class HTTPServerRequest
|
17
17
|
include ContextKey
|
18
18
|
|
19
|
-
class Call < AppMap::Event::
|
19
|
+
class Call < AppMap::Event::MethodCall
|
20
20
|
attr_accessor :payload
|
21
21
|
|
22
|
-
def initialize(
|
23
|
-
super AppMap::Event.next_id_counter, :call,
|
22
|
+
def initialize(payload)
|
23
|
+
super AppMap::Event.next_id_counter, :call, Thread.current.object_id
|
24
24
|
|
25
25
|
self.payload = payload
|
26
26
|
end
|
@@ -47,7 +47,7 @@ module AppMap
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def call(_, started, finished, _, payload) # (name, started, finished, unique_id, payload)
|
50
|
-
event = Call.new(
|
50
|
+
event = Call.new(payload)
|
51
51
|
Thread.current[context_key] = Context.new(event.id, Time.now)
|
52
52
|
AppMap.tracing.record_event(event)
|
53
53
|
end
|
@@ -59,8 +59,8 @@ module AppMap
|
|
59
59
|
class Call < AppMap::Event::MethodReturnIgnoreValue
|
60
60
|
attr_accessor :payload
|
61
61
|
|
62
|
-
def initialize(
|
63
|
-
super AppMap::Event.next_id_counter, :return,
|
62
|
+
def initialize(payload, parent_id, elapsed)
|
63
|
+
super AppMap::Event.next_id_counter, :return, Thread.current.object_id
|
64
64
|
|
65
65
|
self.payload = payload
|
66
66
|
self.parent_id = parent_id
|
@@ -82,7 +82,7 @@ module AppMap
|
|
82
82
|
context = Thread.current[context_key]
|
83
83
|
Thread.current[context_key] = nil
|
84
84
|
|
85
|
-
event = Call.new(
|
85
|
+
event = Call.new(payload, context.id, Time.now - context.start_time)
|
86
86
|
AppMap.tracing.record_event(event)
|
87
87
|
end
|
88
88
|
end
|
@@ -5,11 +5,11 @@ require 'appmap/event'
|
|
5
5
|
module AppMap
|
6
6
|
module Rails
|
7
7
|
class SQLHandler
|
8
|
-
class SQLCall < AppMap::Event::
|
8
|
+
class SQLCall < AppMap::Event::MethodCall
|
9
9
|
attr_accessor :payload
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
super AppMap::Event.next_id_counter, :call,
|
11
|
+
def initialize(payload)
|
12
|
+
super AppMap::Event.next_id_counter, :call, Thread.current.object_id
|
13
13
|
|
14
14
|
self.payload = payload
|
15
15
|
end
|
@@ -20,7 +20,7 @@ module AppMap
|
|
20
20
|
sql: payload[:sql],
|
21
21
|
database_type: payload[:database_type]
|
22
22
|
}.tap do |sql_query|
|
23
|
-
%i[server_version
|
23
|
+
%i[server_version].each do |attribute|
|
24
24
|
sql_query[attribute] = payload[attribute] if payload[attribute]
|
25
25
|
end
|
26
26
|
end
|
@@ -29,8 +29,8 @@ module AppMap
|
|
29
29
|
end
|
30
30
|
|
31
31
|
class SQLReturn < AppMap::Event::MethodReturnIgnoreValue
|
32
|
-
def initialize(
|
33
|
-
super AppMap::Event.next_id_counter, :return,
|
32
|
+
def initialize(parent_id, elapsed)
|
33
|
+
super AppMap::Event.next_id_counter, :return, Thread.current.object_id
|
34
34
|
|
35
35
|
self.parent_id = parent_id
|
36
36
|
self.elapsed = elapsed
|
@@ -76,6 +76,8 @@ module AppMap
|
|
76
76
|
case database_type
|
77
77
|
when :postgres
|
78
78
|
ActiveRecord::Base.connection.postgresql_version
|
79
|
+
when :sqlite
|
80
|
+
ActiveRecord::Base.connection.database_version.to_s
|
79
81
|
else
|
80
82
|
warn "Unable to determine database version for #{database_type.inspect}"
|
81
83
|
end
|
@@ -133,9 +135,9 @@ module AppMap
|
|
133
135
|
|
134
136
|
SQLExaminer.examine payload, sql: sql
|
135
137
|
|
136
|
-
call = SQLCall.new(
|
138
|
+
call = SQLCall.new(payload)
|
137
139
|
AppMap.tracing.record_event(call)
|
138
|
-
AppMap.tracing.record_event(SQLReturn.new(
|
140
|
+
AppMap.tracing.record_event(SQLReturn.new(call.id, finished - started))
|
139
141
|
ensure
|
140
142
|
Thread.current[reentry_key] = nil
|
141
143
|
end
|
data/lib/appmap/rspec.rb
CHANGED
@@ -154,7 +154,7 @@ module AppMap
|
|
154
154
|
end
|
155
155
|
|
156
156
|
labels = labels.map(&:to_s).map(&:strip).reject(&:blank?).map(&:downcase).uniq
|
157
|
-
description.reject!(&:nil?).reject(&:blank?)
|
157
|
+
description.reject!(&:nil?).reject!(&:blank?)
|
158
158
|
default_description = description.last
|
159
159
|
description.reverse!
|
160
160
|
|
data/lib/appmap/trace.rb
CHANGED
@@ -14,34 +14,34 @@ module AppMap
|
|
14
14
|
|
15
15
|
class Tracing
|
16
16
|
def initialize
|
17
|
-
@
|
17
|
+
@tracing = []
|
18
18
|
end
|
19
19
|
|
20
20
|
def empty?
|
21
|
-
@
|
21
|
+
@tracing.empty?
|
22
22
|
end
|
23
23
|
|
24
24
|
def trace(enable: true)
|
25
25
|
Tracer.new.tap do |tracer|
|
26
|
-
@
|
26
|
+
@tracing << tracer
|
27
27
|
tracer.enable if enable
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
def enabled?
|
32
|
-
@
|
32
|
+
@tracing.any?(&:enabled?)
|
33
33
|
end
|
34
34
|
|
35
35
|
def record_event(event, defined_class: nil, method: nil)
|
36
|
-
@
|
36
|
+
@tracing.each do |tracer|
|
37
37
|
tracer.record_event(event, defined_class: defined_class, method: method)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def delete(tracer)
|
42
|
-
return unless @
|
42
|
+
return unless @tracing.member?(tracer)
|
43
43
|
|
44
|
-
@
|
44
|
+
@tracing.delete(tracer)
|
45
45
|
tracer.disable
|
46
46
|
end
|
47
47
|
end
|
data/lib/appmap/util.rb
CHANGED
@@ -35,6 +35,25 @@ module AppMap
|
|
35
35
|
|
36
36
|
[ fname, extension ].join
|
37
37
|
end
|
38
|
+
|
39
|
+
# sanitize_event removes ephemeral values from an event, making
|
40
|
+
# events easier to compare across runs.
|
41
|
+
def sanitize_event(event, &block)
|
42
|
+
event.delete(:thread_id)
|
43
|
+
event.delete(:elapsed)
|
44
|
+
delete_object_id = ->(obj) { (obj || {}).delete(:object_id) }
|
45
|
+
delete_object_id.call(event[:receiver])
|
46
|
+
delete_object_id.call(event[:return_value])
|
47
|
+
(event[:parameters] || []).each(&delete_object_id)
|
48
|
+
(event[:exceptions] || []).each(&delete_object_id)
|
49
|
+
|
50
|
+
case event[:event]
|
51
|
+
when :call
|
52
|
+
event[:path] = event[:path].gsub(Gem.dir + '/', '')
|
53
|
+
end
|
54
|
+
|
55
|
+
event
|
56
|
+
end
|
38
57
|
end
|
39
58
|
end
|
40
59
|
end
|
data/lib/appmap/version.rb
CHANGED
@@ -48,11 +48,11 @@ describe 'AbstractControllerBase' do
|
|
48
48
|
|
49
49
|
expect(appmap).to match(<<-CREATE_CALL.strip)
|
50
50
|
event: call
|
51
|
+
thread_id: .*
|
51
52
|
defined_class: Api::UsersController
|
52
53
|
method_id: build_user
|
53
54
|
path: app/controllers/api/users_controller.rb
|
54
55
|
lineno: 23
|
55
|
-
thread_id: .*
|
56
56
|
static: false
|
57
57
|
parameters:
|
58
58
|
- name: params
|
@@ -47,17 +47,17 @@ describe 'AbstractControllerBase' do
|
|
47
47
|
SERVER_REQUEST
|
48
48
|
end
|
49
49
|
|
50
|
-
it '
|
50
|
+
it 'properly captures method parameters in the appmap' do
|
51
51
|
expect(File).to exist(appmap_json)
|
52
52
|
appmap = JSON.parse(File.read(appmap_json)).to_yaml
|
53
53
|
|
54
54
|
expect(appmap).to match(<<-CREATE_CALL.strip)
|
55
55
|
event: call
|
56
|
+
thread_id: .*
|
56
57
|
defined_class: Api::UsersController
|
57
58
|
method_id: build_user
|
58
59
|
path: app/controllers/api/users_controller.rb
|
59
60
|
lineno: 23
|
60
|
-
thread_id: .*
|
61
61
|
static: false
|
62
62
|
parameters:
|
63
63
|
- name: params
|
@@ -68,5 +68,12 @@ describe 'AbstractControllerBase' do
|
|
68
68
|
receiver:
|
69
69
|
CREATE_CALL
|
70
70
|
end
|
71
|
+
|
72
|
+
it 'returns a minimal event' do
|
73
|
+
expect(File).to exist(appmap_json)
|
74
|
+
appmap = JSON.parse(File.read(appmap_json))
|
75
|
+
event = appmap['events'].find { |event| event['event'] == 'return' && event['return_value'] }
|
76
|
+
expect(event.keys).to eq(%w[id event thread_id parent_id elapsed return_value])
|
77
|
+
end
|
71
78
|
end
|
72
79
|
end
|
@@ -15,6 +15,20 @@ class SingletonMethod
|
|
15
15
|
'defined with self class scope'
|
16
16
|
end
|
17
17
|
|
18
|
+
module AddMethod
|
19
|
+
def self.included(base)
|
20
|
+
base.module_eval do
|
21
|
+
define_method "added_method" do
|
22
|
+
_added_method
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def _added_method
|
28
|
+
'defined by including a module'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
18
32
|
# When called, do_include calls +include+ to bring in the module
|
19
33
|
# AddMethod. AddMethod defines a new instance method, which gets
|
20
34
|
# added to the singleton class of SingletonMethod.
|
@@ -32,23 +46,18 @@ class SingletonMethod
|
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|
35
|
-
|
36
|
-
def to_s
|
37
|
-
'Singleton Method fixture'
|
38
|
-
end
|
39
|
-
end
|
40
49
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
_added_method
|
50
|
+
STRUCT_TEST = Struct.new(:attr) do
|
51
|
+
class << self
|
52
|
+
def say_struct_singleton
|
53
|
+
'singleton for a struct'
|
46
54
|
end
|
47
55
|
end
|
48
56
|
end
|
49
57
|
|
50
|
-
def
|
51
|
-
'
|
58
|
+
def to_s
|
59
|
+
'Singleton Method fixture'
|
52
60
|
end
|
53
61
|
end
|
54
62
|
|
63
|
+
|
data/spec/hook_spec.rb
CHANGED
@@ -16,36 +16,18 @@ end
|
|
16
16
|
Psych::Visitors::YAMLTree.prepend(ShowYamlNulls)
|
17
17
|
|
18
18
|
describe 'AppMap class Hooking', docker: false do
|
19
|
+
require 'appmap/util'
|
19
20
|
def collect_events(tracer)
|
20
21
|
[].tap do |events|
|
21
22
|
while tracer.event?
|
22
23
|
events << tracer.next_event.to_h
|
23
24
|
end
|
24
|
-
end.map
|
25
|
-
event.delete(:thread_id)
|
26
|
-
event.delete(:elapsed)
|
27
|
-
delete_object_id = ->(obj) { (obj || {}).delete(:object_id) }
|
28
|
-
delete_object_id.call(event[:receiver])
|
29
|
-
delete_object_id.call(event[:return_value])
|
30
|
-
(event[:parameters] || []).each(&delete_object_id)
|
31
|
-
(event[:exceptions] || []).each(&delete_object_id)
|
32
|
-
|
33
|
-
case event[:event]
|
34
|
-
when :call
|
35
|
-
event[:path] = event[:path].gsub(Gem.dir + '/', '')
|
36
|
-
when :return
|
37
|
-
# These should be removed from the appmap spec
|
38
|
-
%i[defined_class method_id path lineno static].each do |obsolete_field|
|
39
|
-
event.delete(obsolete_field)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
event
|
43
|
-
end.to_yaml
|
25
|
+
end.map(&AppMap::Util.method(:sanitize_event)).to_yaml
|
44
26
|
end
|
45
27
|
|
46
28
|
def invoke_test_file(file, setup: nil, &block)
|
47
29
|
AppMap.configuration = nil
|
48
|
-
package = AppMap::Package.new(file
|
30
|
+
package = AppMap::Config::Package.new(file)
|
49
31
|
config = AppMap::Config.new('hook_spec', [ package ])
|
50
32
|
AppMap.configuration = config
|
51
33
|
tracer = nil
|
@@ -69,7 +51,8 @@ describe 'AppMap class Hooking', docker: false do
|
|
69
51
|
config, tracer = invoke_test_file(file, setup: setup, &block)
|
70
52
|
|
71
53
|
events = collect_events(tracer)
|
72
|
-
|
54
|
+
|
55
|
+
expect(Diffy::Diff.new(events_yaml, events).to_s).to eq('')
|
73
56
|
|
74
57
|
[ config, tracer ]
|
75
58
|
end
|
@@ -99,7 +82,7 @@ describe 'AppMap class Hooking', docker: false do
|
|
99
82
|
:class: String
|
100
83
|
:value: default
|
101
84
|
YAML
|
102
|
-
|
85
|
+
test_hook_behavior 'spec/fixtures/hook/instance_method.rb', events_yaml do
|
103
86
|
expect(InstanceMethod.new.say_default).to eq('default')
|
104
87
|
end
|
105
88
|
end
|
@@ -117,7 +100,7 @@ describe 'AppMap class Hooking', docker: false do
|
|
117
100
|
InstanceMethod.new.say_default
|
118
101
|
end
|
119
102
|
class_map = AppMap.class_map(tracer.event_methods).to_yaml
|
120
|
-
expect(Diffy::Diff.new(
|
103
|
+
expect(Diffy::Diff.new(<<~YAML, class_map).to_s).to eq('')
|
121
104
|
---
|
122
105
|
- :name: spec/fixtures/hook/instance_method.rb
|
123
106
|
:type: package
|
@@ -359,7 +342,7 @@ describe 'AppMap class Hooking', docker: false do
|
|
359
342
|
:defined_class: SingletonMethod
|
360
343
|
:method_id: added_method
|
361
344
|
:path: spec/fixtures/hook/singleton_method.rb
|
362
|
-
:lineno:
|
345
|
+
:lineno: 21
|
363
346
|
:static: false
|
364
347
|
:parameters: []
|
365
348
|
:receiver:
|
@@ -367,10 +350,10 @@ describe 'AppMap class Hooking', docker: false do
|
|
367
350
|
:value: Singleton Method fixture
|
368
351
|
- :id: 2
|
369
352
|
:event: :call
|
370
|
-
:defined_class: AddMethod
|
353
|
+
:defined_class: SingletonMethod::AddMethod
|
371
354
|
:method_id: _added_method
|
372
355
|
:path: spec/fixtures/hook/singleton_method.rb
|
373
|
-
:lineno:
|
356
|
+
:lineno: 27
|
374
357
|
:static: false
|
375
358
|
:parameters: []
|
376
359
|
:receiver:
|
@@ -412,10 +395,44 @@ describe 'AppMap class Hooking', docker: false do
|
|
412
395
|
load 'spec/fixtures/hook/singleton_method.rb'
|
413
396
|
setup = -> { SingletonMethod.new_with_instance_method }
|
414
397
|
test_hook_behavior 'spec/fixtures/hook/singleton_method.rb', events_yaml, setup: setup do |s|
|
398
|
+
# Make sure we're testing the right thing
|
399
|
+
say_instance_defined = s.method(:say_instance_defined)
|
400
|
+
expect(say_instance_defined.owner.to_s).to start_with('#<Class:#<SingletonMethod:')
|
401
|
+
|
402
|
+
# Verify the native extension works as expected
|
403
|
+
expect(AppMap::Hook.singleton_method_owner_name(say_instance_defined)).to eq('SingletonMethod')
|
404
|
+
|
415
405
|
expect(s.say_instance_defined).to eq('defined for an instance')
|
416
406
|
end
|
417
407
|
end
|
418
408
|
|
409
|
+
it 'hooks a singleton method on an embedded struct' do
|
410
|
+
events_yaml = <<~YAML
|
411
|
+
---
|
412
|
+
- :id: 1
|
413
|
+
:event: :call
|
414
|
+
:defined_class: SingletonMethod::STRUCT_TEST
|
415
|
+
:method_id: say_struct_singleton
|
416
|
+
:path: spec/fixtures/hook/singleton_method.rb
|
417
|
+
:lineno: 52
|
418
|
+
:static: true
|
419
|
+
:parameters: []
|
420
|
+
:receiver:
|
421
|
+
:class: Class
|
422
|
+
:value: SingletonMethod::STRUCT_TEST
|
423
|
+
- :id: 2
|
424
|
+
:event: :return
|
425
|
+
:parent_id: 1
|
426
|
+
:return_value:
|
427
|
+
:class: String
|
428
|
+
:value: singleton for a struct
|
429
|
+
YAML
|
430
|
+
|
431
|
+
test_hook_behavior 'spec/fixtures/hook/singleton_method.rb', events_yaml do
|
432
|
+
expect(SingletonMethod::STRUCT_TEST.say_struct_singleton).to eq('singleton for a struct')
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
419
436
|
it 'Reports exceptions' do
|
420
437
|
events_yaml = <<~YAML
|
421
438
|
---
|
@@ -456,20 +473,6 @@ describe 'AppMap class Hooking', docker: false do
|
|
456
473
|
end
|
457
474
|
end
|
458
475
|
|
459
|
-
context 'OpenSSL::X509::Certificate.sign' do
|
460
|
-
# OpenSSL::X509 is not being hooked.
|
461
|
-
# This might be because the class is being loaded before AppMap, and so the TracePoint
|
462
|
-
# set by AppMap doesn't see it.
|
463
|
-
xit 'is hooked' do
|
464
|
-
events_yaml = <<~YAML
|
465
|
-
---
|
466
|
-
YAML
|
467
|
-
test_hook_behavior 'spec/fixtures/hook/openssl_sign.rb', events_yaml do
|
468
|
-
expect(OpenSSLExample.example).to be_truthy
|
469
|
-
end
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
476
|
context 'ActiveSupport::SecurityUtils.secure_compare' do
|
474
477
|
it 'is hooked' do
|
475
478
|
events_yaml = <<~YAML
|
@@ -513,12 +516,52 @@ describe 'AppMap class Hooking', docker: false do
|
|
513
516
|
:class: Module
|
514
517
|
:value: ActiveSupport::SecurityUtils
|
515
518
|
- :id: 3
|
519
|
+
:event: :call
|
520
|
+
:defined_class: Digest::Instance
|
521
|
+
:method_id: digest
|
522
|
+
:path: Digest::Instance#digest
|
523
|
+
:static: false
|
524
|
+
:parameters:
|
525
|
+
- :name: arg
|
526
|
+
:class: String
|
527
|
+
:value: string
|
528
|
+
:kind: :rest
|
529
|
+
:receiver:
|
530
|
+
:class: Digest::SHA256
|
531
|
+
:value: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
532
|
+
- :id: 4
|
533
|
+
:event: :return
|
534
|
+
:parent_id: 3
|
535
|
+
:return_value:
|
536
|
+
:class: String
|
537
|
+
:value: "G2__)__qc____X____3_].\\x02y__.___/_"
|
538
|
+
- :id: 5
|
539
|
+
:event: :call
|
540
|
+
:defined_class: Digest::Instance
|
541
|
+
:method_id: digest
|
542
|
+
:path: Digest::Instance#digest
|
543
|
+
:static: false
|
544
|
+
:parameters:
|
545
|
+
- :name: arg
|
546
|
+
:class: String
|
547
|
+
:value: string
|
548
|
+
:kind: :rest
|
549
|
+
:receiver:
|
550
|
+
:class: Digest::SHA256
|
551
|
+
:value: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
552
|
+
- :id: 6
|
553
|
+
:event: :return
|
554
|
+
:parent_id: 5
|
555
|
+
:return_value:
|
556
|
+
:class: String
|
557
|
+
:value: "G2__)__qc____X____3_].\\x02y__.___/_"
|
558
|
+
- :id: 7
|
516
559
|
:event: :return
|
517
560
|
:parent_id: 2
|
518
561
|
:return_value:
|
519
562
|
:class: TrueClass
|
520
563
|
:value: 'true'
|
521
|
-
- :id:
|
564
|
+
- :id: 8
|
522
565
|
:event: :return
|
523
566
|
:parent_id: 1
|
524
567
|
:return_value:
|
@@ -559,8 +602,25 @@ describe 'AppMap class Hooking', docker: false do
|
|
559
602
|
:static: true
|
560
603
|
:labels:
|
561
604
|
- security
|
605
|
+
- crypto
|
606
|
+
- :name: openssl
|
607
|
+
:type: package
|
608
|
+
:children:
|
609
|
+
- :name: Digest
|
610
|
+
:type: class
|
611
|
+
:children:
|
612
|
+
- :name: Instance
|
613
|
+
:type: class
|
614
|
+
:children:
|
615
|
+
- :name: digest
|
616
|
+
:type: function
|
617
|
+
:location: Digest::Instance#digest
|
618
|
+
:static: false
|
619
|
+
:labels:
|
620
|
+
- security
|
621
|
+
- crypto
|
562
622
|
YAML
|
563
|
-
|
623
|
+
|
564
624
|
config, tracer = invoke_test_file 'spec/fixtures/hook/compare.rb' do
|
565
625
|
expect(Compare.compare('string', 'string')).to be_truthy
|
566
626
|
end
|
@@ -570,7 +630,43 @@ describe 'AppMap class Hooking', docker: false do
|
|
570
630
|
expect(entry[:name]).to eq('secure_compare')
|
571
631
|
spec = Gem::Specification.find_by_name('activesupport')
|
572
632
|
entry[:location].gsub!(spec.base_dir + '/', '')
|
573
|
-
expect(Diffy::Diff.new(cm.to_yaml
|
633
|
+
expect(Diffy::Diff.new(classmap_yaml, cm.to_yaml).to_s).to eq('')
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
it "doesn't cause expectations on Time.now to fail" do
|
638
|
+
events_yaml = <<~YAML
|
639
|
+
---
|
640
|
+
- :id: 1
|
641
|
+
:event: :call
|
642
|
+
:defined_class: InstanceMethod
|
643
|
+
:method_id: say_the_time
|
644
|
+
:path: spec/fixtures/hook/instance_method.rb
|
645
|
+
:lineno: 24
|
646
|
+
:static: false
|
647
|
+
:parameters: []
|
648
|
+
:receiver:
|
649
|
+
:class: InstanceMethod
|
650
|
+
:value: Instance Method fixture
|
651
|
+
- :id: 2
|
652
|
+
:event: :return
|
653
|
+
:parent_id: 1
|
654
|
+
:return_value:
|
655
|
+
:class: String
|
656
|
+
:value: '2020-01-01 00:00:00 +0000'
|
657
|
+
YAML
|
658
|
+
test_hook_behavior 'spec/fixtures/hook/instance_method.rb', events_yaml do
|
659
|
+
require 'timecop'
|
660
|
+
begin
|
661
|
+
tz = ENV['TZ']
|
662
|
+
ENV['TZ'] = 'UTC'
|
663
|
+
Timecop.freeze(Time.utc('2020-01-01')) do
|
664
|
+
expect(Time).to receive(:now).exactly(3).times.and_call_original
|
665
|
+
expect(InstanceMethod.new.say_the_time).to be
|
666
|
+
end
|
667
|
+
ensure
|
668
|
+
ENV['TZ'] = tz
|
669
|
+
end
|
574
670
|
end
|
575
671
|
end
|
576
672
|
end
|