Commit 3261e6f8 authored by Philipp Gast's avatar Philipp Gast
Browse files

local and network tests now working

Merge branch '74-tests-make-the-tests-for-the-client-server-interface' of gitlab:yfournier/myplotlib into 88-cleanning-pep8-compilance

Conflicts:
	mplServer2.py
	myFig_client.py
	test/network/tests/test_com.py
parents 921e11bb 1b9700a7
Pipeline #494 failed with stage
in 5 minutes and 43 seconds
......@@ -116,7 +116,7 @@ class MplClient2():
# create a Signal of type Query with arguments
self.connect((self.host, self.port))
query = Query(Query.READDATA, {'func': io_function,
'dataname': data_name,
'data_name': data_name,
'args': args,
'kwargs': kwargs})
status = self.send(query)
......
......@@ -16,9 +16,6 @@ from . import D_DEBUG
debug = D_DEBUG
G_RAWDATA = dict()
G_FIGURES = dict()
class MplHandler(SocketServer.StreamRequestHandler):
......@@ -45,11 +42,11 @@ class MplHandler(SocketServer.StreamRequestHandler):
fct = self.server.known_functions[content.get('func')]
args = content.get('args')
kwargs = content.get('kwargs')
data_name = content.get('dataname')
data_name = content.get('data_name')
# Try to execute the instructions
try:
G_RAWDATA[data_name] = fct(*args, **kwargs)
self.server._rawdata[data_name] = fct(*args, **kwargs)
if debug:
print(INFO + "SERVER: I read the data "
"following instructions")
......@@ -62,7 +59,7 @@ class MplHandler(SocketServer.StreamRequestHandler):
return Status(False, "The instructions of readData could not"
" be executed. I tried: " + str(fct.__name__)
+ '(' + str(args) + ', ' + str(kwargs) + ')')
if data_name in G_RAWDATA:
if data_name in self.server._rawdata:
return Status(True, "SERVER: I read the data following"
" instructions" + str(fct.__name__)
+ '(' + str(args) + ', ' + str(kwargs) + ')')
......@@ -75,10 +72,10 @@ class MplHandler(SocketServer.StreamRequestHandler):
fig_class = self.server.known_figures[content.get('fig_class_came')]
# args = content.get('args')
kwargs = content.get('kwargs')
datanames = content.get('dataName')
datas = [G_RAWDATA[name] for name in datanames]
data_name = content.get('data_name')
datas = [self.server._rawdata[name] for name in data_name]
try:
# create the figure:
fig = fig_class(datas, **kwargs)
......@@ -100,26 +97,9 @@ class MplHandler(SocketServer.StreamRequestHandler):
+ str(e.message) + str(e.args))
# add the figure to the global index
G_FIGURES[fig.getfig_id()] = fig
if fig.getfig_id() in G_FIGURES:
return Answer(fig.getfig_id())
def get_fig_by_id(self, fig_id):
""" Identify the figure by ID and return it.
On error it will return a Status Signal"""
# Identify the figure
fig = G_FIGURES.get(fig_id, None)
if fig is None:
if debug:
print(WARN + "The figure ID: " + fig_id + " does not exist.")
return Status(False, "The figure ID: "
+ fig_id + " does not exist.")
elif isinstance(fig, MyFig):
if debug:
print('Figure ', fig_id, ' found in database')
return fig
self.server._figures[fig.getFigID()] = fig
if fig.get_fig_id() in self.server._figures :
return Answer(fig.get_fig_id())
def treat_update_sync_figure(self, content):
""" If client request an update of the keywords of a figure.
......@@ -144,15 +124,15 @@ class MplHandler(SocketServer.StreamRequestHandler):
def treat_sync_fig_format_raw_data(self, fig_id):
# Identify the figure
fig = self.get_fig_by_id(fig_id)
fig = self.server.get_fig_by_id(fig_id)
# if an error occured forward the signal
if isinstance(fig, Signal):
return fig
# Format the rawdata
try:
fig.formatRawData()
fig.format_raw_data()
except Exception as e:
if debug:
print(WARN + "I couldn't format the rawdata.")
......@@ -168,9 +148,9 @@ class MplHandler(SocketServer.StreamRequestHandler):
return Answer(datas)
def treat_delete_sync_figure(self, fig_id):
""" Deletes the figure with ID fig_id from G_FIGURES """
if fig_id in G_FIGURES:
del G_FIGURES[fig_id]
""" Deletes the figure with ID fig_id from _figures """
if fig_id in self.server._figures :
del self.server._figures[fig_id]
return Status(True, 'Figure with ID '
+ str(fig_id) + ' deleted from server.')
else:
......@@ -178,22 +158,22 @@ class MplHandler(SocketServer.StreamRequestHandler):
+ str(fig_id) + ' not found on server side.')
def treat_list_data(self, content):
""" list the keys
(and possibly (later) the location) from G_RAWDATA """
return Answer(G_RAWDATA.keys())
""" list the keys
(and possibly (later)the location) from _rawdata """
return Answer(self.server._rawdata.keys())
def treat_get_data(self, content):
""" from G_FIGURES """
if content in G_RAWDATA:
return Answer(G_RAWDATA[content])
else:
""" from _figures """
if content in self.server._rawdata:
return Answer(self.server._rawdata[content])
else :
return Status(False, 'Dataname not found in index'
' of the server side...')
def treat_list_fig(self, content):
""" list the keys from G_FIGURES """
return Answer(G_FIGURES.keys())
""" list the keys from _figures """
return Answer(self.server._figures.keys())
def handle(self):
print('HANDLING...')
......@@ -290,6 +270,9 @@ class MplServer2(SocketServer.TCPServer):
SocketServer.TCPServer.__init__(self, (ip, port), handler)
self.running = False
self.initialized = True
self._rawdata = dict()
self._figures = dict()
def run(self, as_daemon=True):
self.server_thread = threading.Thread(target=self.serve_forever)
......@@ -301,3 +284,19 @@ class MplServer2(SocketServer.TCPServer):
print('STOPING...')
# self.server_thread.stop()
self.running = False
def get_fig_by_id(self, fig_id):
""" Identify the figure by ID and return it.
On error it will return a Status Signal"""
# Identify the figure
fig = self._figures.get(fig_id,None)
if fig is None:
if debug:
print(WARN + "The figure ID: " + fig_id + " does not exist.")
return Status(False, "The figure ID: "
+ fig_id + " does not exist.")
elif isinstance(fig, MyFig):
if debug:
print('Figure ', fig_id, ' found in database')
return fig
......@@ -72,8 +72,9 @@ from . import D_FIGSIZE, D_INPUTARG, D_DEBUG, D_REFORMAT, D_FORMATTED
from . import D_OFORMAT, D_OPATH
from . import DBUG, SEVR, INFO, SPCE, WARN
from . import MplData
from . import MyAxes
from . import MplAxes
from . import Figure
from . import HorizontalGrid
# Class MyFig Overwriting Matplotlib.figure.Figure
......@@ -97,7 +98,7 @@ class MyFigClient(Figure):
self.debug = kwargs.pop('debug', D_DEBUG)
self.formatted = kwargs.pop('formatted', D_FORMATTED)
self.aliases = {}
self.syncID = -1
self.sync_id = -1
self.client = None
self.FIGSIZE = kwargs.pop('figsize', self.FIGSIZE)
......@@ -107,7 +108,7 @@ class MyFigClient(Figure):
# This is required for the interactive mode
# it ensures that a figure can not be bounded
# to several windows and prevent the loss of canvas.
self.boundedToWin = False
self.bounded_to_win = False
# initialise
self._initialize(*args, **kwargs)
......@@ -115,9 +116,9 @@ class MyFigClient(Figure):
def de_sync_fig(self):
if self.client is not None:
if self.client.deleteSyncFigure(self.syncID):
if self.client.deleteSyncFigure(self.sync_id):
print('The figure was successfully deleted on the server Side')
self.syncID = -1
self.sync_id = -1
else:
print('The figure could not be deleted on the server Side')
else:
......@@ -166,15 +167,15 @@ class MyFigClient(Figure):
if self.client is not None:
# collect the current state of the figure
state = self.getState()
state = self.get_state()
# call the client to create a new figure on the server side
newFig = self.client.newSyncFigure(
newFig = self.client.new_sync_figure(
self.__class__, self.remote_rawdata, **state)
# since the state matches the current instance. only the new syncID
# since the state matches the current instance. only the new sync_id
# is kept.
self.syncID = newFig.syncID
self.sync_id = newFig.sync_id
else:
print(
'The client is not connected to a server yet. Please use the client to set up a sync conection.')
......@@ -183,10 +184,10 @@ class MyFigClient(Figure):
def _initialize(self, *args, **kwargs):
# add the axes
self.addAxes()
self.addAxes() # This will throw a pep8 error but its needed to prevent confusion with matplotlib
# declare the aliases
self.declareAliases()
self.declare_aliases()
# update the attributes and keywords
self._update(**kwargs)
......@@ -237,7 +238,7 @@ class MyFigClient(Figure):
# send the keywords to the server
if self.client is not None:
status = self.client.updateSyncFigure(self.syncID, kwargs)
status = self.client.update_sync_figure(self.sync_id, kwargs)
# if the server reported no errors apply the keywords on client
# side also:
......@@ -256,8 +257,8 @@ class MyFigClient(Figure):
pass
# ADD AXES ---------------------------------------------------------
def add_axes(self, *arg, **kwargs):
pass
def addAxes(self, *arg, **kwargs):
raise(NotImplementedError, 'The addAxes method needs to be implemented.')
# This overwrites MPL add_axes. It gives a name to the axis added so that
# it is easier to refer to
......@@ -307,14 +308,14 @@ class MyFigClient(Figure):
# FORMAT RAW DATA --------------------------------------------------
def format_rawdata(self):
# HEre comes a function that send a signal to the server
# and tells him to execute the format rawdata of the
# synchronized figure (server-side)
if (self.client is not None) and (self.syncID != -1):
""" send a signal to the server
and tells him to execute the format rawdata of the
synchronized figure (server-side) """
if (self.client is not None) and (self.sync_id != -1):
# try:
if (True):
datas = self.client.sync_fig_format_raw_data(self.syncID)
datas = self.client.sync_fig_format_raw_data(self.sync_id)
# except:
# print(SEVR+'The server-side figure could not format the data...')
# return(False)
......@@ -339,7 +340,7 @@ class MyFigClient(Figure):
print(DBUG + "currently formatting the data...")
if((self.reformat) or (not self.formatted)):
status = self.format_raw_data()
status = self.format_rawdata()
if(not status):
return(False)
......@@ -368,11 +369,12 @@ class MyFigClient(Figure):
def print_debug(self):
class_name = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(class_name))
print(SPCE + " Raw data: " + str(self.rawdata))
print(SPCE + " ID the figure: " + str(self.fignum))
print(SPCE + "Size of the figure: " + str(self.FIGSIZE) + ' [inch] \n')
# PRINT 2 FILE -------------------------------------------------------
def print2file(self, filename, *args, **kwargs):
def print_to_file(self, filename, *args, **kwargs):
# get the keywords
debug = kwargs.get('debug', D_DEBUG)
......@@ -383,15 +385,15 @@ class MyFigClient(Figure):
# set the dpi
if(oformat == 'png'):
dpi = 300.
addMetaData = True # NOT YET IMPLEENTED
add_metadata = True # NOT YET IMPLEENTED
else:
dpi = 100.
addMetaData = False # NOT YET IMPLEMENTED
add_metadata = False # NOT YET IMPLEMENTED
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
# if the figure is boundedToWin
# save to canvas in a local variable and restore after saving to file.
if self.boundedToWin:
if self.bounded_to_win:
win_canvas = self.canvas
else:
win_canvas = None
......
......@@ -88,12 +88,12 @@ class MyFigServer(object):
def __init__(self, rawdata, *args, **kwargs):
# for the update function
self._attributesToUpdateKeys = [
self._attributes_to_update_keys = [
'fignum', 'reformat', 'debug', 'formatted', 'aliases']
# initialise the attribute default values and remove them from kwargs
# need to be hard coded for interactive mode
self.fignum = kwargs.pop('fignum', MyFig_server.G_FIGNUM)
self.fignum = kwargs.pop('fignum', MyFigServer.G_FIGNUM)
self.reformat = kwargs.pop('reformat', D_REFORMAT)
self.debug = kwargs.pop('debug', D_DEBUG)
self.formatted = kwargs.pop('formatted', D_FORMATTED)
......@@ -107,16 +107,16 @@ class MyFigServer(object):
self.set_rawdata(rawdata)
# count the global counter up by one
MyFig_server.G_FIGNUM += 1
MyFigServer.G_FIGNUM += 1
# INITIALIZE -------------------------------------------------------
def _initialize(self, *args, **kwargs):
# add the axes
self.addAxes()
self.addAxes() # This will throw a pep8 error but its needed to prevent confusion with matplotlib
# declare the aliases
self.declareAliases()
self.declare_aliases()
# update the attributes and keywords
self.update(**kwargs)
......@@ -132,19 +132,19 @@ class MyFigServer(object):
self.set_rawdata(kwargs['rawdata'])
# if it is an attribute
elif keyword in self._attributesToUpdateKeys:
elif keyword in self._attributes_to_update_keys:
# update value
setattr(self, keyword, kwargs[keyword])
# For each axes update the keywords
for ax in self.get_axes(): # NEED TO CODE GET_AXES
for ax in self.get_axes():
forax = {}
for keyword in kwargs.keys():
# ignore figure attributes
if keyword in ['rawdata'] + self._attributesToUpdateKeys:
if keyword in ['rawdata'] + self._attributes_to_update_keys:
pass
# Check if a key of kwargs has an alias for this axes
......@@ -168,7 +168,7 @@ class MyFigServer(object):
return(True)
# GET FIG ID AS STRING --------------------------------------------
def getFigID(self):
def get_fig_id(self):
return str(self.fignum)
# DECLARE ALIASES -------------------------------------------------
......@@ -176,8 +176,8 @@ class MyFigServer(object):
pass
# ADD AXES ---------------------------------------------------------
def add_axes(self, *arg, **kwargs):
pass
def addAxes(self, *arg, **kwargs):
raise(NotImplementedError, 'The addAxes method needs to be implemented.')
# GET_AXES ---------------------------------------------------------
def get_axes(self):
......@@ -278,11 +278,11 @@ class MyFigServer(object):
str(self.get_axes().index(ax)) +
" formats " +
rawdata.name)
status = ax.testRawData(rawdata)
status = ax.test_rawdata(rawdata)
if status:
status = ax.format_rawdata(rawdata)
else:
status = ax.testRawData(rawdata)
status = ax.test_rawdata(rawdata)
if status:
try:
status = ax.format_rawdata(rawdata)
......@@ -308,8 +308,8 @@ class MyFigServer(object):
# DEBUG --------------------------------------------------------------
def print_debug(self):
className = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(className))
class_name = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(class_name))
print(SPCE + " Raw data: " + str(self.rawdata))
print(SPCE + " ID the figure: " + str(self.fignum))
print(SPCE + "Size of the figure: " + str(self.FIGSIZE) + ' [inch] \n')
......@@ -55,7 +55,7 @@ D_LOGX = False
class AxTest(MyAxes):
# DECLARE KEYWORDS -------------------------------------------------
def declareKeywords(self):
def declare_keywords(self):
self.keywords = {'xRange': D_XRANGE,
'yRange': D_YRANGE}
......@@ -63,7 +63,7 @@ class AxTest(MyAxes):
return(True)
# FORMATTING -------------------------------------------------------
def formatRawData(self, rawdata):
def format_rawdata(self, rawdata):
# give value to data a dict
# with xdata, ydata1, zdata, ydata2 ...
......
......@@ -28,7 +28,7 @@ class FigTest2(MyFig): # Fig wi
self.add_axes(AxTest(self, ratio, frame1),"p1")
self.add_axes(AxTest(self, ratio, frame2),"p2")
def declareAliases(self):
def declare_aAliases(self):
# it is important to not hold additional references to an axes in the figure to avoid memory leaks. use the this function
# get the plot added above
......
......@@ -54,7 +54,7 @@ D_LOGX = False
class AxTest(MyAxes):
# DECLARE KEYWORDS -------------------------------------------------
def declareKeywords(self):
def declare_keywords(self):
self.keywords = {'xRange': D_XRANGE,
'yRange': D_YRANGE}
......@@ -62,7 +62,7 @@ class AxTest(MyAxes):
return(True)
# FORMATTING -------------------------------------------------------
def formatRawData(self, rawdata):
def format_rawdata(self, rawdata):
# give value to data a dict
# with xdata, ydata1, zdata, ydata2 ...
......
......@@ -28,7 +28,7 @@ class FigTest2(MyFig): # Fig wi
self.add_axes(AxTest(self, ratio, frame1),"p1")
self.add_axes(AxTest(self, ratio, frame2),"p2")
def declareAliases(self):
def declare_aliases(self):
# it is important to not hold additional references to an axes in the figure to avoid memory leaks. use the this function
# get the plot added above
......
......@@ -4,33 +4,33 @@ verbose = 2
failed = []
states = {}
#~ # Signal
#~ suite_signal = unittest.TestLoader().loadTestsFromTestCase(SignalTestCase)
#~ states.update({'Signal': unittest.TextTestRunner(verbosity=verbose).run(suite_signal).wasSuccessful()})
#~
#~ # Query
#~ suite_query = unittest.TestLoader().loadTestsFromTestCase(QueryTestCase)
#~ states.update({'Query': unittest.TextTestRunner(verbosity=verbose).run(suite_query).wasSuccessful()})
#~
#~ # Answer
#~ suite_answer = unittest.TestLoader().loadTestsFromTestCase(AnswerTestCase)
#~ states.update({'Answer': unittest.TextTestRunner(verbosity=verbose).run(suite_answer).wasSuccessful()})
#~
#~ # Status
#~ suite_status = unittest.TestLoader().loadTestsFromTestCase(StatusTestCase)
#~ states.update({'Status': unittest.TextTestRunner(verbosity=verbose).run(suite_status).wasSuccessful()})
#~
#~ # Server
#~ suite_server = unittest.TestLoader().loadTestsFromTestCase(ServerTestCase)
#~ states.update({'Server': unittest.TextTestRunner(verbosity=verbose).run(suite_server).wasSuccessful()})
#~
#~ # Client
#~ suite_client = unittest.TestLoader().loadTestsFromTestCase(ClientTestCase)
#~ states.update({'Client': unittest.TextTestRunner(verbosity=verbose).run(suite_client).wasSuccessful()})
#~
#~ # Connection Setup
#~ suite_com = unittest.TestLoader().loadTestsFromTestCase(ComSetupTestCase)
#~ states.update({'Communication': unittest.TextTestRunner(verbosity=verbose).run(suite_com).wasSuccessful()})
# Signal
suite_signal = unittest.TestLoader().loadTestsFromTestCase(SignalTestCase)
states.update({'Signal': unittest.TextTestRunner(verbosity=verbose).run(suite_signal).wasSuccessful()})
# Query
suite_query = unittest.TestLoader().loadTestsFromTestCase(QueryTestCase)
states.update({'Query': unittest.TextTestRunner(verbosity=verbose).run(suite_query).wasSuccessful()})
# Answer
suite_answer = unittest.TestLoader().loadTestsFromTestCase(AnswerTestCase)
states.update({'Answer': unittest.TextTestRunner(verbosity=verbose).run(suite_answer).wasSuccessful()})
# Status
suite_status = unittest.TestLoader().loadTestsFromTestCase(StatusTestCase)
states.update({'Status': unittest.TextTestRunner(verbosity=verbose).run(suite_status).wasSuccessful()})
# Server
suite_server = unittest.TestLoader().loadTestsFromTestCase(ServerTestCase)
states.update({'Server': unittest.TextTestRunner(verbosity=verbose).run(suite_server).wasSuccessful()})
# Client
suite_client = unittest.TestLoader().loadTestsFromTestCase(ClientTestCase)
states.update({'Client': unittest.TextTestRunner(verbosity=verbose).run(suite_client).wasSuccessful()})
# Connection Setup
suite_com = unittest.TestLoader().loadTestsFromTestCase(ComSetupTestCase)
states.update({'Communication': unittest.TextTestRunner(verbosity=verbose).run(suite_com).wasSuccessful()})
# Remote fig creation
suite_figcreation = unittest.TestLoader().loadTestsFromTestCase(RemoteFigTestCase)
......
......@@ -28,7 +28,8 @@ class ComSetupTestCase(unittest.TestCase):
self.server.run(as_daemon=True)
def test_ConnectionSetup(self):
def test_connection_setup(self):
""" Test the basic connection functions"""
print('REQUEST CONNECTION...')
self.client.connect(('localhost', 12345))
print('CONNECTED')
......@@ -55,39 +56,54 @@ class RemoteFigTestCase(unittest.TestCase):
self.client.port = 12345
self.server.run(as_daemon=True)
self.client.connect(('localhost', 12347))
self.client.connect(('localhost',12347))
self.datanames = ['data1','data2']
self.client.read_data('readStupidData', self.datanames[0])
self.client.read_data('readStupidData2', self.datanames[1])
#~ def test_Readdata(self):
#~ rm_data = self.client.list_remote_data()
#~ self.assertEqual(rm_data,self.datanames)
def test_NewSyncFig(self):
def test_read_data(self):
""" Check wether the reading of remote data results in the server creating the datasets """
rm_data = self.client.list_remote_data()
self.assertEqual(rm_data,self.datanames)
def test_new_sync_fig(self):
''' Create a frist synced figure. Test if formating it will result in clinetside.fig.ax.data holding the expected data.'''
fig1 = self.client.new_sync_figure(FigTestc, ('data1',))
self.assertIsInstance(fig1,FigTestc)
#~
#~ def test_MultiFig(self):
#~ fig2 = self.client.new_sync_figure(FigTestc2, ('data1','data2'), xRange_p1=[-2.0, 2.0], xRange_p2=[-3, 3], yRange=[-2.0, 2.0])
#~
#~ self.assertIsInstance(fig2,FigTestc2)
#~ self.assertEqual(len(fig2.get_axes()),2)
#~
#~ # Testing the Alias functionality
#~ self.assertEqual(fig2.get_axes_by_name('p1').keywords['xRange'],[-2.0, 2.0])
#~ self.assertEqual(fig2.get_axes_by_name('p2').keywords['xRange'],[-3, 3])
#~ self.assertEqual(fig2.get_axes_by_name('p1').keywords['yRange'],[-2.0, 2.0])
#~ self.assertEqual(fig2.get_axes_by_name('p2').keywords['yRange'],[-2.0, 2.0])
#~
#~ def test_Update(self):
#~ fig1 = self.client.newSyncFigure(FigTestc, ('data1',))
#~ fig1.update(xRange=[-2, 2],yRange=[-2, 2])
#~ self.assertEqual(fig1.get_axes_by_name('p1').keywords['xRange'],[-2, 2])
#~ self.assertEqual(fig1.get_axes_by_name('p1').keywords['yRange'],[-2, 2])
#~ def test_ReSync(self):
fig1.format_rawdata()
self.assertEqual(fig1.get_axes_by_name('p1').data,
{'xdata': [-1, 1],'ydata': [1, -1]})
def test_multi_fig(self):
""" test if a figure with two axes is created correctly and if the alias set the axis keywords correct during creation """
fig2 = self.client.newSyncFigure(FigTestc2, ('data1','data2'), xRange_p1=[-2.0, 2.0], xRange_p2=[-3, 3], yRange=[-2.0, 2.0])
self.assertIsInstance(fig2,FigTestc2)
self.assertEqual(len(fig2.get_axes()),2)
self.assertEqual(self.server.getFigByID(str(fig2.syncID)).getAxesByName('p1').keywords['xRange'],[-2, 2])
self.assertEqual(self.server.getFigByID(str(fig2.syncID)).getAxesByName('p1').keywords['yRange'],[-2, 2])