embulk-input-marketo 0.2.2 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 17a277c0df4feaded10161dcf1ed102720aec4e4
4
- data.tar.gz: a80c7582a7c4fdd2becd1e4c34ae612b7379d7c7
3
+ metadata.gz: 5485d5527116194e9cf43129e39a686675038d35
4
+ data.tar.gz: 932cd341055835466e2022c950babd2c0f7966ae
5
5
  SHA512:
6
- metadata.gz: c613c70701ccc188deac206d407954804632353ab1fe11fd79bdf1294426e5cbc42b19a7b021d28345cfb93f810e6a7701163d65c6ec2604742fc3beafc9635b
7
- data.tar.gz: af31cd4811d5e8bd3bb3e54977d52e80e295d7770fd7f3b3d0929a7ebe777d455d24714c6ef60f9b8d91e64f710911eb3acf22b03bd2b766247cca28fb6aabec
6
+ metadata.gz: 31b2aa93cbb0e301b1a71fbf15c0b53f0841558aaeafb8e5d38ce884fd6cd9d34c34bc7d44678d57421e47f10739748b9815e523dffd956a6c9c76d7ebe50e41
7
+ data.tar.gz: b25b1163d52542cf8f284396f36e428fb55a35f1f4418784b93885cc678cc2fd320d53c98ea6648b8ace4dab920e431e447a60747295cf18e238dbcc2a2a2c76
data/.travis.yml CHANGED
@@ -19,6 +19,9 @@ gemfile:
19
19
  - gemfiles/embulk-0.6.21
20
20
  - gemfiles/embulk-0.6.22
21
21
  - gemfiles/embulk-0.6.23
22
+ - gemfiles/embulk-0.6.24
23
+ - gemfiles/embulk-0.6.25
24
+ - gemfiles/embulk-0.6.26
22
25
  - gemfiles/embulk-latest
23
26
  matrix:
24
27
  allow_failures:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.2.3 - 2015-09-14
