marty 6.1.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +17 -3
  4. data/.rubocop.yml +5 -0
  5. data/.rubocop_todo.yml +3 -2
  6. data/Gemfile +2 -1
  7. data/app/assets/javascripts/marty/extjs/extensions/marty.js +23 -1
  8. data/app/assets/stylesheets/marty/application.css +4 -1
  9. data/app/assets/stylesheets/marty/dark_mode.css +17 -0
  10. data/app/components/marty/auth_app.rb +10 -1
  11. data/app/components/marty/auth_app/client/auth_app.js +4 -0
  12. data/app/components/marty/extras/layout.rb +2 -2
  13. data/app/components/marty/extras/misc.rb +1 -1
  14. data/app/components/marty/log_view.rb +0 -1
  15. data/app/components/marty/main_auth_app.rb +9 -12
  16. data/app/components/marty/promise_view.rb +5 -0
  17. data/app/components/marty/promise_view/client/promise_view.js +11 -0
  18. data/app/components/marty/schedule_jobs_dashboard.rb +30 -96
  19. data/app/components/marty/schedule_jobs_grid.rb +118 -0
  20. data/app/controllers/marty/application_controller.rb +6 -2
  21. data/app/models/marty/base.rb +48 -48
  22. data/app/models/marty/config.rb +14 -2
  23. data/app/models/marty/user.rb +12 -0
  24. data/app/services/marty/background_job/fetch_missing_in_schedule_cron_jobs.rb +19 -0
  25. data/app/services/marty/enums/report.rb +18 -0
  26. data/app/services/marty/promises/delorean/create.rb +16 -27
  27. data/app/services/marty/promises/ruby/create.rb +10 -1
  28. data/app/views/layouts/marty/application.html.erb +4 -1
  29. data/app/views/marty/diagnostic/op.html.erb +3 -1
  30. data/config/locales/en.yml +2 -0
  31. data/db/migrate/512_add_promise_priority.rb +9 -0
  32. data/db/migrate/513_add_priority_to_promise_view.rb +44 -0
  33. data/db/migrate/514_remove_marty_events.rb +13 -0
  34. data/delorean/enum_report.dl +11 -0
  35. data/delorean/table_report.dl +7 -0
  36. data/docker-compose.dummy.yml +7 -4
  37. data/lib/marty.rb +5 -2
  38. data/lib/marty/api/base.rb +15 -9
  39. data/lib/marty/cache_adapters.rb +2 -0
  40. data/lib/marty/cache_adapters/mcfly_ruby_cache.rb +1 -5
  41. data/lib/marty/cache_adapters/memory_and_redis.rb +93 -0
  42. data/lib/marty/cache_adapters/redis.rb +63 -0
  43. data/lib/marty/delayed_job/scheduled_job_plugin.rb +33 -0
  44. data/lib/marty/diagnostic/database.rb +1 -2
  45. data/lib/marty/logger.rb +50 -17
  46. data/lib/marty/monkey.rb +26 -6
  47. data/lib/marty/promise_ruby_job.rb +2 -0
  48. data/lib/marty/rails_app.rb +29 -0
  49. data/lib/marty/railtie.rb +1 -0
  50. data/lib/marty/version.rb +1 -1
  51. data/marty.gemspec +1 -0
  52. data/spec/controllers/job_controller_spec.rb +2 -2
  53. data/spec/dummy/app/components/gemini/cm_auth_app.rb +12 -0
  54. data/spec/dummy/app/components/gemini/simple_view.rb +17 -0
  55. data/spec/dummy/app/jobs/test_failing_job.rb +14 -0
  56. data/spec/dummy/app/models/gemini/helper.rb +90 -1
  57. data/spec/dummy/config/application.rb +1 -0
  58. data/spec/dummy/db/migrate/20191101132729_add_activity_flag_to_simple.rb +10 -0
  59. data/spec/dummy/delorean/blame_report.dl +1 -0
  60. data/spec/dummy/delorean/enum_report.dl +1 -0
  61. data/spec/dummy/delorean/marty_fields.dl +1 -0
  62. data/spec/dummy/delorean/table_report.dl +1 -0
  63. data/spec/features/data_blame_report_spec.rb +66 -0
  64. data/spec/features/data_grid_spec.rb +1 -1
  65. data/spec/features/enum_values_report_spec.rb +76 -0
  66. data/spec/features/inline_editing_spec.rb +33 -0
  67. data/spec/features/rule_spec.rb +1 -1
  68. data/spec/features/schedule_jobs_dashboard_spec.rb +1 -1
  69. data/spec/features/scripting_spec.rb +1 -1
  70. data/spec/features/user_list_report_spec.rb +74 -0
  71. data/spec/fixtures/misc/struct_compare_tests.txt +15 -5
  72. data/spec/job_helper.rb +39 -0
  73. data/spec/jobs/cron_job_spec.rb +91 -0
  74. data/spec/lib/mcfly_model_spec.rb +9 -0
  75. data/spec/models/promise_spec.rb +168 -1
  76. data/spec/other/diagnostic/delayed_job_workers_spec.rb +1 -1
  77. data/spec/performance/caching_spec.rb +99 -0
  78. data/spec/services/background_job/fetch_missing_in_schedule_cron_jobs_spec.rb +34 -0
  79. data/spec/support/delayed_job_helpers.rb +3 -3
  80. data/spec/support/shared_connection.rb +9 -1
  81. data/spec/support/structure_compare.rb +19 -3
  82. metadata +39 -6
  83. data/app/components/marty/event_view.rb +0 -129
  84. data/app/models/marty/event.rb +0 -317
  85. data/spec/dummy/db/migrate/20160923183516_add_bulk_pricing_event_ops.rb +0 -8
  86. data/spec/dummy/delorean/blame_report.dl +0 -268
  87. data/spec/dummy/delorean/marty_fields.dl +0 -63
  88. data/spec/dummy/delorean/table_report.dl +0 -34
  89. data/spec/models/event_spec.rb +0 -272
