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    
+
+