chef 12.2.1 → 12.3.0.rc.0
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/lib/chef.rb +1 -0
- data/lib/chef/application/apply.rb +5 -0
- data/lib/chef/application/client.rb +10 -0
- data/lib/chef/application/knife.rb +5 -1
- data/lib/chef/application/solo.rb +5 -0
- data/lib/chef/chef_class.rb +130 -0
- data/lib/chef/client.rb +15 -7
- data/lib/chef/config.rb +13 -0
- data/lib/chef/event_loggers/windows_eventlog.rb +11 -5
- data/lib/chef/http.rb +13 -3
- data/lib/chef/http/basic_client.rb +21 -4
- data/lib/chef/http/socketless_chef_zero_client.rb +207 -0
- data/lib/chef/knife.rb +3 -0
- data/lib/chef/knife/bootstrap.rb +1 -1
- data/lib/chef/knife/core/status_presenter.rb +12 -11
- data/lib/chef/knife/ssh.rb +3 -1
- data/lib/chef/knife/status.rb +32 -7
- data/lib/chef/local_mode.rb +13 -3
- data/lib/chef/mixin/provides.rb +32 -0
- data/lib/chef/platform/provider_priority_map.rb +16 -7
- data/lib/chef/platform/resource_priority_map.rb +37 -0
- data/lib/chef/policy_builder/expand_node_object.rb +14 -0
- data/lib/chef/policy_builder/policyfile.rb +0 -1
- data/lib/chef/provider.rb +5 -20
- data/lib/chef/provider/package/rubygems.rb +4 -1
- data/lib/chef/provider/service/macosx.rb +66 -30
- data/lib/chef/provider_resolver.rb +10 -5
- data/lib/chef/resource.rb +5 -39
- data/lib/chef/resource/gem_package.rb +5 -0
- data/lib/chef/resource/link.rb +1 -1
- data/lib/chef/resource/macosx_service.rb +59 -0
- data/lib/chef/resource/remote_file.rb +0 -4
- data/lib/chef/resource_resolver.rb +101 -0
- data/lib/chef/rest.rb +4 -5
- data/lib/chef/search/query.rb +1 -1
- data/lib/chef/server_api.rb +1 -0
- data/lib/chef/version.rb +1 -1
- data/spec/data/lwrp/providers/buck_passer.rb +2 -1
- data/spec/data/lwrp/resources/bar.rb +1 -1
- data/spec/data/{big_json.json → nested.json} +2 -2
- data/spec/functional/event_loggers/windows_eventlog_spec.rb +14 -0
- data/spec/functional/resource/execute_spec.rb +1 -1
- data/spec/integration/client/client_spec.rb +12 -1
- data/spec/integration/client/ipv6_spec.rb +1 -1
- data/spec/integration/knife/common_options_spec.rb +3 -3
- data/spec/integration/recipes/lwrp_inline_resources_spec.rb +1 -1
- data/spec/integration/solo/solo_spec.rb +7 -5
- data/spec/unit/application/client_spec.rb +10 -0
- data/spec/unit/chef_class_spec.rb +91 -0
- data/spec/unit/client_spec.rb +13 -0
- data/spec/unit/http/basic_client_spec.rb +43 -6
- data/spec/unit/http/socketless_chef_zero_client_spec.rb +174 -0
- data/spec/unit/http_spec.rb +14 -0
- data/spec/unit/json_compat_spec.rb +7 -20
- data/spec/unit/knife/ssh_spec.rb +18 -0
- data/spec/unit/knife/status_spec.rb +69 -3
- data/spec/unit/knife_spec.rb +5 -0
- data/spec/unit/provider/package/rubygems_spec.rb +19 -0
- data/spec/unit/provider/service/macosx_spec.rb +230 -203
- data/spec/unit/provider_resolver_spec.rb +1 -0
- data/spec/unit/recipe_spec.rb +48 -0
- data/spec/unit/resource/link_spec.rb +15 -0
- data/spec/unit/resource_spec.rb +6 -6
- data/spec/unit/rest_spec.rb +9 -0
- data/spec/unit/search/query_spec.rb +24 -0
- data/spec/unit/shell_spec.rb +3 -1
- metadata +16 -9
- data/spec/data/big_json_plus_one.json +0 -2
data/spec/unit/recipe_spec.rb
CHANGED
@@ -20,6 +20,7 @@
|
|
20
20
|
#
|
21
21
|
|
22
22
|
require 'spec_helper'
|
23
|
+
require 'chef/platform/resource_priority_map'
|
23
24
|
|
24
25
|
describe Chef::Recipe do
|
25
26
|
|
@@ -136,6 +137,44 @@ describe Chef::Recipe do
|
|
136
137
|
res.kind_of?(YourMom)
|
137
138
|
end
|
138
139
|
|
140
|
+
describe "when there is more than one resource that resolves on a node" do
|
141
|
+
before do
|
142
|
+
node.automatic[:platform] = "nbc_sports"
|
143
|
+
Sounders = Class.new(Chef::Resource)
|
144
|
+
Sounders.provides :football, platform: "nbc_sports"
|
145
|
+
TottenhamHotspur = Class.new(Chef::Resource)
|
146
|
+
TottenhamHotspur.provides :football, platform: "nbc_sports"
|
147
|
+
end
|
148
|
+
|
149
|
+
after do
|
150
|
+
Object.send(:remove_const, :Sounders)
|
151
|
+
Object.send(:remove_const, :TottenhamHotspur)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "warns if resolution of the two resources is ambiguous" do
|
155
|
+
expect(Chef::Log).to receive(:warn).at_least(:once).with(/Ambiguous resource precedence/)
|
156
|
+
res1 = recipe.football "club world cup"
|
157
|
+
expect(res1.name).to eql("club world cup")
|
158
|
+
# the class of res1 is not defined.
|
159
|
+
end
|
160
|
+
|
161
|
+
it "selects one if it is given priority" do
|
162
|
+
expect(Chef::Log).not_to receive(:warn)
|
163
|
+
Chef::Platform::ResourcePriorityMap.instance.send(:priority, :football, TottenhamHotspur, platform: "nbc_sports")
|
164
|
+
res1 = recipe.football "club world cup"
|
165
|
+
expect(res1.name).to eql("club world cup")
|
166
|
+
expect(res1).to be_a_kind_of(TottenhamHotspur)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "selects the other one if it is given priority" do
|
170
|
+
expect(Chef::Log).not_to receive(:warn)
|
171
|
+
Chef::Platform::ResourcePriorityMap.instance.send(:priority, :football, Sounders, platform: "nbc_sports")
|
172
|
+
res1 = recipe.football "club world cup"
|
173
|
+
expect(res1.name).to eql("club world cup")
|
174
|
+
expect(res1).to be_a_kind_of(Sounders)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
139
178
|
end
|
140
179
|
end
|
141
180
|
|
@@ -237,8 +276,17 @@ describe Chef::Recipe do
|
|
237
276
|
action :nothing
|
238
277
|
end
|
239
278
|
end
|
279
|
+
|
280
|
+
it "validating resources via build_resource" do
|
281
|
+
expect {recipe.build_resource(:remote_file, "klopp") do
|
282
|
+
source Chef::DelayedEvaluator.new {"http://chef.io"}
|
283
|
+
end}.to_not raise_error
|
284
|
+
end
|
285
|
+
|
240
286
|
end
|
241
287
|
|
288
|
+
|
289
|
+
|
242
290
|
describe "creating resources via declare_resource" do
|
243
291
|
let(:zm_resource) do
|
244
292
|
recipe.declare_resource(:zen_master, "klopp") do
|
@@ -53,6 +53,21 @@ describe Chef::Resource::Link do
|
|
53
53
|
expect(@resource.target_file).to eql("fakey_fakerton")
|
54
54
|
end
|
55
55
|
|
56
|
+
it "should accept a delayed evaluator as the target path" do
|
57
|
+
@resource.target_file Chef::DelayedEvaluator.new { "my_lazy_name" }
|
58
|
+
expect(@resource.target_file).to eql("my_lazy_name")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should accept a delayed evaluator when accessing via 'path'" do
|
62
|
+
@resource.target_file Chef::DelayedEvaluator.new { "my_lazy_name" }
|
63
|
+
expect(@resource.path).to eql("my_lazy_name")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should accept a delayed evaluator via 'to'" do
|
67
|
+
@resource.to Chef::DelayedEvaluator.new { "my_lazy_name" }
|
68
|
+
expect(@resource.to).to eql("my_lazy_name")
|
69
|
+
end
|
70
|
+
|
56
71
|
it "should accept a string as the link source via 'to'" do
|
57
72
|
expect { @resource.to "/tmp" }.not_to raise_error
|
58
73
|
end
|
data/spec/unit/resource_spec.rb
CHANGED
@@ -709,22 +709,22 @@ describe Chef::Resource do
|
|
709
709
|
end
|
710
710
|
|
711
711
|
it 'adds mappings for a single platform' do
|
712
|
-
expect(Chef::Resource.node_map).to receive(:set).with(
|
713
|
-
:dinobot,
|
712
|
+
expect(Chef::Resource::Klz.node_map).to receive(:set).with(
|
713
|
+
:dinobot, true, { platform: ['autobots'] }
|
714
714
|
)
|
715
715
|
klz.provides :dinobot, platform: ['autobots']
|
716
716
|
end
|
717
717
|
|
718
718
|
it 'adds mappings for multiple platforms' do
|
719
|
-
expect(Chef::Resource.node_map).to receive(:set).with(
|
720
|
-
:energy,
|
719
|
+
expect(Chef::Resource::Klz.node_map).to receive(:set).with(
|
720
|
+
:energy, true, { platform: ['autobots', 'decepticons']}
|
721
721
|
)
|
722
722
|
klz.provides :energy, platform: ['autobots', 'decepticons']
|
723
723
|
end
|
724
724
|
|
725
725
|
it 'adds mappings for all platforms' do
|
726
|
-
expect(Chef::Resource.node_map).to receive(:set).with(
|
727
|
-
:tape_deck,
|
726
|
+
expect(Chef::Resource::Klz.node_map).to receive(:set).with(
|
727
|
+
:tape_deck, true, {}
|
728
728
|
)
|
729
729
|
klz.provides :tape_deck
|
730
730
|
end
|
data/spec/unit/rest_spec.rb
CHANGED
@@ -92,6 +92,15 @@ describe Chef::REST do
|
|
92
92
|
Chef::REST.new(base_url, nil, nil, options)
|
93
93
|
end
|
94
94
|
|
95
|
+
context 'when created with a chef zero URL' do
|
96
|
+
|
97
|
+
let(:url) { "chefzero://localhost:1" }
|
98
|
+
|
99
|
+
it "does not load the signing key" do
|
100
|
+
expect { Chef::REST.new(url) }.to_not raise_error
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
95
104
|
describe "calling an HTTP verb on a path or absolute URL" do
|
96
105
|
it "adds a relative URL to the base url it was initialized with" do
|
97
106
|
expect(rest.create_url("foo/bar/baz")).to eq(URI.parse(base_url + "/foo/bar/baz"))
|
@@ -81,6 +81,9 @@ describe Chef::Search::Query do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
describe "search" do
|
84
|
+
let(:query_string) { "search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=0" }
|
85
|
+
let(:query_string_continue) { "search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=4" }
|
86
|
+
|
84
87
|
let(:response) { {
|
85
88
|
"rows" => [
|
86
89
|
{ "name" => "my-name-is-node",
|
@@ -140,6 +143,19 @@ describe Chef::Search::Query do
|
|
140
143
|
"total" => 4
|
141
144
|
} }
|
142
145
|
|
146
|
+
let(:big_response) {
|
147
|
+
r = response.dup
|
148
|
+
r["total"] = 8
|
149
|
+
r
|
150
|
+
}
|
151
|
+
|
152
|
+
let(:big_response_end) {
|
153
|
+
r = response.dup
|
154
|
+
r["start"] = 4
|
155
|
+
r["total"] = 8
|
156
|
+
r
|
157
|
+
}
|
158
|
+
|
143
159
|
it "accepts a type as the first argument" do
|
144
160
|
expect { query.search("node") }.not_to raise_error
|
145
161
|
expect { query.search(:node) }.not_to raise_error
|
@@ -195,6 +211,14 @@ describe Chef::Search::Query do
|
|
195
211
|
query.search(:node, "*:*", sort: nil, start: 0, rows: 1) { |r| @call_me.do(r) }
|
196
212
|
end
|
197
213
|
|
214
|
+
it "sends multiple API requests when the server indicates there is more data" do
|
215
|
+
expect(rest).to receive(:get_rest).with(query_string).and_return(big_response)
|
216
|
+
expect(rest).to receive(:get_rest).with(query_string_continue).and_return(big_response_end)
|
217
|
+
query.search(:node, "platform:rhel") do |r|
|
218
|
+
nil
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
198
222
|
context "when :filter_result is provided as a result" do
|
199
223
|
include_context "filtered search" do
|
200
224
|
let(:filter_key) { :filter_result }
|
data/spec/unit/shell_spec.rb
CHANGED
@@ -43,6 +43,8 @@ describe Shell do
|
|
43
43
|
before do
|
44
44
|
Shell.irb_conf = {}
|
45
45
|
allow(Shell::ShellSession.instance).to receive(:reset!)
|
46
|
+
allow(Chef::Platform).to receive(:windows?).and_return(false)
|
47
|
+
allow(Chef::Util::PathHelper).to receive(:home).and_return('/home/foo')
|
46
48
|
end
|
47
49
|
|
48
50
|
describe "reporting its status" do
|
@@ -56,7 +58,7 @@ describe Shell do
|
|
56
58
|
describe "configuring IRB" do
|
57
59
|
it "configures irb history" do
|
58
60
|
Shell.configure_irb
|
59
|
-
expect(Shell.irb_conf[:HISTORY_FILE]).to eq(
|
61
|
+
expect(Shell.irb_conf[:HISTORY_FILE]).to eq(Chef::Util::PathHelper.home('.chef', 'chef_shell_history'))
|
60
62
|
expect(Shell.irb_conf[:SAVE_HISTORY]).to eq(1000)
|
61
63
|
end
|
62
64
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 12.
|
4
|
+
version: 12.3.0.rc.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Jacob
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-config
|
@@ -208,14 +208,14 @@ dependencies:
|
|
208
208
|
requirements:
|
209
209
|
- - "~>"
|
210
210
|
- !ruby/object:Gem::Version
|
211
|
-
version: '4.
|
211
|
+
version: '4.1'
|
212
212
|
type: :runtime
|
213
213
|
prerelease: false
|
214
214
|
version_requirements: !ruby/object:Gem::Requirement
|
215
215
|
requirements:
|
216
216
|
- - "~>"
|
217
217
|
- !ruby/object:Gem::Version
|
218
|
-
version: '4.
|
218
|
+
version: '4.1'
|
219
219
|
- !ruby/object:Gem::Dependency
|
220
220
|
name: pry
|
221
221
|
requirement: !ruby/object:Gem::Requirement
|
@@ -559,6 +559,7 @@ files:
|
|
559
559
|
- lib/chef/audit/control_group_data.rb
|
560
560
|
- lib/chef/audit/rspec_formatter.rb
|
561
561
|
- lib/chef/audit/runner.rb
|
562
|
+
- lib/chef/chef_class.rb
|
562
563
|
- lib/chef/chef_fs.rb
|
563
564
|
- lib/chef/chef_fs/chef_fs_data_store.rb
|
564
565
|
- lib/chef/chef_fs/command_line.rb
|
@@ -727,6 +728,7 @@ files:
|
|
727
728
|
- lib/chef/http/json_to_model_output.rb
|
728
729
|
- lib/chef/http/remote_request_id.rb
|
729
730
|
- lib/chef/http/simple.rb
|
731
|
+
- lib/chef/http/socketless_chef_zero_client.rb
|
730
732
|
- lib/chef/http/ssl_policies.rb
|
731
733
|
- lib/chef/http/validate_content_length.rb
|
732
734
|
- lib/chef/json_compat.rb
|
@@ -870,6 +872,7 @@ files:
|
|
870
872
|
- lib/chef/mixin/params_validate.rb
|
871
873
|
- lib/chef/mixin/path_sanity.rb
|
872
874
|
- lib/chef/mixin/powershell_type_coercions.rb
|
875
|
+
- lib/chef/mixin/provides.rb
|
873
876
|
- lib/chef/mixin/recipe_definition_dsl_core.rb
|
874
877
|
- lib/chef/mixin/securable.rb
|
875
878
|
- lib/chef/mixin/shell_out.rb
|
@@ -896,6 +899,7 @@ files:
|
|
896
899
|
- lib/chef/platform/provider_priority_map.rb
|
897
900
|
- lib/chef/platform/query_helpers.rb
|
898
901
|
- lib/chef/platform/rebooter.rb
|
902
|
+
- lib/chef/platform/resource_priority_map.rb
|
899
903
|
- lib/chef/platform/service_helpers.rb
|
900
904
|
- lib/chef/policy_builder.rb
|
901
905
|
- lib/chef/policy_builder/expand_node_object.rb
|
@@ -1058,6 +1062,7 @@ files:
|
|
1058
1062
|
- lib/chef/resource/link.rb
|
1059
1063
|
- lib/chef/resource/log.rb
|
1060
1064
|
- lib/chef/resource/lwrp_base.rb
|
1065
|
+
- lib/chef/resource/macosx_service.rb
|
1061
1066
|
- lib/chef/resource/macports_package.rb
|
1062
1067
|
- lib/chef/resource/mdadm.rb
|
1063
1068
|
- lib/chef/resource/mount.rb
|
@@ -1102,6 +1107,7 @@ files:
|
|
1102
1107
|
- lib/chef/resource_definition.rb
|
1103
1108
|
- lib/chef/resource_definition_list.rb
|
1104
1109
|
- lib/chef/resource_reporter.rb
|
1110
|
+
- lib/chef/resource_resolver.rb
|
1105
1111
|
- lib/chef/resources.rb
|
1106
1112
|
- lib/chef/rest.rb
|
1107
1113
|
- lib/chef/role.rb
|
@@ -1221,8 +1227,6 @@ files:
|
|
1221
1227
|
- spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.0-1_amd64.deb
|
1222
1228
|
- spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.1-1_amd64.deb
|
1223
1229
|
- spec/data/bad-config.rb
|
1224
|
-
- spec/data/big_json.json
|
1225
|
-
- spec/data/big_json_plus_one.json
|
1226
1230
|
- spec/data/bootstrap/encrypted_data_bag_secret
|
1227
1231
|
- spec/data/bootstrap/no_proxy.erb
|
1228
1232
|
- spec/data/bootstrap/secret.erb
|
@@ -1362,6 +1366,7 @@ files:
|
|
1362
1366
|
- spec/data/mac_users/10.9.plist.xml
|
1363
1367
|
- spec/data/mac_users/10.9.shadow.xml
|
1364
1368
|
- spec/data/metadata/quick_start/metadata.rb
|
1369
|
+
- spec/data/nested.json
|
1365
1370
|
- spec/data/nodes/default.rb
|
1366
1371
|
- spec/data/nodes/test.example.com.rb
|
1367
1372
|
- spec/data/nodes/test.rb
|
@@ -1616,6 +1621,7 @@ files:
|
|
1616
1621
|
- spec/unit/audit/control_group_data_spec.rb
|
1617
1622
|
- spec/unit/audit/rspec_formatter_spec.rb
|
1618
1623
|
- spec/unit/audit/runner_spec.rb
|
1624
|
+
- spec/unit/chef_class_spec.rb
|
1619
1625
|
- spec/unit/chef_fs/config_spec.rb
|
1620
1626
|
- spec/unit/chef_fs/data_handler/group_handler_spec.rb
|
1621
1627
|
- spec/unit/chef_fs/diff_spec.rb
|
@@ -1676,6 +1682,7 @@ files:
|
|
1676
1682
|
- spec/unit/http/http_request_spec.rb
|
1677
1683
|
- spec/unit/http/json_input_spec.rb
|
1678
1684
|
- spec/unit/http/simple_spec.rb
|
1685
|
+
- spec/unit/http/socketless_chef_zero_client_spec.rb
|
1679
1686
|
- spec/unit/http/ssl_policies_spec.rb
|
1680
1687
|
- spec/unit/http/validate_content_length_spec.rb
|
1681
1688
|
- spec/unit/http_spec.rb
|
@@ -2033,12 +2040,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
2033
2040
|
version: 2.0.0
|
2034
2041
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
2035
2042
|
requirements:
|
2036
|
-
- - "
|
2043
|
+
- - ">"
|
2037
2044
|
- !ruby/object:Gem::Version
|
2038
|
-
version:
|
2045
|
+
version: 1.3.1
|
2039
2046
|
requirements: []
|
2040
2047
|
rubyforge_project:
|
2041
|
-
rubygems_version: 2.4.
|
2048
|
+
rubygems_version: 2.4.5
|
2042
2049
|
signing_key:
|
2043
2050
|
specification_version: 4
|
2044
2051
|
summary: A systems integration framework, built to bring the benefits of configuration
|
@@ -1,2 +0,0 @@
|
|
1
|
-
{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":{"key":"test"
|
2
|
-
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
|