@@ -1,63 +0,0 @@
1
- PostingField:
2
- field_label = "Posting"
3
- xtype = ":combo"
4
- name = "pt_name"
5
- store = Marty::Posting.
6
- where("created_dt <> 'infinity'").
7
- order("created_dt DESC").limit(10).pluck("name")
8
- value = store[0]
9
-
10
- ######################################################################
11
-
12
- PostingField1: PostingField
13
- field_label = "Posting 1"
14
- name = "pt_name1"
15
-
16
- PostingField2: PostingField
17
- field_label = "Posting 2"
18
- name = "pt_name2"
19
-
20
- ######################################################################
21
-
22
- ClassListField:
23
- field_label = "Tables"
24
- xtype = ":multiselectcombo"
25
- name = "class_list"
26
- store = Marty::DataChange.class_list
27
-
28
- ClassField: ClassListField
29
- xtype = ":combo"
30
- name = "class_name"
31
- store = Marty::DataChange.class_list
32
-
33
- ######################################################################
34
-
35
-
36
- CheckboxField:
37
- xtype = ":checkboxfield"
38
- checked = false
39
- input_value = true
40
- unchecked_value = false
41
-
42
- ######################################################################
43
-
44
- JsonField:
45
- xtype = ":textareafield"
46
- name = "json_field"
47
- field_label = "JSON"
48
- auto_scroll = true
49
- spellcheck = false
50
- field_style = {
51
- "font_family": 'courier new',
52
- "font_size": '12px'
53
- }
54
- height = 400
55
-
56
- CsvField: JsonField
57
- field_label = "CSV"
58
- name = "csv_field"
59
-
60
- TextField:
61
- xtype = ":textfield"
62
- field_label = "Text"
63
- name = "text_field"
@@ -1,34 +0,0 @@
1
- import MartyFields
2
- import Styles
3
-
4
- ReadableField: MartyFields::CheckboxField
5
- name = "readable"
6
- field_label = "Disable Encoding"
7
-
8
- TableReport:
9
- readable =? nil
10
- pt_name =? nil
11
- posting = Marty::Posting.lookup(pt_name)
12
- pt = posting.created_dt
13
- module_name =? nil
14
- class_name =? nil
15
- title =? (class_name || "Table Report") + (
16
- if pt_name then "_" + pt_name else "")
17
- sort_field =? nil
18
- exclude_attrs =? nil
19
-
20
- result_raw = Marty::DataChange.do_export(
21
- pt,
22
- if module_name then module_name + '::' + class_name else class_name,
23
- sort_field,
24
- exclude_attrs || [],
25
- )
26
- row_count = result_raw.length
27
- result = Marty::Helper.to_csv(result_raw, {'readable' : readable})
28
- form = [
29
- MartyFields::PostingField,
30
- MartyFields::ClassField,
31
- ReadableField,
32
- ]
33
- format = "csv"
34
-
@@ -1,272 +0,0 @@
1
- require 'spec_helper'
2
- require 'job_helper'
3
-
4
- describe Marty::Event do
5
- before(:all) do
6
- @clean_file = "/tmp/clean_#{Process.pid}.psql"
7
- @save_file = "/tmp/save_#{Process.pid}.psql"
8
- save_clean_db(@clean_file)
9
-
10
- # transactional fixtures interfere with queueing jobs
11
- self.use_transactional_tests = false
12
-
13
- # Needed here because shutting transactional fixtures off
14
- # means we lose the globally set user
15
- Mcfly.whodunnit = system_user
16
-
17
- Marty::Script.load_script_bodies(promise_bodies, Date.today)
18
- start_delayed_job
19
- Marty::Config['MARTY_EVENT_POLL_SECS'] = 1
20
-
21
- @time = Time.zone.now
22
- @date_string = @time.strftime('%Y-%m-%d')
23
- @old_start = '1970-01-01 08:00:00'
24
- @old_end = '1970-01-01 09:00:00'
25
- # add events
26
- [
27
- ['testcl1', 123, @time, nil, nil, 'AVM', 'a comment',
28
- nil],
29
- ['testcl1', 123, @time + 2.second, nil, nil, 'CRA', 'b comment',
30
- nil],
31
- ['testcl1', 123, @time + 4.seconds, nil, 10000, 'PRICING', 'c comment',
32
- nil],
33
- ['testcl1', 234, @time - 5.seconds, @time, nil, 'PRICING', 'c comment',
34
- false],
35
- ['testcl2', 123, @time, nil, 2, 'AVM', 'e comment', nil],
36
- ['testcl2', 123, @time + 1.second, nil, 4, 'CRA', 'f comment', nil],
37
- ['testcl2', 123, Time.zone.parse(@old_start),
38
- Time.zone.parse(@old_end), nil, 'PRICING', 'old event', 0]
39
- ].each do |klass, subjid, startdt, enddt, expire, op, comment, error|
40
- Marty::Event.create!(klass: klass,
41
- subject_id: subjid,
42
- start_dt: startdt,
43
- end_dt: enddt,
44
- expire_secs: expire,
45
- comment: comment,
46
- enum_event_operation: op,
47
- error: error)
48
- end
49
-
50
- engine = Marty::ScriptSet.new.get_engine(NAME_I)
51
- res = engine.background_eval('SLEEPER', { 'secs' => 5 }, ['a'],
52
- klass: 'testcl3',
53
- id: 987,
54
- operation: 'PRICING')
55
- res.force
56
- engine = Marty::ScriptSet.new.get_engine(NAME_J)
57
- res = engine.background_eval('FAILER', { 'dummy' => 'dummy' }, ['a'],
58
- klass: 'testcl3',
59
- id: 654,
60
- operation: 'PRICING')
61
- res.force rescue nil
62
- sleep 5
63
- save_clean_db(@save_file)
64
- end
65
-
66
- after(:all) do
67
- self.use_transactional_tests = true
68
- restore_clean_db(@clean_file)
69
- stop_delayed_job
70
- end
71
-
72
- before(:each) do
73
- restore_clean_db(@save_file, false)
74
- Marty::Event.clear_cache
75
- end
76
-
77
- it 'reports currently running' do
78
- expect(Marty::Event.currently_running('testcl1', 123)).
79
- to eq(['AVM', 'CRA', 'PRICING'])
80
- expect(Marty::Event.currently_running('testcl2', 123)).to eq([])
81
- expect(Marty::Event.currently_running('testcl3', 987)).to eq([])
82
- expect(Marty::Event.last_event('testcl1', 123)).
83
- to include(
84
- 'klass' => 'testcl1',
85
- 'subject_id' => 123,
86
- 'enum_event_operation' => 'PRICING',
87
- 'comment' => 'c comment', 'expire_secs' => 10000)
88
- expect(Marty::Event.last_event('testcl2', 123)).
89
- to include(
90
- 'klass' => 'testcl2',
91
- 'subject_id' => 123,
92
- 'enum_event_operation' => 'PRICING',
93
- 'comment' => 'old event')
94
- expect(Marty::Event.last_event('testcl3', 987)).
95
- to include(
96
- 'klass' => 'testcl3',
97
- 'subject_id' => 987,
98
- 'enum_event_operation' => 'PRICING',
99
- 'comment' => nil,
100
- 'expire_secs' => nil)
101
-
102
- Timecop.freeze(@time + 1.second)
103
- Marty::Event.clear_cache
104
- expect(Marty::Event.currently_running('testcl1', 123)).
105
- to eq(['AVM', 'CRA', 'PRICING'])
106
- expect(Marty::Event.currently_running('testcl2', 123)).to eq(['AVM', 'CRA'])
107
-
108
- Timecop.freeze(@time + 3.seconds)
109
- Marty::Event.clear_cache
110
- expect(Marty::Event.currently_running('testcl1', 123)).
111
- to eq(['AVM', 'CRA', 'PRICING'])
112
- expect(Marty::Event.currently_running('testcl2', 123)).to eq(['CRA'])
113
-
114
- Timecop.freeze(@time + 6.seconds)
115
- expect(Marty::Event.currently_running('testcl1', 123)).
116
- to eq(['AVM', 'CRA', 'PRICING'])
117
- expect(Marty::Event.currently_running('testcl2', 123)).to eq([])
118
- Timecop.return
119
- end
120
-
121
- it 'misc API tests' do
122
- ev1 = Marty::Event.where(klass: 'testcl3', subject_id: 987).first
123
- ev2 = Marty::Event.where(klass: 'testcl3', subject_id: 654).first
124
- af = Marty::Event.all_finished
125
- ev3 = Marty::Event.where(klass: 'testcl3', subject_id: 987).first
126
- ev4 = Marty::Event.where(klass: 'testcl3', subject_id: 654).first
127
-
128
- # ev1/ev2 should have null start/end
129
- # ev3/ev4 should have start/end populated from promise and error status
130
- expect(ev1.start_dt).to be_nil
131
- expect(ev1.end_dt).to be_nil
132
- expect(ev1.error).to be_falsey
133
- expect(ev2.start_dt).to be_nil
134
- expect(ev2.end_dt).to be_nil
135
- expect(ev2.error).to be_falsey
136
-
137
- expect(ev3.start_dt).not_to be_nil
138
- expect(ev3.end_dt).not_to be_nil
139
- expect(ev3.error).to be_falsey
140
- expect(ev4.start_dt).not_to be_nil
141
- expect(ev4.end_dt).not_to be_nil
142
- expect(ev4.error).to be_truthy
143
-
144
- expect(af.count).to eq(3)
145
- expect(af).to include(['testcl3', 987])
146
- expect(af).to include(['testcl1', 234])
147
- expect(af[['testcl3', 987]]).to include('PRICING')
148
- expect(af[['testcl3', 987]]['PRICING']).to start_with(@date_string)
149
- expect(af[['testcl1', 234]]).to include('PRICING')
150
- expect(af[['testcl1', 234]]['PRICING']).to start_with(@date_string)
151
-
152
- expect(Marty::Event.currently_running('testcl1', 123)).
153
- to eq(['AVM', 'CRA', 'PRICING'])
154
- expect(Marty::Event.op_is_running?('testcl1', 123, 'AVM')).to be_truthy
155
- Marty::Event.finish_event('testcl1', 123, 'AVM', false, 'wassup')
156
- Marty::Event.clear_cache
157
- expect(Marty::Event.currently_running('testcl1', 123)).
158
- to eq(['CRA', 'PRICING'])
159
- expect(Marty::Event.currently_running_multi('testcl1', [123])).
160
- to eq(123 => ['CRA', 'PRICING'])
161
-
162
- expect(Marty::Event.op_is_running?('testcl1', 123, 'AVM')).to be_falsey
163
- expect(Marty::Event.op_is_running?('testcl1', 123, 'CRA')).to be_truthy
164
-
165
- ev = Marty::Event.lookup_event('testcl1', 123, 'AVM')
166
- expect(ev.length).to eq(1)
167
- expect(ev.first).to include('klass' => 'testcl1',
168
- 'subject_id' => 123,
169
- 'enum_event_operation' => 'AVM',
170
- 'comment' => 'wassup',
171
- 'expire_secs' => nil,
172
- 'error' => false)
173
- Marty::Event.update_comment(ev.first, 'updated')
174
- ev = Marty::Event.lookup_event('testcl1', 123, 'AVM')
175
- expect(ev.first).to include('comment' => 'updated')
176
- expect(Marty::Event.compact_end_dt(ev.first)).to match(/\d\d:\d\d/)
177
- expect(Marty::Event.pretty_op(ev.first)).to eq('Avm')
178
- ev = Marty::Event.lookup_event('testcl1', 123, 'PRICING').first
179
- expect(Marty::Event.pretty_op(ev)).to eq('Pricing')
180
- evs = Marty::Event.last_event_multi('testcl1', [123, 234])
181
- expect(evs[123]).to include('klass' => 'testcl1',
182
- 'subject_id' => 123,
183
- 'enum_event_operation' => 'CRA',
184
- 'comment' => 'b comment',
185
- 'expire_secs' => nil,
186
- 'error' => nil)
187
- expect(evs[234]).to include('klass' => 'testcl1',
188
- 'subject_id' => 234,
189
- 'enum_event_operation' => 'PRICING',
190
- 'comment' => 'c comment',
191
- 'expire_secs' => nil,
192
- 'error' => false)
193
-
194
- af = Marty::Event.all_finished
195
- expect(af.count).to eq(4)
196
- expect(af[['testcl3', 987]]).to include('PRICING')
197
- expect(af[['testcl1', 123]]).to include('AVM')
198
- expect(af[['testcl1', 123]]['AVM']).to start_with(@date_string)
199
- end
200
-
201
- it 'raises on error' do
202
- expect do
203
- Marty::Event.create_event('testcl', 1234, 'AVM', Time.zone.now, 600,
204
- 'the comment')
205
- end .not_to raise_error
206
-
207
- expect do
208
- Marty::Event.create_event('testcl', 1234, 'AVM', Time.zone.now, 600,
209
- 'the comment')
210
- end.
211
- to raise_error(%r!AVM is already running for testcl/1234!)
212
- expect do
213
- Marty::Event.create_event('testcl', 2345, 'AVM', Time.zone.now, 600,
214
- 'the comment')
215
- end .not_to raise_error
216
- expect do
217
- Marty::Event.finish_event('testcl', 1234, 'AVM', false,
218
- 'new comment')
219
- end.
220
- not_to raise_error
221
- expect do
222
- Marty::Event.finish_event('testcl', 1234, 'AVM', false,
223
- 'new comment')
224
- end.
225
- to raise_error(%r!event testcl/1234/AVM not found!)
226
- expect { Marty::Event.finish_event('testcl', 2345, 'AVM', false, 'foobar') }.
227
- not_to raise_error
228
- expect { Marty::Event.finish_event('testcl', 2345, 'AVM', false, 'foobar') }.
229
- to raise_error(%r!event testcl/2345/AVM not found!)
230
- expect { Marty::Event.finish_event('testcl', 2345, 'AVM', nil, 'foobar') }.
231
- to raise_error(/error must be true or false/)
232
- expect do
233
- Marty::Event.create_event('testcl', 1234, 'AMV', Time.zone.now, 600,
234
- 'the comment')
235
- end.
236
- to raise_error(%r!PG::.*invalid input value for enum.*"AMV"!)
237
- Marty::Event.clear_cache
238
- af = Marty::Event.all_finished
239
- expect(af.count).to eq(5)
240
- expect(af).to include(['testcl', 1234])
241
- expect(af).to include(['testcl', 2345])
242
- expect(af[['testcl', 1234]]).to include('AVM')
243
- expect(af[['testcl', 2345]]).to include('AVM')
244
- expect(af[['testcl', 1234]]['AVM']).to start_with(@date_string)
245
- expect(af[['testcl', 2345]]['AVM']).to start_with(@date_string)
246
- end
247
-
248
- it 'truncates long comment' do
249
- long_comment = 'comment string abcdefg' * 100
250
- long_comment_truncated = long_comment.truncate(255)
251
- Marty::Event.create_event('testcl', 123, 'PRICING', Time.zone.now, 600,
252
- long_comment)
253
- Marty::Event.create!(klass: 'testcl',
254
- subject_id: 456,
255
- enum_event_operation: 'CRA',
256
- start_dt: Time.zone.now,
257
- expire_secs: 600,
258
- comment: long_comment)
259
-
260
- Marty::Event.create_event('testcl', 789, 'AVM', Time.zone.now, 600,
261
- 'comment')
262
- Marty::Event.finish_event('testcl', 789, 'AVM', false, long_comment)
263
-
264
- e1 = Marty::Event.lookup_event('testcl', 123, 'PRICING').first
265
- e2 = Marty::Event.lookup_event('testcl', 456, 'CRA').first
266
- e3 = Marty::Event.lookup_event('testcl', 789, 'AVM').first
267
-
268
- expect(e1['comment']).to eq(long_comment_truncated)
269
- expect(e2['comment']).to eq(long_comment_truncated)
270
- expect(e3['comment']).to eq(long_comment_truncated)
271
- end
272
- end