2
+
3
+ * [enhancement] Catch config error [#33](https://github.com/treasure-data/embulk-input-marketo/pull/33)
4
+ * [enhancement] Concurrent worker [#31](https://github.com/treasure-data/embulk-input-marketo/pull/31)
5
+
1
6
  ## 0.2.2 - 2015-09-08
2
7
 
3
8
  * [fixed] Fix handling for activity_date_time [#32](https://github.com/treasure-data/embulk-input-marketo/pull/32)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "embulk-input-marketo"
3
- spec.version = "0.2.2"
3
+ spec.version = "0.2.3"
4
4
  spec.authors = ["uu59", "yoshihara"]
5
5
  spec.summary = "Marketo input plugin for Embulk"
6
6
  spec.description = "Loads records from Marketo."
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org/'
2
+ gemspec :path => '../'
3
+
4
+ gem "embulk", "0.6.26"
@@ -41,7 +41,11 @@ module Embulk
41
41
 
42
42
  case column["type"].to_s
43
43
  when "timestamp"
44
- Time.parse(value)
44
+ begin
45
+ Time.parse(value)
46
+ rescue => e
47
+ raise ConfigError, "Can't parse as Time '#{value}' (column is #{column["name"]})"
48
+ end
45
49
  else
46
50
  value
47
51
  end
@@ -67,14 +67,6 @@ module Embulk
67
67
  @soap = MarketoApi.soap_client(task, target)
68
68
  end
69
69
 
70
- def self.logger
71
- Embulk.logger
72
- end
73
-
74
- def logger
75
- self.class.logger
76
- end
77
-
78
70
  private
79
71
 
80
72
  def preview?
@@ -41,36 +41,48 @@ module Embulk
41
41
  columns
42
42
  end
43
43
 
44
+ def init
45
+ @last_updated_at = task[:last_updated_at]
46
+ @columns = task[:columns]
47
+ @ranges = task[:ranges][index]
48
+ @soap = MarketoApi.soap_client(task, target)
49
+ end
50
+
44
51
  def run
45
- count = 0
46
52
  from_datetime = task[:from_datetime]
47
- to_datetime = task[:to_datetime]
53
+ to_datetime = task[:to_datetime] || Time.now
54
+
48
55
  options = {}
49
56
  options[:batch_size] = PREVIEW_COUNT if preview?
50
57
 
51
- soap.each(from_datetime, to_datetime, options) do |lead|
52
- values = @columns.map do |column|
53
- name = column["name"].to_s
54
- value = (lead[name] || {})[:value]
55
- next unless value
58
+ @ranges.each do |range|
59
+ soap.each(range, options) do |lead|
60
+ values = @columns.map do |column|
61
+ name = column["name"].to_s
62
+ value = (lead[name] || {})[:value]
63
+ next unless value
56
64
 
57
- case column["type"]
58
- when "timestamp"
59
- Time.parse(value)
60
- else
61
- value
65
+ case column["type"]
66
+ when "timestamp"
67
+ begin
68
+ Time.parse(value)
69
+ rescue => e
70
+ raise ConfigError, "Can't parse as Time '#{value}' (column is #{column["name"]})"
71
+ end
72
+ else
73
+ value
74
+ end
62
75
  end
63
- end
64
-
65
- page_builder.add(values)
66
76
 
67
- count += 1
68
- break if preview? && count >= PREVIEW_COUNT
77
+ page_builder.add(values)
78
+ end
69
79
  end
70
80
 
71
81
  page_builder.finish
72
82
 
73
- commit_report = {from_datetime: to_datetime}
83
+ commit_report = {
84
+ from_datetime: to_datetime
85
+ }
74
86
  return commit_report
75
87
  end
76
88
  end
@@ -2,6 +2,8 @@ module Embulk
2
2
  module Input
3
3
  module Marketo
4
4
  module Timeslice
5
+ TIMESLICE_COUNT_PER_TASK = 24
6
+
5
7
  def self.included(klass)
6
8
  klass.extend ClassMethods
7
9
  end
@@ -28,10 +30,20 @@ module Embulk
28
30
  from_datetime = config.param(:from_datetime, :string)
29
31
  to_datetime = config.param(:to_datetime, :string, default: Time.now.to_s)
30
32
 
33
+ # check from/to format to parse
34
+ begin
35
+ Time.parse(from_datetime)
36
+ Time.parse(to_datetime)
37
+ rescue => e
38
+ # possibly Time.parse fail
39
+ raise ConfigError, e.message
40
+ end
41
+
31
42
  if Time.parse(from_datetime) > Time.parse(to_datetime)
32
43
  raise ConfigError, "config: from_datetime '#{from_datetime}' is later than '#{to_datetime}'."
33
44
  end
34
45
 
46
+ ranges = timeslice(from_datetime, to_datetime, TIMESLICE_COUNT_PER_TASK)
35
47
  task = {
36
48
  endpoint_url: endpoint_url,
37
49
  wsdl_url: config.param(:wsdl, :string, default: "#{endpoint_url}?WSDL"),
@@ -39,6 +51,7 @@ module Embulk
39
51
  encryption_key: config.param(:encryption_key, :string),
40
52
  from_datetime: from_datetime,
41
53
  to_datetime: to_datetime,
54
+ ranges: ranges,
42
55
  columns: config.param(:columns, :array)
43
56
  }
44
57
 
@@ -51,9 +64,53 @@ module Embulk
51
64
  columns << Column.new(nil, name, type, column["format"])
52
65
  end
53
66
 
54
- # TODO tasks should be executed concurrently.
55
- resume(task, columns, 1, &control)
67
+ resume(task, columns, ranges.size, &control)
56
68
  end
69
+
70
+ def timeslice(from, to, count)
71
+ generate_time_range(from, to).each_slice(count).to_a
72
+ end
73
+
74
+ def generate_time_range(from, to)
75
+ # e.g. from = 2010-01-01 15:00, to = 2010-01-03 09:30
76
+ # convert to such array:
77
+ # [
78
+ # {from: 2010-01-01 15:00, to: 2010-01-01 16:00},
79
+ # {from: 2010-01-01 16:00, to: 2010-01-01 17:00},
80
+ # ...
81
+ # {from: 2010-01-03 08:00, to: 2010-01-03 09:00},
82
+ # {from: 2010-01-03 09:00, to: 2010-01-03 09:30},
83
+ # ]
84
+ # to fetch data from Marketo API with each day as
85
+ # desribed on official blog:
86
+ # http://developers.marketo.com/blog/performance-tuning-api-requests/
87
+ to ||= Time.now
88
+ from = Time.parse(from) unless from.is_a?(Time)
89
+ to = Time.parse(to) unless to.is_a?(Time)
90
+
91
+ result = []
92
+ since = from
93
+ while since < to
94
+ next_since = since + 3600
95
+ if to < next_since
96
+ next_since = to
97
+ end
98
+ result << {
99
+ "from" => since,
100
+ "to" => next_since
101
+ }
102
+ since = next_since
103
+ end
104
+ result
105
+ end
106
+
107
+ def resume(task, columns, count, &control)
108
+ commit_reports = yield(task, columns, count)
109
+
110
+ # all task returns same report as {from_datetime: to_datetime}
111
+ return commit_reports.first
112
+ end
113
+
57
114
  end
58
115
  end
59
116
  end
@@ -1,5 +1,4 @@
1
1
  require "savon"
2
- require "embulk/input/marketo_api/soap/timeslice"
3
2
 
4
3
  module Embulk
5
4
  module Input
@@ -80,10 +79,10 @@ module Embulk
80
79
  # unretryable error such as Authentication Failed, Invalid Request, etc.
81
80
  raise ConfigError, soap_message
82
81
  end
83
- rescue SocketError => e
82
+ rescue SocketError, Errno::ECONNREFUSED => e
84
83
  # maybe endpoint/wsdl domain was wrong
85
- Embulk.logger.debug "SocketError: endpoint=#{endpoint} wsdl=#{wsdl}"
86
- raise ConfigError, "SocketError: #{e.message} (endpoint is '#{endpoint}')"
84
+ Embulk.logger.debug "Connection error: endpoint=#{endpoint} wsdl=#{wsdl}"
85
+ raise ConfigError, "Connection error: #{e.message} (endpoint is '#{endpoint}')"
87
86
  end
88
87
  end
89
88
  end
@@ -5,8 +5,6 @@ module Embulk
5
5
  module MarketoApi
6
6
  module Soap
7
7
  class Lead < Base
8
- include Timeslice
9
-
10
8
  # NOTE: batch_size is allowed at 1000, but that takes 2 minutes in 1 request.
11
9
  # We use 250 for the default (about 30 seconds)
12
10
  BATCH_SIZE_DEFAULT = 250
@@ -17,28 +15,30 @@ module Embulk
17
15
  response.body[:success_describe_m_object][:result][:metadata][:field_list][:field]
18
16
  end
19
17
 
20
- def each(from_datetime, to_datetime, options = {}, &block)
18
+ def each(range, options = {}, &block)
21
19
  # http://developers.marketo.com/documentation/soap/getmultipleleads/
22
- to_datetime ||= Time.now
20
+ from = range["from"]
21
+ to = range["to"]
23
22
 
24
- generate_time_range(from_datetime, to_datetime).each do |range|
25
- request = {
26
- lead_selector: {
27
- oldest_updated_at: range[:from].iso8601,
28
- latest_updated_at: range[:to].iso8601,
29
- },
30
- attributes!: {
31
- lead_selector: {"xsi:type" => "ns1:LastUpdateAtSelector"}
32
- },
33
- batch_size: options[:batch_size] || BATCH_SIZE_DEFAULT,
34
- }
35
- Embulk.logger.info "Fetching from '#{range[:from]}' to '#{range[:to]}'..."
23
+ from = Time.parse(from) unless from.is_a?(Time)
24
+ to = Time.parse(to) unless to.is_a?(Time)
36
25
 
37
- stream_position = fetch(request, &block)
26
+ request = {
27
+ lead_selector: {
28
+ oldest_updated_at: from.iso8601,
29
+ latest_updated_at: to.iso8601,
30
+ },
31
+ attributes!: {
32
+ lead_selector: {"xsi:type" => "ns1:LastUpdateAtSelector"}
33
+ },
34
+ batch_size: options[:batch_size] || BATCH_SIZE_DEFAULT,
35
+ }
36
+ Embulk.logger.info "Fetching from '#{from}' to '#{to}'..."
38
37
 
39
- while stream_position
40
- stream_position = fetch(request.merge(stream_position: stream_position), &block)
41
- end
38
+ stream_position = fetch(request, &block)
39
+
40
+ while stream_position
41
+ stream_position = fetch(request.merge(stream_position: stream_position), &block)
42
42
  end
43
43
  end
44
44
 
@@ -141,6 +141,26 @@ module Embulk
141
141
  @plugin.run
142
142
  end
143
143
 
144
+ def test_wrong_type
145
+ any_instance_of(Savon::Client) do |klass|
146
+ stub(klass).call(:get_lead_changes, message: request) do
147
+ next_stream_activity_logs_response
148
+ end
149
+ end
150
+ stub(@page_builder).add {}
151
+ stub(@page_builder).finish {}
152
+
153
+ task = task()
154
+ task[:columns] = [
155
+ {"name" => "Old Value", "type" => :timestamp}
156
+ ]
157
+ @plugin = ActivityLog.new(task, nil, nil, @page_builder)
158
+
159
+ assert_raise(Embulk::ConfigError) do
160
+ @plugin.run
161
+ end
162
+ end
163
+
144
164
  private
145
165
 
146
166
  def request
@@ -22,6 +22,9 @@ module Embulk
22
22
 
23
23
  def setup_plugin
24
24
  @page_builder = Object.new
25
+ any_instance_of(Embulk::Input::Marketo::Lead) do |klass|
26
+ stub(klass).index { 0 }
27
+ end
25
28
  @plugin = Lead.new(task, nil, nil, @page_builder)
26
29
  mute_logger
27
30
  end
@@ -47,6 +50,49 @@ module Embulk
47
50
  end
48
51
  end
49
52
 
53
+ def test_invalid_datetime_given
54
+ control = proc {} # dummy
55
+
56
+ settings = {
57
+ endpoint: "https://marketo.example.com",
58
+ wsdl: "https://marketo.example.com/?wsdl",
59
+ user_id: "user_id",
60
+ encryption_key: "TOPSECRET",
61
+ from_datetime: "invalid time from",
62
+ to_datetime: "invalid time to",
63
+ columns: [
64
+ {"name" => "Name", "type" => "string"},
65
+ ]
66
+ }
67
+ config = DataSource[settings.to_a]
68
+
69
+ assert_raise(ConfigError) do
70
+ Lead.transaction(config, &control)
71
+ end
72
+ end
73
+
74
+ def test_wrong_type
75
+ control = proc {} # dummy
76
+
77
+ settings = {
78
+ endpoint: "https://marketo.example.com",
79
+ wsdl: "https://marketo.example.com/?wsdl",
80
+ user_id: "user_id",
81
+ encryption_key: "TOPSECRET",
82
+ from_datetime: "invalid time from",
83
+ to_datetime: "invalid time to",
84
+ columns: [
85
+ {"name" => "Name", "type" => "timestamp"},
86
+ ]
87
+ }
88
+
89
+ config = DataSource[settings.to_a]
90
+
91
+ assert_raise(ConfigError) do
92
+ Lead.transaction(config, &control)
93
+ end
94
+ end
95
+
50
96
  class RunTest < self
51
97
  def setup
52
98
  setup_soap
@@ -159,13 +205,84 @@ module Embulk
159
205
  end
160
206
  end
161
207
 
208
+ class TestTimeslice < self
209
+ class TestGenerateTimeRange < self
210
+ def setup
211
+ super
212
+ mute_logger
213
+ end
214
+
215
+ data do
216
+ {
217
+ "8/1 to 8/2" => ["2015-08-01 00:00:00", "2015-08-02 00:00:00", 24],
218
+ "over the days" => ["2015-08-01 19:00:00", "2015-08-03 05:00:00", 34],
219
+ "odd times" => ["2015-08-01 11:11:11", "2015-08-01 22:22:22", 12],
220
+ }
221
+ end
222
+ def test_generate_time_range_by_1hour(data)
223
+ from, to, count = data
224
+ range = Lead.generate_time_range(from, to)
225
+ assert_equal count, range.length
226
+ end
227
+
228
+ def test_if_to_is_nil_use_time_now
229
+ from = "2000-01-01"
230
+ now = Time.now
231
+ stub(Time).now { now }
232
+
233
+ range = Lead.generate_time_range(from, nil)
234
+ assert_equal now, range.last["to"]
235
+ end
236
+ end
237
+
238
+ def test_timeslice
239
+ from = "2015-08-02 20:00:00"
240
+ to = "2015-08-03 08:08:08"
241
+ count = 4
242
+
243
+ raw_expect = [
244
+ [
245
+ {from: "2015-08-02 20:00:00", to: "2015-08-02 21:00:00"},
246
+ {from: "2015-08-02 21:00:00", to: "2015-08-02 22:00:00"},
247
+ {from: "2015-08-02 22:00:00", to: "2015-08-02 23:00:00"},
248
+ {from: "2015-08-02 23:00:00", to: "2015-08-03 00:00:00"},
249
+ ],
250
+ [
251
+ {from: "2015-08-03 00:00:00", to: "2015-08-03 01:00:00"},
252
+ {from: "2015-08-03 01:00:00", to: "2015-08-03 02:00:00"},
253
+ {from: "2015-08-03 02:00:00", to: "2015-08-03 03:00:00"},
254
+ {from: "2015-08-03 03:00:00", to: "2015-08-03 04:00:00"},
255
+ ],
256
+ [
257
+ {from: "2015-08-03 04:00:00", to: "2015-08-03 05:00:00"},
258
+ {from: "2015-08-03 05:00:00", to: "2015-08-03 06:00:00"},
259
+ {from: "2015-08-03 06:00:00", to: "2015-08-03 07:00:00"},
260
+ {from: "2015-08-03 07:00:00", to: "2015-08-03 08:00:00"},
261
+ ],
262
+ [
263
+ {from: "2015-08-03 08:00:00", to: "2015-08-03 08:08:08"},
264
+ ]
265
+ ]
266
+
267
+ expect = raw_expect.map do |slice|
268
+ slice.map do |range|
269
+ {
270
+ "from" => Time.parse(range[:from]),
271
+ "to" => Time.parse(range[:to])
272
+ }
273
+ end
274
+ end
275
+ assert_equal(expect, Lead.timeslice(from, to, count))
276
+ end
277
+ end
278
+
162
279
  private
163
280
 
164
281
  def request
165
282
  {
166
283
  lead_selector: {
167
- oldest_updated_at: timerange.first[:from].iso8601,
168
- latest_updated_at: timerange.first[:to].iso8601,
284
+ oldest_updated_at: timerange.first["from"].iso8601,
285
+ latest_updated_at: timerange.first["to"].iso8601,
169
286
  },
170
287
  attributes!: {lead_selector: {"xsi:type"=>"ns1:LastUpdateAtSelector"}},
171
288
  batch_size: MarketoApi::Soap::Lead::BATCH_SIZE_DEFAULT,
@@ -225,8 +342,7 @@ module Embulk
225
342
  end
226
343
 
227
344
  def timerange
228
- soap = MarketoApi::Soap::Lead.new(settings[:endpoint], settings[:wsdl], settings[:user_id], settings[:encryption_key])
229
- soap.send(:generate_time_range, from_datetime, to_datetime)
345
+ Lead.generate_time_range(from_datetime, to_datetime)
230
346
  end
231
347
 
232
348
  def task
@@ -237,6 +353,7 @@ module Embulk
237
353
  encryption_key: "TOPSECRET",
238
354
  from_datetime: from_datetime,
239
355
  to_datetime: to_datetime,
356
+ ranges: Lead.timeslice(from_datetime, to_datetime, Lead::TIMESLICE_COUNT_PER_TASK),
240
357
  columns: [
241
358
  {"name" => "Name", "type" => "string"},
242
359
  ]
@@ -260,6 +377,70 @@ module Embulk
260
377
  is_dynamic: true,
261
378
  dynamic_field_ref: "leadAttributeList",
262
379
  updated_at: DateTime.parse("2000-01-01 22:22:22")
380
+ },
381
+ {
382
+ name: "FieldInt",
383
+ description: nil,
384
+ display_name: "The Name of Field",
385
+ source_object: "Lead",
386
+ data_type: "integer",
387
+ size: nil,
388
+ is_readonly: false,
389
+ is_update_blocked: false,
390
+ is_name: nil,
391
+ is_primary_key: false,
392
+ is_custom: true,
393
+ is_dynamic: true,
394
+ dynamic_field_ref: "leadAttributeList",
395
+ updated_at: DateTime.parse("2000-01-01 22:22:22")
396
+ },
397
+ {
398
+ name: "FieldBoolean",
399
+ description: nil,
400
+ display_name: "The Name of Field",
401
+ source_object: "Lead",
402
+ data_type: "boolean",
403
+ size: nil,
404
+ is_readonly: false,
405
+ is_update_blocked: false,
406
+ is_name: nil,
407
+ is_primary_key: false,
408
+ is_custom: true,
409
+ is_dynamic: true,
410
+ dynamic_field_ref: "leadAttributeList",
411
+ updated_at: DateTime.parse("2000-01-01 22:22:22")
412
+ },
413
+ {
414
+ name: "FieldFloat",
415
+ description: nil,
416
+ display_name: "The Name of Field",
417
+ source_object: "Lead",
418
+ data_type: "float",
419
+ size: nil,
420
+ is_readonly: false,
421
+ is_update_blocked: false,
422
+ is_name: nil,
423
+ is_primary_key: false,
424
+ is_custom: true,
425
+ is_dynamic: true,
426
+ dynamic_field_ref: "leadAttributeList",
427
+ updated_at: DateTime.parse("2000-01-01 22:22:22")
428
+ },
429
+ {
430
+ name: "FieldString",
431
+ description: nil,
432
+ display_name: "The Name of Field",
433
+ source_object: "Lead",
434
+ data_type: "string",
435
+ size: nil,
436
+ is_readonly: false,
437
+ is_update_blocked: false,
438
+ is_name: nil,
439
+ is_primary_key: false,
440
+ is_custom: true,
441
+ is_dynamic: true,
442
+ dynamic_field_ref: "leadAttributeList",
443
+ updated_at: DateTime.parse("2000-01-01 22:22:22")
263
444
  }
264
445
  ]
265
446
  end
@@ -269,6 +450,10 @@ module Embulk
269
450
  {name: "id", type: "long"},
270
451
  {name: "email", type: "string"},
271
452
  {name: "FieldName", type: "timestamp"},
453
+ {name: "FieldInt", type: "long"},
454
+ {name: "FieldBoolean", type: "boolean"},
455
+ {name: "FieldFloat", type: "double"},
456
+ {name: "FieldString", type: "string"},
272
457
  ]
273
458
  end
274
459
  end
@@ -19,40 +19,31 @@ module Embulk
19
19
  super
20
20
  end
21
21
 
22
- def test_each_invoke_fetch
23
- from_datetime = "2015-07-06"
24
- to_datetime = "2015-07-07"
25
- timerange = soap.send(:generate_time_range, from_datetime, to_datetime)
26
-
27
- stub(soap).fetch { nil }
28
- mock(soap).fetch(anything).times(timerange.length)
29
-
30
- soap.each(from_datetime, to_datetime) { }
31
- end
32
-
33
22
  def test_each_invoke_fetch_with_specified_time
34
- from_datetime = "2015-07-06"
35
- to_datetime = "2015-07-07"
36
- timerange = soap.send(:generate_time_range, from_datetime, to_datetime)
23
+ timerange = {
24
+ "from" => Time.parse("2015-07-06 00:00:00"),
25
+ "to" => Time.parse("2015-07-06 12:00:00"),
26
+ }
37
27
 
38
28
  request = {
39
29
  lead_selector: {
40
- oldest_updated_at: timerange.first[:from].iso8601,
41
- latest_updated_at: timerange.first[:to].iso8601,
30
+ oldest_updated_at: timerange["from"].iso8601,
31
+ latest_updated_at: timerange["to"].iso8601,
42
32
  },
43
33
  attributes!: {lead_selector: {"xsi:type"=>"ns1:LastUpdateAtSelector"}},
44
34
  batch_size: Lead::BATCH_SIZE_DEFAULT,
45
35
  }
46
36
 
47
- stub(soap).fetch { nil }
48
37
  mock(soap).fetch(request)
49
38
 
50
- soap.each(from_datetime, to_datetime) { }
39
+ soap.each(timerange) { }
51
40
  end
52
41
 
53
42
  def test_each_fetch_next_page
54
- from_datetime = "2015-07-06 00:00:00"
55
- to_datetime = "2015-07-06 00:00:01"
43
+ timerange = {
44
+ "from" => Time.parse("2015-07-06 23:30:00"),
45
+ "to" => Time.parse("2015-07-07 00:00:00"),
46
+ }
56
47
 
57
48
  any_instance_of(Savon::Client) do |klass|
58
49
  mock(klass).call(:get_multiple_leads, anything) do
@@ -64,35 +55,7 @@ module Embulk
64
55
  leads_count = next_stream_leads_response.xpath('//leadRecord').length
65
56
  mock(proc).call(anything).times(leads_count)
66
57
 
67
- soap.each(from_datetime, to_datetime, &proc)
68
- end
69
- end
70
-
71
- class TestGenerateTime < self
72
- def setup
73
- mute_logger
74
- end
75
-
76
- data do
77
- {
78
- "8/1 to 8/2" => ["2015-08-01 00:00:00", "2015-08-02 00:00:00", 24],
79
- "over the days" => ["2015-08-01 19:00:00", "2015-08-03 05:00:00", 34],
80
- "odd times" => ["2015-08-01 11:11:11", "2015-08-01 22:22:22", 12],
81
- }
82
- end
83
- def test_generate_time_range_by_1hour(data)
84
- from, to, count = data
85
- range = soap.send(:generate_time_range, from, to)
86
- assert_equal count, range.length
87
- end
88
-
89
- def test_if_to_is_nil_use_time_now
90
- from = "2000-01-01"
91
- now = Time.now
92
- stub(Time).now { now }
93
-
94
- range = soap.send(:generate_time_range, from, nil)
95
- assert_equal now, range.last[:to]
58
+ soap.each(timerange, {}, &proc)
96
59
  end
97
60
  end
98
61
 
data/test/run-test.rb CHANGED
@@ -14,5 +14,8 @@ $LOAD_PATH.unshift(test_dir)
14
14
  ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] ||= "5000"
