image_vise 0.6.0 → 0.8.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 +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +1 -4
- data/CHANGELOG.md +2 -0
- data/examples/error_handling_appsignal.rb +1 -1
- data/image_vise.gemspec +5 -4
- data/lib/image_vise.rb +6 -4
- data/lib/image_vise/image_request.rb +2 -2
- data/lib/image_vise/pipeline.rb +1 -1
- data/lib/image_vise/render_engine.rb +6 -5
- data/lib/image_vise/version.rb +1 -1
- data/spec/image_vise/render_engine_spec.rb +4 -0
- data/spec/spec_helper.rb +1 -0
- metadata +27 -21
- data/lib/measurometer.rb +0 -92
- data/spec/measurometer_spec.rb +0 -58
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 448a0d9a3decdcb6af4a3c0dc52fbed811bca85a8ba1df2775916ee164dffdcf
|
|
4
|
+
data.tar.gz: 3bb7300d2622d442ebe559195276e1ab753a9f1268b955fe2427362041f35036
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c71485f40a843adfc42887ef0d3766df61c83457bb3cbc92763e1c172c82a74ba7b1aba8472f9f16e79a2a35469648d361e7f6a0c85f5bfddba2f8f662283b5d
|
|
7
|
+
data.tar.gz: 6863b83f51d044589e20c6cf40ff6e6843f148374cea3a8c036a9af8fef99f626f6ef941a83bd80a44159eaed2a1a85122c7a2444510a006fddf8825f3195954
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Anywhere in your app code
|
|
2
2
|
module ImageViseAppsignal
|
|
3
3
|
ImageVise::RenderEngine.prepend self
|
|
4
|
-
|
|
4
|
+
Measurometer.drivers << Appsignal # to obtain ImageVise instrumentation
|
|
5
5
|
def setup_error_handling(rack_env)
|
|
6
6
|
txn = Appsignal::Transaction.current
|
|
7
7
|
txn.set_action('%s#%s' % [self.class, 'call'])
|
data/image_vise.gemspec
CHANGED
|
@@ -21,20 +21,21 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
else
|
|
22
22
|
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
spec.files = `git ls-files -z`.split("\x0")
|
|
26
26
|
spec.bindir = "exe"
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
28
28
|
spec.require_paths = ["lib"]
|
|
29
29
|
|
|
30
30
|
spec.add_dependency 'patron', '~> 0.9'
|
|
31
|
-
spec.add_dependency 'rmagick', '~>
|
|
31
|
+
spec.add_dependency 'rmagick', '~> 3'
|
|
32
32
|
spec.add_dependency 'ks'
|
|
33
33
|
spec.add_dependency 'rack', '>= 1', '< 3'
|
|
34
|
-
spec.add_dependency 'format_parser', '
|
|
34
|
+
spec.add_dependency 'format_parser', '~> 0.25'
|
|
35
|
+
spec.add_dependency 'measurometer', '~> 1'
|
|
35
36
|
|
|
36
37
|
spec.add_development_dependency 'magic_bytes', '~> 1'
|
|
37
|
-
spec.add_development_dependency "bundler"
|
|
38
|
+
spec.add_development_dependency "bundler"
|
|
38
39
|
spec.add_development_dependency "rake", "~> 12.2"
|
|
39
40
|
spec.add_development_dependency "rack-test"
|
|
40
41
|
spec.add_development_dependency "rspec", "~> 3"
|
data/lib/image_vise.rb
CHANGED
|
@@ -2,10 +2,10 @@ require 'ks'
|
|
|
2
2
|
require 'json'
|
|
3
3
|
require 'patron'
|
|
4
4
|
require 'rmagick'
|
|
5
|
-
require 'magic_bytes'
|
|
6
5
|
require 'thread'
|
|
7
6
|
require 'base64'
|
|
8
7
|
require 'rack'
|
|
8
|
+
require 'measurometer'
|
|
9
9
|
require 'format_parser'
|
|
10
10
|
|
|
11
11
|
class ImageVise
|
|
@@ -27,7 +27,9 @@ class ImageVise
|
|
|
27
27
|
@allowed_glob_patterns = Set.new
|
|
28
28
|
@fetchers = {}
|
|
29
29
|
@cache_lifetime = DEFAULT_CACHE_LIFETIME
|
|
30
|
-
|
|
30
|
+
|
|
31
|
+
const_set(:Measurometer, ::Measurometer)
|
|
32
|
+
|
|
31
33
|
class << self
|
|
32
34
|
# Resets all allowed hosts
|
|
33
35
|
def reset_allowed_hosts!
|
|
@@ -165,7 +167,7 @@ class ImageVise
|
|
|
165
167
|
return unless maybe_image
|
|
166
168
|
return unless maybe_image.respond_to?(:destroy!)
|
|
167
169
|
return if maybe_image.destroyed?
|
|
168
|
-
|
|
170
|
+
Measurometer.instrument('image_vise.image_destroy_dealloc') do
|
|
169
171
|
maybe_image.destroy!
|
|
170
172
|
end
|
|
171
173
|
end
|
|
@@ -175,7 +177,7 @@ class ImageVise
|
|
|
175
177
|
# in scope but not yet set to an image) we take the possibility of nils into account.
|
|
176
178
|
def self.close_and_unlink(maybe_tempfile)
|
|
177
179
|
return unless maybe_tempfile
|
|
178
|
-
|
|
180
|
+
Measurometer.instrument('image_vise.tempfile_unlink') do
|
|
179
181
|
maybe_tempfile.close unless maybe_tempfile.closed?
|
|
180
182
|
maybe_tempfile.unlink if maybe_tempfile.respond_to?(:unlink)
|
|
181
183
|
end
|
|
@@ -14,11 +14,11 @@ class ImageVise::ImageRequest < Ks.strict(:src_url, :pipeline)
|
|
|
14
14
|
|
|
15
15
|
# Check the signature before decoding JSON (since we will be creating symbols)
|
|
16
16
|
unless valid_signature?(base64_encoded_params, given_signature, secrets)
|
|
17
|
-
|
|
17
|
+
Measurometer.increment_counter('image_vise.params.invalid_signatures', 1)
|
|
18
18
|
raise SignatureError, "Invalid or missing signature"
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Measurometer.increment_counter('image_vise.params.valid_signatures', 1)
|
|
22
22
|
|
|
23
23
|
# Decode the JSON - only AFTER the signature has been validated,
|
|
24
24
|
# so we can use symbol keys
|
data/lib/image_vise/pipeline.rb
CHANGED
|
@@ -47,7 +47,7 @@ class ImageVise::Pipeline
|
|
|
47
47
|
def apply!(magick_image, image_metadata)
|
|
48
48
|
@ops.each do |operator|
|
|
49
49
|
operator_short_classname = operator.class.to_s.split('::').pop
|
|
50
|
-
|
|
50
|
+
Measurometer.instrument('image_vise.op.%s' % operator_short_classname) do
|
|
51
51
|
apply_operator_passing_metadata(magick_image, operator, image_metadata)
|
|
52
52
|
end
|
|
53
53
|
end
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
DEFAULT_HEADERS = {
|
|
16
|
-
'Allow' =>
|
|
16
|
+
'Allow' => 'GET',
|
|
17
|
+
'X-Content-Type-Options' => 'nosniff',
|
|
17
18
|
}.freeze
|
|
18
19
|
|
|
19
20
|
# Headers for error responses that denote an invalid or
|
|
@@ -152,7 +153,7 @@
|
|
|
152
153
|
|
|
153
154
|
# Download/copy the original into a Tempfile
|
|
154
155
|
fetcher = ImageVise.fetcher_for(source_image_uri.scheme)
|
|
155
|
-
source_file =
|
|
156
|
+
source_file = Measurometer.instrument('image_vise.fetch') do
|
|
156
157
|
fetcher.fetch_uri_to_tempfile(source_image_uri)
|
|
157
158
|
end
|
|
158
159
|
file_format = FormatParser.parse(source_file, natures: [:image]).tap { source_file.rewind }
|
|
@@ -162,7 +163,7 @@
|
|
|
162
163
|
render_destination_file = Tempfile.new('imagevise-render').tap{|f| f.binmode }
|
|
163
164
|
|
|
164
165
|
# Do the actual imaging stuff
|
|
165
|
-
expire_after =
|
|
166
|
+
expire_after = Measurometer.instrument('image_vise.render_engine.apply_pipeline') do
|
|
166
167
|
apply_pipeline(source_file.path, pipeline, file_format, render_destination_file.path)
|
|
167
168
|
end
|
|
168
169
|
|
|
@@ -295,7 +296,7 @@
|
|
|
295
296
|
def apply_pipeline(source_file_path, pipeline, source_format_parser_result, render_to_path)
|
|
296
297
|
|
|
297
298
|
# Load the first frame of the animated GIF _or_ the blended compatibility layer from Photoshop
|
|
298
|
-
image_list =
|
|
299
|
+
image_list = Measurometer.instrument('image_vise.load_pixbuf') do
|
|
299
300
|
Magick::Image.read(source_file_path)
|
|
300
301
|
end
|
|
301
302
|
|
|
@@ -312,7 +313,7 @@
|
|
|
312
313
|
# it so that we get a KeyError if some operator has deleted it without providing a replacement.
|
|
313
314
|
# If no operators touched the writer we are going to use the automatic format selection
|
|
314
315
|
writer = metadata.fetch(:writer, ImageVise::AutoWriter.new)
|
|
315
|
-
|
|
316
|
+
Measurometer.instrument('image_vise.write_image') do
|
|
316
317
|
writer.write_image!(magick_image, metadata, render_to_path)
|
|
317
318
|
end
|
|
318
319
|
|
data/lib/image_vise/version.rb
CHANGED
|
@@ -110,6 +110,8 @@ describe ImageVise::RenderEngine do
|
|
|
110
110
|
expect(last_response.headers['Cache-Control']).to match(/public/)
|
|
111
111
|
|
|
112
112
|
expect(last_response.headers['Content-Type']).to eq('application/json')
|
|
113
|
+
expect(last_response['X-Content-Type-Options']).to eq('nosniff')
|
|
114
|
+
|
|
113
115
|
parsed = JSON.load(last_response.body)
|
|
114
116
|
expect(parsed['errors'].to_s).to include("Unfortunate upstream response")
|
|
115
117
|
end
|
|
@@ -182,6 +184,8 @@ describe ImageVise::RenderEngine do
|
|
|
182
184
|
expect(last_response.status).to eq(200)
|
|
183
185
|
|
|
184
186
|
expect(last_response.headers['Content-Type']).to eq('image/jpeg')
|
|
187
|
+
expect(last_response['X-Content-Type-Options']).to eq('nosniff')
|
|
188
|
+
|
|
185
189
|
expect(last_response.headers).to have_key('Content-Length')
|
|
186
190
|
parsed_image = Magick::Image.from_blob(last_response.body)[0]
|
|
187
191
|
expect(parsed_image.columns).to eq(10)
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: image_vise
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Julik Tarkhanov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-09-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: patron
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '3'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '3'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: ks
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -76,22 +76,30 @@ dependencies:
|
|
|
76
76
|
name: format_parser
|
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
|
-
- - "
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version: 0.12.1
|
|
82
|
-
- - "<"
|
|
79
|
+
- - "~>"
|
|
83
80
|
- !ruby/object:Gem::Version
|
|
84
|
-
version: '
|
|
81
|
+
version: '0.25'
|
|
85
82
|
type: :runtime
|
|
86
83
|
prerelease: false
|
|
87
84
|
version_requirements: !ruby/object:Gem::Requirement
|
|
88
85
|
requirements:
|
|
89
|
-
- - "
|
|
86
|
+
- - "~>"
|
|
90
87
|
- !ruby/object:Gem::Version
|
|
91
|
-
version: 0.
|
|
92
|
-
|
|
88
|
+
version: '0.25'
|
|
89
|
+
- !ruby/object:Gem::Dependency
|
|
90
|
+
name: measurometer
|
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
93
94
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: '1
|
|
95
|
+
version: '1'
|
|
96
|
+
type: :runtime
|
|
97
|
+
prerelease: false
|
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '1'
|
|
95
103
|
- !ruby/object:Gem::Dependency
|
|
96
104
|
name: magic_bytes
|
|
97
105
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -110,16 +118,16 @@ dependencies:
|
|
|
110
118
|
name: bundler
|
|
111
119
|
requirement: !ruby/object:Gem::Requirement
|
|
112
120
|
requirements:
|
|
113
|
-
- - "
|
|
121
|
+
- - ">="
|
|
114
122
|
- !ruby/object:Gem::Version
|
|
115
|
-
version: '
|
|
123
|
+
version: '0'
|
|
116
124
|
type: :development
|
|
117
125
|
prerelease: false
|
|
118
126
|
version_requirements: !ruby/object:Gem::Requirement
|
|
119
127
|
requirements:
|
|
120
|
-
- - "
|
|
128
|
+
- - ">="
|
|
121
129
|
- !ruby/object:Gem::Version
|
|
122
|
-
version: '
|
|
130
|
+
version: '0'
|
|
123
131
|
- !ruby/object:Gem::Dependency
|
|
124
132
|
name: rake
|
|
125
133
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -227,6 +235,7 @@ extra_rdoc_files: []
|
|
|
227
235
|
files:
|
|
228
236
|
- ".gitignore"
|
|
229
237
|
- ".travis.yml"
|
|
238
|
+
- CHANGELOG.md
|
|
230
239
|
- DEVELOPMENT.md
|
|
231
240
|
- Gemfile
|
|
232
241
|
- LICENSE.txt
|
|
@@ -260,7 +269,6 @@ files:
|
|
|
260
269
|
- lib/image_vise/version.rb
|
|
261
270
|
- lib/image_vise/writers/auto_writer.rb
|
|
262
271
|
- lib/image_vise/writers/jpeg_writer.rb
|
|
263
|
-
- lib/measurometer.rb
|
|
264
272
|
- spec/image_vise/auto_orient_spec.rb
|
|
265
273
|
- spec/image_vise/background_fill_spec.rb
|
|
266
274
|
- spec/image_vise/crop_spec.rb
|
|
@@ -282,7 +290,6 @@ files:
|
|
|
282
290
|
- spec/image_vise/writers/jpeg_writer_spec.rb
|
|
283
291
|
- spec/image_vise_spec.rb
|
|
284
292
|
- spec/layers-with-blending.psd
|
|
285
|
-
- spec/measurometer_spec.rb
|
|
286
293
|
- spec/spec_helper.rb
|
|
287
294
|
- spec/test_server.rb
|
|
288
295
|
- spec/waterside_magic_hour.jpg
|
|
@@ -311,8 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
311
318
|
- !ruby/object:Gem::Version
|
|
312
319
|
version: '0'
|
|
313
320
|
requirements: []
|
|
314
|
-
|
|
315
|
-
rubygems_version: 2.5.2
|
|
321
|
+
rubygems_version: 3.1.2
|
|
316
322
|
signing_key:
|
|
317
323
|
specification_version: 4
|
|
318
324
|
summary: Runtime thumbnailing proxy
|
data/lib/measurometer.rb
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# Measurometer is 1-1 API compatible with Appsignal,
|
|
2
|
-
# which we use a lot
|
|
3
|
-
class ImageVise::Measurometer
|
|
4
|
-
class << self
|
|
5
|
-
# Permits adding instrumentation drivers. To magically
|
|
6
|
-
# obtain all Appsignal instrumentation, add the Appsignal module
|
|
7
|
-
# as a driver.
|
|
8
|
-
#
|
|
9
|
-
# Measurometer.drivers << Appsignal
|
|
10
|
-
#
|
|
11
|
-
# A driver must be reentrant and thread-safe - it should be possible
|
|
12
|
-
# to have multiple `instrument` calls open from different threads at the
|
|
13
|
-
# same time.
|
|
14
|
-
#
|
|
15
|
-
# The driver must support the same interface as the Measurometer class
|
|
16
|
-
# itself, minus the `drivers` and `instrument_instance_method` methods.
|
|
17
|
-
#
|
|
18
|
-
# @return Array
|
|
19
|
-
def drivers
|
|
20
|
-
@drivers ||= []
|
|
21
|
-
@drivers
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Runs a given block within a cascade of `instrument` blocks of all the
|
|
25
|
-
# added drivers.
|
|
26
|
-
#
|
|
27
|
-
# Measurometer.instrument('do_foo') { compute! }
|
|
28
|
-
#
|
|
29
|
-
# unfolds to
|
|
30
|
-
#
|
|
31
|
-
# Appsignal.instrument('do_foo') do
|
|
32
|
-
# Statsd.timing('do_foo') do
|
|
33
|
-
# compute!
|
|
34
|
-
# end
|
|
35
|
-
# end
|
|
36
|
-
#
|
|
37
|
-
# Note that it is _imperative_ that the block return value is preserved
|
|
38
|
-
# by the drivers and passed as the result of the block.
|
|
39
|
-
#
|
|
40
|
-
# @param block_name[String] under which path to push the metric
|
|
41
|
-
# @param blk[#call] the block to instrument
|
|
42
|
-
# @return [Object] the return value of &blk
|
|
43
|
-
def instrument(block_name, &blk)
|
|
44
|
-
return yield unless @drivers && @drivers.any? # The block wrapping business is not free
|
|
45
|
-
@drivers.inject(blk) { |outer_block, driver|
|
|
46
|
-
-> {
|
|
47
|
-
driver.instrument(block_name, &outer_block)
|
|
48
|
-
}
|
|
49
|
-
}.call
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Adds a distribution value (sample) under a given path
|
|
53
|
-
#
|
|
54
|
-
# @param value_path[String] under which path to push the metric
|
|
55
|
-
# @param value[Numeric] distribution value
|
|
56
|
-
# @return nil
|
|
57
|
-
def add_distribution_value(value_path, value)
|
|
58
|
-
(@drivers || []).each { |d| d.add_distribution_value(value_path, value) }
|
|
59
|
-
nil
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Increment a named counter under a given path
|
|
63
|
-
#
|
|
64
|
-
# @param counter_path[String] under which path to push the metric
|
|
65
|
-
# @param by[Integer] the counter increment to apply
|
|
66
|
-
# @return nil
|
|
67
|
-
def increment_counter(counter_path, by)
|
|
68
|
-
(@drivers || []).each { |d| d.increment_counter(counter_path, by) }
|
|
69
|
-
nil
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Wrap an anonymous module around an instance method in the given class to have
|
|
73
|
-
# it instrumented automatically. The name of the measurement will be interpolated as:
|
|
74
|
-
#
|
|
75
|
-
# "#{prefix}.#{rightmost_class_constant_name}.#{instance_method_name}"
|
|
76
|
-
#
|
|
77
|
-
# @param target_class[Class] the class to instrument
|
|
78
|
-
# @param instance_method_name_to_instrument[Symbol] the method name to instrument
|
|
79
|
-
# @param path_prefix[String] under which path to push the instrumented metric
|
|
80
|
-
# @return void
|
|
81
|
-
def instrument_instance_method(target_class, instance_method_name_to_instrument, path_prefix)
|
|
82
|
-
short_class_name = target_class.to_s.split('::').last
|
|
83
|
-
instrumentation_name = [path_prefix, short_class_name, instance_method_name_to_instrument].join('.')
|
|
84
|
-
instrumenter_module = Module.new do
|
|
85
|
-
define_method(instance_method_name_to_instrument) do |*any|
|
|
86
|
-
::ImageVise::Measurometer.instrument(instrumentation_name) { super(*any) }
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
target_class.prepend(instrumenter_module)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
data/spec/measurometer_spec.rb
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe ImageVise::Measurometer do
|
|
4
|
-
RSpec::Matchers.define :include_counter_or_measurement_named do |named|
|
|
5
|
-
match do |actual|
|
|
6
|
-
actual.any? do |e|
|
|
7
|
-
e[0] == named && e[1] > 0
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
it 'instruments a full cycle FormatParser.parse' do
|
|
13
|
-
driver_class = Class.new do
|
|
14
|
-
attr_accessor :timings, :counters, :distributions
|
|
15
|
-
def initialize
|
|
16
|
-
@timings = []
|
|
17
|
-
@distributions = []
|
|
18
|
-
@counters = []
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def instrument(block_name)
|
|
22
|
-
s = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
23
|
-
yield.tap do
|
|
24
|
-
delta = Process.clock_gettime(Process::CLOCK_MONOTONIC) - s
|
|
25
|
-
@timings << [block_name, delta * 1000]
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def add_distribution_value(value_path, value)
|
|
30
|
-
@distributions << [value_path, value]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def increment_counter(value_path, value)
|
|
34
|
-
@counters << [value_path, value]
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
instrumenter = driver_class.new
|
|
39
|
-
described_class.drivers << instrumenter
|
|
40
|
-
|
|
41
|
-
builder = ImageVise::Pipeline.new
|
|
42
|
-
pipeline = builder.
|
|
43
|
-
auto_orient.
|
|
44
|
-
fit_crop(width: 48, height: 48, gravity: 'c').
|
|
45
|
-
sharpen(radius: 2, sigma: 0.5).
|
|
46
|
-
ellipse_stencil.
|
|
47
|
-
strip_metadata
|
|
48
|
-
|
|
49
|
-
image = Magick::Image.read(test_image_path)[0]
|
|
50
|
-
pipeline.apply! image, {}
|
|
51
|
-
|
|
52
|
-
described_class.drivers.delete(instrumenter)
|
|
53
|
-
expect(described_class.drivers).not_to include(instrumenter)
|
|
54
|
-
|
|
55
|
-
expect(instrumenter.timings).to include_counter_or_measurement_named('image_vise.op.AutoOrient')
|
|
56
|
-
expect(instrumenter.timings).to include_counter_or_measurement_named('image_vise.op.StripMetadata')
|
|
57
|
-
end
|
|
58
|
-
end
|