mobilize-base 1.36 → 1.293
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.
- data/README.md +666 -1
- data/lib/mobilize-base.rb +1 -12
- data/lib/mobilize-base/extensions/array.rb +3 -8
- data/lib/mobilize-base/extensions/google_drive/acl.rb +1 -1
- data/lib/mobilize-base/extensions/google_drive/client_login_fetcher.rb +1 -2
- data/lib/mobilize-base/extensions/google_drive/file.rb +37 -11
- data/lib/mobilize-base/extensions/string.rb +6 -11
- data/lib/mobilize-base/extensions/yaml.rb +7 -10
- data/lib/mobilize-base/handlers/gbook.rb +38 -25
- data/lib/mobilize-base/handlers/gdrive.rb +4 -20
- data/lib/mobilize-base/handlers/gfile.rb +10 -64
- data/lib/mobilize-base/handlers/gridfs.rb +24 -19
- data/lib/mobilize-base/handlers/gsheet.rb +29 -45
- data/lib/mobilize-base/handlers/resque.rb +10 -17
- data/lib/mobilize-base/jobtracker.rb +196 -22
- data/lib/mobilize-base/models/job.rb +77 -107
- data/lib/mobilize-base/models/runner.rb +122 -36
- data/lib/mobilize-base/models/stage.rb +37 -18
- data/lib/mobilize-base/tasks.rb +13 -50
- data/lib/mobilize-base/version.rb +1 -1
- data/lib/samples/gdrive.yml +0 -15
- data/lib/samples/gridfs.yml +3 -0
- data/lib/samples/gsheet.yml +4 -4
- data/lib/samples/jobtracker.yml +6 -0
- data/mobilize-base.gemspec +3 -3
- data/test/base_job_rows.yml +11 -0
- data/test/mobilize-base_test.rb +106 -0
- data/test/test_base_1.yml +3 -0
- data/test/test_helper.rb +0 -155
- metadata +24 -36
- data/lib/mobilize-base/extensions/time.rb +0 -20
- data/lib/mobilize-base/helpers/job_helper.rb +0 -54
- data/lib/mobilize-base/helpers/jobtracker_helper.rb +0 -143
- data/lib/mobilize-base/helpers/runner_helper.rb +0 -83
- data/lib/mobilize-base/helpers/stage_helper.rb +0 -38
- data/lib/samples/gfile.yml +0 -9
- data/test/fixtures/base1_stage1.in.yml +0 -10
- data/test/fixtures/integration_expected.yml +0 -25
- data/test/fixtures/integration_jobs.yml +0 -12
- data/test/fixtures/is_due.yml +0 -97
- data/test/integration/mobilize-base_test.rb +0 -57
- data/test/unit/mobilize-base_test.rb +0 -33
@@ -1,83 +0,0 @@
|
|
1
|
-
#this module adds convenience methods to the Runner model
|
2
|
-
module Mobilize
|
3
|
-
module RunnerHelper
|
4
|
-
def headers
|
5
|
-
%w{name active trigger status stage1 stage2 stage3 stage4 stage5}
|
6
|
-
end
|
7
|
-
|
8
|
-
def title
|
9
|
-
r = self
|
10
|
-
r.path.split("/").first
|
11
|
-
end
|
12
|
-
|
13
|
-
def worker
|
14
|
-
r = self
|
15
|
-
Mobilize::Resque.find_worker_by_path(r.path)
|
16
|
-
end
|
17
|
-
|
18
|
-
def dataset
|
19
|
-
r = self
|
20
|
-
Dataset.find_or_create_by_handler_and_path("gsheet",r.path)
|
21
|
-
end
|
22
|
-
|
23
|
-
def gbook(gdrive_slot)
|
24
|
-
r = self
|
25
|
-
title = r.path.split("/").first
|
26
|
-
Gbook.find_by_path(title,gdrive_slot)
|
27
|
-
end
|
28
|
-
|
29
|
-
def gsheet(gdrive_slot)
|
30
|
-
r = self
|
31
|
-
u = r.user
|
32
|
-
jobs_sheet = Gsheet.find_by_path(r.path,gdrive_slot)
|
33
|
-
#make sure the user has a runner with a jobs sheet and has write privileges on the spreadsheet
|
34
|
-
unless (jobs_sheet and jobs_sheet.spreadsheet.acl_entry(u.email).ie{|e| e and e.role=="writer"})
|
35
|
-
#only give the user edit permissions if they're the ones
|
36
|
-
#creating it
|
37
|
-
jobs_sheet = Gsheet.find_or_create_by_path(r.path,gdrive_slot)
|
38
|
-
unless jobs_sheet.spreadsheet.acl_entry(u.email).ie{|e| e and e.role=="owner"}
|
39
|
-
jobs_sheet.spreadsheet.update_acl(u.email)
|
40
|
-
end
|
41
|
-
jobs_sheet.add_headers(r.headers)
|
42
|
-
begin;jobs_sheet.delete_sheet1;rescue;end #don't care if sheet1 deletion fails
|
43
|
-
end
|
44
|
-
return jobs_sheet
|
45
|
-
end
|
46
|
-
|
47
|
-
def jobs(jname=nil)
|
48
|
-
r = self
|
49
|
-
js = Job.where(:path=>/^#{r.path.escape_regex}/).to_a
|
50
|
-
if jname
|
51
|
-
return js.sel{|j| j.name == jname}.first
|
52
|
-
else
|
53
|
-
return js
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def user
|
58
|
-
r = self
|
59
|
-
user_name = r.path.split("_")[1..-1].join("_").split("(").first.split("/").first
|
60
|
-
User.where(:name=>user_name).first
|
61
|
-
end
|
62
|
-
|
63
|
-
def update_status(msg)
|
64
|
-
r = self
|
65
|
-
r.update_attributes(:status=>msg, :status_at=>Time.now.utc)
|
66
|
-
Mobilize::Resque.set_worker_args_by_path(r.path,{'status'=>msg})
|
67
|
-
return true
|
68
|
-
end
|
69
|
-
|
70
|
-
def is_working?
|
71
|
-
r = self
|
72
|
-
Mobilize::Resque.active_paths.include?(r.path)
|
73
|
-
end
|
74
|
-
|
75
|
-
def is_due?
|
76
|
-
r = self.reload
|
77
|
-
return false if r.is_working?
|
78
|
-
prev_due_time = Time.now.utc - Jobtracker.runner_read_freq
|
79
|
-
return true if r.started_at.nil? or r.started_at < prev_due_time
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
#this module adds convenience methods to the Stage model
|
2
|
-
module Mobilize
|
3
|
-
module StageHelper
|
4
|
-
def idx
|
5
|
-
s = self
|
6
|
-
s.path.split("/").last.gsub("stage","").to_i
|
7
|
-
end
|
8
|
-
|
9
|
-
def out_dst
|
10
|
-
#this gives a dataset that points to the output
|
11
|
-
#allowing you to determine its size
|
12
|
-
#before committing to a read or write
|
13
|
-
s = self
|
14
|
-
Dataset.find_by_url(s.response['out_url']) if s.response and s.response['out_url']
|
15
|
-
end
|
16
|
-
|
17
|
-
def err_dst
|
18
|
-
#this gives a dataset that points to the output
|
19
|
-
#allowing you to determine its size
|
20
|
-
#before committing to a read or write
|
21
|
-
s = self
|
22
|
-
Dataset.find_by_url(s.response['err_url']) if s.response and s.response['err_url']
|
23
|
-
end
|
24
|
-
|
25
|
-
def params
|
26
|
-
s = self
|
27
|
-
p = YAML.easy_load(s.param_string)
|
28
|
-
raise "Must resolve to Hash" unless p.class==Hash
|
29
|
-
return p
|
30
|
-
end
|
31
|
-
|
32
|
-
def job
|
33
|
-
s = self
|
34
|
-
job_path = s.path.split("/")[0..-2].join("/")
|
35
|
-
Job.where(:path=>job_path).first
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
data/lib/samples/gfile.yml
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- path: "jobtracker"
|
3
|
-
state: working
|
4
|
-
count: 1
|
5
|
-
confirmed_ats: []
|
6
|
-
- path: "Runner_mobilize(test)/jobs"
|
7
|
-
state: working
|
8
|
-
count: 2
|
9
|
-
confirmed_ats: []
|
10
|
-
- path: "Runner_mobilize(test)/jobs/base1/stage1"
|
11
|
-
state: working
|
12
|
-
count: 1
|
13
|
-
confirmed_ats: []
|
14
|
-
- path: "Runner_mobilize(test)/jobs/base1/stage2"
|
15
|
-
state: working
|
16
|
-
count: 1
|
17
|
-
confirmed_ats: []
|
18
|
-
- path: "Runner_mobilize(test)/jobs/base2/stage1"
|
19
|
-
state: working
|
20
|
-
count: 1
|
21
|
-
confirmed_ats: []
|
22
|
-
- path: "Runner_mobilize(test)/jobs/base2/stage1"
|
23
|
-
state: failed
|
24
|
-
count: 2
|
25
|
-
confirmed_ats: []
|
@@ -1,12 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- name: base1
|
3
|
-
active: true
|
4
|
-
trigger: once
|
5
|
-
status: ""
|
6
|
-
stage1: gfile.write source:"gsheet://base1_stage1.in", target:"gfile://base1_stage1.out"
|
7
|
-
stage2: gsheet.write source:"gfile://base1_stage1.out", target:"gsheet://base1_stage2.out"
|
8
|
-
- name: base2
|
9
|
-
active: true
|
10
|
-
trigger: after base1
|
11
|
-
status: ""
|
12
|
-
stage1: gsheet.write source:"base1."_"", target:"base2_stage1.out"
|
data/test/fixtures/is_due.yml
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- name: once_active
|
3
|
-
active: true
|
4
|
-
trigger: once
|
5
|
-
status: ""
|
6
|
-
stage1: gsheet.method source:"source", target:"target"
|
7
|
-
expected: true
|
8
|
-
- name: once_inactive
|
9
|
-
active: false
|
10
|
-
trigger: once
|
11
|
-
status: ""
|
12
|
-
stage1: gfile.method source:"source", target:"target"
|
13
|
-
expected: false
|
14
|
-
- name: 1h_comp_never
|
15
|
-
active: true
|
16
|
-
trigger: every 1.hour
|
17
|
-
status: ""
|
18
|
-
stage1: gsheet.method source:"source", target:"target"
|
19
|
-
expected: true
|
20
|
-
- name: 1h_comp_0.5h_ago
|
21
|
-
active: true
|
22
|
-
trigger: every 1.hour
|
23
|
-
status: ""
|
24
|
-
stage1: gsheet.method source:"source", target:"target"
|
25
|
-
completed_at: Time.now.utc - 1800.seconds
|
26
|
-
expected: false
|
27
|
-
- name: 1h_comp_1.5h_ago
|
28
|
-
active: true
|
29
|
-
trigger: every 1.hour
|
30
|
-
status: ""
|
31
|
-
stage1: gsheet.method source:"source", target:"target"
|
32
|
-
completed_at: Time.now.utc - 5400.seconds
|
33
|
-
expected: true
|
34
|
-
- name: 1h_aft45_comp_2_45_marks_ago
|
35
|
-
active: true
|
36
|
-
trigger: 'every 1.hour after 45'
|
37
|
-
status: ""
|
38
|
-
stage1: gsheet.method source:"source", target:"target"
|
39
|
-
completed_at: Time.at_marks_ago(2,'hour', '45')
|
40
|
-
expected: true
|
41
|
-
- name: 1h_aft45_comp_aft_1_45_mark_ago
|
42
|
-
active: true
|
43
|
-
trigger: 'every 1.hour after :45'
|
44
|
-
status: ""
|
45
|
-
stage1: gsheet.method source:"source", target:"target"
|
46
|
-
completed_at: Time.at_marks_ago(1,'hour', '45')
|
47
|
-
expected: false
|
48
|
-
- name: 1d_aft0135_comp_2_0135_marks_ago
|
49
|
-
active: true
|
50
|
-
trigger: 'every 1.day after 01:35'
|
51
|
-
status: ""
|
52
|
-
stage1: gsheet.method source:"source", target:"target"
|
53
|
-
completed_at: Time.at_marks_ago(2,'day', '0135')
|
54
|
-
expected: true
|
55
|
-
- name: 1d_aft0135_comp_1_0135_mark_ago
|
56
|
-
active: true
|
57
|
-
trigger: 'every 1.day after 0135'
|
58
|
-
status: ""
|
59
|
-
stage1: gsheet.method source:"source", target:"target"
|
60
|
-
completed_at: Time.at_marks_ago(1,'day', '0135')
|
61
|
-
expected: false
|
62
|
-
- name: 5d_aft0135_comp_5_0135_mark_ago
|
63
|
-
active: true
|
64
|
-
trigger: 'every 5.day after 01:35'
|
65
|
-
status: ""
|
66
|
-
stage1: gsheet.method source:"source", target:"target"
|
67
|
-
completed_at: Time.at_marks_ago(5,'day', '0135')
|
68
|
-
expected: false
|
69
|
-
- name: 5d_aft0135_comp_6_0135_mark_ago
|
70
|
-
active: true
|
71
|
-
trigger: 'every 5.day after 01:35'
|
72
|
-
status: ""
|
73
|
-
stage1: gsheet.method source:"source", target:"target"
|
74
|
-
completed_at: Time.at_marks_ago(6,'day', '0135')
|
75
|
-
expected: true
|
76
|
-
- name: parent_comp_child_fail
|
77
|
-
active: true
|
78
|
-
trigger: 'after once_inactive'
|
79
|
-
status: ""
|
80
|
-
stage1: gsheet.method source:"source", target:"target"
|
81
|
-
parent: {completed_at: Time.now.utc - 1.second}
|
82
|
-
failed_at: Time.now.utc
|
83
|
-
expected: true
|
84
|
-
- name: parent_comp_child_comp
|
85
|
-
active: true
|
86
|
-
trigger: 'after once_inactive'
|
87
|
-
status: ""
|
88
|
-
stage1: gsheet.method source:"source", target:"target"
|
89
|
-
parent: {completed_at: Time.now.utc - 1.second}
|
90
|
-
completed_at: Time.now.utc
|
91
|
-
expected: false
|
92
|
-
- name: missing_module
|
93
|
-
active: true
|
94
|
-
trigger: once
|
95
|
-
status: ""
|
96
|
-
stage1: handler.method source:"source", target:"target"
|
97
|
-
expected: false
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
describe Mobilize do
|
3
|
-
|
4
|
-
it "runs integration test" do
|
5
|
-
|
6
|
-
puts "restart test redis"
|
7
|
-
TestHelper.restart_test_redis
|
8
|
-
TestHelper.drop_test_db
|
9
|
-
|
10
|
-
puts "restart workers"
|
11
|
-
Mobilize::Jobtracker.restart_workers!
|
12
|
-
|
13
|
-
u = TestHelper.owner_user
|
14
|
-
r = u.runner
|
15
|
-
user_name = u.name
|
16
|
-
gdrive_slot = u.email
|
17
|
-
|
18
|
-
puts "build test runner"
|
19
|
-
TestHelper.build_test_runner(user_name)
|
20
|
-
assert Mobilize::Jobtracker.workers.length == Mobilize::Resque.config['max_workers'].to_i
|
21
|
-
|
22
|
-
puts "add base1_stage1.in sheet"
|
23
|
-
input_fixture_name = "base1_stage1.in"
|
24
|
-
input_target_url = "gsheet://#{r.title}/#{input_fixture_name}"
|
25
|
-
TestHelper.write_fixture(input_fixture_name, input_target_url, 'replace' => true)
|
26
|
-
|
27
|
-
puts "add jobs sheet with integration jobs"
|
28
|
-
jobs_fixture_name = "integration_jobs"
|
29
|
-
jobs_target_url = "gsheet://#{r.title}/jobs"
|
30
|
-
TestHelper.write_fixture(jobs_fixture_name, jobs_target_url, 'update' => true)
|
31
|
-
|
32
|
-
puts "wait for stages"
|
33
|
-
Mobilize::Jobtracker.start
|
34
|
-
#wait for stages to complete
|
35
|
-
expected_fixture_name = "integration_expected"
|
36
|
-
TestHelper.confirm_expected_jobs(expected_fixture_name)
|
37
|
-
#stop jobtracker
|
38
|
-
Mobilize::Jobtracker.stop!
|
39
|
-
|
40
|
-
puts "jobtracker posted test sheet data to test destination, and checksum succeeded?"
|
41
|
-
tsv_hash = {}
|
42
|
-
["base1_stage1.in", "base1_stage2.out"].each do |sheet_name|
|
43
|
-
url = "gsheet://#{r.title}/#{sheet_name}"
|
44
|
-
data = Mobilize::Dataset.read_by_url(url,user_name,gdrive_slot)
|
45
|
-
assert TestHelper.check_output(url, 'min_length' => 10) == true
|
46
|
-
tsv_hash[sheet_name] = data
|
47
|
-
end
|
48
|
-
|
49
|
-
assert tsv_hash["base1_stage2.out"] == tsv_hash["base1_stage1.in"]
|
50
|
-
|
51
|
-
err_url = "gsheet://#{r.title}/base2_stage1.err"
|
52
|
-
err_response = "Unable to parse stage params, make sure you don't have issues with your quotes, commas, or colons."
|
53
|
-
|
54
|
-
assert TestHelper.check_output(err_url, 'match' => err_response) == true
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
class TestUnit < MiniTest::Unit::TestCase
|
3
|
-
def setup
|
4
|
-
TestHelper.restart_test_redis
|
5
|
-
TestHelper.drop_test_db
|
6
|
-
end
|
7
|
-
|
8
|
-
#this test checks that several job triggers work as expected
|
9
|
-
def test_is_due
|
10
|
-
u = TestHelper.owner_user
|
11
|
-
job_hashes = TestHelper.load_fixture("is_due")
|
12
|
-
job_hashes.each do |jh|
|
13
|
-
job_path = "#{u.runner.path}/#{jh['name']}"
|
14
|
-
j = Mobilize::Job.find_or_create_by_path(job_path)
|
15
|
-
#update job params
|
16
|
-
j.update_from_hash(jh)
|
17
|
-
#apply the completed_at, failed at, and parent attributes where appropriate
|
18
|
-
if jh['completed_at']
|
19
|
-
j.stages.last.update_attributes(:completed_at=>eval(jh['completed_at']))
|
20
|
-
end
|
21
|
-
if jh['failed_at']
|
22
|
-
j.stages.last.update_attributes(:failed_at=>eval(jh['failed_at']))
|
23
|
-
end
|
24
|
-
if jh['parent']
|
25
|
-
j.parent.stages.last.update_attributes(:completed_at=>eval(jh['parent']['completed_at'])) if jh['parent']['completed_at']
|
26
|
-
j.parent.stages.last.update_attributes(:failed_at=>eval(jh['parent']['failed_at'])) if jh['parent']['failed_at']
|
27
|
-
end
|
28
|
-
expected = jh['expected']
|
29
|
-
#check if is_due
|
30
|
-
assert expected == j.is_due?
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|