Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4512670
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/README-testing b/README-testing
new file mode 100644
index 0000000..3c50858
--- /dev/null
+++ b/README-testing
@@ -0,0 +1,22 @@
+
+=== Simple tests (commandline, config file)
+
+
+Run
+
+ # make check-TESTS
+
+to run the tests written in python.
+
+
+
+
+=== Unit tests
+
+These use gdb and pexpect to set boothd state to some configured value,
+injecting some input and looking at the output.
+
+ # python script/unit-test.py src/boothd unit-tests/
+
+
+
diff --git a/script/unit-test.py b/script/unit-test.py
new file mode 100644
index 0000000..0c15a39
--- /dev/null
+++ b/script/unit-test.py
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+
+import os
+import re
+import shutil
+import sys
+import time
+import pexpect
+
+binary = sys.argv[1]
+test_base = sys.argv[2] + "/"
+
+
+class Common():
+ gdb = None
+ booth = None
+ prompt = "CUSTOM-GDB-PROMPT-%d-%d" % (os.getpid(), time.time())
+
+ def sync(timeout=-1):
+ gdb.expect(prompt, timeout)
+
+ def __init__(self):
+ booth = pexpect.spawn(binary, args=["daemon", "-D", "-c", test_base + "/booth.conf"])
+ booth.expect("o") # TODO
+
+ gdb = pexpect.spawn("gdb",
+ args=["-quiet", "-p", booth.pid],
+ timeout=30,
+ maxread=32768)
+ gdb.expect("(gdb)")
+ gdb.sendline("set pagination off\n")
+ gdb.sendline("set prompt " + prompt + "\n");
+ self.sync(2000)
+
+ def send_cmd(stg):
+ gdb.sendline(stg + "\n")
+ gdb.sync()
+
+ def set_val(name, value, numeric_conv=None):
+ # string value?
+ if re.match('^"', value):
+ send_cmd("print strcpy(" + name + ", " + value + ")")
+ # numeric
+ elif numeric_conv:
+ send_cmd("set variable " + name + " = " + numeric_conv + "(" + value + ")")
+ else:
+ send_cmd("set variable " + name + " = " + value)
+
+
+class Message(Common):
+ def set_break():
+ "message_recv"
+
+ def send_vals(data):
+ for (n, v) in data:
+ set_val("msg->" + n, v, "htonl")
+
+class Ticket(Common):
+ def send_vals(data):
+ for (n, v) in data:
+ set_val(n, v)
+
+def read_test_input(file, state=None):
+ fo = open(file, "r")
+ m = { "ticket": {}, "message" : {} }
+ for line in fo.readlines():
+ # comment?
+ if re.match("^\\s*#", line):
+ continue
+
+ # message resp. ticket
+ res = re.match("^\\s*(\\w+)\\s*:\\s*$", line)
+ if res:
+ state = res.group(1)
+ continue
+
+ res = re.match("^\\s*(\\S+)\\s*(.*)\\s*$", line)
+ if res:
+ assert(state)
+ if not m[state]:
+ m[state] = {}
+ m[state][ res.group(1) ] = res.group(2)
+ return m
+
+if __name__ == '__main__':
+ if os.geteuid() == 0:
+ sys.stderr.write("Must be run non-root; aborting.\n")
+ sys.exit(1)
+
+ defaults = read_test_input(test_base + "_defaults.txt", state="ticket")
+ print defaults
+ sys.exit(0)
+
+
+##
+##name value
+##
+##value.match
+##
+##function void():
+## tmp_path = '/tmp/booth-tests'
+## if not os.path.exists(tmp_path):
+## os.makedirs(tmp_path)
+## test_run_path = tempfile.mkdtemp(prefix='%d.' % time.time(), dir=tmp_path)
+##
+## suite = unittest.TestSuite()
+## testclasses = [
+## SiteConfigTests,
+## #ArbitratorConfigTests,
+## ClientConfigTests,
+## ]
+## for testclass in testclasses:
+## testclass.test_run_path = test_run_path
+## suite.addTests(unittest.TestLoader().loadTestsFromTestCase(testclass))
+##
+## runner_args = {
+## 'verbosity' : 4,
+## }
+## major, minor, micro, releaselevel, serial = sys.version_info
+## if major > 2 or (major == 2 and minor >= 7):
+## # New in 2.7
+## runner_args['buffer'] = True
+## runner_args['failfast'] = True
+## pass
+##
+## # not root anymore, so safe
+## # needed because old instances might still use the UDP port.
+## os.system("killall boothd")
+##
+## runner = unittest.TextTestRunner(**runner_args)
+## result = runner.run(suite)
+##
+## if result.wasSuccessful():
+## shutil.rmtree(test_run_path)
+## sys.exit(0)
+## else:
+## print "Left %s for debugging" % test_run_path
+## s
+##
diff --git a/unit-tests/_defaults.txt b/unit-tests/_defaults.txt
new file mode 100644
index 0000000..e96e4f0
--- /dev/null
+++ b/unit-tests/_defaults.txt
@@ -0,0 +1,42 @@
+# vim: ft=sh et :
+
+
+# ticket defaults, mostly set via config file.
+ticket:
+
+ name "ticket"
+
+ ## these would matter if testing via GDB had high latencies
+ #expiry 60
+ #timeout 10
+ #acquire_after 30
+
+
+
+ # defaults for all tests
+ state ST_INIT
+ next_cron time(0)+500
+ # local is site[0] per convention
+
+ owner booth_conf->site[1]
+ expires time(0)+600
+ last_ack_ballot 242
+
+ proposer 0
+ proposed_owner 0
+ new_ballot 0
+ proposal_acknowledges 0
+ retry_number 0
+
+
+
+# defaults for input message.
+# sender is a peer, and it wants something.
+message:
+
+ header.id "ticket"
+ owner -1
+ ballot 0
+ prev_ballot 0
+ expiry 0
+
diff --git a/unit-tests/booth.conf b/unit-tests/booth.conf
new file mode 100644
index 0000000..2988387
--- /dev/null
+++ b/unit-tests/booth.conf
@@ -0,0 +1,16 @@
+# "local"
+site=127.0.0.1
+
+# these should not exist, although it shouldn't matter much
+# because no packets should be sent anyway
+arbitrator="127.0.0.243"
+site="127.0.0.244"
+
+# The ticket name, which corresponds to a set of resources which can be
+# fail-overed among different sites.
+ticket="ticketA"
+ticket="ticketB"
+ expire = 60
+ timeout = 10
+ acquire-after = 30
+ weights = 1,2,3
diff --git a/unit-tests/init-catchup.txt b/unit-tests/init-catchup.txt
new file mode 100644
index 0000000..621c209
--- /dev/null
+++ b/unit-tests/init-catchup.txt
@@ -0,0 +1,6 @@
+
+
+
+input:
+ :
+
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jun 25, 6:27 AM (10 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1952434
Default Alt Text
(6 KB)
Attached To
Mode
rB Booth
Attached
Detach File
Event Timeline
Log In to Comment