15
15
 
16
16
  CodeClimate::TestReporter.start
17
+ SimpleCov.start do
18
+ add_filter "/test/"
19
+ end if ENV["COV"]
17
20
 
18
21
  exit Test::Unit::AutoRunner.run(true, test_dir)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-marketo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - uu59
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-09-08 00:00:00.000000000 Z
12
+ date: 2015-09-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  requirement: !ruby/object:Gem::Requirement
@@ -170,6 +170,7 @@ files:
170
170
  - gemfiles/embulk-0.6.23
171
171
  - gemfiles/embulk-0.6.24
172
172
  - gemfiles/embulk-0.6.25
173
+ - gemfiles/embulk-0.6.26
173
174
  - gemfiles/embulk-latest
174
175
  - gemfiles/template.erb
175
176
  - lib/embulk/input/marketo/activity_log.rb
@@ -180,7 +181,6 @@ files:
180
181
  - lib/embulk/input/marketo_api/soap/activity_log.rb
181
182
  - lib/embulk/input/marketo_api/soap/base.rb
182
183
  - lib/embulk/input/marketo_api/soap/lead.rb
183
- - lib/embulk/input/marketo_api/soap/timeslice.rb
184
184
  - test/activity_log_fixtures.rb
185
185
  - test/embulk/input/marketo/test_activity_log.rb
