seems nearly all the message template building code is tested and covered (would be 100% if the testrunner didn't include import statements and class method definitions)
This commit is contained in:
committed by
Salad Dais
parent
03f309b012
commit
6857444a27
@@ -77,8 +77,8 @@ class MsgBlockData(object):
|
||||
def add_variable(self, var):
|
||||
self.variable_map[var.name] = var
|
||||
|
||||
def add_data(self, var_name, data, data_size):
|
||||
self.get_variable(var_name).add_data(data, data_size)
|
||||
def add_data(self, var_name, data, size):
|
||||
self.get_variable(var_name).add_data(data, size)
|
||||
|
||||
class MsgVariableData(object):
|
||||
""" Used as a Message Block variable that is being created that will be
|
||||
@@ -87,15 +87,14 @@ class MsgVariableData(object):
|
||||
self.name = name
|
||||
#data_size holds info whether or not the variable is of type
|
||||
#MVT_VARIABLE
|
||||
self.data_size = 0
|
||||
self.size = -1
|
||||
self.type = tp
|
||||
self.data = None
|
||||
|
||||
#how DO we add data? What format will it be in?
|
||||
def add_data(self, data, data_size):
|
||||
def add_data(self, data, size):
|
||||
self.data = data
|
||||
self.size = data_size
|
||||
self.size = size
|
||||
|
||||
class MessageTemplateVariable(object):
|
||||
def __init__(self, name, tp, size):
|
||||
@@ -105,6 +104,7 @@ class MessageTemplateVariable(object):
|
||||
|
||||
class MessageTemplateBlock(object):
|
||||
def __init__(self, name):
|
||||
self.variables = []
|
||||
self.variable_map = {}
|
||||
self.name = name
|
||||
self.block_type = None
|
||||
@@ -112,15 +112,17 @@ class MessageTemplateBlock(object):
|
||||
|
||||
def add_variable(self, var):
|
||||
self.variable_map[var.name] = var
|
||||
self.variables.append(var)
|
||||
|
||||
def get_variables(self):
|
||||
return self.variable_map.values()
|
||||
return self.variables #self.variable_map.values()
|
||||
|
||||
def get_variable(self, name):
|
||||
return self.variable_map[name]
|
||||
|
||||
class MessageTemplate(object):
|
||||
def __init__(self, name):
|
||||
self.blocks = []
|
||||
self.block_map = {}
|
||||
#this is the function or object that will handle this type of message
|
||||
self.handler = None
|
||||
@@ -138,9 +140,10 @@ class MessageTemplate(object):
|
||||
|
||||
def add_block(self, block):
|
||||
self.block_map[block.name] = block
|
||||
self.blocks.append(block)
|
||||
|
||||
def get_blocks(self):
|
||||
return self.block_map.values()
|
||||
return self.blocks #self.block_map.values()
|
||||
|
||||
def get_block(self, name):
|
||||
return self.block_map[name]
|
||||
|
||||
@@ -24,12 +24,6 @@ class MessageTemplateBuilder(object):
|
||||
self.cur_block_name = ''
|
||||
|
||||
self.packer = DataPacker()
|
||||
|
||||
def get_current_message(self):
|
||||
return self.current_msg
|
||||
|
||||
def get_current_block(self):
|
||||
return self.current_block
|
||||
|
||||
def build_message(self):
|
||||
""" Builds the message by serializing the data. Creates a packet ready
|
||||
@@ -90,18 +84,19 @@ class MessageTemplateBuilder(object):
|
||||
bytes += 1
|
||||
|
||||
for block in block_list:
|
||||
for variable in message_block.get_variables():
|
||||
for v in template_block.get_variables(): #message_block.get_variables():
|
||||
#this mapping has to occur to make sure the data is written in correct order
|
||||
variable = message_block.get_variable(v.name)
|
||||
var_size = variable.size
|
||||
|
||||
|
||||
if var_size == -1:
|
||||
raise Exception('Variable ' + variable.name + ' in block ' + \
|
||||
message_block.name + ' of message ' + message_data.name + \
|
||||
' wasn"t set prior to buildMessage call')
|
||||
|
||||
data_size = variable.data_size
|
||||
#variable's data_size represents whether or not it is of the type
|
||||
#MVT_VARIABLE. If it is positive, it is
|
||||
if data_size > 0:
|
||||
#if its a VARIABLE type, we have to write in the size of the data
|
||||
if variable.type == MsgType.MVT_VARIABLE:
|
||||
data_size = template_block.get_variable(variable.name).size
|
||||
if data_size == 1:
|
||||
block_buffer += struct.pack('>B', var_size)
|
||||
elif data_size == 2:
|
||||
@@ -136,11 +131,8 @@ class MessageTemplateBuilder(object):
|
||||
self.current_msg.add_block(block_data)
|
||||
|
||||
def next_block(self, block_name):
|
||||
#if it doesn't exist, create a new block (may be a VARIABLE or MULTIPLE type
|
||||
#block
|
||||
if block_name not in self.current_template.block_map:
|
||||
#error:
|
||||
print 'ERROR: template doesn"t have the block'
|
||||
return
|
||||
|
||||
template_block = self.current_template.get_block(block_name)
|
||||
@@ -159,40 +151,64 @@ class MessageTemplateBuilder(object):
|
||||
return
|
||||
|
||||
#although we may have a block already, there are some cases where we can have
|
||||
#more than one block of the same name (when type is MULTIPLE or VARIABLE)
|
||||
#more than one block of the same name (when type is MULTIPLE or VARIABLE), so we
|
||||
#might have to create a whole new block
|
||||
else:
|
||||
#make sure it isn't SINGLE
|
||||
if self.template_block.type == MsgBlockType.MBT_SINGLE:
|
||||
#error: can't have more than 1 block when its supposed to be 1
|
||||
print 'ERROR: can"t have more than 1 block when its supposed to be 1'
|
||||
return
|
||||
#make sure it isn't SINGLE and trying to create a new block
|
||||
if template_block.type == MsgBlockType.MBT_SINGLE:
|
||||
raise Exception('ERROR: can"t have more than 1 block when its supposed to be 1')
|
||||
|
||||
elif self.template_block.type == MsgBlockType.MBT_MULTIPLE and \
|
||||
self.template_block.block_number == block_data.block_number:
|
||||
#error: we are about to exceed block total
|
||||
print 'ERROR: we are about to exceed block total'
|
||||
return
|
||||
elif template_block.type == MsgBlockType.MBT_MULTIPLE and \
|
||||
template_block.block_number == block_data.block_number:
|
||||
raise Exception('ERROR: we are about to exceed block total')
|
||||
|
||||
block_data.block_number += 1
|
||||
self.current_block = MsgBlockData(block.name)
|
||||
self.current_block = MsgBlockData(block_name)
|
||||
self.current_msg.add_block(self.current_block)
|
||||
self.cur_block_name = block_name
|
||||
|
||||
for variable in self.current_block.variables:
|
||||
for variable in template_block.get_variables():
|
||||
var_data = MsgVariableData(variable.name, variable.type)
|
||||
self.current_block.add_variable(var_data)
|
||||
|
||||
def add_data(self, var_name, data, data_type):
|
||||
""" the data type is passed in to make sure that the programmer is aware of
|
||||
what type (and therefore size) of the data that is being passed in. """
|
||||
self.__check_size(var_name, data, data_type)
|
||||
self.current_block.add_data(var_name, data, data_type)
|
||||
if self.current_template == None:
|
||||
raise Exception('Attempting to add data to a null message')
|
||||
|
||||
def __check_size(self, var_name, data, data_type):
|
||||
if self.current_block == None:
|
||||
raise Exception('Attempting to add data to a null block')
|
||||
|
||||
template_variable = self.current_template.get_block(self.cur_block_name).get_variable(var_name)
|
||||
if template_variable == None:
|
||||
raise Exception('Variable is not in the block')
|
||||
|
||||
#this should be the size of the actual data
|
||||
size = sizeof(data_type)
|
||||
|
||||
if data_type == MsgType.MVT_VARIABLE:
|
||||
#if its a MVT_VARIABLE type of data, then size will be -1 for the type
|
||||
#so the actual size we will have to get from the data itself
|
||||
#HACK - this may cause a bug if the data type doesn't have len
|
||||
size = len(data)
|
||||
#template holds the max size the data can be
|
||||
data_size = template_variable.size
|
||||
#error check - size can't be larger than the bytes will hold
|
||||
|
||||
self.current_block.add_data(var_name, data, size)
|
||||
|
||||
else:
|
||||
#size check can't be done on VARIABLE sized variables
|
||||
if self.__check_size(var_name, data, size) == False:
|
||||
raise Exception('Variable size isn"t the same as the template size')
|
||||
|
||||
self.current_block.add_data(var_name, data, size)
|
||||
|
||||
def __check_size(self, var_name, data, data_size):
|
||||
block = self.template_list[self.cur_msg_name].get_block(self.cur_block_name)
|
||||
data_size = sizeof(data_type)
|
||||
size = block.get_variable(var_name).size
|
||||
if size != data_size:
|
||||
#warning
|
||||
#for now, exception
|
||||
raise Exception('Variable size isn"t the same as the template size')
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#standard libraries
|
||||
import unittest, doctest
|
||||
from uuid import UUID
|
||||
|
||||
#local libraries
|
||||
from pyogp.lib.base.data import msg_tmpl
|
||||
@@ -8,7 +9,7 @@ from pyogp.lib.base.message_template_parser import MessageTemplateParser
|
||||
from pyogp.lib.base.message_template_builder import MessageTemplateBuilder
|
||||
from pyogp.lib.base.message_template_dict import TemplateDictionary
|
||||
from pyogp.lib.base.message_types import MsgType
|
||||
from indra.base.lluuid import UUID
|
||||
#from indra.base.lluuid import UUID
|
||||
|
||||
class TestTemplateBuilder(unittest.TestCase):
|
||||
|
||||
@@ -36,18 +37,18 @@ class TestTemplateBuilder(unittest.TestCase):
|
||||
except:
|
||||
assert True
|
||||
|
||||
assert builder.get_current_message() == None, "Created a message despite its non-existence"
|
||||
assert builder.current_msg == None, "Created a message despite its non-existence"
|
||||
|
||||
def test_create_message(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
assert builder.get_current_message() == None, "Message exists before it was created"
|
||||
assert builder.current_msg == None, "Message exists before it was created"
|
||||
builder.new_message('AddCircuitCode')
|
||||
assert builder.get_current_message() != None, "Create message failed"
|
||||
assert builder.current_msg != None, "Create message failed"
|
||||
|
||||
def test_create_message_blocks(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('AvatarTextureUpdate')
|
||||
blocks = builder.get_current_message().block_map
|
||||
blocks = builder.current_msg.block_map
|
||||
assert len(blocks) == 3, "Blocks not added to the message"
|
||||
try:
|
||||
t_block = blocks['AgentData']
|
||||
@@ -70,10 +71,10 @@ class TestTemplateBuilder(unittest.TestCase):
|
||||
def test_next_block(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('AvatarTextureUpdate')
|
||||
assert builder.get_current_block() == None, "Message block exists before it was created"
|
||||
assert builder.current_block == None, "Message block exists before it was created"
|
||||
builder.next_block('AgentData')
|
||||
assert builder.get_current_block() != None, "Setting next block failed"
|
||||
assert builder.get_current_block().name == 'AgentData', "Wrong block set"
|
||||
assert builder.current_block != None, "Setting next block failed"
|
||||
assert builder.current_block.name == 'AgentData', "Wrong block set"
|
||||
|
||||
def test_next_block_fail(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
@@ -84,13 +85,88 @@ class TestTemplateBuilder(unittest.TestCase):
|
||||
assert False, "Using block AgentSocialIdeas that doesn't exist"
|
||||
except:
|
||||
assert True
|
||||
assert builder.get_current_block() == None, "Set block without one existing"
|
||||
assert builder.current_block == None, "Set block without one existing"
|
||||
|
||||
def test_next_single(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('TestMessage')
|
||||
builder.next_block('TestBlock1')
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
try:
|
||||
builder.next_block('TestBlock1')
|
||||
assert False, "Adding 2 blocks of the same type to a MBT_SINGLE block"
|
||||
except:
|
||||
assert True
|
||||
|
||||
def test_nextmultiple_exceed(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('TestMessage')
|
||||
builder.next_block('TestBlock1')
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
try:
|
||||
builder.next_block('NeighborBlock')
|
||||
assert False, "Allowed to add more than specified number of blocks"
|
||||
except:
|
||||
assert True
|
||||
|
||||
def test_build_variable(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('PacketAck')
|
||||
builder.next_block('Packets')
|
||||
builder.add_data('ID', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('Packets')
|
||||
builder.add_data('ID', 0x00000001, MsgType.MVT_U32)
|
||||
msg, size = builder.build_message()
|
||||
assert msg == '\xff\xff\xff\xfb' + '\x02' + \
|
||||
'\x00\x00\x00\x01\x00\x00\x00\x01', \
|
||||
"Building variable block failed"
|
||||
|
||||
def test_build_empty_var(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('PacketAck')
|
||||
builder.next_block('Packets')
|
||||
try:
|
||||
msg, size = builder.build_message()
|
||||
assert False, "Building with a variable that wasn't set"
|
||||
except:
|
||||
assert True
|
||||
|
||||
def test_build_variable_var(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('UpdateSimulator')
|
||||
builder.next_block('SimulatorInfo')
|
||||
builder.add_data('RegionID', UUID("550e8400-e29b-41d4-a716-446655440000"), MsgType.MVT_LLUUID)
|
||||
builder.add_data('SimName', "Testing", MsgType.MVT_VARIABLE)
|
||||
builder.add_data('EstateID', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('SimAccess', 0x01, MsgType.MVT_U8)
|
||||
msg, size = builder.build_message()
|
||||
|
||||
assert_string = '\xff\xff\x00\x11' + UUID("550e8400-e29b-41d4-a716-446655440000").bytes + \
|
||||
'\x07' + 'Testing' + '\x00\x00\x00\x01' + '\x01'
|
||||
assert msg == assert_string, "Building variable block failed"
|
||||
|
||||
|
||||
def test_next_block_variables(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('AvatarTextureUpdate')
|
||||
builder.next_block('AgentData')
|
||||
variables = builder.get_current_block().variable_map
|
||||
variables = builder.current_block.variable_map
|
||||
|
||||
assert len(variables) == 2, "Variables not added to the block"
|
||||
try:
|
||||
@@ -115,7 +191,7 @@ class TestTemplateBuilder(unittest.TestCase):
|
||||
builder.next_block('AgentData')
|
||||
builder.add_data('TexturesChanged', True, MsgType.MVT_BOOL)
|
||||
#need a way to determine the right variable data is sent compared to the type
|
||||
assert builder.get_current_block().variable_map['TexturesChanged'].data == True,\
|
||||
assert builder.current_block.variable_map['TexturesChanged'].data == True,\
|
||||
"Data not set correctly"
|
||||
|
||||
def test_add_lluuid(self):
|
||||
@@ -123,9 +199,9 @@ class TestTemplateBuilder(unittest.TestCase):
|
||||
builder.new_message('AvatarTextureUpdate')
|
||||
builder.next_block('AgentData')
|
||||
builder.add_data('AgentID', UUID("550e8400-e29b-41d4-a716-446655440000"), MsgType.MVT_LLUUID)
|
||||
assert builder.get_current_block().variable_map['AgentID'].data == UUID("550e8400-e29b-41d4-a716-446655440000"),\
|
||||
assert builder.current_block.variable_map['AgentID'].data == UUID("550e8400-e29b-41d4-a716-446655440000"),\
|
||||
"Data not set correctly"
|
||||
#assert builder.get_current_block().variables['AgentID'].get_size() == ?
|
||||
#assert builder.current_block.variables['AgentID'].get_size() == ?
|
||||
|
||||
#test should go with the packer mostly
|
||||
def test_serialize_u8_fail(self):
|
||||
@@ -139,6 +215,65 @@ class TestTemplateBuilder(unittest.TestCase):
|
||||
except:
|
||||
assert True
|
||||
|
||||
def test_build_fail(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
msg = builder.build_message()
|
||||
assert msg == None, "Got a message without calling new first"
|
||||
|
||||
|
||||
def test_build_multiple_fail(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('TestMessage')
|
||||
builder.next_block('TestBlock1')
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
try:
|
||||
msg, size = builder.build_message()
|
||||
assert False, "Message block should be 1, where it should be 4"
|
||||
except:
|
||||
assert True
|
||||
|
||||
def test_build_multiple(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('TestMessage')
|
||||
builder.next_block('TestBlock1')
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
|
||||
msg = None
|
||||
size = 0
|
||||
|
||||
try:
|
||||
msg, size = builder.build_message()
|
||||
|
||||
except Exception, e:
|
||||
assert False, "Multiple blocks not working correctly"
|
||||
|
||||
assert msg == '\xff\xff\x00\x01' + '\x00\x00\x00\x01' + \
|
||||
'\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01' + \
|
||||
'\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01' + \
|
||||
'\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01' + \
|
||||
'\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01', \
|
||||
'TestMessage data not built correctly'
|
||||
|
||||
def test_serialize_u8(self):
|
||||
builder = MessageTemplateBuilder(self.template_dict)
|
||||
builder.new_message('CompletePingCheck')
|
||||
|
||||
Reference in New Issue
Block a user