def configure(self, config): CompositeNode.configure(self, config) set_attribute(self, 'dev', REQUIRED, config) set_attribute(self, 'parity', parity_to_int('none'), config, parity_to_int) set_attribute(self, 'baud', 9600, config, str) if self.baud == 'Custom': self.baud = -1 # flag for later processing of custom_baud else: self.baud = int(self.baud) # normal path set_attributes(self, (('bits', 8), ('stop_bits', 1), ('debug', 0), ('dump_cpl', 16)), config, int) set_attribute(self, 'custom_baud', 76800, config, int) set_attribute(self, 'flow_control', flowctl_to_int('none'), config, flowctl_to_int) set_attribute(self, 'lock_directory', properties.get('VAR_LOCK'), config, str) set_attribute(self, 'VINTR', '\x03', config, str) set_attribute(self, 'VQUIT', '\x1c', config, str) set_attribute(self, 'VERASE', '\x7f', config, str) set_attribute(self, 'VKILL', '\x15', config, str) set_attribute(self, 'VEOF', '\x04', config, str) set_attribute(self, 'VTIME', 0, config, int) set_attribute(self, 'VMIN', 1, config, int) set_attribute(self, 'VSWTC', '\x00', config, str) set_attribute(self, 'VSTART', '\x11', config, str) set_attribute(self, 'VSTOP', '\x13', config, str) set_attribute(self, 'VSUSP', '\x1a', config, str) set_attribute(self, 'VEOL', '\x00', config, str) set_attribute(self, 'VREPRINT', '\x12', config, str) set_attribute(self, 'VDISCARD', '\x0f', config, str) set_attribute(self, 'VWERASE', '\x17', config, str) set_attribute(self, 'VLNEXT', '\x16', config, str) set_attribute(self, 'VEOL2', '\x00', config, str) set_attribute(self, 'cc17', '\x00', config, str) set_attribute(self, 'cc18', '/', config, str) set_attribute(self, 'cc19', '\x00', config, str) set_attribute(self, 'cc20', '\x00', config, str) set_attribute(self, 'cc21', '\x00', config, str) set_attribute(self, 'cc22', '\x00', config, str) set_attribute(self, 'cc23', '\x00', config, str) set_attribute(self, 'cc24', '\x00', config, str) set_attribute(self, 'cc25', '\x00', config, str) set_attribute(self, 'cc26', '\x00', config, str) set_attribute(self, 'cc27', '\x00', config, str) set_attribute(self, 'cc28', '\x00', config, str) set_attribute(self, 'cc29', '\x00', config, str) set_attribute(self, 'cc30', '\x00', config, str) set_attribute(self, 'cc31', '\x00', config, str) self._devlock = DeviceLock(self.dev, self.lock_directory) if self.is_open(): self._set_serial() return
def __init__( self, devPath, lock_directory = None ): if lock_directory: self.lock_directory = lock_directory else: self.lock_directory = properties.get( 'VAR_LOCK', '/var/lock' ) # Filename that conforms to the Filesystem Hierarchy Standard (FHS) 2.2 # (see http://www.pathname.com/fhs/2.2/). self._devName = os.path.split( devPath )[-1] LockFile.__init__( self, os.path.join( self.lock_directory, 'LCK..%s' % self._devName ) )
def configure(self,config): CompositeNode.configure(self,config) set_attribute(self, 'dev', REQUIRED, config) set_attribute(self, 'parity', parity_to_int('none'), config, parity_to_int) set_attribute(self, 'baud', 9600, config, str) if self.baud == 'Custom': self.baud = -1 # flag for later processing of custom_baud else: self.baud = int(self.baud) # normal path set_attributes(self, (('bits',8), ('stop_bits',1), ('debug',0), ('dump_cpl',16)), config, int) set_attribute(self, 'custom_baud', 76800, config, int) set_attribute(self, 'flow_control', flowctl_to_int('none'), config, flowctl_to_int) set_attribute(self, 'lock_directory', properties.get('VAR_LOCK'), config, str) set_attribute(self, 'VINTR', '\x03', config, str) set_attribute(self, 'VQUIT', '\x1c', config, str) set_attribute(self, 'VERASE', '\x7f', config, str) set_attribute(self, 'VKILL', '\x15', config, str) set_attribute(self, 'VEOF', '\x04', config, str) set_attribute(self, 'VTIME', 0, config, int) set_attribute(self, 'VMIN', 1, config, int) set_attribute(self, 'VSWTC', '\x00', config, str) set_attribute(self, 'VSTART', '\x11', config, str) set_attribute(self, 'VSTOP', '\x13', config, str) set_attribute(self, 'VSUSP', '\x1a', config, str) set_attribute(self, 'VEOL', '\x00', config, str) set_attribute(self, 'VREPRINT', '\x12', config, str) set_attribute(self, 'VDISCARD', '\x0f', config, str) set_attribute(self, 'VWERASE', '\x17', config, str) set_attribute(self, 'VLNEXT', '\x16', config, str) set_attribute(self, 'VEOL2', '\x00', config, str) set_attribute(self, 'cc17', '\x00', config, str) set_attribute(self, 'cc18', '/', config, str) set_attribute(self, 'cc19', '\x00', config, str) set_attribute(self, 'cc20', '\x00', config, str) set_attribute(self, 'cc21', '\x00', config, str) set_attribute(self, 'cc22', '\x00', config, str) set_attribute(self, 'cc23', '\x00', config, str) set_attribute(self, 'cc24', '\x00', config, str) set_attribute(self, 'cc25', '\x00', config, str) set_attribute(self, 'cc26', '\x00', config, str) set_attribute(self, 'cc27', '\x00', config, str) set_attribute(self, 'cc28', '\x00', config, str) set_attribute(self, 'cc29', '\x00', config, str) set_attribute(self, 'cc30', '\x00', config, str) set_attribute(self, 'cc31', '\x00', config, str) set_attribute(self, 'raw_mode', 0, config, as_boolean) self._devlock = DeviceLock(self.dev, self.lock_directory) if self.is_open(): self._set_serial()
def __init__(self, devPath, lock_directory=None): if lock_directory: self.lock_directory = lock_directory else: self.lock_directory = properties.get('VAR_LOCK', '/var/lock') # Filename that conforms to the Filesystem Hierarchy Standard (FHS) 2.2 # (see http://www.pathname.com/fhs/2.2/). self._devName = os.path.split(devPath)[-1] LockFile.__init__( self, os.path.join(self.lock_directory, 'LCK..%s' % self._devName))
def configure(self, config): CompositeNode.configure(self, config) set_attribute(self, "dev", REQUIRED, config) set_attribute(self, "parity", parity_to_int("none"), config, parity_to_int) set_attribute(self, "baud", 9600, config, str) if self.baud == "Custom": self.baud = -1 # flag for later processing of custom_baud else: self.baud = int(self.baud) # normal path set_attributes(self, (("bits", 8), ("stop_bits", 1), ("debug", 0), ("dump_cpl", 16)), config, int) set_attribute(self, "custom_baud", 76800, config, int) set_attribute(self, "flow_control", flowctl_to_int("none"), config, flowctl_to_int) set_attribute(self, "lock_directory", properties.get("VAR_LOCK"), config, str) set_attribute(self, "VINTR", "\x03", config, str) set_attribute(self, "VQUIT", "\x1c", config, str) set_attribute(self, "VERASE", "\x7f", config, str) set_attribute(self, "VKILL", "\x15", config, str) set_attribute(self, "VEOF", "\x04", config, str) set_attribute(self, "VTIME", 0, config, int) set_attribute(self, "VMIN", 1, config, int) set_attribute(self, "VSWTC", "\x00", config, str) set_attribute(self, "VSTART", "\x11", config, str) set_attribute(self, "VSTOP", "\x13", config, str) set_attribute(self, "VSUSP", "\x1a", config, str) set_attribute(self, "VEOL", "\x00", config, str) set_attribute(self, "VREPRINT", "\x12", config, str) set_attribute(self, "VDISCARD", "\x0f", config, str) set_attribute(self, "VWERASE", "\x17", config, str) set_attribute(self, "VLNEXT", "\x16", config, str) set_attribute(self, "VEOL2", "\x00", config, str) set_attribute(self, "cc17", "\x00", config, str) set_attribute(self, "cc18", "/", config, str) set_attribute(self, "cc19", "\x00", config, str) set_attribute(self, "cc20", "\x00", config, str) set_attribute(self, "cc21", "\x00", config, str) set_attribute(self, "cc22", "\x00", config, str) set_attribute(self, "cc23", "\x00", config, str) set_attribute(self, "cc24", "\x00", config, str) set_attribute(self, "cc25", "\x00", config, str) set_attribute(self, "cc26", "\x00", config, str) set_attribute(self, "cc27", "\x00", config, str) set_attribute(self, "cc28", "\x00", config, str) set_attribute(self, "cc29", "\x00", config, str) set_attribute(self, "cc30", "\x00", config, str) set_attribute(self, "cc31", "\x00", config, str) self._devlock = DeviceLock(self.dev, self.lock_directory) if self.is_open(): self._set_serial() return
def configure(self,config): set_attribute(self, 'mac_address', self.mac_address, config) #mac address of client self.mac_address = aero.MacAddress(self.mac_address) self.dev = self.mac_address.value Port.configure(self,config) set_attribute(self, 'parity', parity_to_int('none'), config, parity_to_int) set_attribute(self, 'baud', 9600, config, str) if self.baud == 'Custom': self.baud = -1 # flag for later processing of custom_baud else: self.baud = int(self.baud) # normal path set_attributes(self, (('bits',8), ('stop_bits',1), ('dump_cpl',16)), config, int) set_attribute(self, 'custom_baud', 76800, config, int) set_attribute(self, 'flow_control', flowctl_to_int('none'), config, flowctl_to_int) set_attribute(self, 'lock_directory', properties.get('VAR_LOCK'), config, str) set_attribute(self, 'debug', self.parent.debug, config, int)
def handle_request(self, request): if not request.user_object().is_admin(): request.error(401, 'Unauthorized Access') return command = request.get_command() if self.debug: msg = ('got command:<%s>' % command) msglog.log(self.name, msglog.types.DB, msg) if command not in ('GET', 'PUT', 'HEAD'): request.error(400) # bad request return # This stuff is ignored for now, but may be useful in the future for accessing # nodedefs and MD5 checksums. (path, params, query, fragment) = request.split_uri() if '%' in path: path = unquote(path) while path and path[0] == '/': path = path[1:] path = properties.get('CONFIGURATION_FILE') if command == 'PUT': user = request.user_object() groups = os.getgroups() is_root = not os.getuid() uid = os.geteuid() gid = os.getegid() if not is_root: msg = ('Framework is not running as root so effective uid ' 'and gid are not being changed prior to doing %s: ' '%s' % (request.get_command(), path)) msglog.log(self.name, msglog.types.WARN, msg) else: if self.debug: msg = ('%s command: file %s, user %s' % (request.get_command(), path, user.name())) msglog.log(self.name, msglog.types.DB, msg) os.setgroups(user.group_ids()) os.setegid(user.gid()) os.seteuid(user.uid()) try: self._process_put(path, request) return finally: if is_root: os.seteuid(uid) os.setegid(gid) os.setgroups(groups) # Must be GET or HEAD command file_length = os.stat(path)[stat.ST_SIZE] last_modified = os.stat(path)[stat.ST_MTIME] ims_header = request.get_header_match(_IF_MODIFIED_SINCE) if ims_header: length = file_length if ims_header.group(4): try: length = string.atoi(ims_header.group(4)) except: pass ims_time = parse_http_date(ims_header.group(1)) if (length == file_length) and (last_modified <= ims_time): request.reply(304) return try: file = open(path, 'rb') except IOError, ioe: msglog.log(self.name, msglog.types.DB, ioe.strerror) request.error(404) return
import os import socket import select from select import poll as _poll from select import POLLIN as _POLLIN from moab.lib import uptime from mpx import properties from mpx.lib import msglog from mpx.lib.thread import allocate_lock from mpx.lib.threading import Lock from mpx.lib.threading import gettid _tmp_dir = properties.get('TEMP_DIR') ## # Used to truncate the argument passed to select.poll.poll(ms) to # avoid overflows. # @fixme Probably should detect on a per-platform bases. _MAX_MS = 0x7FFFFFFF class Condition: def __init__(self): self._lock = Lock() self._locks = [] socket_name = os.path.join(_tmp_dir, 'Scheduler.%d' % gettid()) while os.path.exists(socket_name): try: os.remove(socket_name) except: socket_name += 'x'
class TestCase(DefaultTestFixture): TEMP_DIR = properties.get('TEMP_DIR') FILE_COUNT = 0 def temp_file_name(self): TestCase.FILE_COUNT += 1 return os.path.join( self.TEMP_DIR, '_test_case_xml_formatter.%d.%d' % (os.getpid(), self.FILE_COUNT)) def setUp(self): DefaultTestFixture.setUp(self) self.data = [] ts = float(15 * int(time.time() / 15)) for x in range(1, 20): entry = {} entry['timestamp'] = ts entry['column-A'] = x self.data.append(entry) ts += 15 return def new_column_a_log(self): self.new_node_tree() logger = BogusLogger() logger.configure({ 'name': 'logger', 'parent': as_internal_node('/services') }) log = BogusLog() log.configure({'name': 'bogus_log', 'parent': logger}) columns = BogusColumns() columns.configure({'name': 'columns', 'parent': log}) timestamp_column = BogusColumn() timestamp_column.configure({'name': 'timstamp', 'parent': columns}) column_a = BogusColumn() column_a.configure({'name': 'column-A', 'parent': columns}) column_a_decorator = MeterMailColumnDecorator() column_a_decorator.configure({ 'name': 'metermail_column_decorator', 'parent': column_a, 'mmafmt_channel_id': 'column-A', 'mmafmt_channel_label': 'kW a', }) exporters = BogusExporters() exporters.configure({'name': 'exporters', 'parent': log}) periodic_exporter = BogusPeriodicExporter() periodic_exporter.configure({ 'name': 'periodic_exporter', 'parent': exporters }) formatter = MeterMailFormatter() formatter.configure({ 'name': 'metermail_formatter', 'parent': periodic_exporter, 'device_name': 'device_name', 'data_recorder_id': 'data_recorder_id', 'data_recorder_label': 'data_recorder_label', }) return def test_valid_xml(self): self.new_column_a_log() tmp_file = None tmp_file = self.temp_file_name() f = open(tmp_file, 'w') as_internal_node('/').start() stream = as_internal_node( '/services/logger/bogus_log/exporters/periodic_exporter/' 'metermail_formatter').format(self.data) output = '' data = stream.read(1024) while data: output += data data = stream.read(1024) f.write(output) f.close() command = 'xmllint ' + str(tmp_file) stdin, stdout, stderr = os.popen3(command) out = stdout.readlines() err = stderr.readlines() if err: error = '' for e in err: error += e + '\n' pass self.fail('File is not a valid XML file:\n' + error) return def test_timestamp_exception(self): self.new_column_a_log() as_internal_node('/').start() formatter = as_internal_node( '/services/logger/bogus_log/exporters/periodic_exporter/' 'metermail_formatter') data = [] for x in range(1, 10): entry = {} entry['column-A'] = x data.append(entry) try: xml = formatter.format(data) while xml.read(100): pass self.fail( 'If no timestamp field it should throw an EIncompatiableFormat' ) except EIncompatiableFormat: pass
class SocketTrigger(asyncore.dispatcher): TMPDIR = properties.get('TEMP_DIR') def __init__(self, socketmap): asyncore.dispatcher.__init__(self, None, socketmap) self._connecting = False self._setup_socketname() self._setup_listener_socket() try: self._setup_input_socket() self._setup_output_socket() finally: self._cleanup_setup() def readable(self): return 1 def writable(self): return 0 def handle_read(self): try: self.socket.recv(8192) except socket.error: return def trigger_event(self): self._output_socket.send('X') def set_debugmode(self): assert self.writable is not self._debug_writable self._writable = self.writable self._readable = self.readable self._handle_read = self.handle_read self._trigger_event = self.trigger_event self.writable = self._debug_writable self.readable = self._debug_readable self.handle_read = self._debug_handle_read self.trigger_event = self._debug_trigger_event def clear_debugmode(self): assert self.writable is self._debug_writable self.writable = self._writable self.readable = self._readable self.handle_read = self._handle_read self.trigger_event = self._trigger_event def _setup_socketname(self): socket_name = os.path.join(TMPDIR, 'SocketTrigger.%d' % gettid()) while os.path.exists(socket_name): try: os.remove(socket_name) except: socket_name += 'x' self._socket_name = socket_name def _setup_listener_socket(self): listener = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listener.bind(self._socket_name) listener.listen(1) self._listener_socket = listener def _setup_input_socket(self): self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM) self._connecting = True self.connect(self._socket_name) def _setup_output_socket(self): assert self._connecting output, addr = self._listener_socket.accept() output.setblocking(0) self._connecting = False self._output_socket = output def _cleanup_setup(self): self._listener_socket.close() self._listener_socket = None os.remove(self._socket_name) def _debug_writable(self): writable = self._writable() print 'EventChannel.writable() -> %d' % writable return writable def _debug_readable(self): readable = self._readable() print 'EventChannel.readable() -> %d' % readable return readable def _debug_handle_read(self): print 'EventChannel.handle_read()' return self._handle_read() def _debug_trigger_event(self): print 'EventChannel.trigger_event()' return self._trigger_event()
from cStringIO import StringIO from asynchat import async_chat as AsyncChat from errno import EWOULDBLOCK from urllib import unquote from mpx import properties from mpx.lib import msglog, socket from mpx.lib.threading import Lock from mpx.lib.threading import Event from mpx.service.network.http.responders import Responder from mpx.service.network.utilities.counting import Counter from mpx.service.network. async .connection.trigger import Trigger from _request import Request from _request import crack_request VERSION_STRING = properties.RELEASE _tmp_dir = properties.get('TEMP_DIR') # Map of all sockets used by Redusa (so other threads can use asyncore to). REDUSA_SOCKET_MAP = {} class Channel(AsyncChat, object): request_manager = Request.singleton.request_manager ac_out_buffer_size = 1 << 16 current_request = None channel_counter = Counter() linger = struct.pack("ii", 0, 0) def __init__(self, server, conn, addr): self.channel_number = Channel.channel_counter.increment() self.addr = addr
import asyncore import os import socket import weakref from errno import EWOULDBLOCK from mpx import properties from mpx.lib.exceptions import EInternalError from mpx.lib.exceptions import EUnreachableCode from mpx.lib.threading import Lock from mpx.lib.threading import gettid TMP_DIR = properties.get('TEMP_DIR') ## # @note SocketMapNotifier assumes all access is semaphored. It does not # provide it's own locking because that could lead to deadlocks. All # access should be indirect, via the SocketMap. class SocketMapNotifier(asyncore.dispatcher, object): usednames = weakref.WeakValueDictionary() classlock = Lock() def __unused_socket_name(self, suffix): while True: socket_name = os.path.join( TMP_DIR, 'SocketMapNotifier-%d.%04d' % (gettid(), suffix) ) if not self.usednames.has_key(socket_name): return socket_name, suffix
from mpx import properties from moab.user.manager import PasswdFile, PasswdEntry, GroupFile, GroupEntry from moab.user.identity import crypted_password as _crypted_password from moab.user.identity import csiked_password as _csiked_password from moab.linux.templates import motd from moab.linux.lib.servicemgr import InittabManager, InittabGroup # @fixme mpxconfig uses tools.lib, which should probably be cloned somewhere. ROOT = properties.ROOT # @fixme MPX_PYTHON_LIB + MOAB + SITE-PACKAGES == 'headache' MPX_PYTHON_LIB = os.path.realpath(properties.MPX_PYTHON_LIB) VAR_RUN = os.path.realpath(properties.get('VAR_RUN', '/var/run')) # VAR_RUN_BROADWAY is not really a property. It is always relative to VAR_RUN. VAR_RUN_BROADWAY = os.path.join(VAR_RUN, 'broadway') TARGET_ROOT = properties.TARGET_ROOT HOME_ROOT = properties.HOME_ROOT SBIN_DIR = properties.SBIN_DIR LIB_DIR = properties.LIB_DIR BIN_DIR = properties.BIN_DIR ETC_DIR = properties.ETC_DIR ETCDHCPC_DIR = os.path.join(properties.ETC_DIR, 'dhcpc') MPX_UID = properties.MPX_UID MPX_GID = properties.MPX_GID MPXCONFIG_SCRIPT = os.path.join(BIN_DIR, 'mpxconfig')
import asyncore import os import socket import weakref from errno import EWOULDBLOCK from mpx import properties from mpx.lib.exceptions import EInternalError from mpx.lib.exceptions import EUnreachableCode from mpx.lib.threading import Lock from mpx.lib.threading import gettid TMP_DIR = properties.get('TEMP_DIR') ## # @note SocketMapNotifier assumes all access is semaphored. It does not # provide it's own locking because that could lead to deadlocks. All # access should be indirect, via the SocketMap. class SocketMapNotifier(asyncore.dispatcher, object): usednames = weakref.WeakValueDictionary() classlock = Lock() def __unused_socket_name(self, suffix): while True: socket_name = os.path.join( TMP_DIR, 'SocketMapNotifier-%d.%04d' % (gettid(), suffix)) if not self.usednames.has_key(socket_name):
from mpx import properties from moab.user.manager import PasswdFile, PasswdEntry, GroupFile, GroupEntry from moab.user.identity import crypted_password as _crypted_password from moab.user.identity import csiked_password as _csiked_password from moab.linux.templates import motd from moab.linux.lib.servicemgr import InittabManager, InittabGroup # @fixme mpxconfig uses tools.lib, which should probably be cloned somewhere. ROOT = properties.ROOT # @fixme MPX_PYTHON_LIB + MOAB + SITE-PACKAGES == 'headache' MPX_PYTHON_LIB = os.path.realpath(properties.MPX_PYTHON_LIB) VAR_RUN = os.path.realpath(properties.get("VAR_RUN", "/var/run")) # VAR_RUN_BROADWAY is not really a property. It is always relative to VAR_RUN. VAR_RUN_BROADWAY = os.path.join(VAR_RUN, "broadway") TARGET_ROOT = properties.TARGET_ROOT HOME_ROOT = properties.HOME_ROOT SBIN_DIR = properties.SBIN_DIR LIB_DIR = properties.LIB_DIR BIN_DIR = properties.BIN_DIR ETC_DIR = properties.ETC_DIR ETCDHCPC_DIR = os.path.join(properties.ETC_DIR, "dhcpc") MPX_UID = properties.MPX_UID MPX_GID = properties.MPX_GID MPXCONFIG_SCRIPT = os.path.join(BIN_DIR, "mpxconfig")
def handle_request(self, request): if not request.user_object().is_admin(): request.error(401, "Unauthorized Access") return command = request.get_command() if self.debug: msg = "got command:<%s>" % command msglog.log(self.name, msglog.types.DB, msg) if command not in ("GET", "PUT", "HEAD"): request.error(400) # bad request return # This stuff is ignored for now, but may be useful in the future for accessing # nodedefs and MD5 checksums. (path, params, query, fragment) = request.split_uri() if "%" in path: path = unquote(path) while path and path[0] == "/": path = path[1:] path = properties.get("CONFIGURATION_FILE") if command == "PUT": user = request.user_object() groups = os.getgroups() is_root = not os.getuid() uid = os.geteuid() gid = os.getegid() if not is_root: msg = ( "Framework is not running as root so effective uid " "and gid are not being changed prior to doing %s: " "%s" % (request.get_command(), path) ) msglog.log(self.name, msglog.types.WARN, msg) else: if self.debug: msg = "%s command: file %s, user %s" % (request.get_command(), path, user.name()) msglog.log(self.name, msglog.types.DB, msg) os.setgroups(user.group_ids()) os.setegid(user.gid()) os.seteuid(user.uid()) try: self._process_put(path, request) return finally: if is_root: os.seteuid(uid) os.setegid(gid) os.setgroups(groups) # Must be GET or HEAD command file_length = os.stat(path)[stat.ST_SIZE] last_modified = os.stat(path)[stat.ST_MTIME] ims_header = request.get_header_match(_IF_MODIFIED_SINCE) if ims_header: length = file_length if ims_header.group(4): try: length = string.atoi(ims_header.group(4)) except: pass ims_time = parse_http_date(ims_header.group(1)) if (length == file_length) and (last_modified <= ims_time): request.reply(304) return try: file = open(path, "rb") except IOError, ioe: msglog.log(self.name, msglog.types.DB, ioe.strerror) request.error(404) return
class TestCase(DefaultTestFixture): TEMP_DIR = properties.get('TEMP_DIR') FILE_COUNT = 0 def temp_file_name(self): TestCase.FILE_COUNT += 1 return os.path.join(self.TEMP_DIR, '_test_case_xml_formatter.%d.%d' % \ (os.getpid(), self.FILE_COUNT)) def setUp(self): DefaultTestFixture.setUp(self) self.data = [] for x in range(1, 20): entry = {} entry['timestamp'] = time.time() entry['column-A'] = x self.data.append(entry) return def test_Valid_1(self): tmp_file = None tmp_file = self.temp_file_name() f = open(tmp_file, 'w') formatter = XMLFormatter() formatter.configure({'name': 'xmlformatter', 'parent': _Parent()}) stream = formatter.format(self.data) output = '' data = stream.read(1024) while data: output += data data = stream.read(1024) f.write(output) f.close() command = 'xmllint ' + str(tmp_file) stdin, stdout, stderr = os.popen3(command) out = stdout.readlines() err = stderr.readlines() if err: error = '' for e in err: error += e + '\n' pass self.fail('File is not a valid XML file:\n' + error) return def get_dtd(self): dtd = '<?xml version="1.0" encoding="UTF-8"?> ' dtd += '<!ELEMENT data (entry*)> ' dtd += '<!ATTLIST data ' dtd += 'info CDATA #IMPLIED >' dtd += '<!ELEMENT entry (value*)> ' dtd += '<!ATTLIST entry ' dtd += 'timestamp CDATA #REQUIRED> ' dtd += '<!ELEMENT value (#PCDATA)> ' dtd += '<!ATTLIST value ' dtd += 'name CDATA #REQUIRED>' return dtd def test_DTD_1(self): try: tmp_file = None tmp_file = self.temp_file_name() tmp_file2 = self.temp_file_name() f2 = open(tmp_file2, 'w') f2.write(self.get_dtd()) f2.close() f = open(tmp_file, 'w') formatter = XMLFormatter() formatter.configure({'name': 'xmlformatter', 'parent': _Parent()}) stream = formatter.format(self.data) output = '' data = stream.read(1024) while data: output += data data = stream.read(1024) f.write(output) f.close() command = 'xmllint -dtdvalid ' + str(tmp_file2) + ' ' + str( tmp_file) stdin, stdout, stderr = os.popen3(command) out = stdout.readlines() err = stderr.readlines() if err: error = '' for e in err: error += e + '\n' self.fail('File does not conform to the DTD:\n' + error) finally: if tmp_file: try: os.unlink(tmp_file) except: pass if tmp_file2: try: os.unlink(tmp_file2) except: pass def test_timestamp_exception(self): formatter = XMLFormatter() formatter.configure({'name': 'xmlformatter', 'parent': _Parent()}) data = [] for x in range(1, 10): entry = {} entry['column-A'] = x data.append(entry) try: xml = formatter.format(data) while xml.read(100): pass self.fail( 'If no timestamp field it should throw an EIncompatiableFormat' ) except EIncompatiableFormat: pass