marty 1.0.44 → 1.0.46
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.
- 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
|