appmap 0.57.1 → 0.60.0
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/CHANGELOG.md +36 -0
- data/config-schema.yml +57 -0
- data/exe/appmap-agent-validate +19 -0
- data/lib/appmap/command/agent_setup/status.rb +14 -11
- data/lib/appmap/command/agent_setup/validate.rb +24 -0
- data/lib/appmap/event.rb +9 -1
- data/lib/appmap/handler/rails/template.rb +9 -4
- data/lib/appmap/service/config_analyzer.rb +7 -8
- data/lib/appmap/service/integration_test_path_finder.rb +44 -0
- data/lib/appmap/service/test_command_provider.rb +77 -0
- data/lib/appmap/service/test_framework_detector.rb +21 -0
- data/lib/appmap/service/validator/config_validator.rb +80 -0
- data/lib/appmap/service/validator/violation.rb +50 -0
- data/lib/appmap/trace.rb +2 -2
- data/lib/appmap/util.rb +9 -0
- data/lib/appmap/version.rb +4 -1
- data/spec/fixtures/config/invalid_config.yml +2 -2
- data/spec/fixtures/config/invalid_yaml_config.yml +3 -0
- data/spec/fixtures/rails6_users_app/test/controllers/functional_calc_test.rb +10 -0
- data/spec/fixtures/rails6_users_app/test/integration/integration_calc_test.rb +12 -0
- data/spec/service/config_analyzer_spec.rb +1 -1
- data/spec/service/validator/violation_spec.rb +68 -0
- data/test/agent_setup_status_test.rb +67 -13
- data/test/agent_setup_validate_test.rb +58 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 832f968242440a6bac78181dbb49ca1b34d75c37074810df66c3d1b1d546c0cf
|
4
|
+
data.tar.gz: 26ffec9cffe15f63dc661563ec7bee9c8b4659a54c0a8888dd797b6253518954
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09eb7e68782f397a59a960ba617af180ee2d0746316db9b7d2c4cd011755e815205a5b484d0a90cd19224ab7f4be7231a96c664ea87e962c02372e155088cc82'
|
7
|
+
data.tar.gz: eea1765efb3ab76716d7c8c74f9f7b9d860923d815dab0bd003ecf8f07dc62ac6d3660e43ba0576b615bd6de094156e14e8a5be876dfe3851d4dc2c95cd82368
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
# [0.60.0](https://github.com/applandinc/appmap-ruby/compare/v0.59.2...v0.60.0) (2021-07-08)
|
2
|
+
|
3
|
+
|
4
|
+
### Features
|
5
|
+
|
6
|
+
* add agent-setup-validate command ([d9b3bc1](https://github.com/applandinc/appmap-ruby/commit/d9b3bc15e01bf89994aa67b0256dd69b9983be76))
|
7
|
+
* validate ruby version (+ better config loading validation) ([1756e6c](https://github.com/applandinc/appmap-ruby/commit/1756e6c30b5c44a033c23eb47c27c56732d12470))
|
8
|
+
|
9
|
+
## [0.59.2](https://github.com/applandinc/appmap-ruby/compare/v0.59.1...v0.59.2) (2021-07-08)
|
10
|
+
|
11
|
+
|
12
|
+
### Bug Fixes
|
13
|
+
|
14
|
+
* Remove improper reliance on Rails 'try' ([c6b5b16](https://github.com/applandinc/appmap-ruby/commit/c6b5b16a6963988e20bab5f88b99401e25691f3c))
|
15
|
+
|
16
|
+
## [0.59.1](https://github.com/applandinc/appmap-ruby/compare/v0.59.0...v0.59.1) (2021-07-08)
|
17
|
+
|
18
|
+
|
19
|
+
### Bug Fixes
|
20
|
+
|
21
|
+
* Events may be constructed in stages ([b0b23f5](https://github.com/applandinc/appmap-ruby/commit/b0b23f59a84158b8162424b84430894fe4278324))
|
22
|
+
|
23
|
+
# [0.59.0](https://github.com/applandinc/appmap-ruby/compare/v0.58.0...v0.59.0) (2021-07-07)
|
24
|
+
|
25
|
+
|
26
|
+
### Features
|
27
|
+
|
28
|
+
* define commands as objects ([1b43203](https://github.com/applandinc/appmap-ruby/commit/1b432039040277e1b5349cc2f75aa436238ea873))
|
29
|
+
|
30
|
+
# [0.58.0](https://github.com/applandinc/appmap-ruby/compare/v0.57.1...v0.58.0) (2021-07-06)
|
31
|
+
|
32
|
+
|
33
|
+
### Features
|
34
|
+
|
35
|
+
* Add `test_commands` sections to `appmap-agent-status` executable ([4cd8fe5](https://github.com/applandinc/appmap-ruby/commit/4cd8fe58acb4af72b7818db96de9e479562b9ea0))
|
36
|
+
|
1
37
|
## [0.57.1](https://github.com/applandinc/appmap-ruby/compare/v0.57.0...v0.57.1) (2021-07-02)
|
2
38
|
|
3
39
|
|
data/config-schema.yml
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
type: object
|
2
|
+
additionalProperties: false
|
3
|
+
required:
|
4
|
+
- name
|
5
|
+
properties:
|
6
|
+
name:
|
7
|
+
type: string
|
8
|
+
packages:
|
9
|
+
type: array
|
10
|
+
items:
|
11
|
+
anyOf:
|
12
|
+
- type: object
|
13
|
+
additionalProperties: false
|
14
|
+
required:
|
15
|
+
- path
|
16
|
+
properties:
|
17
|
+
path:
|
18
|
+
type: string
|
19
|
+
shallow:
|
20
|
+
type: boolean
|
21
|
+
exclude:
|
22
|
+
type: array
|
23
|
+
items:
|
24
|
+
type: string
|
25
|
+
- type: object
|
26
|
+
additionalProperties: false
|
27
|
+
required:
|
28
|
+
- gem
|
29
|
+
properties:
|
30
|
+
gem:
|
31
|
+
type: string
|
32
|
+
shallow:
|
33
|
+
type: boolean
|
34
|
+
exclude:
|
35
|
+
type: array
|
36
|
+
items:
|
37
|
+
type: string
|
38
|
+
exclude:
|
39
|
+
type: array
|
40
|
+
items:
|
41
|
+
type: string
|
42
|
+
functions:
|
43
|
+
type: array
|
44
|
+
items:
|
45
|
+
type: object
|
46
|
+
additionalProperties: false
|
47
|
+
properties:
|
48
|
+
package:
|
49
|
+
type: string
|
50
|
+
class:
|
51
|
+
type: string
|
52
|
+
function:
|
53
|
+
type: string
|
54
|
+
labels:
|
55
|
+
type: array
|
56
|
+
items:
|
57
|
+
type: string
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
require 'appmap'
|
6
|
+
require 'appmap/command/agent_setup/validate'
|
7
|
+
|
8
|
+
@options = { config_file: AppMap::DEFAULT_CONFIG_FILE_PATH }
|
9
|
+
|
10
|
+
OptionParser.new do |parser|
|
11
|
+
parser.banner = 'Usage: appmap-agent-validate [options]'
|
12
|
+
|
13
|
+
description = "AppMap configuration file path (default: #{AppMap::DEFAULT_CONFIG_FILE_PATH})"
|
14
|
+
parser.on('-c', '--config=FILEPATH', description) do |filepath|
|
15
|
+
@options[:config_file] = filepath
|
16
|
+
end
|
17
|
+
end.parse!
|
18
|
+
|
19
|
+
AppMap::Command::AgentSetup::Validate.new(@options[:config_file]).perform
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'json'
|
4
4
|
require 'appmap/service/config_analyzer'
|
5
|
+
require 'appmap/service/integration_test_path_finder'
|
6
|
+
require 'appmap/service/test_command_provider'
|
5
7
|
|
6
8
|
module AppMap
|
7
9
|
module Command
|
@@ -11,22 +13,23 @@ module AppMap
|
|
11
13
|
class Status < StatusStruct
|
12
14
|
def perform
|
13
15
|
status = {
|
14
|
-
:
|
15
|
-
|
16
|
-
|
17
|
-
:
|
18
|
-
:
|
16
|
+
test_commands: Service::TestCommandProvider.all,
|
17
|
+
properties: {
|
18
|
+
config: {
|
19
|
+
app: config_analyzer.app_name,
|
20
|
+
present: config_analyzer.present?,
|
21
|
+
valid: config_analyzer.valid?
|
19
22
|
},
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
23
|
+
project: {
|
24
|
+
agentVersion: AppMap::VERSION,
|
25
|
+
language: 'ruby',
|
26
|
+
remoteRecordingCapable: Gem.loaded_specs.has_key?('rails'),
|
27
|
+
integrationTests: Service::IntegrationTestPathFinder.count_paths > 0
|
25
28
|
}
|
26
29
|
}
|
27
30
|
}
|
28
31
|
|
29
|
-
puts status
|
32
|
+
puts JSON.pretty_generate(status)
|
30
33
|
end
|
31
34
|
|
32
35
|
private
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'appmap/service/validator/config_validator'
|
5
|
+
|
6
|
+
module AppMap
|
7
|
+
module Command
|
8
|
+
module AgentSetup
|
9
|
+
ValidateStruct = Struct.new(:config_file)
|
10
|
+
|
11
|
+
class Validate < ValidateStruct
|
12
|
+
def perform
|
13
|
+
puts JSON.pretty_generate(config_validator.valid? ? [] : config_validator.violations.map(&:to_h))
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def config_validator
|
19
|
+
@validator ||= Service::Validator::ConfigValidator.new(config_file)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/appmap/event.rb
CHANGED
@@ -119,6 +119,14 @@ module AppMap
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
122
|
+
|
123
|
+
# An event may be partially constructed, and then completed at a later time. When the event
|
124
|
+
# is only partially constructed, it's not ready for serialization to the AppMap file.
|
125
|
+
#
|
126
|
+
# @return false until the event is fully constructed and available.
|
127
|
+
def ready?
|
128
|
+
true
|
129
|
+
end
|
122
130
|
|
123
131
|
protected
|
124
132
|
|
@@ -240,7 +248,7 @@ module AppMap
|
|
240
248
|
next_exception = exception
|
241
249
|
exceptions = []
|
242
250
|
while next_exception
|
243
|
-
exception_backtrace = next_exception.backtrace_locations
|
251
|
+
exception_backtrace = AppMap::Util.try(next_exception.backtrace_locations, :[], 0)
|
244
252
|
exceptions << {
|
245
253
|
class: best_class_name(next_exception),
|
246
254
|
message: display_string(next_exception.message),
|
@@ -71,11 +71,16 @@ module AppMap
|
|
71
71
|
attr_reader :render_instance
|
72
72
|
# Path to the view template.
|
73
73
|
attr_accessor :path
|
74
|
-
|
74
|
+
# Indicates when the event is fully constructed.
|
75
|
+
attr_accessor :ready
|
76
|
+
|
77
|
+
alias ready? ready
|
78
|
+
|
75
79
|
def initialize(render_instance)
|
76
80
|
super :call
|
77
81
|
|
78
82
|
AppMap::Event::MethodEvent.build_from_invocation(:call, event: self)
|
83
|
+
@ready = false
|
79
84
|
@render_instance = render_instance
|
80
85
|
end
|
81
86
|
|
@@ -95,8 +100,7 @@ module AppMap
|
|
95
100
|
object_id: render_instance.__id__,
|
96
101
|
value: AppMap::Event::MethodEvent.display_string(render_instance)
|
97
102
|
}
|
98
|
-
|
99
|
-
end
|
103
|
+
end.compact
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
@@ -158,7 +162,8 @@ module AppMap
|
|
158
162
|
end
|
159
163
|
|
160
164
|
def handle_return(call_event_id, elapsed, return_value, exception)
|
161
|
-
Array(Thread.current[TEMPLATE_RENDERER]).pop
|
165
|
+
template_call = Array(Thread.current[TEMPLATE_RENDERER]).pop
|
166
|
+
template_call.ready = true
|
162
167
|
|
163
168
|
AppMap::Event::MethodReturnIgnoreValue.build_from_invocation(call_event_id, elapsed: elapsed)
|
164
169
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'appmap/service/validator/config_validator'
|
4
|
+
|
3
5
|
module AppMap
|
4
6
|
module Service
|
5
7
|
class ConfigAnalyzer
|
@@ -7,11 +9,10 @@ module AppMap
|
|
7
9
|
|
8
10
|
def initialize(config_file)
|
9
11
|
@config_file = config_file
|
10
|
-
@config = load_config
|
11
12
|
end
|
12
13
|
|
13
14
|
def app_name
|
14
|
-
|
15
|
+
config_validator.config.to_h['name'] if present?
|
15
16
|
end
|
16
17
|
|
17
18
|
def present?
|
@@ -19,16 +20,14 @@ module AppMap
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def valid?
|
22
|
-
|
23
|
+
config_validator.valid?
|
23
24
|
end
|
24
25
|
|
25
26
|
private
|
26
27
|
|
27
|
-
def
|
28
|
-
AppMap::
|
29
|
-
rescue
|
30
|
-
nil
|
28
|
+
def config_validator
|
29
|
+
@validator ||= AppMap::Service::Validator::ConfigValidator.new(@config_file)
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
34
|
-
end
|
33
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'appmap/service/test_framework_detector'
|
4
|
+
|
5
|
+
module AppMap
|
6
|
+
module Service
|
7
|
+
class IntegrationTestPathFinder
|
8
|
+
class << self
|
9
|
+
def find
|
10
|
+
@paths ||= begin
|
11
|
+
paths = { rspec: [], minitest: [], cucumber: [] }
|
12
|
+
paths[:rspec] = find_rspec_paths if TestFrameworkDetector.rspec_present?
|
13
|
+
paths[:minitest] = find_minitest_paths if TestFrameworkDetector.minitest_present?
|
14
|
+
paths[:cucumber] = find_cucumber_paths if TestFrameworkDetector.cucumber_present?
|
15
|
+
paths
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def count_paths
|
20
|
+
find.flatten(2).length - 3
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def find_rspec_paths
|
26
|
+
find_non_empty_paths(%w[spec/controllers spec/requests spec/integration spec/api spec/features spec/system])
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def find_minitest_paths
|
31
|
+
find_non_empty_paths(%w[test/controllers test/integration])
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_cucumber_paths
|
35
|
+
find_non_empty_paths(%w[features])
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_non_empty_paths(paths)
|
39
|
+
paths.select { |path| Dir.exist?(path) && !Dir.empty?(path) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'appmap/service/test_framework_detector'
|
4
|
+
require 'appmap/service/integration_test_path_finder'
|
5
|
+
|
6
|
+
module AppMap
|
7
|
+
module Service
|
8
|
+
class TestCommandProvider
|
9
|
+
class << self
|
10
|
+
def all
|
11
|
+
commands = []
|
12
|
+
|
13
|
+
if TestFrameworkDetector.rspec_present? && !integration_test_paths[:rspec].empty?
|
14
|
+
commands << {
|
15
|
+
framework: :rspec,
|
16
|
+
command: {
|
17
|
+
program: 'bundle',
|
18
|
+
args: %w[exec rspec] + integration_test_paths[:rspec].map { |path| "./#{path}" },
|
19
|
+
environment: {
|
20
|
+
APPMAP: 'true'
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
if TestFrameworkDetector.minitest_present? && !integration_test_paths[:minitest].empty?
|
27
|
+
commands += minitest_commands
|
28
|
+
end
|
29
|
+
if TestFrameworkDetector.cucumber_present? && !integration_test_paths[:cucumber].empty?
|
30
|
+
commands << {
|
31
|
+
framework: :cucumber,
|
32
|
+
command: {
|
33
|
+
program: 'bundle',
|
34
|
+
args: %w[exec cucumber],
|
35
|
+
environment: { APPMAP: 'true' }
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
commands
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def minitest_commands
|
46
|
+
if Gem.loaded_specs.has_key?('rails')
|
47
|
+
[
|
48
|
+
{
|
49
|
+
framework: :minitest,
|
50
|
+
command: {
|
51
|
+
program: 'bundle',
|
52
|
+
args: %w[exec rails test] + integration_test_paths[:minitest].map { |path| "./#{path}" },
|
53
|
+
environment: { APPMAP: 'true' }
|
54
|
+
}
|
55
|
+
}
|
56
|
+
]
|
57
|
+
else
|
58
|
+
integration_test_paths[:minitest].map do |path|
|
59
|
+
{
|
60
|
+
framework: :minitest,
|
61
|
+
command: {
|
62
|
+
program: 'bundle',
|
63
|
+
args: ['exec', 'ruby', "./#{path}"],
|
64
|
+
environment: { APPMAP: 'true' }
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def integration_test_paths
|
72
|
+
@paths ||= Service::IntegrationTestPathFinder.find
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AppMap
|
4
|
+
module Service
|
5
|
+
class TestFrameworkDetector
|
6
|
+
class << self
|
7
|
+
def rspec_present?
|
8
|
+
Gem.loaded_specs.has_key?('rspec-core')
|
9
|
+
end
|
10
|
+
|
11
|
+
def minitest_present?
|
12
|
+
Gem.loaded_specs.has_key?('minitest')
|
13
|
+
end
|
14
|
+
|
15
|
+
def cucumber_present?
|
16
|
+
Gem.loaded_specs.has_key?('cucumber')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'appmap/service/validator/violation'
|
4
|
+
|
5
|
+
module AppMap
|
6
|
+
module Service
|
7
|
+
module Validator
|
8
|
+
class ConfigValidator
|
9
|
+
attr_reader :violations
|
10
|
+
|
11
|
+
def initialize(config_file)
|
12
|
+
@config_file = config_file
|
13
|
+
@violations = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
parse_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
validate_ruby_version
|
22
|
+
validate_config_presence
|
23
|
+
parse_config
|
24
|
+
validate_config_load
|
25
|
+
@violations.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def present?
|
31
|
+
File.exist?(@config_file)
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_config
|
35
|
+
return unless present?
|
36
|
+
|
37
|
+
@config_data ||= YAML.load_file(@config_file)
|
38
|
+
rescue Psych::SyntaxError => e
|
39
|
+
@violations << Violation.error(
|
40
|
+
filename: @config_file,
|
41
|
+
message: 'AppMap configuration is not valid YAML',
|
42
|
+
detailed_message: e.message
|
43
|
+
)
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_config_load
|
48
|
+
return unless @config_data
|
49
|
+
|
50
|
+
AppMap::Config.load(@config_data)
|
51
|
+
rescue StandardError => e
|
52
|
+
@violations << Violation.error(
|
53
|
+
filename: @config_file,
|
54
|
+
message: 'AppMap configuration could not be loaded',
|
55
|
+
detailed_message: e.message
|
56
|
+
)
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_config_presence
|
61
|
+
unless present?
|
62
|
+
@violations << Violation.error(
|
63
|
+
filename: @config_file,
|
64
|
+
message: 'AppMap configuration file does not exist'
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_ruby_version
|
70
|
+
unless RUBY_VERSION =~ AppMap::SUPPORTED_RUBY_VERSIONS_REGEX
|
71
|
+
@violations << Violation.error(
|
72
|
+
message: "AppMap does not support Ruby #{RUBY_VERSION}. " \
|
73
|
+
"Supported versions are: #{AppMap::SUPPORTED_RUBY_VERSIONS.join(', ')}."
|
74
|
+
)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AppMap
|
4
|
+
module Service
|
5
|
+
module Validator
|
6
|
+
class Violation
|
7
|
+
attr_reader :level, :setting, :filename, :message, :detailed_message, :help_urls
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def error(message:, setting: nil, filename: nil, detailed_message: nil, help_urls: nil)
|
11
|
+
self.new(
|
12
|
+
level: :error,
|
13
|
+
message: message,
|
14
|
+
setting: setting,
|
15
|
+
filename: filename,
|
16
|
+
detailed_message: detailed_message,
|
17
|
+
help_urls: help_urls
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def warning(message:, setting: nil, filename: nil, detailed_message: nil, help_urls: nil)
|
22
|
+
self.new(
|
23
|
+
level: :warning,
|
24
|
+
message: message,
|
25
|
+
setting: setting,
|
26
|
+
filename: filename,
|
27
|
+
detailed_message: detailed_message,
|
28
|
+
help_urls: help_urls
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(level:, message:, setting:, filename:, detailed_message:, help_urls:)
|
34
|
+
@level = level
|
35
|
+
@setting = setting
|
36
|
+
@filename = filename
|
37
|
+
@message = message
|
38
|
+
@detailed_message = detailed_message
|
39
|
+
@help_urls = help_urls
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_h
|
43
|
+
instance_variables.each_with_object({}) do |var, hash|
|
44
|
+
hash[var.to_s.delete("@")] = self.instance_variable_get(var)
|
45
|
+
end.compact
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/appmap/trace.rb
CHANGED
@@ -143,12 +143,12 @@ module AppMap
|
|
143
143
|
|
144
144
|
# Whether there is an event available for processing.
|
145
145
|
def event?
|
146
|
-
!@events.empty?
|
146
|
+
!@events.empty? && @events.first.ready?
|
147
147
|
end
|
148
148
|
|
149
149
|
# Gets the next available event, if any.
|
150
150
|
def next_event
|
151
|
-
@events.shift
|
151
|
+
@events.shift if event?
|
152
152
|
end
|
153
153
|
end
|
154
154
|
end
|
data/lib/appmap/util.rb
CHANGED
@@ -183,6 +183,15 @@ module AppMap
|
|
183
183
|
false
|
184
184
|
end
|
185
185
|
|
186
|
+
# https://github.com/rails/rails/blob/8cd143900978902ed9bbba10b34099a3140de5c6/activesupport/lib/active_support/core_ext/object/try.rb
|
187
|
+
def try(obj, *methods)
|
188
|
+
return nil if methods.empty?
|
189
|
+
|
190
|
+
return nil unless obj.respond_to?(methods.first)
|
191
|
+
|
192
|
+
obj.public_send(*methods)
|
193
|
+
end
|
194
|
+
|
186
195
|
def startup_message(msg)
|
187
196
|
if defined?(::Rails) && defined?(::Rails.logger) && ::Rails.logger
|
188
197
|
::Rails.logger.info msg
|
data/lib/appmap/version.rb
CHANGED
@@ -3,10 +3,13 @@
|
|
3
3
|
module AppMap
|
4
4
|
URL = 'https://github.com/applandinc/appmap-ruby'
|
5
5
|
|
6
|
-
VERSION = '0.
|
6
|
+
VERSION = '0.60.0'
|
7
7
|
|
8
8
|
APPMAP_FORMAT_VERSION = '1.5.1'
|
9
9
|
|
10
|
+
SUPPORTED_RUBY_VERSIONS_REGEX = /^2\.[567]\./.freeze
|
11
|
+
SUPPORTED_RUBY_VERSIONS = %w[2.5 2.6 2.7].freeze
|
12
|
+
|
10
13
|
DEFAULT_APPMAP_DIR = 'tmp/appmap'.freeze
|
11
14
|
DEFAULT_CONFIG_FILE_PATH = 'appmap.yml'.freeze
|
12
15
|
end
|
@@ -1,2 +1,2 @@
|
|
1
|
-
name:
|
2
|
-
packages:
|
1
|
+
name: name
|
2
|
+
packages: [1,2,3]
|
@@ -51,7 +51,7 @@ describe AppMap::Service::ConfigAnalyzer do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
context 'with invalid YAML config' do
|
54
|
-
let(:config_file) { 'spec/fixtures/config/
|
54
|
+
let(:config_file) { 'spec/fixtures/config/invalid_yaml_config.yml'}
|
55
55
|
|
56
56
|
describe '.app_name' do
|
57
57
|
it 'returns app name value from config' do
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'appmap/service/validator/violation'
|
5
|
+
|
6
|
+
describe AppMap::Service::Validator::Violation do
|
7
|
+
describe '.error' do
|
8
|
+
let(:message) { 'error' }
|
9
|
+
|
10
|
+
context 'with default parameters' do
|
11
|
+
subject { described_class.error(message: :message) }
|
12
|
+
|
13
|
+
it 'builds an error' do
|
14
|
+
expect(subject.level).to be :error
|
15
|
+
expect(subject.message).to be :message
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with default parameters' do
|
20
|
+
subject do
|
21
|
+
described_class.error(
|
22
|
+
message: :message,
|
23
|
+
setting: :setting,
|
24
|
+
filename: :filename,
|
25
|
+
detailed_message: :detailed_message,
|
26
|
+
help_urls: :help_urls
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:filename) { 'filename' }
|
31
|
+
let(:setting) { 'setting' }
|
32
|
+
let(:detailed_message) { 'details' }
|
33
|
+
let(:help_urls) { %w[123 456] }
|
34
|
+
|
35
|
+
it 'builds an error' do
|
36
|
+
expect(subject.level).to be :error
|
37
|
+
expect(subject.message).to be :message
|
38
|
+
expect(subject.setting).to be :setting
|
39
|
+
expect(subject.detailed_message).to be :detailed_message
|
40
|
+
expect(subject.help_urls).to be :help_urls
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.warning' do
|
45
|
+
let(:message) { 'warning' }
|
46
|
+
|
47
|
+
context 'with default parameters' do
|
48
|
+
subject { described_class.warning(message: :message) }
|
49
|
+
|
50
|
+
it 'builds an error' do
|
51
|
+
expect(subject.level).to be :warning
|
52
|
+
expect(subject.message).to be :message
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#to_hash' do
|
58
|
+
subject { described_class.warning(message: :message) }
|
59
|
+
|
60
|
+
let(:message) { 'warning' }
|
61
|
+
|
62
|
+
it 'returns correct hash' do
|
63
|
+
expect(subject.to_h['level']).to be :warning
|
64
|
+
expect(subject.to_h['message']).to be :message
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -4,24 +4,78 @@
|
|
4
4
|
require 'test_helper'
|
5
5
|
|
6
6
|
class AgentSetupInitTest < Minitest::Test
|
7
|
-
def
|
7
|
+
def test_status_gem
|
8
8
|
output = `./exe/appmap-agent-status`
|
9
9
|
assert_equal 0, $CHILD_STATUS.exitstatus
|
10
10
|
expected = {
|
11
|
-
:
|
12
|
-
|
13
|
-
|
14
|
-
:
|
15
|
-
:
|
11
|
+
test_commands: [],
|
12
|
+
properties: {
|
13
|
+
config: {
|
14
|
+
app: 'AppMap Rubygem',
|
15
|
+
present: true,
|
16
|
+
valid: true
|
16
17
|
},
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
18
|
+
project: {
|
19
|
+
agentVersion: AppMap::VERSION,
|
20
|
+
language: 'ruby',
|
21
|
+
remoteRecordingCapable: false,
|
22
|
+
integrationTests: false
|
22
23
|
}
|
23
24
|
}
|
24
|
-
}
|
25
|
-
assert_equal expected, output.strip
|
25
|
+
}
|
26
|
+
assert_equal JSON.pretty_generate(expected), output.strip
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_status_rails_app
|
30
|
+
output = `cd spec/fixtures/rails6_users_app && bundle exec ../../../exe/appmap-agent-status`
|
31
|
+
assert_equal 0, $CHILD_STATUS.exitstatus
|
32
|
+
expected = {
|
33
|
+
test_commands: [
|
34
|
+
{
|
35
|
+
framework: :rspec,
|
36
|
+
command: {
|
37
|
+
program: 'bundle',
|
38
|
+
args: %w[exec rspec ./spec/controllers],
|
39
|
+
environment: {
|
40
|
+
APPMAP: 'true'
|
41
|
+
}
|
42
|
+
}
|
43
|
+
},
|
44
|
+
{
|
45
|
+
framework: :minitest,
|
46
|
+
command: {
|
47
|
+
program: 'bundle',
|
48
|
+
args: %w[exec ruby ./test/controllers],
|
49
|
+
environment: {
|
50
|
+
APPMAP: 'true'
|
51
|
+
}
|
52
|
+
}
|
53
|
+
},
|
54
|
+
{
|
55
|
+
framework: :minitest,
|
56
|
+
command: {
|
57
|
+
program: 'bundle',
|
58
|
+
args: %w[exec ruby ./test/integration],
|
59
|
+
environment: {
|
60
|
+
APPMAP: 'true'
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
],
|
65
|
+
properties: {
|
66
|
+
config: {
|
67
|
+
app: 'rails6_users_app',
|
68
|
+
present: true,
|
69
|
+
valid: false
|
70
|
+
},
|
71
|
+
project: {
|
72
|
+
agentVersion: AppMap::VERSION,
|
73
|
+
language: 'ruby',
|
74
|
+
remoteRecordingCapable: false,
|
75
|
+
integrationTests: true
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
assert_equal JSON.pretty_generate(expected), output.strip
|
26
80
|
end
|
27
81
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'test_helper'
|
5
|
+
|
6
|
+
class AgentSetupValidateTest < Minitest::Test
|
7
|
+
NON_EXISTING_CONFIG_FILENAME = '123.yml'
|
8
|
+
INVALID_YAML_CONFIG_FILENAME = 'spec/fixtures/config/invalid_yaml_config.yml'
|
9
|
+
INVALID_CONFIG_FILENAME = 'spec/fixtures/config/invalid_config.yml'
|
10
|
+
|
11
|
+
def test_init_when_config_exists
|
12
|
+
output = `./exe/appmap-agent-validate`
|
13
|
+
assert_equal 0, $CHILD_STATUS.exitstatus
|
14
|
+
assert_equal JSON.pretty_generate([]), output.strip
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_init_with_non_existing_config_file
|
18
|
+
output = `./exe/appmap-agent-validate -c #{NON_EXISTING_CONFIG_FILENAME}`
|
19
|
+
assert_equal 0, $CHILD_STATUS.exitstatus
|
20
|
+
expected = JSON.pretty_generate([
|
21
|
+
{
|
22
|
+
level: :error,
|
23
|
+
filename: NON_EXISTING_CONFIG_FILENAME,
|
24
|
+
message: 'AppMap configuration file does not exist'
|
25
|
+
}
|
26
|
+
])
|
27
|
+
assert_equal expected, output.strip
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_init_with_invalid_YAML
|
31
|
+
output = `./exe/appmap-agent-validate -c #{INVALID_YAML_CONFIG_FILENAME}`
|
32
|
+
assert_equal 0, $CHILD_STATUS.exitstatus
|
33
|
+
expected = JSON.pretty_generate([
|
34
|
+
{
|
35
|
+
level: :error,
|
36
|
+
filename: INVALID_YAML_CONFIG_FILENAME,
|
37
|
+
message: 'AppMap configuration is not valid YAML',
|
38
|
+
detailed_message: "(#{INVALID_YAML_CONFIG_FILENAME}): " \
|
39
|
+
'did not find expected key while parsing a block mapping at line 1 column 1'
|
40
|
+
}
|
41
|
+
])
|
42
|
+
assert_equal expected, output.strip
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_init_with_invalid_data_config
|
46
|
+
output = `./exe/appmap-agent-validate -c #{INVALID_CONFIG_FILENAME}`
|
47
|
+
assert_equal 0, $CHILD_STATUS.exitstatus
|
48
|
+
expected = JSON.pretty_generate([
|
49
|
+
{
|
50
|
+
level: :error,
|
51
|
+
filename: INVALID_CONFIG_FILENAME,
|
52
|
+
message: 'AppMap configuration could not be loaded',
|
53
|
+
detailed_message: "no implicit conversion of String into Integer"
|
54
|
+
}
|
55
|
+
])
|
56
|
+
assert_equal expected, output.strip
|
57
|
+
end
|
58
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.60.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gilpin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -296,6 +296,7 @@ email:
|
|
296
296
|
executables:
|
297
297
|
- appmap-agent-init
|
298
298
|
- appmap-agent-status
|
299
|
+
- appmap-agent-validate
|
299
300
|
- appmap-inspect
|
300
301
|
extensions:
|
301
302
|
- ext/appmap/extconf.rb
|
@@ -317,6 +318,7 @@ files:
|
|
317
318
|
- Rakefile
|
318
319
|
- appmap.gemspec
|
319
320
|
- appmap.yml
|
321
|
+
- config-schema.yml
|
320
322
|
- examples/install.rb
|
321
323
|
- examples/mock_webapp/Gemfile
|
322
324
|
- examples/mock_webapp/appmap.yml
|
@@ -326,6 +328,7 @@ files:
|
|
326
328
|
- examples/mock_webapp/lib/mock_webapp/user.rb
|
327
329
|
- exe/appmap-agent-init
|
328
330
|
- exe/appmap-agent-status
|
331
|
+
- exe/appmap-agent-validate
|
329
332
|
- exe/appmap-inspect
|
330
333
|
- ext/appmap/appmap.c
|
331
334
|
- ext/appmap/extconf.rb
|
@@ -334,6 +337,7 @@ files:
|
|
334
337
|
- lib/appmap/class_map.rb
|
335
338
|
- lib/appmap/command/agent_setup/init.rb
|
336
339
|
- lib/appmap/command/agent_setup/status.rb
|
340
|
+
- lib/appmap/command/agent_setup/validate.rb
|
337
341
|
- lib/appmap/command/inspect.rb
|
338
342
|
- lib/appmap/command_error.rb
|
339
343
|
- lib/appmap/config.rb
|
@@ -356,6 +360,11 @@ files:
|
|
356
360
|
- lib/appmap/rspec.rb
|
357
361
|
- lib/appmap/service/config_analyzer.rb
|
358
362
|
- lib/appmap/service/guesser.rb
|
363
|
+
- lib/appmap/service/integration_test_path_finder.rb
|
364
|
+
- lib/appmap/service/test_command_provider.rb
|
365
|
+
- lib/appmap/service/test_framework_detector.rb
|
366
|
+
- lib/appmap/service/validator/config_validator.rb
|
367
|
+
- lib/appmap/service/validator/violation.rb
|
359
368
|
- lib/appmap/swagger.rb
|
360
369
|
- lib/appmap/swagger/configuration.rb
|
361
370
|
- lib/appmap/swagger/markdown_descriptions.rb
|
@@ -370,6 +379,7 @@ files:
|
|
370
379
|
- spec/config_spec.rb
|
371
380
|
- spec/fixtures/config/incomplete_config.yml
|
372
381
|
- spec/fixtures/config/invalid_config.yml
|
382
|
+
- spec/fixtures/config/invalid_yaml_config.yml
|
373
383
|
- spec/fixtures/config/valid_config.yml
|
374
384
|
- spec/fixtures/hook/.gitignore
|
375
385
|
- spec/fixtures/hook/app/controllers/api/api_keys_controller.rb
|
@@ -543,6 +553,8 @@ files:
|
|
543
553
|
- spec/fixtures/rails6_users_app/spec/models/user_spec.rb
|
544
554
|
- spec/fixtures/rails6_users_app/spec/rails_helper.rb
|
545
555
|
- spec/fixtures/rails6_users_app/spec/spec_helper.rb
|
556
|
+
- spec/fixtures/rails6_users_app/test/controllers/functional_calc_test.rb
|
557
|
+
- spec/fixtures/rails6_users_app/test/integration/integration_calc_test.rb
|
546
558
|
- spec/fixtures/rails6_users_app/users_app/.gitignore
|
547
559
|
- spec/hook_spec.rb
|
548
560
|
- spec/open_spec.rb
|
@@ -553,11 +565,13 @@ files:
|
|
553
565
|
- spec/record_sql_rails_pg_spec.rb
|
554
566
|
- spec/remote_recording_spec.rb
|
555
567
|
- spec/service/config_analyzer_spec.rb
|
568
|
+
- spec/service/validator/violation_spec.rb
|
556
569
|
- spec/spec_helper.rb
|
557
570
|
- spec/swagger/swagger_spec.rb
|
558
571
|
- spec/util_spec.rb
|
559
572
|
- test/agent_setup_init_test.rb
|
560
573
|
- test/agent_setup_status_test.rb
|
574
|
+
- test/agent_setup_validate_test.rb
|
561
575
|
- test/bundle_vendor_test.rb
|
562
576
|
- test/cucumber_test.rb
|
563
577
|
- test/expectations/openssl_test_key_sign1.json
|