httpimagestore 1.8.1 → 1.9.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.
Files changed (64) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +7 -7
  3. data/Gemfile.lock +20 -20
  4. data/README.md +165 -37
  5. data/Rakefile +7 -2
  6. data/VERSION +1 -1
  7. data/bin/httpimagestore +74 -41
  8. data/lib/httpimagestore/configuration/file.rb +20 -11
  9. data/lib/httpimagestore/configuration/handler.rb +96 -257
  10. data/lib/httpimagestore/configuration/handler/source_store_base.rb +37 -0
  11. data/lib/httpimagestore/configuration/handler/statement.rb +114 -0
  12. data/lib/httpimagestore/configuration/identify.rb +17 -9
  13. data/lib/httpimagestore/configuration/output.rb +33 -61
  14. data/lib/httpimagestore/configuration/path.rb +2 -2
  15. data/lib/httpimagestore/configuration/request_state.rb +131 -0
  16. data/lib/httpimagestore/configuration/s3.rb +41 -29
  17. data/lib/httpimagestore/configuration/thumbnailer.rb +189 -96
  18. data/lib/httpimagestore/configuration/validate_hmac.rb +170 -0
  19. data/lib/httpimagestore/error_reporter.rb +6 -1
  20. data/lib/httpimagestore/ruby_string_template.rb +10 -19
  21. metadata +40 -102
  22. data/.rspec +0 -1
  23. data/features/cache-control.feature +0 -41
  24. data/features/compatibility.feature +0 -165
  25. data/features/data-uri.feature +0 -55
  26. data/features/encoding.feature +0 -103
  27. data/features/error-reporting.feature +0 -281
  28. data/features/flexi.feature +0 -259
  29. data/features/health-check.feature +0 -29
  30. data/features/request-matching.feature +0 -211
  31. data/features/rewrite.feature +0 -122
  32. data/features/s3-store-and-thumbnail.feature +0 -82
  33. data/features/source-failover.feature +0 -71
  34. data/features/step_definitions/httpimagestore_steps.rb +0 -203
  35. data/features/storage.feature +0 -198
  36. data/features/support/env.rb +0 -116
  37. data/features/support/test-large.jpg +0 -0
  38. data/features/support/test.empty +0 -0
  39. data/features/support/test.jpg +0 -0
  40. data/features/support/test.png +0 -0
  41. data/features/support/test.txt +0 -1
  42. data/features/support/tiny.png +0 -0
  43. data/features/xid-forwarding.feature +0 -49
  44. data/httpimagestore.gemspec +0 -145
  45. data/load_test/load_test.1k.23a022f6e.m1.small-comp.csv +0 -3
  46. data/load_test/load_test.1k.ec9bde794.m1.small.csv +0 -4
  47. data/load_test/load_test.jmx +0 -317
  48. data/load_test/thumbnail_specs.csv +0 -11
  49. data/load_test/thumbnail_specs_v2.csv +0 -10
  50. data/spec/configuration_file_spec.rb +0 -333
  51. data/spec/configuration_handler_spec.rb +0 -255
  52. data/spec/configuration_identify_spec.rb +0 -67
  53. data/spec/configuration_output_spec.rb +0 -821
  54. data/spec/configuration_path_spec.rb +0 -138
  55. data/spec/configuration_s3_spec.rb +0 -911
  56. data/spec/configuration_source_failover_spec.rb +0 -101
  57. data/spec/configuration_spec.rb +0 -90
  58. data/spec/configuration_thumbnailer_spec.rb +0 -483
  59. data/spec/ruby_string_template_spec.rb +0 -61
  60. data/spec/spec_helper.rb +0 -89
  61. data/spec/support/compute.jpg +0 -0
  62. data/spec/support/cuba_response_env.rb +0 -40
  63. data/spec/support/full.cfg +0 -183
  64. data/spec/support/utf_string.txt +0 -1
