configtoolkit 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/FAQ.txt +113 -25
- data/Hash.txt +128 -0
- data/History.txt +45 -2
- data/KeyValue.txt +235 -0
- data/Manifest.txt +66 -4
- data/README.txt +666 -202
- data/Rakefile +3 -5
- data/Ruby.txt +172 -0
- data/YAML.txt +188 -0
- data/examples/hash_example.rb +71 -0
- data/examples/key_value_example.dump.cfg +5 -0
- data/examples/key_value_example.normal1.cfg +20 -0
- data/examples/key_value_example.normal2.cfg +15 -0
- data/examples/key_value_example.rb +72 -0
- data/examples/key_value_example.wacky.cfg +13 -0
- data/examples/load_example.rb +32 -0
- data/examples/load_example.yaml +34 -0
- data/examples/load_group_example.rb +28 -0
- data/examples/load_group_example.yaml +33 -0
- data/examples/machineconfig.rb +77 -0
- data/examples/ruby_example.rb +32 -0
- data/examples/ruby_example.rcfg +52 -0
- data/examples/usage_example.rb +93 -0
- data/examples/yaml_example.dump.yaml +12 -0
- data/examples/yaml_example.rb +48 -0
- data/examples/yaml_example.yaml +59 -0
- data/lib/configtoolkit.rb +1 -1
- data/lib/configtoolkit/baseconfig.rb +522 -418
- data/lib/configtoolkit/hasharrayvisitor.rb +242 -0
- data/lib/configtoolkit/hashreader.rb +41 -0
- data/lib/configtoolkit/hashwriter.rb +45 -0
- data/lib/configtoolkit/keyvalueconfig.rb +105 -0
- data/lib/configtoolkit/keyvaluereader.rb +597 -0
- data/lib/configtoolkit/keyvaluewriter.rb +157 -0
- data/lib/configtoolkit/prettyprintwriter.rb +167 -0
- data/lib/configtoolkit/reader.rb +62 -0
- data/lib/configtoolkit/rubyreader.rb +270 -0
- data/lib/configtoolkit/types.rb +42 -26
- data/lib/configtoolkit/writer.rb +116 -0
- data/lib/configtoolkit/yamlreader.rb +10 -6
- data/lib/configtoolkit/yamlwriter.rb +113 -71
- data/test/bad_array_index.rcfg +1 -0
- data/test/bad_containing_object_assignment.rcfg +2 -0
- data/test/bad_directive.cfg +1 -0
- data/test/bad_include1.cfg +2 -0
- data/test/bad_include2.cfg +3 -0
- data/test/bad_parameter_reference.rcfg +1 -0
- data/test/contained_sample.cfg +10 -0
- data/test/contained_sample.pretty_print +30 -0
- data/test/contained_sample.rcfg +22 -0
- data/test/contained_sample.yaml +22 -21
- data/test/containers.cfg +6 -0
- data/test/exta_string_after_container.cfg +2 -0
- data/test/extra_container_closing.cfg +2 -0
- data/test/extra_string_after_container.cfg +2 -0
- data/test/extra_string_after_nested_container.cfg +1 -0
- data/test/missing_array_closing.cfg +2 -0
- data/test/missing_array_element.cfg +2 -0
- data/test/missing_directive.cfg +1 -0
- data/test/missing_hash_closing.cfg +2 -0
- data/test/missing_hash_element.cfg +2 -0
- data/test/missing_hash_value.cfg +1 -0
- data/test/missing_include_argument.cfg +1 -0
- data/test/missing_key_value_delimiter.cfg +1 -0
- data/test/readerwritertest.rb +28 -7
- data/test/sample.cfg +10 -0
- data/test/sample.pretty_print +30 -0
- data/test/sample.rcfg +26 -0
- data/test/test_baseconfig.rb +152 -38
- data/test/test_hash.rb +82 -0
- data/test/test_keyvalue.rb +185 -0
- data/test/test_prettyprint.rb +28 -0
- data/test/test_ruby.rb +50 -0
- data/test/test_yaml.rb +33 -26
- data/test/wacky_sample1.cfg +16 -0
- data/test/wacky_sample2.cfg +5 -0
- data/test/wacky_sample3.cfg +4 -0
- data/test/wacky_sample4.cfg +1 -0
- metadata +101 -10
- data/lib/configtoolkit/toolkit.rb +0 -20
- data/test/common.rb +0 -5
@@ -0,0 +1 @@
|
|
1
|
+
config.unknown_array[0] = 2
|
@@ -0,0 +1 @@
|
|
1
|
+
*bogus directive
|
@@ -0,0 +1 @@
|
|
1
|
+
config.bad_parameter_reference(10)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
first.second.req_integer = 5
|
2
|
+
first.second.req_big_integer = 10000000000
|
3
|
+
first.second.req_float = 5.678
|
4
|
+
first.second.req_string = sample string
|
5
|
+
first.second.req_boolean = false
|
6
|
+
first.second.req_pathname = /usr/designingpatterns
|
7
|
+
first.second.req_uri = http://www.designingpatterns.com
|
8
|
+
first.second.req_symbol = sample_symbol
|
9
|
+
first.second.nested_config = {req_nested_integer => 33, req_nested_array => [{req_second_nested_pathname => /usr/designingpatterns/Applications, req_second_nested_array => [5, 19]}, {req_second_nested_pathname => /usr/designingpatterns/Applications/etc, req_second_nested_array => [200, 201]}]}
|
10
|
+
first.second.opt_integer = 42
|
@@ -0,0 +1,30 @@
|
|
1
|
+
first.second: {
|
2
|
+
req_integer : 5
|
3
|
+
req_big_integer: 10000000000
|
4
|
+
req_float : 5.678
|
5
|
+
req_string : sample string
|
6
|
+
req_boolean : false
|
7
|
+
req_pathname : /usr/designingpatterns
|
8
|
+
req_uri : http://www.designingpatterns.com
|
9
|
+
req_symbol : sample_symbol
|
10
|
+
nested_config : {
|
11
|
+
req_nested_integer: 33
|
12
|
+
req_nested_array : [
|
13
|
+
{
|
14
|
+
req_second_nested_pathname: /usr/designingpatterns/Applications
|
15
|
+
req_second_nested_array : [
|
16
|
+
5,
|
17
|
+
19
|
18
|
+
]
|
19
|
+
},
|
20
|
+
{
|
21
|
+
req_second_nested_pathname: /usr/designingpatterns/Applications/etc
|
22
|
+
req_second_nested_array : [
|
23
|
+
200,
|
24
|
+
201
|
25
|
+
]
|
26
|
+
}
|
27
|
+
]
|
28
|
+
}
|
29
|
+
opt_integer : 42
|
30
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
config.first.second.req_integer = 5
|
2
|
+
config.first.second.req_big_integer = 10000000000
|
3
|
+
config.first.second.req_float = 5.678
|
4
|
+
config.first.second.req_string = "sample string"
|
5
|
+
config.first.second.req_boolean = false
|
6
|
+
config.first.second.req_pathname = "/usr/designingpatterns"
|
7
|
+
config.first.second.req_uri = "http://www.designingpatterns.com"
|
8
|
+
config.first.second.req_symbol = :sample_symbol
|
9
|
+
config.first.second.nested_config.req_nested_integer = 33
|
10
|
+
config.first.second.nested_config.req_nested_array =
|
11
|
+
[
|
12
|
+
{
|
13
|
+
:req_second_nested_pathname => "/usr/designingpatterns/Applications",
|
14
|
+
:req_second_nested_array => [5, 19]
|
15
|
+
},
|
16
|
+
{
|
17
|
+
:req_second_nested_pathname => "/usr/designingpatterns/Applications/etc",
|
18
|
+
:req_second_nested_array => [200, 201]
|
19
|
+
}
|
20
|
+
]
|
21
|
+
|
22
|
+
config.first.second.opt_integer = 37 + config.first.second.req_integer
|
data/test/contained_sample.yaml
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
2
|
+
first:
|
3
|
+
second:
|
4
|
+
opt_integer: 42
|
5
|
+
req_uri: http://www.designingpatterns.com
|
6
|
+
req_float: 5.678
|
7
|
+
req_pathname: /usr/designingpatterns
|
8
|
+
req_integer: 5
|
9
|
+
req_string: sample string
|
10
|
+
req_boolean: false
|
11
|
+
req_symbol: sample_symbol
|
12
|
+
req_big_integer: 10000000000
|
13
|
+
nested_config:
|
14
|
+
req_nested_array:
|
15
|
+
- req_second_nested_pathname: /usr/designingpatterns/Applications
|
16
|
+
req_second_nested_array:
|
17
|
+
- 5
|
18
|
+
- 19
|
19
|
+
- req_second_nested_pathname: /usr/designingpatterns/Applications/etc
|
20
|
+
req_second_nested_array:
|
21
|
+
- 200
|
22
|
+
- 201
|
23
|
+
req_nested_integer: 33
|
data/test/containers.cfg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
extra_butterscotch = {type => soft serve, toppings => [sprinkles, cherries, oreos]butterscotch, flavor => cookie dough}
|
@@ -0,0 +1 @@
|
|
1
|
+
*
|
@@ -0,0 +1 @@
|
|
1
|
+
missing_topping_value = {type => soft serve, topping => , flavor => cookie dough
|
@@ -0,0 +1 @@
|
|
1
|
+
*include
|
@@ -0,0 +1 @@
|
|
1
|
+
favorite ice cream
|
data/test/readerwritertest.rb
CHANGED
@@ -8,7 +8,8 @@ require 'uri'
|
|
8
8
|
|
9
9
|
class SampleSecondNestedConfig < ConfigToolkit::BaseConfig
|
10
10
|
add_required_param(:req_second_nested_pathname, Pathname)
|
11
|
-
add_required_param(:req_second_nested_array,
|
11
|
+
add_required_param(:req_second_nested_array,
|
12
|
+
ConfigToolkit::ConstrainedArray.new(Integer))
|
12
13
|
end
|
13
14
|
|
14
15
|
class SampleNestedConfig < ConfigToolkit::BaseConfig
|
@@ -73,7 +74,7 @@ REFERENCE_CONTAINED_SAMPLE_CONFIG.nested_config.req_nested_array[0].req_second_n
|
|
73
74
|
REFERENCE_CONTAINED_SAMPLE_CONFIG.nested_config.req_nested_array[1].req_second_nested_pathname = Pathname.new("/usr/designingpatterns/Applications/etc")
|
74
75
|
REFERENCE_CONTAINED_SAMPLE_CONFIG.nested_config.req_nested_array[1].req_second_nested_array = [200, 201]
|
75
76
|
REFERENCE_CONTAINED_SAMPLE_CONFIG.opt_integer = 42
|
76
|
-
REFERENCE_CONTAINED_SAMPLE_CONFIG.instance_variable_set(:@containing_object_name, "
|
77
|
+
REFERENCE_CONTAINED_SAMPLE_CONFIG.instance_variable_set(:@containing_object_name, "first.second")
|
77
78
|
|
78
79
|
module ReaderWriterTest
|
79
80
|
def run_reader_test(reader_class,
|
@@ -85,15 +86,35 @@ module ReaderWriterTest
|
|
85
86
|
assert_equal(reference_config, config)
|
86
87
|
end
|
87
88
|
|
88
|
-
def get_sorted_file_contents(file_name)
|
89
|
+
def get_sorted_file_contents(file_name, sort_type)
|
89
90
|
file_contents = File.open(file_name, "r") do |file|
|
90
91
|
file.read()
|
91
92
|
end
|
92
93
|
|
93
|
-
|
94
|
+
if(sort_type == :sort_lines)
|
95
|
+
return file_contents.split("\n").sort().join("\n")
|
96
|
+
elsif(sort_type == :sort_lines_and_line_contents)
|
97
|
+
return file_contents.split("\n").sort().map do |line|
|
98
|
+
line.split("").sort().join()
|
99
|
+
end.join("\n")
|
100
|
+
end
|
94
101
|
end
|
95
102
|
|
103
|
+
#
|
104
|
+
# Often (always?), the output of a writer depends on the order in which it
|
105
|
+
# encounters parameters in the Hash that its write() method is
|
106
|
+
# passed. Of course, hash table elements have no guaranteed
|
107
|
+
# ordering, and so it is impossible to construct reference files
|
108
|
+
# since the order of the parameters in the file is undefined.
|
109
|
+
# So, the contents of the reference and dumped files are sorted
|
110
|
+
# before the comparison. If each parameter occupies at least one
|
111
|
+
# line, then just the lines need to be sorted (sort_type = :sort_lines).
|
112
|
+
# If multiple parameters can occur on the same line, then the lines
|
113
|
+
# need to be sorted, and the contents of each line must be
|
114
|
+
# sorted (sort_type = :sort_lines_and_line_contents).
|
115
|
+
#
|
96
116
|
def run_writer_test(writer_class,
|
117
|
+
sort_type,
|
97
118
|
reference_config,
|
98
119
|
reference_file_name,
|
99
120
|
dump_file_name,
|
@@ -101,8 +122,8 @@ module ReaderWriterTest
|
|
101
122
|
writer = writer_class.new(*writer_constructor_args)
|
102
123
|
reference_config.dump(writer)
|
103
124
|
|
104
|
-
assert_equal(get_sorted_file_contents(reference_file_name),
|
105
|
-
get_sorted_file_contents(dump_file_name))
|
125
|
+
assert_equal(get_sorted_file_contents(reference_file_name, sort_type),
|
126
|
+
get_sorted_file_contents(dump_file_name, sort_type))
|
106
127
|
end
|
107
128
|
|
108
129
|
def run_reader_writer_test(reader_class,
|
@@ -112,7 +133,7 @@ module ReaderWriterTest
|
|
112
133
|
writer_constructor_args)
|
113
134
|
writer = writer_class.new(*writer_constructor_args)
|
114
135
|
reference_config.dump(writer)
|
115
|
-
|
136
|
+
|
116
137
|
reader = reader_class.new(*reader_constructor_args)
|
117
138
|
config = SampleConfig.load(reader, reference_config.containing_object_name)
|
118
139
|
|
data/test/sample.cfg
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
req_integer = 6
|
2
|
+
req_big_integer = 90000000000
|
3
|
+
req_float = 3.14
|
4
|
+
req_string = sample string2
|
5
|
+
req_boolean = true
|
6
|
+
req_pathname = /usr/designingpatterns/bin
|
7
|
+
req_uri = http://blogs.designingpatterns.com
|
8
|
+
req_symbol = sample_symbol2
|
9
|
+
nested_config = {req_nested_integer => 34, req_nested_array => [{req_second_nested_pathname => /usr/designingpatterns/Applications/pattmake, req_second_nested_array => [6, 20]}, {req_second_nested_pathname => /usr, req_second_nested_array => [205, 206]}]}
|
10
|
+
opt_integer = 56
|
@@ -0,0 +1,30 @@
|
|
1
|
+
{
|
2
|
+
req_integer : 6
|
3
|
+
req_big_integer: 90000000000
|
4
|
+
req_float : 3.14
|
5
|
+
req_string : sample string2
|
6
|
+
req_boolean : true
|
7
|
+
req_pathname : /usr/designingpatterns/bin
|
8
|
+
req_uri : http://blogs.designingpatterns.com
|
9
|
+
req_symbol : sample_symbol2
|
10
|
+
nested_config : {
|
11
|
+
req_nested_integer: 34
|
12
|
+
req_nested_array : [
|
13
|
+
{
|
14
|
+
req_second_nested_pathname: /usr/designingpatterns/Applications/pattmake
|
15
|
+
req_second_nested_array : [
|
16
|
+
6,
|
17
|
+
20
|
18
|
+
]
|
19
|
+
},
|
20
|
+
{
|
21
|
+
req_second_nested_pathname: /usr
|
22
|
+
req_second_nested_array : [
|
23
|
+
205,
|
24
|
+
206
|
25
|
+
]
|
26
|
+
}
|
27
|
+
]
|
28
|
+
}
|
29
|
+
opt_integer : 56
|
30
|
+
}
|
data/test/sample.rcfg
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
config.req_integer = 6
|
5
|
+
config.req_big_integer = 90000000000
|
6
|
+
config.req_float = 3.14
|
7
|
+
config.req_string = "sample string2"
|
8
|
+
config.req_boolean = true
|
9
|
+
config.req_pathname = Pathname.new("/usr/designingpatterns/bin")
|
10
|
+
config.req_uri = URI("http://blogs.designingpatterns.com")
|
11
|
+
config.req_symbol = :sample_symbol2
|
12
|
+
config.nested_config = {
|
13
|
+
:req_nested_integer => 34,
|
14
|
+
:req_nested_array => [
|
15
|
+
{
|
16
|
+
:req_second_nested_pathname => Pathname("/usr/designingpatterns/Applications/pattmake"),
|
17
|
+
:req_second_nested_array => [6, 20]
|
18
|
+
},
|
19
|
+
{
|
20
|
+
:req_second_nested_pathname => Pathname("/usr"),
|
21
|
+
:req_second_nested_array => [205, 206]
|
22
|
+
}
|
23
|
+
]
|
24
|
+
}
|
25
|
+
|
26
|
+
config.opt_integer = 56
|
data/test/test_baseconfig.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'common'
|
4
|
-
|
5
3
|
require 'configtoolkit'
|
6
4
|
require 'configtoolkit/yamlreader'
|
7
5
|
require 'configtoolkit/yamlwriter'
|
6
|
+
require 'configtoolkit/hasharrayvisitor'
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'assertions'
|
10
|
+
require 'relative'
|
8
11
|
|
9
12
|
require 'pathname'
|
10
13
|
require 'test/unit'
|
@@ -74,7 +77,7 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
|
-
MACHINES_CONFIG_FILE_NAME =
|
80
|
+
MACHINES_CONFIG_FILE_NAME = File.expand_path_relative_to_caller("machines.yaml")
|
78
81
|
|
79
82
|
#
|
80
83
|
# Test whether the methods for MachineConfig's attributes
|
@@ -102,9 +105,31 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
102
105
|
#
|
103
106
|
config_param_values.each do |param_name, param_value|
|
104
107
|
assert_equal(nil, config.send(param_name))
|
108
|
+
assert_not(config.send("#{param_name}?"))
|
105
109
|
setter = "#{param_name}=".to_sym()
|
110
|
+
|
106
111
|
config.send(setter, param_value)
|
107
112
|
assert_equal(param_value, config.send(param_name))
|
113
|
+
assert(config.send("#{param_name}?"))
|
114
|
+
|
115
|
+
#
|
116
|
+
# Verify that the single optional parameter, :behind_firewall,
|
117
|
+
# has a clear method, and that the clear method works
|
118
|
+
# properly. Verify that the required parameters do not have
|
119
|
+
# clear methods.
|
120
|
+
#
|
121
|
+
clear_method = "clear_#{param_name}".to_sym()
|
122
|
+
if(param_name == :behind_firewall)
|
123
|
+
config.send(clear_method)
|
124
|
+
assert_equal(nil, config.send(param_name))
|
125
|
+
assert_not(config.send("#{param_name}?"))
|
126
|
+
|
127
|
+
config.send(setter, param_value)
|
128
|
+
assert_equal(param_value, config.send(param_name))
|
129
|
+
assert(config.send("#{param_name}?"))
|
130
|
+
else
|
131
|
+
assert_not(config.respond_to?(clear_method))
|
132
|
+
end
|
108
133
|
end
|
109
134
|
|
110
135
|
#
|
@@ -116,6 +141,29 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
116
141
|
puts config
|
117
142
|
end
|
118
143
|
|
144
|
+
def test_initialize
|
145
|
+
config = MachineConfig.new() do |config|
|
146
|
+
config.name = "apple"
|
147
|
+
config.architecture = "powerpc"
|
148
|
+
config.os = "AIX"
|
149
|
+
config.num_cpus = 32
|
150
|
+
config.behind_firewall = false
|
151
|
+
config.contains_sensitive_data = false
|
152
|
+
config.addresses = [
|
153
|
+
URI("http://default.designingpatterns.com"),
|
154
|
+
URI("http://apple.designingpatterns.com")
|
155
|
+
]
|
156
|
+
end
|
157
|
+
|
158
|
+
reader = ConfigToolkit::YAMLReader.new(File.expand_path_relative_to_caller("machines.yaml"))
|
159
|
+
assert_equal(MachineConfig.load(reader), config)
|
160
|
+
|
161
|
+
assert_raise_message("missing parameter(s): name, architecture, os, num_cpus, contains_sensitive_data, addresses", ConfigToolkit::Error) do
|
162
|
+
config = MachineConfig.new() do
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
119
167
|
def verify_correct_dump(config_file_name, containing_object_name)
|
120
168
|
reader = ConfigToolkit::YAMLReader.new(config_file_name)
|
121
169
|
config = MachineConfig.load(reader, containing_object_name)
|
@@ -134,21 +182,14 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
134
182
|
def verify_dump_error(config, message)
|
135
183
|
dump_stream = StringIO.new()
|
136
184
|
writer = ConfigToolkit::YAMLWriter.new(dump_stream, true)
|
137
|
-
|
138
|
-
rescued_exception = false
|
139
|
-
begin
|
185
|
+
assert_raise_message(message, ConfigToolkit::Error) do
|
140
186
|
config.dump(writer)
|
141
|
-
rescue ConfigToolkit::Error => e
|
142
|
-
assert_equal(message, e.message)
|
143
|
-
rescued_exception = true
|
144
187
|
end
|
145
|
-
|
146
|
-
assert(rescued_exception)
|
147
188
|
end
|
148
189
|
|
149
190
|
def test_dump
|
150
|
-
verify_correct_dump(
|
151
|
-
verify_correct_dump(
|
191
|
+
verify_correct_dump(File.expand_path_relative_to_caller("firewall.yaml"), "firewall")
|
192
|
+
verify_correct_dump(File.expand_path_relative_to_caller("webserver.yaml"), "")
|
152
193
|
|
153
194
|
#
|
154
195
|
# Verify that dumping a config sets the config's optional
|
@@ -164,7 +205,7 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
164
205
|
dump_stream = StringIO.new()
|
165
206
|
writer = ConfigToolkit::YAMLWriter.new(dump_stream, true)
|
166
207
|
assert_equal(nil, config.behind_firewall)
|
167
|
-
config.dump(
|
208
|
+
config.dump(writer)
|
168
209
|
assert_equal(true, config.behind_firewall)
|
169
210
|
|
170
211
|
config = MachineConfig.new()
|
@@ -177,7 +218,7 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
177
218
|
config.behind_firewall = false
|
178
219
|
config.num_cpus = 2
|
179
220
|
config.addresses = ["http://uniq.designingpatterns.com", "http://ftp.designingpatterns.com"]
|
180
|
-
verify_dump_error(config, "BaseConfigTest::MachineConfig#validate_all_values
|
221
|
+
verify_dump_error(config, "BaseConfigTest::MachineConfig#validate_all_values error: a machine cannot contain sensitive data and not be behind the firewall")
|
181
222
|
end
|
182
223
|
|
183
224
|
def verify_correct_load(config_file_name,
|
@@ -204,29 +245,17 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
204
245
|
def verify_load_error(config_file_name, containing_object_name, message)
|
205
246
|
reader = ConfigToolkit::YAMLReader.new(config_file_name)
|
206
247
|
|
207
|
-
|
208
|
-
begin
|
248
|
+
assert_raise_message(message, ConfigToolkit::Error) do
|
209
249
|
config = MachineConfig.load(reader, containing_object_name)
|
210
|
-
rescue ConfigToolkit::Error => e
|
211
|
-
assert_equal(message, e.message)
|
212
|
-
rescued_exception = true
|
213
250
|
end
|
214
|
-
|
215
|
-
assert(rescued_exception)
|
216
251
|
end
|
217
252
|
|
218
253
|
def verify_load_group_error(config_file_name, containing_object_name, message)
|
219
254
|
reader = ConfigToolkit::YAMLReader.new(config_file_name)
|
220
255
|
|
221
|
-
|
222
|
-
begin
|
256
|
+
assert_raise_message(message, ConfigToolkit::Error) do
|
223
257
|
config = MachineConfig.load_group(reader, containing_object_name)
|
224
|
-
rescue ConfigToolkit::Error => e
|
225
|
-
assert_equal(message, e.message)
|
226
|
-
rescued_exception = true
|
227
258
|
end
|
228
|
-
|
229
|
-
assert(rescued_exception)
|
230
259
|
end
|
231
260
|
|
232
261
|
#
|
@@ -274,13 +303,13 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
274
303
|
verify_correct_load(MACHINES_CONFIG_FILE_NAME, "test", config)
|
275
304
|
|
276
305
|
verify_correct_load_group(MACHINES_CONFIG_FILE_NAME, "db_cluster1",
|
277
|
-
|
278
|
-
|
279
|
-
|
306
|
+
:db1 => MachineConfig.load(ConfigToolkit::YAMLReader.new(MACHINES_CONFIG_FILE_NAME), "db1"),
|
307
|
+
:db2 => MachineConfig.load(ConfigToolkit::YAMLReader.new(MACHINES_CONFIG_FILE_NAME), "db2"),
|
308
|
+
:db3 => MachineConfig.load(ConfigToolkit::YAMLReader.new(MACHINES_CONFIG_FILE_NAME), "db3"))
|
280
309
|
end
|
281
310
|
|
282
311
|
def test_load_errors
|
283
|
-
verify_load_error(
|
312
|
+
verify_load_error(File.expand_path_relative_to_caller("bad_config.yaml"),
|
284
313
|
"",
|
285
314
|
"ConfigToolkit::YAMLReader#read returned Array rather than Hash")
|
286
315
|
|
@@ -298,26 +327,111 @@ class BaseConfigTest < Test::Unit::TestCase
|
|
298
327
|
|
299
328
|
verify_load_error(MACHINES_CONFIG_FILE_NAME,
|
300
329
|
"bad_num_cpus",
|
301
|
-
"error setting
|
330
|
+
"error setting bad_num_cpus.num_cpus with value -2: num_cpus must be greater than zero.")
|
302
331
|
|
303
332
|
verify_load_error(MACHINES_CONFIG_FILE_NAME,
|
304
333
|
"bad_addresses_element_type",
|
305
|
-
"error setting
|
334
|
+
"error setting bad_addresses_element_type.addresses[0] with value 2: cannot convert from value class Fixnum to specified class URI.")
|
306
335
|
|
307
336
|
verify_load_error(MACHINES_CONFIG_FILE_NAME,
|
308
337
|
"bad_addresses_max_num_elements",
|
309
|
-
"error setting
|
338
|
+
"error setting bad_addresses_max_num_elements.addresses with value [http://test.designingpatterns.com, http://bananna.designingpatterns.com, http://fruitsalad.designingpatterns.com, http://parfait.designingpatterns.com]: the number of elements (4) is greater than the specified maximum number of elements (3).")
|
310
339
|
|
311
340
|
verify_load_error(MACHINES_CONFIG_FILE_NAME,
|
312
341
|
"bad_addresses_min_num_elements",
|
313
|
-
"error setting
|
342
|
+
"error setting bad_addresses_min_num_elements.addresses with value [http://bananna.designingpatterns.com]: the number of elements (1) is less than the specified minimum number of elements (2).")
|
314
343
|
|
315
344
|
verify_load_error(MACHINES_CONFIG_FILE_NAME,
|
316
345
|
"bad_contains_sensitive_data_behind_firewall_combo",
|
317
|
-
"BaseConfigTest::MachineConfig#validate_all_values
|
346
|
+
"BaseConfigTest::MachineConfig#validate_all_values error for bad_contains_sensitive_data_behind_firewall_combo: a machine cannot contain sensitive data and not be behind the firewall")
|
318
347
|
|
319
348
|
verify_load_group_error(MACHINES_CONFIG_FILE_NAME,
|
320
349
|
"bad_group",
|
321
350
|
"error: BaseConfigTest::MachineConfig.load_group found Array rather than Hash when reading the bad_group.bad_element containing object")
|
322
351
|
end
|
352
|
+
|
353
|
+
class BadConfig < ConfigToolkit::BaseConfig
|
354
|
+
add_optional_param(:optional_param_with_default_value, String, "hello")
|
355
|
+
add_optional_param(:optional_param_without_default_value, String)
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_configuration_definition
|
359
|
+
assert_raise_message("error setting default value for bad_param with value nil: cannot convert from value class NilClass to specified class Fixnum.", ConfigToolkit::Error) do
|
360
|
+
BadConfig.send(:add_optional_param, :bad_param, Fixnum, nil)
|
361
|
+
end
|
362
|
+
|
363
|
+
assert_raise_message("error setting default value for bad_param with value 1: cannot convert from value class Fixnum to specified class String.", ConfigToolkit::Error) do
|
364
|
+
BadConfig.send(:add_optional_param, :bad_param, String, 1)
|
365
|
+
end
|
366
|
+
|
367
|
+
#
|
368
|
+
# After initializing a BadConfig instance with no parameters:
|
369
|
+
# * optional_param_with_default_value should have its default value of
|
370
|
+
# "hello"
|
371
|
+
# * optional_param_without_default_value should have no value
|
372
|
+
#
|
373
|
+
config = BadConfig.new() do
|
374
|
+
end
|
375
|
+
|
376
|
+
assert(config.optional_param_with_default_value?)
|
377
|
+
assert_equal("hello", config.optional_param_with_default_value)
|
378
|
+
|
379
|
+
assert_not(config.optional_param_without_default_value?)
|
380
|
+
assert_equal(nil, config.optional_param_without_default_value)
|
381
|
+
end
|
382
|
+
|
383
|
+
class NestedConfig < ConfigToolkit::BaseConfig
|
384
|
+
add_required_param(:name, String)
|
385
|
+
end
|
386
|
+
|
387
|
+
class ConfigWithNestedConfig < ConfigToolkit::BaseConfig
|
388
|
+
add_optional_param(:nested_config,
|
389
|
+
NestedConfig,
|
390
|
+
NestedConfig.new() { |config| config.name = "stuff" })
|
391
|
+
end
|
392
|
+
|
393
|
+
def test_nested_config
|
394
|
+
#
|
395
|
+
# Test the basic setter functionality with nested config instances.
|
396
|
+
# In particular, verify that a default nested config parameter value
|
397
|
+
# correctly is set (with the value being duped).
|
398
|
+
#
|
399
|
+
config1 = ConfigWithNestedConfig.new() { |config| }
|
400
|
+
assert_equal("stuff", config1.nested_config.name)
|
401
|
+
config1.nested_config.name = "stuff2"
|
402
|
+
assert_equal("stuff2", config1.nested_config.name)
|
403
|
+
|
404
|
+
config2 = ConfigWithNestedConfig.new() { |config| }
|
405
|
+
assert_equal("stuff", config2.nested_config.name)
|
406
|
+
assert_equal("stuff2", config1.nested_config.name) # Should be unchanged
|
407
|
+
end
|
408
|
+
|
409
|
+
class ConfigWithNestedArray < ConfigToolkit::BaseConfig
|
410
|
+
add_optional_param(:nested_array, Array, [1, 2, 3])
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_nested_array
|
414
|
+
#
|
415
|
+
# Test that Array (not ConfigToolkit::ConstrainedArray) can be
|
416
|
+
# specified as a parameter value class.
|
417
|
+
#
|
418
|
+
config1 = ConfigWithNestedArray.new() { |c| }
|
419
|
+
assert_equal([1, 2, 3], config1.nested_array)
|
420
|
+
config1.nested_array = ["a", "b", "c"]
|
421
|
+
|
422
|
+
config2 = ConfigWithNestedArray.new() { |c| }
|
423
|
+
assert_equal([1, 2, 3], config2.nested_array)
|
424
|
+
assert_equal(["a", "b", "c"], config1.nested_array) # Should be unchanged
|
425
|
+
end
|
426
|
+
|
427
|
+
def test_hash_array_visitor
|
428
|
+
#
|
429
|
+
# The core functionality adequately is tested by the various writer
|
430
|
+
# unit tests.
|
431
|
+
#
|
432
|
+
visitor = ConfigToolkit::HashArrayVisitor.new()
|
433
|
+
assert_raise_message("The argument to HashArrayVisitor::visit must be a Hash or Array; instead, a Fixnum (3) was passed!", ArgumentError) do
|
434
|
+
visitor.visit(3)
|
435
|
+
end
|
436
|
+
end
|
323
437
|
end
|