Skip to content

Commit

Permalink
test infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Bernauer committed Oct 20, 2011
1 parent b8dd01a commit d44f3e1
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
dist/
.quickfix
*.swp
10 changes: 9 additions & 1 deletion bitcoin-script-engine.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ library
build-depends:
bytestring >= 0.9.1.10
exposed-modules:
Language.Bitcoin.Opcodes
Language.Bitcoin.Machine
Language.Bitcoin.Opcodes
Language.Bitcoin.Simulator

executable bitcoin-script-engine
hs-source-dirs: src
main-is: Main.hs
build-depends: base >= 4
ghc-options: -Wall

executable Test
hs-source-dirs: src, test
main-is: Test.hs
build-depends:
HUnit >= 1.2.2.1
other-modules:
Language.Bitcoin.Test.Opcodes
73 changes: 73 additions & 0 deletions make
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env python
#vim: set filetype=python

import subprocess
import sys
import os

def execute(commandline):
proc = subprocess.Popen(commandline.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
sys.stdout.write(out)
sys.stdout.write(err)
return (proc.returncode, out, err)

def notify(text, color):
cmd = "/usr/bin/osd_cat -A right -p bottom -o -40 -d 2 -c %s" % color

if os.fork() == 0:
subprocess.Popen(cmd.split(' '), stdin=subprocess.PIPE).communicate(text)
sys.exit(0)

def getFirstLine(text, predicate):
return filter(predicate, text.split("\n"))[0]

def isBuildError(line):
return line.startswith("src/Ocram") or line.startswith("test/Ocram")

def isTestError(line):
return line.startswith('### Failure in:') or line.startswith('### Error in:')

def diff_code(text):
expected = []
got = []

for line in text.split("\n"):
if line.startswith('expected: "') and line.count('"') == 2:
(pre, code, post) = line.split('"')
expected.append(code)
if line.startswith(' but got: "') and line.count('"') == 2:
(pre, code, post) = line.split('"')
got.append(code)

assert len(expected) == len(got), str(expected) + "\n" + str(got)

def paste(name, code):
f = open(name, "w")
f.write(code.replace(r'\n', '\n'))
f.close()

inf = "/tmp/infile.c"
outf = "/tmp/outfile.c"

for (ins, outs) in zip(got, expected):
print "----- diff"
paste(inf, ins)
paste(outf, outs)

proc = subprocess.Popen(["wdiff", inf, outf])
proc.wait()

(code, out, err) = execute("runhaskell Setup.hs build")
if code != 0:
open("./.quickfix", "w").write(err)
notify(getFirstLine(err, isBuildError), "red")
sys.exit(1)

(code, out, err) = execute("./dist/build/Test/Test")
if code != 0:
notify("failed", "red")
sys.exit(1)

notify("success", "green")
sys.exit(0)
4 changes: 3 additions & 1 deletion src/Language/Bitcoin/Machine.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import Data.ByteString
data Word =
WrdData ByteString
| WrdNum Int
deriving (Show, Eq)

type Stack = [Word]

data Command =
CmdOpcode Opcode
| CmdData ByteString
deriving (Show, Eq)

type Script = [Command]

data Machine = Machine Stack Script
data Machine = Machine Script Stack deriving (Show)
19 changes: 19 additions & 0 deletions src/Language/Bitcoin/Simulator.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Language.Bitcoin.Simulator
(
run_simulator
) where

import Language.Bitcoin.Machine
import Language.Bitcoin.Opcodes

run_simulator :: Machine -> Either (String, Machine) Stack
run_simulator (Machine [] stack) = Right stack
run_simulator machine =
case execute machine of
Left what -> Left (what, machine)
Right machine' -> run_simulator machine'

execute :: Machine -> Either String Machine
execute (Machine ((CmdOpcode OP_0):ops) stack) = Right $ Machine ops $ (WrdNum 0) : stack
execute (Machine ((CmdOpcode OP_FALSE):ops) stack) = Right $ Machine ops $ (WrdNum 0) : stack
execute _ = error "sorry, not supported yet"
19 changes: 19 additions & 0 deletions test/Language/Bitcoin/Test/Opcodes.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Language.Bitcoin.Test.Opcodes
(
tests
) where

import Language.Bitcoin.Opcodes
import Language.Bitcoin.Machine
import Language.Bitcoin.Simulator
import Test.HUnit

tests = TestLabel "Opcodes" $ TestList $ map runTest testCases

testCases = [([CmdOpcode(OP_0)], [], [WrdNum 0])]

runTest :: (Script, Stack, Stack) -> Test
runTest (script, stack, expected) = TestCase $
case run_simulator (Machine script stack) of
Left (what, machine) -> assertString $ show what ++ "\n" ++ show machine
Right stack' -> expected @=? stack'
15 changes: 15 additions & 0 deletions test/Test.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Test.HUnit (Test(TestList), runTestText, putTextToHandle, Counts(errors, failures))
import System.IO (stderr)
import System.Exit (exitWith, ExitCode(ExitFailure))

import qualified Language.Bitcoin.Test.Opcodes as A

tests = TestList [A.tests]

main = do
(count, _ ) <- runTestText (putTextToHandle stderr False) tests
if errors count > 0 || failures count > 0
then
exitWith $ ExitFailure 1
else
return ()

0 comments on commit d44f3e1

Please sign in to comment.