@@ -1,3 +0,0 @@
1
- sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
2
- classes,985,15101,8288,36838,857,211337,0.017258883248730966,0.10672951825329396,0.16322841998894347
3
- TOTAL,985,15101,8288,36838,857,211337,0.017258883248730966,0.10672951825329396,0.16322841998894347
@@ -1,4 +0,0 @@
1
- sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
2
- original,989,7755,2917,21931,164,96522,0.0010111223458038423,0.10461638578207254,0.020651782131933853
3
- thumbnail fit,43516,905,748,1558,76,11358,0.0010111223458038423,4.594225650846874,97.8148328278794
4
- TOTAL,44505,1058,758,1621,76,96522,0.0010111223458038423,4.689206890273507,97.63903046024716
@@ -1,317 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <jmeterTestPlan version="1.2" properties="2.4" jmeter="2.9 r1437961">
3
- <hashTree>
4
- <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
5
- <stringProp name="TestPlan.comments"></stringProp>
6
- <boolProp name="TestPlan.functional_mode">false</boolProp>
7
- <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
8
- <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
9
- <collectionProp name="Arguments.arguments">
10
- <elementProp name="iss_server" elementType="Argument">
11
- <stringProp name="Argument.name">iss_server</stringProp>
12
- <stringProp name="Argument.value">localhost</stringProp>
13
- <stringProp name="Argument.metadata">=</stringProp>
14
- </elementProp>
15
- <elementProp name="test_data_dir" elementType="Argument">
16
- <stringProp name="Argument.name">test_data_dir</stringProp>
17
- <stringProp name="Argument.value">${__property(user.dir)}/test_data</stringProp>
18
- <stringProp name="Argument.metadata">=</stringProp>
19
- </elementProp>
20
- <elementProp name="test_data_list" elementType="Argument">
21
- <stringProp name="Argument.name">test_data_list</stringProp>
22
- <stringProp name="Argument.value">tatoos-1k.csv</stringProp>
23
- <stringProp name="Argument.metadata">=</stringProp>
24
- </elementProp>
25
- </collectionProp>
26
- </elementProp>
27
- <stringProp name="TestPlan.user_define_classpath"></stringProp>
28
- </TestPlan>
29
- <hashTree>
30
- <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
31
- <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
32
- <collectionProp name="Arguments.arguments"/>
33
- </elementProp>
34
- <stringProp name="HTTPSampler.domain">${iss_server}</stringProp>
35
- <stringProp name="HTTPSampler.port">3000</stringProp>
36
- <stringProp name="HTTPSampler.connect_timeout"></stringProp>
37
- <stringProp name="HTTPSampler.response_timeout"></stringProp>
38
- <stringProp name="HTTPSampler.protocol"></stringProp>
39
- <stringProp name="HTTPSampler.contentEncoding"></stringProp>
40
- <stringProp name="HTTPSampler.path"></stringProp>
41
- <stringProp name="HTTPSampler.implementation">Java</stringProp>
42
- <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
43
- </ConfigTestElement>
44
- <hashTree/>
45
- <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Flexi API" enabled="true">
46
- <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
47
- <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
48
- <boolProp name="LoopController.continue_forever">false</boolProp>
49
- <intProp name="LoopController.loops">-1</intProp>
50
- </elementProp>
51
- <stringProp name="ThreadGroup.num_threads">5</stringProp>
52
- <stringProp name="ThreadGroup.ramp_time">1</stringProp>
53
- <longProp name="ThreadGroup.start_time">1373879489000</longProp>
54
- <longProp name="ThreadGroup.end_time">1373879489000</longProp>
55
- <boolProp name="ThreadGroup.scheduler">false</boolProp>
56
- <stringProp name="ThreadGroup.duration"></stringProp>
57
- <stringProp name="ThreadGroup.delay"></stringProp>
58
- </ThreadGroup>
59
- <hashTree>
60
- <CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="test files" enabled="true">
61
- <stringProp name="delimiter">,</stringProp>
62
- <stringProp name="fileEncoding"></stringProp>
63
- <stringProp name="filename">${test_data_dir}/${test_data_list}</stringProp>
64
- <boolProp name="quotedData">true</boolProp>
65
- <boolProp name="recycle">false</boolProp>
66
- <stringProp name="shareMode">All threads</stringProp>
67
- <boolProp name="stopThread">true</boolProp>
68
- <stringProp name="variableNames">test_file</stringProp>
69
- </CSVDataSet>
70
- <hashTree/>
71
- <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="original" enabled="true">
72
- <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
73
- <collectionProp name="Arguments.arguments"/>
74
- </elementProp>
75
- <stringProp name="HTTPSampler.domain"></stringProp>
76
- <stringProp name="HTTPSampler.port"></stringProp>
77
- <stringProp name="HTTPSampler.connect_timeout"></stringProp>
78
- <stringProp name="HTTPSampler.response_timeout"></stringProp>
79
- <stringProp name="HTTPSampler.protocol"></stringProp>
80
- <stringProp name="HTTPSampler.contentEncoding"></stringProp>
81
- <stringProp name="HTTPSampler.path">/iss/v2/thumbnails/pictures</stringProp>
82
- <stringProp name="HTTPSampler.method">POST</stringProp>
83
- <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
84
- <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
85
- <boolProp name="HTTPSampler.use_keepalive">false</boolProp>
86
- <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
87
- <elementProp name="HTTPsampler.Files" elementType="HTTPFileArgs">
88
- <collectionProp name="HTTPFileArgs.files">
89
- <elementProp name="${test_data_dir}/${test_file}" elementType="HTTPFileArg">
90
- <stringProp name="File.path">${test_data_dir}/${test_file}</stringProp>
91
- <stringProp name="File.paramname"></stringProp>
92
- <stringProp name="File.mimetype">image/jpeg</stringProp>
93
- </elementProp>
94
- </collectionProp>
95
- </elementProp>
96
- <boolProp name="HTTPSampler.monitor">false</boolProp>
97
- <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
98
- </HTTPSamplerProxy>
99
- <hashTree>
100
- <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="store_path extractor" enabled="true">
101
- <stringProp name="RegexExtractor.useHeaders">unescaped</stringProp>
102
- <stringProp name="RegexExtractor.refname">store_path</stringProp>
103
- <stringProp name="RegexExtractor.regex">([^\r]+)</stringProp>
104
- <stringProp name="RegexExtractor.template">$1$</stringProp>
105
- <stringProp name="RegexExtractor.default"></stringProp>
106
- <stringProp name="RegexExtractor.match_number">1</stringProp>
107
- </RegexExtractor>
108
- <hashTree/>
109
- <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="contains .jpg file path" enabled="true">
110
- <collectionProp name="Asserion.test_strings">
111
- <stringProp name="1475827">.jpg</stringProp>
112
- </collectionProp>
113
- <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
114
- <boolProp name="Assertion.assume_success">false</boolProp>
115
- <intProp name="Assertion.test_type">16</intProp>
116
- </ResponseAssertion>
117
- <hashTree/>
118
- </hashTree>
119
- <LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="iterations" enabled="true">
120
- <boolProp name="LoopController.continue_forever">true</boolProp>
121
- <stringProp name="LoopController.loops">1</stringProp>
122
- </LoopController>
123
- <hashTree>
124
- <LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="specs counter" enabled="true">
125
- <boolProp name="LoopController.continue_forever">true</boolProp>
126
- <stringProp name="LoopController.loops">10</stringProp>
127
- </LoopController>
128
- <hashTree>
129
- <CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="thumbnail specs" enabled="true">
130
- <stringProp name="filename">thumbnail_specs_v2.csv</stringProp>
131
- <stringProp name="fileEncoding"></stringProp>
132
- <stringProp name="variableNames">type,operation,width,height,options</stringProp>
133
- <stringProp name="delimiter">,</stringProp>
134
- <boolProp name="quotedData">true</boolProp>
135
- <boolProp name="recycle">true</boolProp>
136
- <boolProp name="stopThread">false</boolProp>
137
- <stringProp name="shareMode">Current thread</stringProp>
138
- </CSVDataSet>
139
- <hashTree/>
140
- <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="query string param thumbnail" enabled="true">
141
- <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
142
- <collectionProp name="Arguments.arguments"/>
143
- </elementProp>
144
- <stringProp name="HTTPSampler.domain"></stringProp>
145
- <stringProp name="HTTPSampler.port"></stringProp>
146
- <stringProp name="HTTPSampler.connect_timeout"></stringProp>
147
- <stringProp name="HTTPSampler.response_timeout"></stringProp>
148
- <stringProp name="HTTPSampler.protocol"></stringProp>
149
- <stringProp name="HTTPSampler.contentEncoding"></stringProp>
150
- <stringProp name="HTTPSampler.path">/iss/v2/thumbnails/${__BeanShell(vars.get(&quot;store_path&quot;).replace(&quot;/:&quot;\, &quot;%2f&quot;))}?operation=${operation}&amp;width=${width}&amp;height=${height}&amp;options=${options}</stringProp>
151
- <stringProp name="HTTPSampler.method">GET</stringProp>
152
- <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
153
- <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
154
- <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
155
- <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
156
- <boolProp name="HTTPSampler.monitor">false</boolProp>
157
- <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
158
- </HTTPSamplerProxy>
159
- <hashTree>
160
- <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="image type" enabled="true">
161
- <collectionProp name="Asserion.test_strings">
162
- <stringProp name="-722923736">Content-Type: image/</stringProp>
163
- </collectionProp>
164
- <stringProp name="Assertion.test_field">Assertion.response_headers</stringProp>
165
- <boolProp name="Assertion.assume_success">false</boolProp>
166
- <intProp name="Assertion.test_type">16</intProp>
167
- </ResponseAssertion>
168
- <hashTree/>
169
- </hashTree>
170
- <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="query string param thumbnail - data URI output" enabled="true">
171
- <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
172
- <collectionProp name="Arguments.arguments"/>
173
- </elementProp>
174
- <stringProp name="HTTPSampler.domain"></stringProp>
175
- <stringProp name="HTTPSampler.port"></stringProp>
176
- <stringProp name="HTTPSampler.connect_timeout"></stringProp>
177
- <stringProp name="HTTPSampler.response_timeout"></stringProp>
178
- <stringProp name="HTTPSampler.protocol"></stringProp>
179
- <stringProp name="HTTPSampler.contentEncoding"></stringProp>
180
- <stringProp name="HTTPSampler.path">/iss/v2/thumbnails/${__BeanShell(vars.get(&quot;store_path&quot;).replace(&quot;/:&quot;\, &quot;%2f&quot;))}?operation=${operation}&amp;width=${width}&amp;height=${height}&amp;options=${options}&amp;data-uri=true</stringProp>
181
- <stringProp name="HTTPSampler.method">GET</stringProp>
182
- <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
183
- <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
184
- <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
185
- <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
186
- <boolProp name="HTTPSampler.monitor">false</boolProp>
187
- <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
188
- </HTTPSamplerProxy>
189
- <hashTree>
190
- <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="text/uri-list" enabled="true">
191
- <collectionProp name="Asserion.test_strings">
192
- <stringProp name="530900877">Content-Type: text/uri-list</stringProp>
193
- </collectionProp>
194
- <stringProp name="Assertion.test_field">Assertion.response_headers</stringProp>
195
- <boolProp name="Assertion.assume_success">false</boolProp>
196
- <intProp name="Assertion.test_type">16</intProp>
197
- </ResponseAssertion>
198
- <hashTree/>
199
- <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="base64 response" enabled="true">
200
- <collectionProp name="Asserion.test_strings">
201
- <stringProp name="-586062814">;base64,</stringProp>
202
- </collectionProp>
203
- <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
204
- <boolProp name="Assertion.assume_success">false</boolProp>
205
- <intProp name="Assertion.test_type">16</intProp>
206
- </ResponseAssertion>
207
- <hashTree/>
208
- </hashTree>
209
- </hashTree>
210
- </hashTree>
211
- <DebugPostProcessor guiclass="TestBeanGUI" testclass="DebugPostProcessor" testname="Debug PostProcessor" enabled="false">
212
- <boolProp name="displayJMeterProperties">false</boolProp>
213
- <boolProp name="displayJMeterVariables">true</boolProp>
214
- <boolProp name="displaySamplerProperties">true</boolProp>
215
- <boolProp name="displaySystemProperties">false</boolProp>
216
- </DebugPostProcessor>
217
- <hashTree/>
218
- </hashTree>
219
- <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
220
- <boolProp name="ResultCollector.error_logging">false</boolProp>
221
- <objProp>
222
- <name>saveConfig</name>
223
- <value class="SampleSaveConfiguration">
224
- <time>true</time>
225
- <latency>true</latency>
226
- <timestamp>true</timestamp>
227
- <success>true</success>
228
- <label>true</label>
229
- <code>true</code>
230
- <message>true</message>
231
- <threadName>true</threadName>
232
- <dataType>true</dataType>
233
- <encoding>false</encoding>
234
- <assertions>true</assertions>
235
- <subresults>true</subresults>
236
- <responseData>false</responseData>
237
- <samplerData>false</samplerData>
238
- <xml>false</xml>
239
- <fieldNames>false</fieldNames>
240
- <responseHeaders>false</responseHeaders>
241
- <requestHeaders>false</requestHeaders>
242
- <responseDataOnError>false</responseDataOnError>
243
- <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
244
- <assertionsResultsToSave>0</assertionsResultsToSave>
245
- <bytes>true</bytes>
246
- </value>
247
- </objProp>
248
- <stringProp name="filename"></stringProp>
249
- </ResultCollector>
250
- <hashTree/>
251
- <ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="Aggregate Report" enabled="true">
252
- <boolProp name="ResultCollector.error_logging">false</boolProp>
253
- <objProp>
254
- <name>saveConfig</name>
255
- <value class="SampleSaveConfiguration">
256
- <time>true</time>
257
- <latency>true</latency>
258
- <timestamp>true</timestamp>
259
- <success>true</success>
260
- <label>true</label>
261
- <code>true</code>
262
- <message>true</message>
263
- <threadName>true</threadName>
264
- <dataType>true</dataType>
265
- <encoding>false</encoding>
266
- <assertions>true</assertions>
267
- <subresults>true</subresults>
268
- <responseData>false</responseData>
269
- <samplerData>false</samplerData>
270
- <xml>false</xml>
271
- <fieldNames>false</fieldNames>
272
- <responseHeaders>false</responseHeaders>
273
- <requestHeaders>false</requestHeaders>
274
- <responseDataOnError>false</responseDataOnError>
275
- <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
276
- <assertionsResultsToSave>0</assertionsResultsToSave>
277
- <bytes>true</bytes>
278
- </value>
279
- </objProp>
280
- <stringProp name="filename"></stringProp>
281
- </ResultCollector>
282
- <hashTree/>
283
- <ResultCollector guiclass="GraphVisualizer" testclass="ResultCollector" testname="Graph Results" enabled="true">
284
- <boolProp name="ResultCollector.error_logging">false</boolProp>
285
- <objProp>
286
- <name>saveConfig</name>
287
- <value class="SampleSaveConfiguration">
288
- <time>true</time>
289
- <latency>true</latency>
290
- <timestamp>true</timestamp>
291
- <success>true</success>
292
- <label>true</label>
293
- <code>true</code>
294
- <message>true</message>
295
- <threadName>true</threadName>
296
- <dataType>true</dataType>
297
- <encoding>false</encoding>
298
- <assertions>true</assertions>
299
- <subresults>true</subresults>
300
- <responseData>false</responseData>
301
- <samplerData>false</samplerData>
302
- <xml>false</xml>
303
- <fieldNames>false</fieldNames>
304
- <responseHeaders>false</responseHeaders>
305
- <requestHeaders>false</requestHeaders>
306
- <responseDataOnError>false</responseDataOnError>
307
- <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
308
- <assertionsResultsToSave>0</assertionsResultsToSave>
309
- <bytes>true</bytes>
310
- </value>
311
- </objProp>
312
- <stringProp name="filename"></stringProp>
313
- </ResultCollector>
314
- <hashTree/>
315
- </hashTree>
316
- </hashTree>
317
- </jmeterTestPlan>
@@ -1,11 +0,0 @@
1
- "original","crop","input","input","background-color:0xF0F0F0"
2
- "search","pad","162","162","background-color:0xF0F0F0"
3
- "search_thumb","pad","28","28","background-color:0xF0F0F0"
4
- "brochure","pad","264","264","background-color:0xF0F0F0"
5
- "brochure_thumb","pad","40","40","background-color:0xF0F0F0"
6
- "admin","pad","160","160","background-color:0xF0F0F0"
7
- "admin_thumb","pad","65","65","background-color:0xF0F0F0"
8
- "treatment_thumb","pad","80","60","background-color:0xF0F0F0"
9
- "staff_member_thumb","pad","50","50","background-color:0xF0F0F0"
10
- "consultation","pad","126","126","background-color:0xF0F0F0"
11
- "clinic_google_map_thumb","pad","74","74","background-color:0xF0F0F0"
@@ -1,10 +0,0 @@
1
- "storage","limit","2160","2160","quality:95"
2
- "crop","pad","98","148",""
3
- "float-crop","crop","242","162","float-x:0.8,float-y:0.2"
4
- "pad","pad","220","220","background-color:0xeeede8"
5
- "pad2","pad","40","40","background-color:0xF0F0F0"
6
- "pad3","pad","65","65","background-color:0xF0F0F0"
7
- "fit","fit","65","65",""
8
- "limit","limit","80","60",""
9
- "float-pad","pad","50","50","float-x:0.8,float-y:0.2"
10
- "large","limit","1200","900","background-color:white,interlace:PlaneInterlace"
@@ -1,333 +0,0 @@
1
- require_relative 'spec_helper'
2
- require 'httpimagestore/configuration'
3
- MemoryLimit.logger = Configuration::Scope.logger = RootLogger.new('/dev/null')
4
-
5
- require 'httpimagestore/configuration/file'
6
- require 'httpimagestore/configuration/output'
7
-
8
- describe Configuration do
9
- let :state do
10
- Configuration::RequestState.new('abc')
11
- end
12
-
13
- describe Configuration::FileSource do
14
- subject do
15
- Configuration.read(<<-EOF)
16
- path {
17
- "in" "test.in"
18
- }
19
-
20
- get "small" {
21
- source_file "original" root="/tmp" path="in"
22
- }
23
- EOF
24
- end
25
-
26
- let :in_file do
27
- Pathname.new("/tmp/test.in")
28
- end
29
-
30
- before :each do
31
- in_file.open('w'){|io| io.write('abc')}
32
- end
33
-
34
- after :each do
35
- in_file.unlink
36
- end
37
-
38
- it 'should source image from file using path spec' do
39
- subject.handlers[0].sources[0].should be_a Configuration::FileSource
40
- subject.handlers[0].sources[0].realize(state)
41
-
42
- state.images["original"].should_not be_nil
43
- state.images["original"].data.should == 'abc'
44
- end
45
-
46
- it 'should have nil mime type' do
47
- subject.handlers[0].sources[0].realize(state)
48
-
49
- state.images["original"].mime_type.should be_nil
50
- end
51
-
52
- it 'should have source path and url' do
53
- subject.handlers[0].sources[0].realize(state)
54
-
55
- state.images['original'].source_path.to_s.should == "test.in"
56
- state.images['original'].source_url.to_s.should == "file:/test.in"
57
- end
58
-
59
- describe 'context locals' do
60
- before :all do
61
- Pathname.new('/tmp/test-image-name.jpg').open('w') do |io|
62
- io.write('hello world')
63
- end
64
- end
65
-
66
- subject do
67
- Configuration.read(<<-EOF)
68
- path "image_name" "\#{image_name}.jpg"
69
-
70
- get "small" {
71
- source_file "test-image-name" root="/tmp" path="image_name"
72
- }
73
- EOF
74
- end
75
-
76
- it 'should provide image name to be used as #{image_name}' do
77
- subject.handlers[0].sources[0].realize(state)
78
- state.images['test-image-name'].source_path.to_s.should == 'test-image-name.jpg'
79
- state.images['test-image-name'].data.should == 'hello world'
80
- end
81
- end
82
-
83
- describe 'error handling' do
84
- it 'should raise StorageOutsideOfRootDirError on bad paths' do
85
- subject = Configuration.read(<<-EOF)
86
- path {
87
- "bad" "../test.in"
88
- }
89
-
90
- get "bad_path" {
91
- source_file "original" root="/tmp" path="bad"
92
- }
93
- EOF
94
-
95
- expect {
96
- subject.handlers[0].sources[0].realize(state)
97
- }.to raise_error Configuration::FileStorageOutsideOfRootDirError, %{error while processing image 'original': file storage path '../test.in' outside of root direcotry}
98
- end
99
-
100
- it 'should raise NoSuchFileError on missing file' do
101
- subject = Configuration.read(<<-EOF)
102
- path {
103
- "missing" "blah"
104
- }
105
-
106
- get "bad_path" {
107
- source_file "original" root="/tmp" path="missing"
108
- }
109
- EOF
110
-
111
- expect {
112
- subject.handlers[0].sources[0].realize(state)
113
- }.to raise_error Configuration::NoSuchFileError, %{error while processing image 'original': file 'blah' not found}
114
- end
115
-
116
- it 'should raise NoValueError on missing image name' do
117
- expect {
118
- Configuration.read(<<-EOF)
119
- get "test" {
120
- source_file root="/tmp" path="hash"
121
- }
122
- EOF
123
- }.to raise_error Configuration::NoValueError, %{syntax error while parsing 'source_file path="hash" root="/tmp"': expected image name}
124
- end
125
-
126
- it 'should raise NoAttributeError on missing root argument' do
127
- expect {
128
- Configuration.read(<<-EOF)
129
- get "test" {
130
- source_file "original" path="hash"
131
- }
132
- EOF
133
- }.to raise_error Configuration::NoAttributeError, %{syntax error while parsing 'source_file "original" path="hash"': expected 'root' attribute to be set}
134
- end
135
-
136
- it 'should raise NoAttributeError on missing path argument' do
137
- expect {
138
- Configuration.read(<<-EOF)
139
- get "test" {
140
- source_file "original" root="/tmp"
141
- }
142
- EOF
143
- }.to raise_error Configuration::NoAttributeError, %{syntax error while parsing 'source_file "original" root="/tmp"': expected 'path' attribute to be set}
144
- end
145
- end
146
-
147
- describe 'memory limit' do
148
- let :state do
149
- Configuration::RequestState.new('abc', {}, '', {}, MemoryLimit.new(1))
150
- end
151
-
152
- it 'should rais MemoryLimit::MemoryLimitedExceededError error if limit exceeded runing file sourcing' do
153
- expect {
154
- subject.handlers[0].sources[0].realize(state)
155
- }.to raise_error MemoryLimit::MemoryLimitedExceededError, 'memory limit exceeded'
156
- end
157
- end
158
-
159
- context 'in failover context' do
160
- subject do
161
- Configuration.read(<<-EOF)
162
- path "in" "test.in"
163
-
164
- get "test" {
165
- source_failover {
166
- source_file "first_fail_1" root="/tmp/bogous" path="in"
167
- source_file "first_fail_2" root="/tmp" path="in"
168
- }
169
- }
170
- EOF
171
- end
172
-
173
- it 'should source second image' do
174
- subject.handlers[0].sources[0].should be_a Configuration::SourceFailover
175
- subject.handlers[0].sources[0].realize(state)
176
-
177
- state.images.keys.should == ['first_fail_2']
178
- state.images['first_fail_2'].should_not be_nil
179
- state.images['first_fail_2'].data.should == 'abc'
180
- end
181
- end
182
- end
183
-
184
- describe Configuration::FileStore do
185
- subject do
186
- Configuration.read(<<-EOF)
187
- path {
188
- "out" "test.out"
189
- }
190
-
191
- post "small" {
192
- store_file "input" root="/tmp" path="out"
193
- }
194
- EOF
195
- end
196
-
197
- let :out_file do
198
- Pathname.new("/tmp/test.out")
199
- end
200
-
201
- before :each do
202
- out_file.unlink if out_file.exist?
203
- subject.handlers[0].sources[0].realize(state)
204
- end
205
-
206
- after :each do
207
- out_file.unlink if out_file.exist?
208
- end
209
-
210
- it 'should store image in file using path spec' do
211
- subject.handlers[0].stores[0].should be_a Configuration::FileStore
212
- subject.handlers[0].stores[0].realize(state)
213
-
214
- out_file.should exist
215
- out_file.read.should == 'abc'
216
- end
217
-
218
- it 'should have store path and url' do
219
- subject.handlers[0].stores[0].realize(state)
220
-
221
- state.images['input'].store_path.should == "test.out"
222
- state.images['input'].store_url.to_s.should == "file:/test.out"
223
- end
224
-
225
- describe 'conditional inclusion support' do
226
- subject do
227
- Configuration.read(<<-'EOF')
228
- path {
229
- "out" "test.out"
230
- }
231
-
232
- post "small" {
233
- store_file "input1" root="/tmp" path="out" if-image-name-on="#{list}"
234
- store_file "input2" root="/tmp" path="out" if-image-name-on="#{list}"
235
- store_file "input3" root="/tmp" path="out" if-image-name-on="#{list}"
236
- }
237
- EOF
238
- end
239
-
240
- let :state do
241
- Configuration::RequestState.new('abc', {list: 'input1,input3'})
242
- end
243
-
244
- it 'should mark stores to ib included when image name match if-image-name-on list' do
245
- subject.handlers[0].stores[0].excluded?(state).should be_false
246
- subject.handlers[0].stores[1].excluded?(state).should be_true
247
- subject.handlers[0].stores[2].excluded?(state).should be_false
248
- end
249
- end
250
-
251
- describe 'context locals' do
252
- subject do
253
- Configuration.read(<<-'EOF')
254
- path "image_name" "#{image_name}.jpg"
255
- path "image_mime_extension" "test-store-file.#{image_mime_extension}"
256
-
257
- post "small" {
258
- store_file "input" root="/tmp" path="image_name"
259
- store_file "input" root="/tmp" path="image_mime_extension"
260
- }
261
- EOF
262
- end
263
-
264
- it 'should provide image name to be used as #{image_name}' do
265
- subject.handlers[0].stores[0].realize(state)
266
-
267
- state.images['input'].store_path.should == 'input.jpg'
268
- end
269
-
270
- it 'should provide image mime type based file extension to be used as #{image_mime_extension}' do
271
- state.images['input'].mime_type = 'image/jpeg'
272
- subject.handlers[0].stores[1].realize(state)
273
-
274
- state.images['input'].store_path.should == 'test-store-file.jpg'
275
- end
276
-
277
- it 'should raise PathRenderingError if there is on mime type for image defined and path contains #{image_mime_extension}' do
278
- expect {
279
- subject.handlers[0].stores[1].realize(state)
280
- }.to raise_error Configuration::PathRenderingError, %q{cannot generate path 'image_mime_extension' from template 'test-store-file.#{image_mime_extension}': image 'input' does not have data for variable 'image_mime_extension'}
281
- end
282
- end
283
-
284
- describe 'error handling' do
285
- it 'should raise StorageOutsideOfRootDirError on bad paths' do
286
- subject = Configuration.read(<<-EOF)
287
- path {
288
- "bad" "../test.in"
289
- }
290
-
291
- post "bad_path" {
292
- store_file "input" root="/tmp" path="bad"
293
- }
294
- EOF
295
-
296
- expect {
297
- subject.handlers[0].stores[0].realize(state)
298
- }.to raise_error Configuration::FileStorageOutsideOfRootDirError, %{error while processing image 'input': file storage path '../test.in' outside of root direcotry}
299
- end
300
-
301
- it 'should raise NoValueError on missing image name' do
302
- expect {
303
- Configuration.read(<<-EOF)
304
- get "test" {
305
- store_file root="/tmp" path="hash"
306
- }
307
- EOF
308
- }.to raise_error Configuration::NoValueError, %{syntax error while parsing 'store_file path="hash" root="/tmp"': expected image name}
309
- end
310
-
311
- it 'should raise NoAttributeError on missing root argument' do
312
- expect {
313
- Configuration.read(<<-EOF)
314
- get "test" {
315
- store_file "original" path="hash"
316
- }
317
- EOF
318
- }.to raise_error Configuration::NoAttributeError, %{syntax error while parsing 'store_file "original" path="hash"': expected 'root' attribute to be set}
319
- end
320
-
321
- it 'should raise NoAttributeError on missing path argument' do
322
- expect {
323
- Configuration.read(<<-EOF)
324
- get "test" {
325
- store_file "original" root="/tmp"
326
- }
327
- EOF
328
- }.to raise_error Configuration::NoAttributeError, %{syntax error while parsing 'store_file "original" root="/tmp"': expected 'path' attribute to be set}
329
- end
330
- end
331
- end
332
- end
333
-