marty 1.0.44 → 1.0.46
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/Gemfile.lock +4 -2
- data/app/controllers/marty/diagnostic_controller.rb +324 -72
- data/app/controllers/marty/rpc_controller.rb +10 -4
- data/app/models/marty/data_grid.rb +47 -95
- data/app/views/marty/diagnostic/op.html.erb +58 -0
- data/config/routes.rb +1 -2
- data/db/js/errinfo_v1.js +16 -0
- data/db/js/lookup_grid_distinct_v1.js +64 -0
- data/db/js/query_grid_dir_v1.js +61 -0
- data/db/migrate/400_create_dg_plv8_v1_fns.rb +12 -0
- data/lib/marty/migrations.rb +20 -0
- data/lib/marty/schema_helper.rb +41 -0
- data/lib/marty/version.rb +1 -1
- data/spec/controllers/diagnostic_controller_spec.rb +157 -67
- data/spec/controllers/rpc_controller_spec.rb +45 -10
- data/spec/dummy/public/{404.html → 400.html} +0 -0
- data/spec/lib/logger_spec.rb +1 -0
- data/spec/models/data_grid_spec.rb +0 -1
- metadata +8 -4
- data/app/views/marty/diagnostic/diagnostic.html.erb +0 -15
data/lib/marty/schema_helper.rb
CHANGED
@@ -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,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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
56
|
+
def version_display_fail val
|
57
|
+
<<-ERB
|
58
|
+
<h3>Version</h3>
|
59
|
+
<h3 class="error"> ⚠ 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
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
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 '
|
58
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
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 '
|
78
|
-
|
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(
|
82
|
-
expect(
|
83
|
-
|
84
|
-
expect(
|
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 '
|
89
|
-
|
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(
|
93
|
-
expect(
|
94
|
-
expect(
|
95
|
-
|
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" :
|
263
|
-
"opttf" :
|
264
|
-
"opttrue" :
|
265
|
-
"optfalse" :
|
266
|
-
"
|
267
|
-
"
|
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
|
-
[
|
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
|
-
|
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
|
data/spec/lib/logger_spec.rb
CHANGED
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.
|
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-
|
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/
|
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/
|
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
|