Commit 8023760a authored by Naoki Kambe's avatar Naoki Kambe
Browse files

[trac930] remove unneeded mockups, fake modules and dummy data

parent cc0d6e46
......@@ -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
......
# 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)
# 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))
# 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
EXTRA_DIST = __init__.py server.py
CLEANFILES = __init__.pyc server.pyc
CLEANDIRS = __pycache__
clean-local:
rm -rf $(CLEANDIRS)
# 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()
SUBDIRS = cc config util log log_messages
EXTRA_DIST = __init__.py
CLEANFILES = __init__.pyc
CLEANDIRS = __pycache__
clean-local:
rm -rf $(CLEANDIRS)
EXTRA_DIST = __init__.py session.py
CLEANFILES = __init__.pyc session.pyc
CLEANDIRS = __pycache__
clean-local:
rm -rf $(CLEANDIRS)
# 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.")
EXTRA_DIST = __init__.py ccsession.py
CLEANFILES = __init__.pyc ccsession.pyc
CLEANDIRS = __pycache__
clean-local:
rm -rf $(CLEANDIRS)
# 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: