Skip to content
Snippets Groups Projects
Commit 469abde1 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Adedd a test suite that currently seems to work with Python, C and C#

parent 11902762
Branches
Tags
No related merge requests found
......@@ -18,3 +18,5 @@ lib/java/se/lth/control/labcomm/LabCommSample.class
lib/java/se/lth/control/labcomm/LabCommType.class
lib/java/se/lth/control/labcomm/LabCommWriter.class
gen
labcomm.dll
labcomm.jar
Makefile 0 → 100644
export LABCOMM_JAR=$(shell pwd)/compiler/labComm.jar
export LABCOMM=java -jar $(LABCOMM_JAR)
all: compiler
$(MAKE) -C lib
$(MAKE) -C lib/c run-test
.PHONY: compiler
compiler:
cd compiler ; ant jar
.PHONY: test
test:
$(MAKE) -C test -e
TESTS=basic simple
LABCOMM_JAR=../compiler/labComm.jar
LABCOMM=java -jar $(LABCOMM_JAR)
all: $(TESTS:%=test_%)
# PYTHONPATH=../lib/python \
# ./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc
.PHONY: clean
clean:
rm -rf gen
.PHONY: test_%
test_%: gen/%/c_relay \
gen/%/cs_code.cs \
gen/%/cs_relay.exe \
gen/%/signatures.py \
gen/%/java_code
PYTHONPATH=../lib/python ./test_encoder_decoder.py \
--signatures=gen/$*/signatures.py \
--test /bin/tee gen/$*/testdata \
--test gen/$*/c_relay /dev/stdin /dev/stdout \
--test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout
.PRECIOUS: gen/%/
gen/%/:
mkdir -p $@
.PRECIOUS: gen/%/typeinfo
gen/%/typeinfo: %.lc Makefile | gen/%/
$(LABCOMM) --typeinfo=$@ $<
.PRECIOUS: gen/%/signatures.py
gen/%/signatures.py: %.lc Makefile | gen/%/
$(LABCOMM) --python=$@ $<
# C relay test rules
.PRECIOUS: gen/%/c_code.h gen/%/c_code.c
gen/%/c_code.h gen/%/c_code.c: %.lc Makefile | gen/%/
$(LABCOMM) --c=gen/$*/c_code.c --h=gen/$*/c_code.h $<
.PRECIOUS: gen/%/c_relay.c
gen/%/c_relay.c: gen/%/typeinfo relay_gen_c.py Makefile
./relay_gen_c.py $< > $@
.PRECIOUS: gen/%/c_relay
gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile
$(CC) $(CFLAGS) -o $@ $< -I../lib/c -I. \
-DLABCOMM_FD_OMIT_VERSION \
-DLABCOMM_ENCODER_LINEAR_SEARCH \
gen/$*/c_code.c \
../lib/c/labcomm.c \
../lib/c/labcomm_fd_*.c \
../lib/c/labcomm_dynamic_buffer_writer.c
# C# relay test rules
.PRECIOUS: gen/%/cs_code.cs
gen/%/cs_code.cs: %.lc Makefile | gen/%/
$(LABCOMM) --cs=$@ $<
.PRECIOUS: gen/%/cs_relay.cs
gen/%/cs_relay.cs: gen/%/typeinfo relay_gen_cs.py Makefile
./relay_gen_cs.py $< > $@
.PRECIOUS: gen/%/labcomm.dll
gen/%/labcomm.dll:
ln -s ../../../lib/csharp/labcomm.dll $@
.PRECIOUS: gen/%/cs_relay.exe
gen/%/cs_relay.exe: gen/%/cs_relay.cs gen/%/cs_code.cs \
gen/%/labcomm.dll Makefile
mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm
# Java relay test rules
.PRECIOUS: gen/%/java_code
gen/%/java_code: %.lc | gen/%/
mkdir -p $@
$(LABCOMM) --java=$@ $<
sample void s_void;
sample byte s_byte;
sample short s_short;
sample int s_int;
sample long s_long;
sample float s_float;
sample double s_double;
sample boolean s_boolean;
sample string s_string;
\ No newline at end of file
def gen(f, signatures):
print """
#include <labcomm.h>
#include <labcomm_fd_reader_writer.h>
#include "%(f)s.h"
""" % { 'f': f }
for s in [s.name for s in signatures]:
t = "%s_%s" % (f, s)
print """
void handle_%(t)s(%(t)s *v, void *context)
{
struct labcomm_encoder *e = context;
labcomm_encode_%(t)s(e, v);
}
""" % {'t':t}
print """
int main(int argc, char *argv[]) {
struct labcomm_decoder *d;
struct labcomm_encoder *e;
"""
#!/usr/bin/python
import os
import re
import subprocess
import sys
def gen(classname, namespace, signatures):
yield 'using System;'
yield 'using System.IO;'
yield 'using se.lth.control.labcomm;'
yield ''
yield 'class %s :' % classname
for s in signatures[0:-1]:
yield '%s%s.Handler,' % (namespace, s.name)
yield '%s%s.Handler' % (namespace, signatures[-1].name)
yield '{'
yield ''
yield ' LabCommEncoderChannel encoder;'
for s in signatures:
yield ''
if s.type == 'void':
yield ' void %s%s.Handler.handle() {' % ( namespace, s.name)
else:
yield ' void %s%s.Handler.handle(%s data) {' % (
namespace, s.name, s.type)
yield ' Console.Error.WriteLine("%s%s");' % (namespace, s.name)
if s.type == 'void':
yield ' %s%s.encode(encoder);' % (namespace, s.name)
else:
yield ' %s%s.encode(encoder, data);' % (namespace, s.name)
yield ' }'
yield ''
yield ' public %s(String InName, String OutName) {' % (classname)
yield ' FileStream InFile = new FileStream(InName,'
yield ' FileMode.Open, '
yield ' FileAccess.Read);'
yield ' LabCommDecoderChannel d = new LabCommDecoderChannel(InFile);'
yield ' FileStream OutFile = new FileStream(OutName, '
yield ' FileMode.OpenOrCreate, '
yield ' FileAccess.Write);'
yield ' encoder = new LabCommEncoderChannel(OutFile);'
yield ''
for s in signatures:
yield ' %s%s.register(d, this);' % (namespace, s.name)
yield ''
for s in signatures:
yield ' %s%s.register(encoder);' % (namespace, s.name)
yield ''
yield ' try {'
yield ' d.run();'
yield ' } catch (EndOfStreamException) {'
yield ' }'
yield ''
yield ' }'
yield ''
yield ' static void Main(String[] arg) {'
yield ' new %s(arg[0], arg[1]);' % (classname)
yield ' }'
yield ''
yield '}'
class Signature:
def __init__(self, name, type):
self.name = name
self.type = type
def test_program(target, typeinfo):
f = open(typeinfo)
signature = []
for l in f:
m = re.match('C#,sample,([^,]+),(.*)', l)
if m:
signature.append(Signature(m.group(1), m.group(2)))
f.close()
f = open(target, "w")
for l in gen("x", "", signature):
f.write(l + "\n")
f.close()
if __name__ == "__main__":
#os.system("labcomm --typeinfo=/dev/stdout %s" % sys.argv[1])
typeinfo = subprocess.Popen(["labcomm",
"--typeinfo=/dev/stdout %s" % sys.argv[1]],
stdout=subprocess.PIPE)
signature = []
for l in typeinfo.stdout:
m = re.match('C#,sample,([^,]+),(.*)', l)
if m:
signature.append(Signature(m.group(1), m.group(2)))
for l in gen("x", "", signature):
print l
#!/usr/bin/python
import re
import sys
def split_match(pattern, multiline):
def match(s):
m = re.match(pattern, s)
if m:
return m.group(1)
pass
return filter(lambda s: s != None, map(match, multiline.split('\n')))
if __name__ == '__main__':
f = open(sys.argv[1])
sample = []
for l in map(lambda s: s.strip(), f):
lang,kind,func,arg = l[1:].split(l[0])
if lang == 'C' and kind == 'sample':
sample.append((func, arg))
pass
pass
result = []
result.extend(split_match('^[^|]*\|(.*)$', """
|#include <sys/types.h>
|#include <sys/stat.h>
|#include <fcntl.h>
|#include <labcomm.h>
|#include <labcomm_fd_reader.h>
|#include <labcomm_fd_writer.h>
|#include "c_code.h"
"""))
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
|void handle_%(func)s(%(arg)s *v, void *context)
|{
| struct labcomm_encoder *e = context;
| labcomm_encode_%(func)s(e, v);
|}""" % { 'func': func, 'arg': arg }))
pass
result.extend(split_match('^[^|]*\|(.*)$', """
|int main(int argc, char *argv[]) {
| struct labcomm_encoder *e;
| struct labcomm_decoder *d;
| int in, out;
|
| if (argc < 3) { return 1; }
| in = open(argv[1], O_RDONLY);
| if (in < 0) { return 1; }
| out = open(argv[2], O_WRONLY);
| if (out < 0) { return 1; }
| e = labcomm_encoder_new(labcomm_fd_writer, &out);
| d = labcomm_decoder_new(labcomm_fd_reader, &in);
"""))
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_encoder_register_%(func)s(e);
| labcomm_decoder_register_%(func)s(d, handle_%(func)s, e);
""" % { 'func': func, 'arg': arg }))
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_decoder_run(d);
| return 0;
|}
"""))
print "\n".join(result)
pass
#!/usr/bin/python
import re
import sys
def split_match(pattern, multiline):
def match(s):
m = re.match(pattern, s)
if m:
return m.group(1)
pass
return filter(lambda s: s != None, map(match, multiline.split('\n')))
if __name__ == '__main__':
f = open(sys.argv[1])
sample = []
for l in map(lambda s: s.strip(), f):
lang,kind,func,arg = l[1:].split(l[0])
if lang == 'C#' and kind == 'sample':
sample.append((func, arg))
pass
pass
result = []
result.extend(split_match('^[^|]*\|(.*)$', """
|using System;
|using System.IO;
|using se.lth.control.labcomm;
|
|public class cs_relay :
"""))
for func,arg in sample[0:-1]:
result.append(' %s.Handler,' % func)
pass
result.append(' %s.Handler' % sample[-1][0])
result.extend(split_match('^[^|]*\|(.*)$', """
|{
| LabCommEncoderChannel encoder;
"""))
for func,arg in sample:
if arg == 'void':
result.extend(split_match('^[^|]*\|(.*)$', """
| void %(func)s.Handler.handle() {
| %(func)s.encode(encoder);
| }
""" % { 'func': func}))
pass
else:
result.extend(split_match('^[^|]*\|(.*)$', """
| void %(func)s.Handler.handle(%(arg)s data) {
| %(func)s.encode(encoder, data);
| }
""" % { 'func': func, 'arg': arg}))
pass
pass
result.extend(split_match('^[^|]*\|(.*)$', """
| public cs_relay(String InName, String OutName) {
| FileStream InFile = new FileStream(InName,
| FileMode.Open,
| FileAccess.Read);
| LabCommDecoderChannel d = new LabCommDecoderChannel(InFile);
| FileStream OutFile = new FileStream(OutName,
| FileMode.OpenOrCreate,
| FileAccess.Write);
| encoder = new LabCommEncoderChannel(OutFile);
|
"""))
for func,arg in sample:
result.append(' %s.register(d, this);' % func)
pass
for func,arg in sample:
result.append(' %s.register(encoder);' % func)
pass
result.extend(split_match('^[^|]*\|(.*)$', """
| try {
| d.run();
| } catch (EndOfStreamException) {
| }
| }
| static void Main(String[] arg) {
| new cs_relay(arg[0], arg[1]);
| }
|}
"""))
print "\n".join(result)
exit(0)
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
|void handle_%(func)s(%(arg)s *v, void *context)
|{
| struct labcomm_encoder *e = context;
| labcomm_encode_%(func)s(e, v);
|}""" % { 'func': func, 'arg': arg }))
pass
result.extend(split_match('^[^|]*\|(.*)$', """
|int main(int argc, char *argv[]) {
| struct labcomm_encoder *e;
| struct labcomm_decoder *d;
| int in, out;
|
| if (argc < 3) { return 1; }
| in = open(argv[1], O_RDONLY);
| if (in < 0) { return 1; }
| out = open(argv[2], O_WRONLY);
| if (out < 0) { return 1; }
| e = labcomm_encoder_new(labcomm_fd_writer, &out);
| d = labcomm_decoder_new(labcomm_fd_reader, &in);
"""))
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_encoder_register_%(func)s(e);
| labcomm_decoder_register_%(func)s(d, handle_%(func)s, e);
""" % { 'func': func, 'arg': arg }))
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_decoder_run(d);
| return 0;
|}
"""))
print "\n".join(result)
pass
#!/usr/bin/python
# -*- coding: iso8859-15 -*-
import math
import os
import sys
import re
import traceback
def run_labcomm(base):
if not os.path.exists("gen/java/%s" % base):
os.makedirs("gen/java/%s" % base)
cmd = " ".join([
"java -jar ../compiler/labComm.jar",
"--c=gen/%s.c" % base,
"--h=gen/%s.h" % base,
"--python=gen/%s.py" % base,
"--java=gen/java/%s" % base,
"%s.lc" % base
])
print cmd
os.system(cmd)
class hexwriter(object):
def __init__(self):
self.pos = 0
self.ascii = ''
def write(self, data):
for c in data:
if ' ' <= c and c <= '}':
self.ascii += c
else:
self.ascii += '.'
sys.stdout.write("%2.2x " % ord(c))
self.pos += 1
if self.pos >= 15:
sys.stdout.write("%s\n" % self.ascii)
self.pos = 0
self.ascii = ""
def mark(self):
pass
def flush(self):
for i in range(self.pos, 15):
sys.stdout.write(" ")
sys.stdout.write("%s\n" % self.ascii)
self.pos = 0
self.ascii = ""
def generate(decl):
if decl.__class__ == labcomm.sample:
result = []
for values in generate(decl.decl):
result.append((decl, values))
return result
elif decl.__class__ == labcomm.struct:
result = []
if len(decl.field) == 0:
result.append({})
else:
values1 = generate(decl.field[0][1])
values2 = generate(labcomm.struct(decl.field[1:]))
for v1 in values1:
for v2 in values2:
v = dict(v2)
v[decl.field[0][0]] = v1
result.append(v)
return result
elif decl.__class__ == labcomm.array:
if len(decl.indices) == 1:
values = generate(decl.decl)
if decl.indices[0] == 0:
lengths = [0, 1, 2]
else:
lengths = [ decl.indices[0] ]
else:
values = generate(labcomm.array(decl.indices[1:],decl.decl))
if decl.indices[0] == 0:
lengths = [1, 2]
else:
lengths = [ decl.indices[0] ]
result = []
for v in values:
for i in lengths:
element = []
for j in range(i):
element.append(v)
result.append(element)
return result
elif decl.__class__ == labcomm.BOOLEAN:
return [False, True]
elif decl.__class__ == labcomm.BYTE:
return [-128, 0, 127]
elif decl.__class__ == labcomm.SHORT:
return [-32768, 0, 32767]
elif decl.__class__ == labcomm.INTEGER:
return [-2147483648, 0, 2147483647]
elif decl.__class__ == labcomm.LONG:
return [-9223372036854775808, 0, 9223372036854775807]
elif decl.__class__ == labcomm.FLOAT:
return [-math.pi, 0.0, math.pi]
elif decl.__class__ == labcomm.DOUBLE:
return [-math.pi, 0.0, math.pi]
elif decl.__class__ == labcomm.STRING:
return ['string',
'teckenstrng'.decode("iso8859-15")]
print decl
raise Exception("unhandled decl %s" % decl.__class__)
if __name__ == "__main__":
sys.path.insert(0, "../lib/python/")
import labcomm
print os.getcwd(), sys.argv
if not os.path.exists("gen"):
os.makedirs("gen")
files = sys.argv[1:]
print sys.argv, files
if len(files) == 0:
files = os.listdir(".")
for f in files:
m = re.match("(.*).lc", f)
if m:
run_labcomm(m.group(1))
sys.path.insert(0, "gen")
for f in files:
m = re.match("(.*).lc", f)
if m:
print f
h = hexwriter()
encoder = labcomm.Encoder(h)
signatures = []
i = __import__(m.group(1))
for k in dir(i):
v = getattr(i, k)
try:
s = v.signature
except:
s = None
if s:
signatures.append(s)
encoder.add_decl(s)
for s in signatures:
for e in generate(s):
encoder.encode(e[1], s)
h.flush()
#!/usr/bin/python
# -*- coding: iso8859-15 -*-
# -*- coding: utf-8 -*-
import argparse
import imp
import labcomm
import math
import os
import sys
import re
import traceback
import ccode
import cscode
def run_labcomm(base):
if not os.path.exists("gen/java/%s" % base):
os.makedirs("gen/java/%s" % base)
if not os.path.exists("gen/csharp"):
os.makedirs("gen/csharp")
if not os.path.exists("gen/c"):
os.makedirs("gen/c")
if not os.path.exists("gen/python"):
os.makedirs("gen/python")
cmd = " ".join([
"java -jar ../compiler/labComm.jar",
"--c=gen/c/%s.c" % base,
"--h=gen/c/%s.h" % base,
"--cs=gen/csharp/%s.cs" % base,
"--python=gen/python/%s.py" % base,
"--java=gen/java/%s" % base,
"--typeinfo=gen/%s.typeinfo" % base,
"%s.lc" % base
])
err = os.system(cmd)
if err != 0:
sys.exit(err / 256)
import struct
import subprocess
import sys
import threading
class hexwriter(object):
def __init__(self, filename=None):
def __init__(self, outfile):
self.pos = 0
self.ascii = ''
if filename:
self.outfile = open(filename, "w")
else:
self.outfile = None
self.outfile = outfile
def write(self, data):
for c in data:
......@@ -53,9 +30,10 @@ class hexwriter(object):
sys.stdout.write("%s\n" % self.ascii)
self.pos = 0
self.ascii = ""
self.outfile.write(data)
#self.outfile.write(data)
def mark(self):
self.flush()
pass
def flush(self):
......@@ -127,19 +105,149 @@ def generate(decl):
return [-9223372036854775808, 0, 9223372036854775807]
elif decl.__class__ == labcomm.FLOAT:
return [-math.pi, 0.0, math.pi]
def tofloat(v):
return struct.unpack('f', struct.pack('f', v))[0]
return [tofloat(-math.pi), 0.0, tofloat(math.pi)]
elif decl.__class__ == labcomm.DOUBLE:
return [-math.pi, 0.0, math.pi]
elif decl.__class__ == labcomm.STRING:
return ['string',
'teckenstrng'.decode("iso8859-15")]
return ['string', u'sträng' ]
print decl
raise Exception("unhandled decl %s" % decl.__class__)
def labcomm_compile(lc, name, args):
for lang in [ 'c', 'csharp', 'java', 'python']:
destdir = 'gen/%s/%s' % (name, lang)
if not os.path.exists(destdir):
os.makedirs(destdir)
pass
pass
cmd = args.labcomm.split() + [
"--c=gen/%s/c/%s.c" % (name, name),
"--h=gen/%s/c/%s.h" % (name, name),
"--cs=gen/%s/csharp/%s.cs" % (name, name),
"--python=gen/%s/python/%s.py" % (name, name),
"--java=gen/%s/java/" % name,
"--typeinfo=gen/%s/%s.typeinfo" % (name, name),
lc]
subprocess.check_call(cmd)
pass
def get_signatures(path):
fp, pathname, description = imp.find_module(os.path.basename(path)[0:-3],
[ os.path.dirname(path) ])
with fp as fp:
m = imp.load_module('signatures', fp, pathname, description)
pass
return m.signatures
class Test:
def __init__(self, program, signatures):
self.program = program
self.signatures = signatures
pass
def run(self):
print 'Testing', self.program
p = subprocess.Popen(self.program,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
self.expected = None
self.failed = False
self.next = threading.Semaphore(0)
decoder = threading.Thread(target=self.decode, args=(p.stdout,))
decoder.start()
class Writer:
def write(self, data):
p.stdin.write(data)
pass
def mark(self):
p.stdin.flush()
pass
pass
h = hexwriter(p.stdin)
encoder = labcomm.Encoder(Writer())
for name,signature in self.signatures:
encoder.add_decl(signature)
pass
print self.signatures
for name,signature in self.signatures:
print "Checking", name,
sys.stdout.flush()
for decl,value in generate(signature):
sys.stdout.write('.')
#print name,decl,value,value.__class__
self.expected = value
encoder.encode(value, decl)
self.next.acquire()
if self.failed:
p.terminate()
exit(1)
pass
print
pass
p.stdin.close()
print p.wait()
pass
def decode(self, f):
class Reader:
def read(self, count):
result = f.read(count)
if len(result) == 0:
raise EOFError()
return result
def mark(self, value, decl):
pass
pass
decoder = labcomm.Decoder(Reader())
try:
while True:
value,decl = decoder.decode()
if value != None:
if value != self.expected:
print "Coding error", value, self.expected, decl
self.failed = True
self.next.release()
pass
pass
except EOFError:
pass
print 'Done'
pass
pass
def run(test, signatures):
t = Test(test, signatures)
t.run()
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Run encoding test.')
class test_action(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
old = getattr(namespace, self.dest)
old.append(values)
parser.add_argument('--signatures')
parser.add_argument('--test', nargs='*', action=test_action, default=[])
args = parser.parse_args()
signatures = get_signatures(args.signatures)
for test in args.test:
run(test, signatures)
exit(0)
for lc in args.lc:
run(lc, args)
pass
exit(0)
print os.getcwd(), sys.argv
if not os.path.exists("gen"):
os.makedirs("gen")
......@@ -148,9 +256,6 @@ if __name__ == "__main__":
else:
files = [s[0:-3] for s in os.listdir(".") if s.endswith('.lc')]
for f in files:
run_labcomm(f)
for f in files:
cscode.test_program("gen/csharp/test_%s.cs" % f,
"gen/%s.typeinfo" % f)
......
#include <labcomm.h>
#include <labcomm_fd_reader_writer.h>
#include "gen/simple.h"
void simple_an_int_handler(simple_an_int *v,
void *context)
{
struct labcomm_encoder *e = context;
labcomm_encode_simple_an_int(e, v);
}
int main(int argc, char *argv[]) {
struct labcomm_decoder *d;
struct labcomm_encoder *e;
labcomm_decoder_register_simple_an_int(d, simple_an_int_handler, e);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment