marty 1.0.44 → 1.0.46

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,6 +25,47 @@ class Marty::SchemaHelper
25
25
  end
26
26
 
27
27
  # if conds is true, var_array columns we be required
28
+ delorean_fn :disallow_if_conds, sig: [2, 20] do
29
+ |var_array, *conds_array|
30
+ {"anyOf"=>[{"not"=>{"allOf"=> conds_array}},
31
+ {"properties"=> var_array.each_with_object({}) do
32
+ |v,h|
33
+ h[v] = { "not" => {} }
34
+ end
35
+ }]}
36
+ end
37
+
38
+
39
+ # if param is present, disallow cols
40
+ delorean_fn :disallow_if_present, sig: [2, 20] do
41
+ |dep_column, *var_array|
42
+ dep_check(dep_column,
43
+ {"properties"=> var_array.each_with_object({}) do
44
+ |v,h|
45
+ h[v] = { "not" => {} }
46
+ end
47
+ })
48
+ end
49
+
50
+ # if param is not present, disallow cols
51
+ # note: small problem, probably not fixable:
52
+ # if this condition fails (i.e. dep_column is not present,
53
+ # but var(s) in var_array are are present)
54
+ # it will report both the required clause and the not clauses
55
+ # as failed. so the caller will see a message that a
56
+ # required field is missing (which is not really a required field)
57
+ delorean_fn :disallow_if_not_present, sig: [2, 20] do
58
+ |dep_column, *var_array|
59
+ { "anyOf" => [
60
+ {"required" => [dep_column] },
61
+ {"properties"=> var_array.each_with_object({}) do
62
+ |v,h|
63
+ h[v] = { "not" => {} }
64
+ end
65
+ }]}
66
+ end
67
+
68
+ # if conds is true, var_array columns are not allowed
28
69
  delorean_fn :required_if, sig: [2, 20] do
29
70
  |var_array, *conds_array|
30
71
  {"anyOf"=>[{"not"=>{"allOf"=> conds_array}},
data/lib/marty/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Marty
2
- VERSION = "1.0.44"
2
+ VERSION = "1.0.46"
3
3
  end
@@ -1,102 +1,192 @@
1
1
  require 'spec_helper'
2
-
3
2
  module Marty
4
3
  RSpec.describe DiagnosticController, type: :controller do
5
4
  before(:each) { @routes = Marty::Engine.routes }
6
5
  let(:json_response) { JSON.parse(response.body) }
7
6
 
8
- describe 'GET #index' do
9
- it 'returns http success' do
10
- get :index, testop: :version
11
-
12
- expect(response).to have_http_status(:success)
13
- end
14
-
15
- it 'returns the current version' do
16
- get :index, testop: :version
7
+ def version
8
+ {"Git" => "",
9
+ "Marty" => Marty::VERSION,
10
+ "Delorean" => Delorean::VERSION,
11
+ "Mcfly" => Mcfly::VERSION}
12
+ end
17
13
 
18
- aggregate_failures do
19
- expect(assigns('details').count).to eq(3)
20
- expect(assigns('details').third.methods)
21
- .to include(:name, :status, :description)
22
- expect(assigns('details').third.description).to eq(Marty::VERSION)
23
- end
24
- end
14
+ def environment
15
+ rbv = "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})"
16
+ {'Environment' => Rails.env,
17
+ 'Rails' => Rails.version,
18
+ 'Netzke Core' => Netzke::Core::VERSION,
19
+ 'Netzke Basepack' => Netzke::Basepack::VERSION,
20
+ 'Ruby' => rbv,
21
+ 'RubyGems' => Gem::VERSION,
22
+ 'Database Adapter' => described_class::Database.db_adapter_name,
23
+ 'Database Server' => described_class::Database.db_server_name,
24
+ 'Database Version' => described_class::Database.db_version,
25
+ 'Database Schema Version' => described_class::Database.db_schema}
26
+ end
25
27
 
26
- it 'returns the appropriate json' do
27
- get :index, {format: :json, testop: :version}
28
+ def version_display
29
+ <<-ERB
30
+ <h3>Version</h3>
31
+ <div class="wrapper">
32
+ <table>
33
+ <th class=""><small>consistent</small></th>
34
+ <th class=""></th>
35
+ <tr class="passed">
36
+ <td>Git</td>
37
+ <td class="overflow"></td>
38
+ </tr>
39
+ <tr class="passed">
40
+ <td>Marty</td>
41
+ <td class="overflow">#{Marty::VERSION}</td>
42
+ </tr>
43
+ <tr class="passed">
44
+ <td>Delorean</td>
45
+ <td class="overflow">#{Delorean::VERSION}</td>
46
+ </tr>
47
+ <tr class="passed">
48
+ <td>Mcfly</td>
49
+ <td class="overflow">#{Mcfly::VERSION}</td>
50
+ </tr>
51
+ </table>
52
+ </div>
53
+ ERB
54
+ end
28
55
 
29
- aggregate_failures do
30
- expect(json_response.first['diag_count']).to eq(3)
31
- expect(json_response.first['error_count']).to eq(0)
32
- expect(json_response
33
- .find { |d| d['name'] == 'Marty Version' }['description'])
34
- .to eq(Marty::VERSION)
35
- end
36
- end
56
+ def version_display_fail val
57
+ <<-ERB
58
+ <h3>Version</h3>
59
+ <h3 class="error"> &#x26a0; Issues Detected </h3>
60
+ <div class="wrapper">
61
+ <table>
62
+ <th class="error">node1</th>
63
+ <th class="error"></th>
64
+ <tr class="passed">
65
+ <td>Git</td>
66
+ <td class="overflow"></td>
67
+ </tr>
68
+ <tr class="passed">
69
+ <td>Marty</td>
70
+ <td class="overflow">#{Marty::VERSION}</td>
71
+ </tr>
72
+ <tr class="passed">
73
+ <td>Delorean</td>
74
+ <td class="overflow">#{Delorean::VERSION}</td>
75
+ </tr>
76
+ <tr class="passed">
77
+ <td>Mcfly</td>
78
+ <td class="overflow">#{Mcfly::VERSION}</td>
79
+ </tr>
80
+ </table>
81
+ <table>
82
+ <th class="error">node2</th>
83
+ <th class="error"></th>
84
+ <tr class="passed">
85
+ <td>Git</td>
86
+ <td class="overflow"></td>
87
+ </tr>
88
+ <tr class="passed">
89
+ <td>Marty</td>
90
+ <td class="overflow">#{val}</td>
91
+ </tr>
92
+ <tr class="passed">
93
+ <td>Delorean</td>
94
+ <td class="overflow">#{Delorean::VERSION}</td>
95
+ </tr>
96
+ <tr class="passed">
97
+ <td>Mcfly</td>
98
+ <td class="overflow">#{Mcfly::VERSION}</td>
99
+ </tr>
100
+ </table>
101
+ </div>
102
+ ERB
37
103
  end
38
104
 
39
- describe 'GET #version' do
40
- it 'returns http success' do
41
- get :version
105
+ def minimize(str)
106
+ str.gsub(/\s+/, "")
107
+ end
42
108
 
109
+ describe 'GET #op' do
110
+ it 'returns http success with local scope' do
111
+ get :op, op: 'version', scope: 'local'
43
112
  expect(response).to have_http_status(:success)
44
113
  end
45
114
 
46
- it 'returns the current version' do
47
- get :version
115
+ it 'returns the current version JSON' do
116
+ get :op, format: :json, op: 'version', scope: 'local'
117
+ expect(assigns('result')).to eq(version)
118
+ end
48
119
 
49
- aggregate_failures do
50
- expect(assigns('details').count).to eq(3)
51
- expect(assigns('details').third.methods)
52
- .to include(:name, :status, :description)
53
- expect(assigns('details').third.description).to eq(Marty::VERSION)
54
- end
120
+ it 'returns the correct environment JSON' do
121
+ get :op, format: :json, op: 'environment', scope: 'local'
122
+ expect(assigns('result')).to eq(environment)
55
123
  end
56
124
 
57
- it 'returns the appropriate json' do
58
- get :version, format: :json
125
+ it 'produces an html display of the diagnostic (version)' do
126
+ test = described_class::Version.display({'stub' => version})
127
+ expect(minimize(test)).to eq(minimize(version_display))
128
+ end
59
129
 
60
- aggregate_failures do
61
- expect(json_response.first['diag_count']).to eq(3)
62
- expect(json_response.first['error_count']).to eq(0)
63
- expect(json_response
64
- .find { |d| d['name'] == 'Marty Version' }['description'])
65
- .to eq(Marty::VERSION)
66
- end
130
+ it 'masks consistent nodes for display (version)' do
131
+ data = {'node1' => version, 'node2' => version}
132
+ test = described_class::Version.display(data)
133
+ expect(minimize(test)).to eq(minimize(version_display))
67
134
  end
68
- end
69
135
 
70
- describe 'GET #environment' do
71
- it 'returns http success' do
72
- get :environment
136
+ it 'displays all nodes when there is an inconsistent node (version)' do
137
+ ver = '0.0.0'
138
+ data = {'node1' => version, 'node2' => version + {'Marty' => ver}}
139
+ expected = version_display_fail(ver)
140
+ test = described_class::Version.display(data)
141
+ expect(minimize(expected)).to eq(minimize(test))
142
+ end
143
+ end
73
144
 
74
- expect(response).to have_http_status(:success)
145
+ describe 'diagnostic classes and aggregate functions' do
146
+ it 'has access to DiagnosticController request' do
147
+ get :op, op: 'version', scope: 'local'
148
+ expect(described_class::Base.request).not_to eq(nil)
75
149
  end
76
150
 
77
- it 'returns the environment details' do
78
- get :environment
151
+ it 'can aggregate diagnostics and return appropriate JSON' do
152
+ # simulate open-uri nodal diag request
153
+ uri_stub = {:open => nil, :readlines => [version.to_json]}
154
+ nodes = ['node1', 'node2', 'node3']
155
+ expected = nodes.each_with_object({}){|n, h| h[n] = version}
79
156
 
157
+ # mock nodes and diag request to node
158
+ allow(described_class::Base.request).to receive(:port).and_return(nil)
159
+ allow(described_class::Base).to receive(:get_nodes).and_return(nodes)
160
+ allow(described_class::Base).to receive_message_chain(uri_stub)
161
+
162
+ # perform aggregation using Base class function and Version class
163
+ expect(described_class::Base.get_nodal_diags('version')).to eq(expected)
164
+ expect(described_class::Version.aggregate).to eq(expected)
165
+ end
166
+
167
+ # returns true if there are differences in nodes for Base/Version
168
+ it 'determines diff of aggregate diagnostic' do
169
+ inconsistent = {'1' => version, '2' => version + {'Git' => '123'}}
170
+ consistent = inconsistent + {'2' => version}
80
171
  aggregate_failures do
81
- expect(assigns('details').count).to eq(9)
82
- expect(assigns('details').first.methods)
83
- .to include(:name, :status, :description)
84
- expect(assigns('details').first.description).to eq('test')
172
+ expect(described_class::Base.diff(inconsistent)).to eq(true)
173
+ expect(described_class::Base.diff(consistent)).to eq(false)
174
+ expect(described_class::Version.diff(inconsistent)).to eq(true)
175
+ expect(described_class::Version.diff(consistent)).to eq(false)
85
176
  end
86
177
  end
87
178
 
88
- it 'returns the appropriate json' do
89
- get :environment, format: :json
90
-
179
+ it 'can detects errors in diagnostic' do
180
+ error_free = version
181
+ error_test = version + {'Git' => described_class::Base.
182
+ error('Failed accessing git')}
91
183
  aggregate_failures do
92
- expect(json_response.first['diag_count']).to eq(9)
93
- expect(json_response.first['error_count']).to eq(0)
94
- expect(json_response
95
- .find { |d| d['name'] == 'Environment' }['description'])
96
- .to eq('test')
184
+ expect(described_class::Base.errors(error_free)).to eq(0)
185
+ expect(described_class::Base.errors(error_test)).to eq(1)
186
+ expect(described_class::Version.errors(error_free)).to eq(0)
187
+ expect(described_class::Version.errors(error_test)).to eq(1)
97
188
  end
98
189
  end
99
190
  end
100
-
101
191
  end
102
192
  end
@@ -259,12 +259,13 @@ eof
259
259
  script10_schema = <<eof
260
260
  A:
261
261
  properties = {
262
- "opt1" : { "type" : "string" },
263
- "opttf" : { "type" : "boolean" },
264
- "opttrue" : { "type" : "string" },
265
- "optfalse" : { "type" : "string" },
266
- "req1" : { "pg_enum" : "CondEnum" },
267
- "req2" : { "pg_enum" : "CondEnum" }
262
+ "opt1" : { "type" : "string" },
263
+ "opttf" : { "type" : "boolean" },
264
+ "opttrue" : { "type" : "string" },
265
+ "optfalse" : { "type" : "string" },
266
+ "optdisallow" : { "type" : "string" },
267
+ "req1" : { "pg_enum" : "CondEnum" },
268
+ "req2" : { "pg_enum" : "CondEnum" }
268
269
  }
269
270
 
270
271
  req1_is_opt1 = Marty::SchemaHelper.enum_is('req1', ['opt1'])
@@ -290,11 +291,22 @@ A:
290
291
  optfalse_check = Marty::SchemaHelper.required_if(['optfalse'],
291
292
  opttf_is_false)
292
293
 
294
+ # optdisallow is not allowed if opttf is false
295
+ optdisallow_check = Marty::SchemaHelper.disallow_if_conds(['optdisallow'],
296
+ opttf_is_false)
297
+
293
298
  # opttf is optional (contingent on req3) so eval of opttrue_check
294
299
  # and optfalse_check is dependent upon opttf existing
295
300
  opttruefalse_check = Marty::SchemaHelper.dep_check('opttf',
296
301
  opttrue_check,
297
- optfalse_check)
302
+ optfalse_check,
303
+ optdisallow_check)
304
+
305
+ dip_check = Marty::SchemaHelper.disallow_if_present('opttf',
306
+ 'opt3', 'opt4')
307
+
308
+ dinp_check = Marty::SchemaHelper.disallow_if_not_present('opttf',
309
+ 'opt5', 'opt6')
298
310
 
299
311
  v1 = { "properties": properties,
300
312
  "required": ["req1", "req2", "req3"],
@@ -302,7 +314,9 @@ A:
302
314
  opt1_check,
303
315
  optn_check,
304
316
  opttf_check,
305
- opttruefalse_check
317
+ opttruefalse_check,
318
+ dip_check,
319
+ dinp_check
306
320
  ] }
307
321
  eof
308
322
 
@@ -1126,6 +1140,12 @@ describe Marty::RpcController do
1126
1140
  params = optionals.merge({"req1" => req1,
1127
1141
  "req2"=> req2,
1128
1142
  "req3"=> req3}).to_json
1143
+
1144
+ # to see what the schema helpers generated:
1145
+ # engine = Marty::ScriptSet.new(nil).get_engine("M10Schemas")
1146
+ # x=engine.evaluate("A", ["v1"], {})
1147
+ # binding.pry
1148
+
1129
1149
  get 'evaluate', {
1130
1150
  format: :json,
1131
1151
  script: "M10",
@@ -1133,18 +1153,21 @@ describe Marty::RpcController do
1133
1153
  attrs: attrs,
1134
1154
  params: params
1135
1155
  }
1156
+
1136
1157
  end
1137
1158
 
1138
1159
  it "does conditional" do
1139
1160
  aggregate_failures "conditionals" do
1140
- [# first group has all required fields
1161
+ [
1162
+ # first group has all required fields
1141
1163
  [['opt1', 'no opts', 'no opts', opt1: 'hi mom'], "hi mom"],
1142
1164
  [['no opts', 'no opts', 'no opts', opt1: 'hi mom'], "no opts"],
1143
1165
  [['opt2', 'opt2', 'no opts', optn: 'foo'], 'foo'],
1144
1166
  [['opt2', 'no opts', 'opt2'], 'req3'],
1145
1167
  [['opt2', 'no opts', 'opttf', opttf: true, opttrue: 'bar'], 'bar'],
1146
1168
  [['opt2', 'no opts', 'opttf', opttf: false, optfalse: 'baz'], 'baz'],
1147
- # second group is missing fields
1169
+
1170
+ # second group is missing fields or has other errors
1148
1171
  [['opt1', 'no opts', 'no opts'],
1149
1172
  "did not contain a required property of 'opt1'"],
1150
1173
  [['opt2', 'opt2', 'no opts',],
@@ -1155,11 +1178,23 @@ describe Marty::RpcController do
1155
1178
  "did not contain a required property of 'opttrue'"],
1156
1179
  [['opt2', 'no opts', 'opttf', opttf: false],
1157
1180
  "did not contain a required property of 'optfalse'"],
1181
+ [['opt2', 'no opts', 'opttf', opttf: false, optfalse: "val",
1182
+ optdisallow: "hi mom"],
1183
+ "disallowed parameter 'optdisallow' of type string was received"],
1184
+ [['opt2', 'no opts', 'opttf', opttf: false, optfalse: "val",
1185
+ opt3: "hi"],
1186
+ "disallowed parameter 'opt3' of type string was received"],
1187
+ [['opt2', 'no opts', 'opttf', opttf: true, opttrue: "val",
1188
+ opt4: "mom"],
1189
+ "disallowed parameter 'opt4' of type string was received"],
1190
+ [['opt2', 'no opts', 'xyz', opt5: "hi"],
1191
+ "disallowed parameter 'opt5' of type string was received"],
1158
1192
  ].each do
1159
1193
  |a, exp|
1160
1194
  do_call(*a)
1161
1195
  res_hash = JSON.parse(response.body)
1162
1196
  got = res_hash.is_a?(Array) ? res_hash[0] : res_hash["error"]
1197
+
1163
1198
  expect(got).to include(exp)
1164
1199
  end
1165
1200
  end
File without changes
@@ -10,6 +10,7 @@ module Marty
10
10
  Marty::Log.delete_all
11
11
  end
12
12
  after(:all) do
13
+ Marty::Log.delete_all
13
14
  self.use_transactional_fixtures = true
14
15
  end
15
16
 
@@ -718,7 +718,6 @@ EOS
718
718
 
719
719
  res = dgc.lookup_grid_distinct_entry('2/2/2014',
720
720
  {"property_state" => "CA"})
721
-
722
721
  expect(res["result"]).to eq(70)
723
722
 
724
723
  res = dgc.lookup_grid_distinct_entry('2/2/2015',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.44
4
+ version: 1.0.46
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2017-10-11 00:00:00.000000000 Z
17
+ date: 2017-10-31 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: pg
@@ -440,10 +440,13 @@ files:
440
440
  - app/models/marty/user_role.rb
441
441
  - app/views/layouts/marty/application.html.erb
442
442
  - app/views/layouts/marty/diagnostic.html.erb
443
- - app/views/marty/diagnostic/diagnostic.html.erb
443
+ - app/views/marty/diagnostic/op.html.erb
444
444
  - config/database.yml.travis
445
445
  - config/locales/en.yml
446
446
  - config/routes.rb
447
+ - db/js/errinfo_v1.js
448
+ - db/js/lookup_grid_distinct_v1.js
449
+ - db/js/query_grid_dir_v1.js
447
450
  - db/migrate/001_create_marty_scripts.rb
448
451
  - db/migrate/003_create_marty_users.rb
449
452
  - db/migrate/004_create_marty_roles.rb
@@ -478,6 +481,7 @@ files:
478
481
  - db/migrate/301_create_marty_api_log.rb
479
482
  - db/migrate/302_add_api_configs_validate_result.rb
480
483
  - db/migrate/303_create_marty_logs.rb
484
+ - db/migrate/400_create_dg_plv8_v1_fns.rb
481
485
  - db/seeds.rb
482
486
  - delorean/script_report.dl
483
487
  - gemini_deprecations.md
@@ -585,7 +589,7 @@ files:
585
589
  - spec/dummy/lib/assets/.gitkeep
586
590
  - spec/dummy/lib/class_list.rb
587
591
  - spec/dummy/log/.gitkeep
588
- - spec/dummy/public/404.html
592
+ - spec/dummy/public/400.html
589
593
  - spec/dummy/public/422.html
590
594
  - spec/dummy/public/500.html
591
595
  - spec/dummy/public/favicon.ico