1 # Copyright (C) 2011 W. Trevor King <wking@drexel.edu>
3 # This file is part of h5config.
5 # h5config is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation, either version 3 of the License, or (at your
8 # option) any later version.
10 # h5config is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with h5config. If not, see <http://www.gnu.org/licenses/>.
18 """Define a test config object using all the setting types
20 The first time you a storage backend, the file it creates will
21 probably be empty or not exist.
25 >>> from h5config.storage.hdf5 import pprint_HDF5, HDF5_Storage
27 >>> fd,filename = tempfile.mkstemp(suffix='.h5', prefix='h5config-')
30 >>> c = TestConfig(storage=HDF5_Storage(filename=filename, group='/base'))
33 Loading will create a stub group group if it hadn't existed before.
35 >>> pprint_HDF5(filename)
39 Saving fills in all the config values.
41 >>> c['syslog'] = True
43 >>> pprint_HDF5(filename) # doctest: +REPORT_UDIFF, +ELLIPSIS
46 <HDF5 dataset "age": shape (), type "<f8">
48 <HDF5 dataset "alive": shape (), type "|b1">
50 <HDF5 dataset "bids": shape (3,), type "<f8">
52 <HDF5 dataset "children": shape (), type "|S1">
54 <HDF5 dataset "claws": shape (2,), type "<i8">
56 <HDF5 dataset "daisies": shape (), type "<i...">
58 <HDF5 dataset "name": shape (), type "|S1">
60 <HDF5 dataset "species": shape (), type "|S14">
62 <HDF5 dataset "spouse": shape (), type "|S1">
64 <HDF5 dataset "words": shape (2,), type "|S7">
67 If you want more details, you can dump with help strings.
69 >>> print(c.dump(help=True)) # doctest: +REPORT_UDIFF, +NORMALIZE_WHITESPACE
70 name: (The parrot's name. Default: .)
71 species: Norwegian Blue (Type of parrot. Default: Norwegian Blue.
72 Choices: Norwegian Blue, Macaw)
73 alive: no (The parrot is alive. Default: no. Choices: yes, no)
74 daisies: 13 (Number of daisies pushed up by the parrot.
76 age: 1.3 (Parrot age in years Default: 1.3.)
77 words: cracker,wants (Words known by the parrot. Default: cracker,wants.)
78 claws: 1,2 (Claws on each foot. Default: 1,2.)
79 bids: 5.4,3.2,1 (Prices offered for parrot. Default: 5.4,3.2,1.)
80 spouse: (This parrot's significant other. Default: .)
81 children: (This parrot's children. Default: .)
83 As you can see from the `age` setting, settings also support `None`,
84 even if they have numeric types.
86 Cleanup our temporary config file.
88 >>> os.remove(filename)
93 import tempfile as _tempfile
95 from . import LOG as _LOG
96 from . import config as _config
97 from .storage import FileStorage as _FileStorage
98 from .storage.hdf5 import HDF5_Storage
99 from .storage.yaml import YAML_Storage
102 class TestConfig (_config.Config):
103 "Test all the setting types for the h5config module"
107 help="The parrot's name."),
108 _config.ChoiceSetting(
110 help='Type of parrot.',
112 choices=[('Norwegian Blue', 0), ('Macaw', 1)]),
113 _config.BooleanSetting(
115 help='The parrot is alive.',
117 _config.IntegerSetting(
119 help="Number of daisies pushed up by the parrot.",
121 _config.FloatSetting(
123 help='Parrot age in years',
127 help='Words known by the parrot.',
128 default=['cracker', 'wants']),
129 _config.IntegerListSetting(
131 help='Claws on each foot.',
133 _config.FloatListSetting(
135 help='Prices offered for parrot.',
136 default=[5.4, 3.2, 1]),
137 _config.ConfigSetting(
139 help="This parrot's significant other."),
140 _config.ConfigListSetting(
142 help="This parrot's children."),
145 # must define self-references after completing the TestConfig class
146 for s in TestConfig.settings:
147 if s.name in ['spouse', 'children']:
148 s.config_class = TestConfig
151 def _alternative_test_config(name):
156 _ALTERNATIVES = { # alternative settings for testing
157 'name': 'Captain Flint',
162 'words': ['arrrr', 'matey'],
165 'spouse': _alternative_test_config(name='Lory'),
166 'children': [_alternative_test_config(name=n)
167 for n in ['Washington Post', 'Eli Yale']],
169 # TODO: share children with spouse to test references
171 def test(storage=None):
173 storage = [HDF5_Storage, YAML_Storage]
177 _LOG.debug('testing {}'.format(storage))
178 _basic_tests(storage)
179 if issubclass(storage, _FileStorage):
180 _file_storage_tests(storage)
182 def _basic_tests(storage):
185 def _file_storage_tests(storage):
186 fd,filename = _tempfile.mkstemp(
187 suffix='.'+storage.extension, prefix='h5config-')
190 c = TestConfig(storage=storage(filename=filename))
194 nd = list(_non_defaults(c))
195 assert not nd, (storage, nd)
196 for key,value in _ALTERNATIVES.items():
200 na = dict(_non_alternatives(c))
201 assert not na, (storage, na)
203 nd = list(_non_defaults(c))
204 assert not nd, (storage, nd)
206 na = dict(_non_alternatives(c))
207 assert not na, (storage, na)
211 def _non_defaults(config):
212 for setting in TestConfig.settings:
213 value = config[setting.name]
214 if value != setting.default:
215 yield (setting.name, value)
217 def _non_alternatives(config, alternatives=None):
218 if alternatives is None:
219 alternatives = _ALTERNATIVES
220 for setting in TestConfig.settings:
221 value = config[setting.name]
222 alt = alternatives[setting.name]
224 _LOG.error('{} value missmatch: {} vs {}'.format(
225 setting.name, value, alt))
226 yield (setting.name, value)
227 elif type(value) != type(alt):
228 _LOG.error('{} type missmatch: {} vs {}'.format(
229 setting.name, type(value), type(alt)))
230 yield (setting.name, value)