Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
8023760a
Commit
8023760a
authored
Jul 08, 2011
by
Naoki Kambe
Browse files
[trac930] remove unneeded mockups, fake modules and dummy data
parent
cc0d6e46
Changes
22
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
8023760a
...
...
@@ -817,14 +817,6 @@ AC_CONFIG_FILES([Makefile
src/bin/zonemgr/tests/Makefile
src/bin/stats/Makefile
src/bin/stats/tests/Makefile
src/bin/stats/tests/isc/Makefile
src/bin/stats/tests/isc/cc/Makefile
src/bin/stats/tests/isc/config/Makefile
src/bin/stats/tests/isc/util/Makefile
src/bin/stats/tests/isc/log/Makefile
src/bin/stats/tests/isc/log_messages/Makefile
src/bin/stats/tests/testdata/Makefile
src/bin/stats/tests/http/Makefile
src/bin/usermgr/Makefile
src/bin/tests/Makefile
src/lib/Makefile
...
...
src/bin/stats/tests/fake_select.py
deleted
100644 → 0
View file @
cc0d6e46
# Copyright (C) 2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
A mock-up module of select
*** NOTE ***
It is only for testing stats_httpd module and not reusable for
external module.
"""
import
fake_socket
import
errno
class
error
(
Exception
):
pass
def
select
(
rlst
,
wlst
,
xlst
,
timeout
):
if
type
(
timeout
)
!=
int
and
type
(
timeout
)
!=
float
:
raise
TypeError
(
"Error: %s must be integer or float"
%
timeout
.
__class__
.
__name__
)
for
s
in
rlst
+
wlst
+
xlst
:
if
type
(
s
)
!=
fake_socket
.
socket
:
raise
TypeError
(
"Error: %s must be a dummy socket"
%
s
.
__class__
.
__name__
)
s
.
_called
=
s
.
_called
+
1
if
s
.
_called
>
3
:
raise
error
(
"Something is happened!"
)
elif
s
.
_called
>
2
:
raise
error
(
errno
.
EINTR
)
return
(
rlst
,
wlst
,
xlst
)
src/bin/stats/tests/fake_socket.py
deleted
100644 → 0
View file @
cc0d6e46
# Copyright (C) 2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
A mock-up module of socket
*** NOTE ***
It is only for testing stats_httpd module and not reusable for
external module.
"""
import
re
AF_INET
=
'AF_INET'
AF_INET6
=
'AF_INET6'
_ADDRFAMILY
=
AF_INET
has_ipv6
=
True
_CLOSED
=
False
class
gaierror
(
Exception
):
pass
class
error
(
Exception
):
pass
class
socket
:
def
__init__
(
self
,
family
=
None
):
if
family
is
None
:
self
.
address_family
=
_ADDRFAMILY
else
:
self
.
address_family
=
family
self
.
_closed
=
_CLOSED
if
self
.
_closed
:
raise
error
(
'socket is already closed!'
)
self
.
_called
=
0
def
close
(
self
):
self
.
_closed
=
True
def
fileno
(
self
):
return
id
(
self
)
def
bind
(
self
,
server_class
):
(
self
.
server_address
,
self
.
server_port
)
=
server_class
if
self
.
address_family
not
in
set
([
AF_INET
,
AF_INET6
]):
raise
error
(
"Address family not supported by protocol: %s"
%
self
.
address_family
)
if
self
.
address_family
==
AF_INET6
and
not
has_ipv6
:
raise
error
(
"Address family not supported in this machine: %s has_ipv6: %s"
%
(
self
.
address_family
,
str
(
has_ipv6
)))
if
self
.
address_family
==
AF_INET
and
re
.
search
(
':'
,
self
.
server_address
)
is
not
None
:
raise
gaierror
(
"Address family for hostname not supported : %s %s"
%
(
self
.
server_address
,
self
.
address_family
))
if
self
.
address_family
==
AF_INET6
and
re
.
search
(
':'
,
self
.
server_address
)
is
None
:
raise
error
(
"Cannot assign requested address : %s"
%
str
(
self
.
server_address
))
if
type
(
self
.
server_port
)
is
not
int
:
raise
TypeError
(
"an integer is required: %s"
%
str
(
self
.
server_port
))
if
self
.
server_port
<
0
or
self
.
server_port
>
65535
:
raise
OverflowError
(
"port number must be 0-65535.: %s"
%
str
(
self
.
server_port
))
src/bin/stats/tests/fake_time.py
deleted
100644 → 0
View file @
cc0d6e46
# Copyright (C) 2010 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
__version__
=
"$Revision$"
# This is a dummy time class against a Python standard time class.
# It is just testing use only.
# Other methods which time class has is not implemented.
# (This class isn't orderloaded for time class.)
# These variables are constant. These are example.
_TEST_TIME_SECS
=
1283364938.229088
_TEST_TIME_STRF
=
'2010-09-01T18:15:38Z'
def
time
():
"""
This is a dummy time() method against time.time()
"""
# return float constant value
return
_TEST_TIME_SECS
def
gmtime
():
"""
This is a dummy gmtime() method against time.gmtime()
"""
# always return nothing
return
None
def
strftime
(
*
arg
):
"""
This is a dummy gmtime() method against time.gmtime()
"""
return
_TEST_TIME_STRF
src/bin/stats/tests/http/Makefile.am
deleted
100644 → 0
View file @
cc0d6e46
EXTRA_DIST
=
__init__.py server.py
CLEANFILES
=
__init__.pyc server.pyc
CLEANDIRS
=
__pycache__
clean-local
:
rm
-rf
$(CLEANDIRS)
src/bin/stats/tests/http/__init__.py
deleted
100644 → 0
View file @
cc0d6e46
src/bin/stats/tests/http/server.py
deleted
100644 → 0
View file @
cc0d6e46
# Copyright (C) 2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
A mock-up module of http.server
*** NOTE ***
It is only for testing stats_httpd module and not reusable for
external module.
"""
import
fake_socket
class
DummyHttpResponse
:
def
__init__
(
self
,
path
):
self
.
path
=
path
self
.
headers
=
{}
self
.
log
=
""
def
_write_log
(
self
,
msg
):
self
.
log
=
self
.
log
+
msg
class
HTTPServer
:
"""
A mock-up class of http.server.HTTPServer
"""
address_family
=
fake_socket
.
AF_INET
def
__init__
(
self
,
server_class
,
handler_class
):
self
.
socket
=
fake_socket
.
socket
(
self
.
address_family
)
self
.
server_class
=
server_class
self
.
socket
.
bind
(
self
.
server_class
)
self
.
_handler
=
handler_class
(
None
,
None
,
self
)
def
handle_request
(
self
):
pass
def
server_close
(
self
):
self
.
socket
.
close
()
class
BaseHTTPRequestHandler
:
"""
A mock-up class of http.server.BaseHTTPRequestHandler
"""
def
__init__
(
self
,
request
,
client_address
,
server
):
self
.
path
=
"/path/to"
self
.
headers
=
{}
self
.
server
=
server
self
.
response
=
DummyHttpResponse
(
path
=
self
.
path
)
self
.
response
.
write
=
self
.
_write
self
.
wfile
=
self
.
response
def
send_response
(
self
,
code
=
0
):
if
self
.
path
!=
self
.
response
.
path
:
self
.
response
=
DummyHttpResponse
(
path
=
self
.
path
)
self
.
response
.
code
=
code
def
send_header
(
self
,
key
,
value
):
if
self
.
path
!=
self
.
response
.
path
:
self
.
response
=
DummyHttpResponse
(
path
=
self
.
path
)
self
.
response
.
headers
[
key
]
=
value
def
end_headers
(
self
):
if
self
.
path
!=
self
.
response
.
path
:
self
.
response
=
DummyHttpResponse
(
path
=
self
.
path
)
self
.
response
.
wrote_headers
=
True
def
send_error
(
self
,
code
,
message
=
None
):
if
self
.
path
!=
self
.
response
.
path
:
self
.
response
=
DummyHttpResponse
(
path
=
self
.
path
)
self
.
response
.
code
=
code
self
.
response
.
body
=
message
def
address_string
(
self
):
return
'dummyhost'
def
log_date_time_string
(
self
):
return
'[DD/MM/YYYY HH:MI:SS]'
def
_write
(
self
,
obj
):
if
self
.
path
!=
self
.
response
.
path
:
self
.
response
=
DummyHttpResponse
(
path
=
self
.
path
)
self
.
response
.
body
=
obj
.
decode
()
src/bin/stats/tests/isc/Makefile.am
deleted
100644 → 0
View file @
cc0d6e46
SUBDIRS
=
cc config util log log_messages
EXTRA_DIST
=
__init__.py
CLEANFILES
=
__init__.pyc
CLEANDIRS
=
__pycache__
clean-local
:
rm
-rf
$(CLEANDIRS)
src/bin/stats/tests/isc/__init__.py
deleted
100644 → 0
View file @
cc0d6e46
src/bin/stats/tests/isc/cc/Makefile.am
deleted
100644 → 0
View file @
cc0d6e46
EXTRA_DIST
=
__init__.py session.py
CLEANFILES
=
__init__.pyc session.pyc
CLEANDIRS
=
__pycache__
clean-local
:
rm
-rf
$(CLEANDIRS)
src/bin/stats/tests/isc/cc/__init__.py
deleted
100644 → 0
View file @
cc0d6e46
from
isc.cc.session
import
*
src/bin/stats/tests/isc/cc/session.py
deleted
100644 → 0
View file @
cc0d6e46
# Copyright (C) 2010,2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
A mock-up module of isc.cc.session
*** NOTE ***
It is only for testing stats_httpd module and not reusable for
external module.
"""
import
sys
import
fake_socket
# set a dummy lname
_TEST_LNAME
=
'123abc@xxxx'
class
Queue
():
def
__init__
(
self
,
msg
=
None
,
env
=
{}):
self
.
msg
=
msg
self
.
env
=
env
def
dump
(
self
):
return
{
'msg'
:
self
.
msg
,
'env'
:
self
.
env
}
class
SessionError
(
Exception
):
pass
class
SessionTimeout
(
Exception
):
pass
class
Session
:
def
__init__
(
self
,
socket_file
=
None
,
verbose
=
False
):
self
.
_lname
=
_TEST_LNAME
self
.
message_queue
=
[]
self
.
old_message_queue
=
[]
try
:
self
.
_socket
=
fake_socket
.
socket
()
except
fake_socket
.
error
as
se
:
raise
SessionError
(
se
)
self
.
verbose
=
verbose
@
property
def
lname
(
self
):
return
self
.
_lname
def
close
(
self
):
self
.
_socket
.
close
()
def
_clear_queues
(
self
):
while
len
(
self
.
message_queue
)
>
0
:
self
.
dequeue
()
def
_next_sequence
(
self
,
que
=
None
):
return
len
(
self
.
message_queue
)
def
enqueue
(
self
,
msg
=
None
,
env
=
{}):
if
self
.
_socket
.
_closed
:
raise
SessionError
(
"Session has been closed."
)
seq
=
self
.
_next_sequence
()
env
.
update
({
"seq"
:
0
})
# fixed here
que
=
Queue
(
msg
=
msg
,
env
=
env
)
self
.
message_queue
.
append
(
que
)
if
self
.
verbose
:
sys
.
stdout
.
write
(
"[Session] enqueue: "
+
str
(
que
.
dump
())
+
"
\n
"
)
return
seq
def
dequeue
(
self
):
if
self
.
_socket
.
_closed
:
raise
SessionError
(
"Session has been closed."
)
que
=
None
try
:
que
=
self
.
message_queue
.
pop
(
0
)
# always pop at index 0
self
.
old_message_queue
.
append
(
que
)
except
IndexError
:
que
=
Queue
()
if
self
.
verbose
:
sys
.
stdout
.
write
(
"[Session] dequeue: "
+
str
(
que
.
dump
())
+
"
\n
"
)
return
que
def
get_queue
(
self
,
seq
=
None
):
if
self
.
_socket
.
_closed
:
raise
SessionError
(
"Session has been closed."
)
if
seq
is
None
:
seq
=
len
(
self
.
message_queue
)
-
1
que
=
None
try
:
que
=
self
.
message_queue
[
seq
]
except
IndexError
:
raise
IndexError
que
=
Queue
()
if
self
.
verbose
:
sys
.
stdout
.
write
(
"[Session] get_queue: "
+
str
(
que
.
dump
())
+
"
\n
"
)
return
que
def
group_sendmsg
(
self
,
msg
,
group
,
instance
=
"*"
,
to
=
"*"
):
return
self
.
enqueue
(
msg
=
msg
,
env
=
{
"type"
:
"send"
,
"from"
:
self
.
_lname
,
"to"
:
to
,
"group"
:
group
,
"instance"
:
instance
})
def
group_recvmsg
(
self
,
nonblock
=
True
,
seq
=
0
):
que
=
self
.
dequeue
()
if
que
.
msg
!=
None
:
cmd
=
que
.
msg
.
get
(
"command"
)
if
cmd
and
cmd
[
0
]
==
'getstats'
:
# Create answer for command 'getstats'
retdata
=
{
"stats_data"
:
{
'bind10.boot_time'
:
"1970-01-01T00:00:00Z"
}}
return
{
'result'
:
[
0
,
retdata
]},
que
.
env
return
que
.
msg
,
que
.
env
def
group_reply
(
self
,
routing
,
msg
):
return
self
.
enqueue
(
msg
=
msg
,
env
=
{
"type"
:
"send"
,
"from"
:
self
.
_lname
,
"to"
:
routing
[
"from"
],
"group"
:
routing
[
"group"
],
"instance"
:
routing
[
"instance"
],
"reply"
:
routing
[
"seq"
]
})
def
get_message
(
self
,
group
,
to
=
'*'
):
if
self
.
_socket
.
_closed
:
raise
SessionError
(
"Session has been closed."
)
que
=
Queue
()
for
q
in
self
.
message_queue
:
if
q
.
env
[
'group'
]
==
group
:
self
.
message_queue
.
remove
(
q
)
self
.
old_message_queue
.
append
(
q
)
que
=
q
if
self
.
verbose
:
sys
.
stdout
.
write
(
"[Session] get_message: "
+
str
(
que
.
dump
())
+
"
\n
"
)
return
q
.
msg
def
group_subscribe
(
self
,
group
,
instance
=
"*"
):
if
self
.
_socket
.
_closed
:
raise
SessionError
(
"Session has been closed."
)
def
group_unsubscribe
(
self
,
group
,
instance
=
"*"
):
if
self
.
_socket
.
_closed
:
raise
SessionError
(
"Session has been closed."
)
src/bin/stats/tests/isc/config/Makefile.am
deleted
100644 → 0
View file @
cc0d6e46
EXTRA_DIST
=
__init__.py ccsession.py
CLEANFILES
=
__init__.pyc ccsession.pyc
CLEANDIRS
=
__pycache__
clean-local
:
rm
-rf
$(CLEANDIRS)
src/bin/stats/tests/isc/config/__init__.py
deleted
100644 → 0
View file @
cc0d6e46
from
isc.config.ccsession
import
*
src/bin/stats/tests/isc/config/ccsession.py
deleted
100644 → 0
View file @
cc0d6e46
# Copyright (C) 2010,2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
A mock-up module of isc.cc.session
*** NOTE ***
It is only for testing stats_httpd module and not reusable for
external module.
"""
import
json
import
os
import
time
from
isc.cc.session
import
Session
COMMAND_CONFIG_UPDATE
=
"config_update"
def
parse_answer
(
msg
):
assert
'result'
in
msg
try
:
return
msg
[
'result'
][
0
],
msg
[
'result'
][
1
]
except
IndexError
:
return
msg
[
'result'
][
0
],
None
def
create_answer
(
rcode
,
arg
=
None
):
if
arg
is
None
:
return
{
'result'
:
[
rcode
]
}
else
:
return
{
'result'
:
[
rcode
,
arg
]
}
def
parse_command
(
msg
):
assert
'command'
in
msg
try
:
return
msg
[
'command'
][
0
],
msg
[
'command'
][
1
]
except
IndexError
:
return
msg
[
'command'
][
0
],
None
def
create_command
(
command_name
,
params
=
None
):
if
params
is
None
:
return
{
"command"
:
[
command_name
]}
else
:
return
{
"command"
:
[
command_name
,
params
]}
def
module_spec_from_file
(
spec_file
,
check
=
True
):
try
:
file
=
open
(
spec_file
)
json_str
=
file
.
read
()
module_spec
=
json
.
loads
(
json_str
)
file
.
close
()
return
ModuleSpec
(
module_spec
[
'module_spec'
],
check
)
except
IOError
as
ioe
:
raise
ModuleSpecError
(
"JSON read error: "
+
str
(
ioe
))
except
ValueError
as
ve
:
raise
ModuleSpecError
(
"JSON parse error: "
+
str
(
ve
))
except
KeyError
as
err
:
raise
ModuleSpecError
(
"Data definition has no module_spec element"
)
class
ModuleSpecError
(
Exception
):
pass
class
ModuleSpec
:
def
__init__
(
self
,
module_spec
,
check
=
True
):
# check only confi_data for testing
if
check
and
"config_data"
in
module_spec
:
_check_config_spec
(
module_spec
[
"config_data"
])
self
.
_module_spec
=
module_spec
def
get_config_spec
(
self
):
return
self
.
_module_spec
[
'config_data'
]
def
get_commands_spec
(
self
):
return
self
.
_module_spec
[
'commands'
]
def
get_module_name
(
self
):
return
self
.
_module_spec
[
'module_name'
]
def
_check_config_spec
(
config_data
):
# config data is a list of items represented by dicts that contain
# things like "item_name", depending on the type they can have
# specific subitems
"""Checks a list that contains the configuration part of the
specification. Raises a ModuleSpecError if there is a
problem."""
if
type
(
config_data
)
!=
list
:
raise
ModuleSpecError
(
"config_data is of type "
+
str
(
type
(
config_data
))
+
", not a list of items"
)
for
config_item
in
config_data
:
_check_item_spec
(
config_item
)
def
_check_item_spec
(
config_item
):
"""Checks the dict that defines one config item
(i.e. containing "item_name", "item_type", etc.
Raises a ModuleSpecError if there is an error"""
if
type
(
config_item
)
!=
dict
:
raise
ModuleSpecError
(
"item spec not a dict"
)
if
"item_name"
not
in
config_item
:
raise
ModuleSpecError
(
"no item_name in config item"
)
if
type
(
config_item
[
"item_name"
])
!=
str
:
raise
ModuleSpecError
(
"item_name is not a string: "
+
str
(
config_item
[
"item_name"
]))
item_name
=
config_item
[
"item_name"
]
if
"item_type"
not
in
config_item
:
raise
ModuleSpecError
(
"no item_type in config item"
)
item_type
=
config_item
[
"item_type"
]
if
type
(
item_type
)
!=
str
:
raise
ModuleSpecError
(
"item_type in "
+
item_name
+
" is not a string: "
+
str
(
type
(
item_type
)))
if
item_type
not
in
[
"integer"
,
"real"
,
"boolean"
,
"string"
,
"list"
,
"map"
,
"any"
]:
raise
ModuleSpecError
(
"unknown item_type in "
+
item_name
+
": "
+
item_type
)
if
"item_optional"
in
config_item
:
if
type
(
config_item
[
"item_optional"
])
!=
bool
:
raise
ModuleSpecError
(
"item_default in "
+
item_name
+
" is not a boolean"
)
if
not
config_item
[
"item_optional"
]
and
"item_default"
not
in
config_item
:
raise
ModuleSpecError
(
"no default value for non-optional item "
+
item_name
)
else
:
raise
ModuleSpecError
(
"item_optional not in item "
+
item_name
)
if
"item_default"
in
config_item
: