mobilize-base 1.36 → 1.293

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/README.md +666 -1
  2. data/lib/mobilize-base.rb +1 -12
  3. data/lib/mobilize-base/extensions/array.rb +3 -8
  4. data/lib/mobilize-base/extensions/google_drive/acl.rb +1 -1
  5. data/lib/mobilize-base/extensions/google_drive/client_login_fetcher.rb +1 -2
  6. data/lib/mobilize-base/extensions/google_drive/file.rb +37 -11
  7. data/lib/mobilize-base/extensions/string.rb +6 -11
  8. data/lib/mobilize-base/extensions/yaml.rb +7 -10
  9. data/lib/mobilize-base/handlers/gbook.rb +38 -25
  10. data/lib/mobilize-base/handlers/gdrive.rb +4 -20
  11. data/lib/mobilize-base/handlers/gfile.rb +10 -64
  12. data/lib/mobilize-base/handlers/gridfs.rb +24 -19
  13. data/lib/mobilize-base/handlers/gsheet.rb +29 -45
  14. data/lib/mobilize-base/handlers/resque.rb +10 -17
  15. data/lib/mobilize-base/jobtracker.rb +196 -22
  16. data/lib/mobilize-base/models/job.rb +77 -107
  17. data/lib/mobilize-base/models/runner.rb +122 -36
  18. data/lib/mobilize-base/models/stage.rb +37 -18
  19. data/lib/mobilize-base/tasks.rb +13 -50
  20. data/lib/mobilize-base/version.rb +1 -1
  21. data/lib/samples/gdrive.yml +0 -15
  22. data/lib/samples/gridfs.yml +3 -0
  23. data/lib/samples/gsheet.yml +4 -4
  24. data/lib/samples/jobtracker.yml +6 -0
  25. data/mobilize-base.gemspec +3 -3
  26. data/test/base_job_rows.yml +11 -0
  27. data/test/mobilize-base_test.rb +106 -0
  28. data/test/test_base_1.yml +3 -0
  29. data/test/test_helper.rb +0 -155
  30. metadata +24 -36
  31. data/lib/mobilize-base/extensions/time.rb +0 -20
  32. data/lib/mobilize-base/helpers/job_helper.rb +0 -54
  33. data/lib/mobilize-base/helpers/jobtracker_helper.rb +0 -143
  34. data/lib/mobilize-base/helpers/runner_helper.rb +0 -83
  35. data/lib/mobilize-base/helpers/stage_helper.rb +0 -38
  36. data/lib/samples/gfile.yml +0 -9
  37. data/test/fixtures/base1_stage1.in.yml +0 -10
  38. data/test/fixtures/integration_expected.yml +0 -25
  39. data/test/fixtures/integration_jobs.yml +0 -12
  40. data/test/fixtures/is_due.yml +0 -97
  41. data/test/integration/mobilize-base_test.rb +0 -57
  42. 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
@@ -1,9 +0,0 @@
1
- ---
2
- development:
3
- max_length: 100000000 #about 100MB
4
- test:
5
- max_length: 100000000 #about 100MB
6
- staging:
7
- max_length: 100000000 #about 100MB
8
- production:
9
- max_length: 100000000 #about 100MB
@@ -1,10 +0,0 @@
1
- ---
2
- - date: 2013-01-01
3
- snake_date: 2013-02-01
4
- camelDate: 2013-03-01
5
- - date: 2013-01-01
6
- snake_date: 2013-02-02
7
- camelDate: 2013-03-02
8
- - date: 2013-01-01
9
- snake_date: 2013-02-03
10
- camelDate: 2013-03-03
@@ -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"
@@ -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