186
186
  - test/embulk/input/marketo/test_base.rb
@@ -1,44 +0,0 @@
1
- module Embulk
2
- module Input
3
- module MarketoApi
4
- module Soap
5
- module Timeslice
6
- private
7
-
8
- def generate_time_range(from, to)
9
- # e.g. from = 2010-01-01 15:00, to = 2010-01-03 09:30
10
- # convert to such array:
11
- # [
12
- # {from: 2010-01-01 15:00, to: 2010-01-01 16:00},
13
- # {from: 2010-01-01 16:00, to: 2010-01-01 17:00},
14
- # ...
15
- # {from: 2010-01-03 08:00, to: 2010-01-03 09:00},
16
- # {from: 2010-01-03 09:00, to: 2010-01-03 09:30},
17
- # ]
18
- # to fetch data from Marketo API with each day as
19
- # desribed on official blog:
20
- # http://developers.marketo.com/blog/performance-tuning-api-requests/
21
- to ||= Time.now
22
- from = Time.parse(from) unless from.is_a?(Time)
23
- to = Time.parse(to) unless to.is_a?(Time)
24
-
25
- result = []
26
- since = from
27
- while since < to
28
- next_since = since + 3600
29
- if to < next_since
30
- next_since = to
31
- end
32
- result << {
33
- from: since,
34
- to: next_since
35
- }
36
- since = next_since
37
- end
38
- result
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end