Adding test classes, test builder with state machine generators, and test cases for Eap TLS
diff --git a/src/test/builder/Makefile b/src/test/builder/Makefile
new file mode 100644
index 0000000..df52584
--- /dev/null
+++ b/src/test/builder/Makefile
@@ -0,0 +1,7 @@
+## Test State Machine builder
+
+all: build_tls_fsm
+build_tls_fsm:
+ @sh buildTlsFsm.sh ../fsm
+clean:
+ rm -f *~ *.pyc ../fsm/*
diff --git a/src/test/builder/buildTlsFsm.sh b/src/test/builder/buildTlsFsm.sh
new file mode 100644
index 0000000..e6bb8b2
--- /dev/null
+++ b/src/test/builder/buildTlsFsm.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+odir="$1"
+if [ -z "$odir" ]; then
+ odir = "./"
+fi
+python yamlFsm.py -p TlsAuthHolder -f noseTlsAuthTest.yaml > ${odir}/noseTlsAuthHolder.py
diff --git a/src/test/builder/noseTlsAuthTest.yaml b/src/test/builder/noseTlsAuthTest.yaml
new file mode 100644
index 0000000..5a7f828
--- /dev/null
+++ b/src/test/builder/noseTlsAuthTest.yaml
@@ -0,0 +1,32 @@
+States:
+ ST_EAP_SETUP:
+ Events:
+ EVT_EAP_SETUP:
+ Actions:
+ - _eapSetup
+ NextState: ST_EAP_START
+ ST_EAP_START:
+ Events:
+ EVT_EAP_START:
+ Actions:
+ - _eapStart
+ NextState: ST_EAP_ID_REQ
+ ST_EAP_ID_REQ:
+ Events:
+ EVT_EAP_ID_REQ:
+ Actions:
+ - _eapIdReq
+ NextState: ST_EAP_TLS_HELLO_REQ
+ ST_EAP_TLS_HELLO_REQ:
+ Events:
+ EVT_EAP_TLS_HELLO_REQ:
+ Actions:
+ - _eapTlsHelloReq
+ NextState: ST_EAP_TLS_CERT_REQ
+ ST_EAP_TLS_CERT_REQ:
+ Events:
+ EVT_EAP_TLS_CERT_REQ:
+ Actions:
+ - _eapTlsCertReq
+ NextState: ST_EAP_TLS_DONE
+
\ No newline at end of file
diff --git a/src/test/builder/yamlFsm.py b/src/test/builder/yamlFsm.py
new file mode 100755
index 0000000..661fa54
--- /dev/null
+++ b/src/test/builder/yamlFsm.py
@@ -0,0 +1,313 @@
+#!/usr/bin/env python
+
+import yaml, pprint, sys, pdb
+#import configFsm
+
+stateHash = {}
+
+header = '''#!python
+'''
+
+# ---------------------------- DOT -----------------------------------
+colorList = ['aquamarine4', 'crimson', 'chartreuse4', 'darkolivegreen', 'darkgoldenrod', 'dodgerblue3', 'blue4', 'cyan4']
+rankdict = {}
+# ---------------------------- DOT -----------------------------------
+
+
+if __name__ == '__main__':
+
+ usage = ''
+
+ # optparse
+ from optparse import OptionParser
+
+ parser = OptionParser(usage)
+
+ parser.add_option('-p', '--prefix', dest='prefix', type='string', action='store', help='prefix for state table')
+ parser.add_option('-f', '--file', dest='file', type='string', action='store', help='input yaml filename')
+ parser.add_option('-d', '--dot', dest='dot', default=False, action='store_true', help='output DOT')
+
+ (opts, args) = parser.parse_args()
+
+ prefix = opts.prefix
+
+ f = open(opts.file, 'r')
+ y = yaml.load(f)
+ f.close()
+
+ stateHash = y['States']
+
+ eventHash = {}
+
+ # GLOBAL DOT DIRECTIVES
+ stateRadiate = y.get('DOT_StateRadiate')
+ ignoredIntensity = abs(int(y.get('DOT_IgnoredIntensity', 100)) - 100)
+ eventGroups = y.get('DOT_EventGroups')
+
+ if stateRadiate is not None:
+ stateRadiate = str(stateRadiate)
+
+ actionStrLen = [0]
+ stateColorIdx = 0
+ for k, v in stateHash.iteritems():
+ events = v.get('Events')
+ if events:
+ for event in events.keys():
+ eventHash[event] = {}
+
+ actionStr = ''
+
+ for ev in events.values():
+ if ev.get('Actions'):
+ actionStr = ','.join(['obj.%s' % action for action in ev['Actions']]) + ','
+ actionStrLen.append(len(actionStr))
+
+
+ ievents = v.get('IgnoredEvents')
+ if ievents:
+ for event in ievents.keys():
+ eventHash[event] = {}
+
+ # ---------------------------- DOT -----------------------------------
+
+ # rankdict setup
+ rank = v.get('DOT_Rank')
+ if rank:
+ print >>sys.stderr, '%s rank %s' % (k, str(rank))
+ rankdict.setdefault(rank, []).append(k)
+
+ # assign a possible color if not specified
+ color = v.get('DOT_Color')
+ if color:
+ print >>sys.stderr, 'using user assigned color %s for %s' % (color, k)
+ else:
+ if stateRadiate and stateRadiate.lower() == 'auto':
+ color = colorList[stateColorIdx % len(colorList)]
+ stateColorIdx+= 1
+ else:
+ color = 'black'
+
+ stateHash[k]['DOT_Color'] = color
+
+ # ---------------------------- DOT -----------------------------------
+
+ # ---------------------------- DOT -----------------------------------
+ # update the event hash with information from the event groups (if present)
+ if eventGroups:
+ for group in eventGroups.values():
+ for event in group['Events'].keys():
+ for attr, val in group['Attrs'].iteritems():
+ eventHash[event][attr] = val
+ print >>sys.stderr, 'assigning event group attr event %s attr %s val %s' % (event, attr, val)
+ # ---------------------------- DOT -----------------------------------
+
+ '''
+ for key in stateHash.keys():
+# try:
+ print key
+ x = eval('configFsm.cfgSt.%s' % key)
+# except AttributeError, e:
+ print '%s not in config.cfgSt!' % x
+
+
+ for key in eventHash.keys():
+ print key
+# try:
+ x = eval('configFsm.cfgEv.%s' % key)
+# except KeyError, e:
+ print '%s not in config.cfgEv!' % x
+ '''
+
+
+ maxStateLen = reduce(max, [len(x) for x in stateHash.keys()]) + 5 + len(prefix)
+ maxEventLen = reduce(max, [len(x) for x in eventHash.keys()]) + 5 + len(prefix)
+ maxActionLen = reduce(max, actionStrLen) + 5
+
+ if opts.dot:
+
+ print 'digraph G {'
+ print ' edge [fontname="Tahoma", fontsize="10", minlen=2];'
+ print ' node [fontname="Tahoma", fontsize="10"];'
+ print ' graph [fontname="Tahoma", label="%s"];' % prefix
+
+# rankdict = {}
+
+ print >>sys.stderr, 'stateRadiate:%s\nignoredIntensity:%d' % (stateRadiate, ignoredIntensity)
+
+ # emit state declarations
+ for state in stateHash.keys():
+ print ' %s[color="%s"];' % (state, stateHash[state]['DOT_Color'])
+
+ # emit rankings
+ for k, v in rankdict.iteritems():
+ print >>sys.stderr, '%s rank %s' % (k, str(v))
+
+ print 'subgraph { rank = same;'
+ for state in v:
+ print ' %s;' % state
+ print '}'
+
+ for state, va in stateHash.iteritems():
+
+ # emit ignored events
+ if va.get('IgnoredEvents'):
+ for event, v in va['IgnoredEvents'].iteritems():
+ stateStr = state
+ eventStr = event
+
+ print '%s -> %s [label="%s/",minlen=1, fontcolor="grey%d", color="grey%d"];' % (stateStr, stateStr, eventStr, ignoredIntensity, ignoredIntensity)
+
+ # emit transitions
+ if va.get('Events'):
+ for event, v in va['Events'].iteritems():
+ stateStr = state
+ eventStr = event
+ actionStr = ''
+ if v.get('Actions'):
+ actionStr = '\\n'.join([a.strip('_') for a in v['Actions']])
+ nextStr = v['NextState']
+
+ labelStr = '%s/\\n%s' % (eventStr, actionStr)
+
+ if stateRadiate:
+ color = va['DOT_Color']
+ elif len(eventHash[event]):
+ color = eventHash[event]['Color']
+ else:
+ color = 'black'
+
+ fontColor = color
+
+ styleStr = ''
+ style = eventHash[event].get('Style')
+ if style:
+ styleStr = ',style="%s"' % (style)
+
+ if style == 'invis':
+ fontColor = 'white'
+
+ print '%s -> %s [label="%s", color="%s", fontcolor="%s" %s];' % (stateStr, nextStr, labelStr, color, fontColor, styleStr)
+
+ print
+
+ print '}'
+
+
+# pprint.pprint(states)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ else:
+
+### emit it
+
+ print header
+
+### enumerations
+ '''
+ print '%sSt = Enumeration("%sState",(' % (prefix, prefix)
+ for state in stateHash.keys():
+ print '%s"%s",' % (' '*12, state)
+ print '%s))' % (' '*12)
+
+ print
+
+ print '%sEv = Enumeration("%sEvent",(' % (prefix, prefix)
+ for event in eventHash.keys():
+ print '%s"%s",' % (' '*12, event)
+ print '%s))' % (' '*12)
+ '''
+
+
+### table
+
+ fmt = ' (%' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + '):( %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s),'
+ cfmt= ' ## %' + '-%d.%ds' % (maxStateLen, maxStateLen) + '%' + '-%d.%ds' % (maxEventLen, maxEventLen) + ' %' +' -%d.%ds' % (maxActionLen, maxActionLen) + '%s'
+
+ print 'def init%s%sFsmTable(obj,St,Ev):' % (prefix[0].upper(), prefix[1:])
+# print " %sFsmTable = {" % prefix
+ print " return {"
+ print
+
+ for state, va in stateHash.iteritems():
+
+ print cfmt % ('CurrentState', 'Event', 'Actions', 'NextState')
+ print
+
+ if va.get('IgnoredEvents'):
+ for event, v in va['IgnoredEvents'].iteritems():
+ stateStr = '%sSt.' % ('') + state + ','
+ eventStr = '%sEv.' % ('') + event
+
+ print fmt % (stateStr, eventStr, '(),', stateStr.strip(','))
+
+ if va.get('Events'):
+ for event, v in va['Events'].iteritems():
+ stateStr = '%sSt.' % ('') + state + ','
+ eventStr = '%sEv.' % ('') + event
+ actionStr = ''
+ if v.get('Actions'):
+ actionStr = ','.join(['obj.%s' % action for action in v['Actions']]) + ','
+
+ nextStr = '%sSt.' % ('') + v['NextState']
+
+ print fmt % (stateStr, eventStr, '(%s),' % actionStr , nextStr)
+
+ print
+
+ print "}"
+ print
+
+