diff --git a/site_ansto/instrument/TEST_SICS/unit_tests/sics_hdb.py b/site_ansto/instrument/TEST_SICS/unit_tests/sics_hdb.py index 9c54f308..96ad23b7 100644 --- a/site_ansto/instrument/TEST_SICS/unit_tests/sics_hdb.py +++ b/site_ansto/instrument/TEST_SICS/unit_tests/sics_hdb.py @@ -76,20 +76,22 @@ class HipadabaTree(object): self.root = root def short_tree(self, tree=None): - """ + """Creates a map from the tree/node that can be used or printed """ if tree is None: tree = self.root - if isinstance(tree, type(self.root)): + if "attrib" not in dir(tree) or 'id' not in tree.attrib: tree_part = {"name": ""} else: tree_part = {"name": tree.attrib['id']} - tree_part["children"] = [ch.attrib['id'] for ch in tree.findall('component')] - tree_part["properties"] = [ch.attrib['id'] for ch in tree.findall('property')] + tree_part["children"] = sorted([ch.attrib['id'] for ch in tree.findall('component')]) + tree_part["properties"] = sorted([ch.attrib['id'] for ch in tree.findall('property')]) return tree_part def find_path(self, path, tree=None): - debug = True + """Finds a node from the given tree and path + """ + debug = False if tree is None: tree = self.root if debug: @@ -115,7 +117,7 @@ class HipadabaTree(object): if tree is None: tree = self.root text = [] - if isinstance(tree, type(self.root)): + if "attrib" not in dir(tree) or 'id' not in tree.attrib: text += [' '*indent + '* ' + ''] else: text += [' '*indent + '* ' + tree.attrib['id']] @@ -138,6 +140,15 @@ class HipadabaTree(object): def getNode(self, path, tree=None): return self.find_path(path, tree) + def getValue(self, path, tree=None): + node = self.find_path(path, tree) + if node is None: + return None + items = [ch.text for ch in node.findall('value') if ch.text is not None] + if len(items) == 0: + return "" + return ','.join(items) + def getProperty(self, path, property, tree=None): node = self.find_path(path, tree) if node is None: @@ -149,7 +160,7 @@ class HipadabaTree(object): items = [ch.text for ch in node.findall('value') if ch.text is not None] if len(items) == 0: return "" - return ' '.join(items) + return ','.join(items) def getProperties(self, path, tree=None): node = self.find_path(path, tree) @@ -159,11 +170,13 @@ class HipadabaTree(object): def getChildren(self, path, tree=None): node = self.find_path(path, tree) - if node: + if node is not None: return sorted([ch.attrib['id'] for ch in node.findall('component')]) return None if __name__ == "__main__": + """this test uses a "junk.xml" file extracted for SICS + """ filename = "junk.xml" fd = open(filename, "r") lines = fd.readlines() diff --git a/site_ansto/instrument/TEST_SICS/unit_tests/sics_test.py b/site_ansto/instrument/TEST_SICS/unit_tests/sics_test.py index 500c2907..256d7bd9 100644 --- a/site_ansto/instrument/TEST_SICS/unit_tests/sics_test.py +++ b/site_ansto/instrument/TEST_SICS/unit_tests/sics_test.py @@ -42,7 +42,7 @@ class Able(unittest.TestCase): def load_hipadaba(self): def cb0(result, *args, **kw): - with open("junksh.xml", "w") as outfile: + with open("hipadaba.xml", "w") as outfile: for line in result: outfile.write(line + '\n') if result[0][0] != '<': @@ -52,7 +52,7 @@ class Able(unittest.TestCase): self.hipadaba = HipadabaTree('\n'.join(result)) self.tree_deferred.callback(self.hipadaba) self.tree_deferred = defer.Deferred() - d = self.send_command("getgumtreexml /") + d = self.send_command("tcl:test_suite::getsicsxml /") d.addCallback(cb0) return self.tree_deferred @@ -76,7 +76,7 @@ class Baker(Able): print "Login:", result, args, kw if self.sics.login != 2: raise Exception("Bad login:" + repr(self.sics.login)) - d = self.send_command("fileeval TEST_SICS/test_suite.tcl") + d = self.send_command("fileeval TEST_SICS/unit_tests/test_suite.tcl") d.addCallback(cb1) def cb1(result, *args, **kw): if debug: @@ -177,13 +177,13 @@ class Baker(Able): d.addCallback(cb3) return d - def test_004_000_xml(self): + def test_004_000_gumtreexml(self): #raise unittest.SkipTest("Not doing this test now") d = self.send_command("getgumtreexml /") def cb3(result, *args, **kw): - global root + global gumtreexml #print "XML:", len(result) - with open("junk.xml", "w") as outfile: + with open("gumtree.xml", "w") as outfile: for line in result: outfile.write(line + '\n') if "" != result[-1]: @@ -191,31 +191,41 @@ class Baker(Able): txt = [] for line in result: txt.append(''.join(c for c in line if ord(c) >= 32)) - root = HipadabaTree('\n'.join(txt)).root + gumtreexml = HipadabaTree('\n'.join(txt)).root d.addCallback(cb3) return d - def test_004_001_xml(self): - print - print "Root:", root, root.attrib - for child in root.findall('component'): - print child, child.tag, child.attrib + def test_004_001_gumtreexml(self): + self.assertTrue(gumtreexml.attrib == {}) + id_list = [] + for child in gumtreexml.findall('component'): + id_list.append(child.attrib['id']) + #print child, child.tag, child.attrib #for grandchild in child.findall('component'): # print " ", grandchild.attrib + self.assertTrue('commands' in id_list) + self.assertTrue('instrument' in id_list) + self.assertTrue('sample' in id_list) + self.assertTrue('monitor' in id_list) + self.assertTrue('user' in id_list) + self.assertTrue('experiment' in id_list) + self.assertTrue('control' in id_list) - def test_004_002_xml(self): - print - child = root + def test_004_002_gumtreexml(self): + child = gumtreexml for node in "/sample/ps9/".strip('/').split('/'): children = [ch for ch in child.findall('component') if ch.attrib['id'].lower() == node.lower()] - print children + self.assertTrue(len(children) > 0) child = children[0] - print child - print child.attrib - print [ch.attrib['id'] for ch in child.findall('component')] - print [(ch.attrib['id'], [v.text for v in ch.findall('value')]) for ch in child.findall('property')] + self.assertTrue(len(child.attrib) > 0) + self.assertTrue(len([ch.attrib['id'] for ch in child.findall('component')]) > 0) + self.assertTrue(len([(ch.attrib['id'], [v.text for v in ch.findall('value')]) for ch in child.findall('property')]) > 0) def test_005_drive(self): + """Skipping example + + Skips on the basis that the equipment to be tested is not configured + """ global motors if not "ds9" in motors: raise unittest.SkipTest("Cannot drive motor ds9: does not exist") @@ -228,13 +238,39 @@ class Baker(Able): return d def test_006_drive(self): - d = self.send_command("drive m1 20 m2 20 ") + """Drive to where the motors already are + + Should finish quickly + """ + self.deferred = defer.Deferred() def cb3(result, *args, **kw): #print "Drive:", result if "Driving finished successfully" != result[-1]: raise Exception("Drive is not complete, ends:" + repr(result[-1])) - d.addCallback(cb3) - return d + for item in result: + if item.startswith("New m1 position:"): + self.assertTrue(round(float(item.split(":")[1]) - self.m1, 3) == 0) + if item.startswith("New m2 position:"): + self.assertTrue(round(float(item.split(":")[1]) - self.m2, 3) == 0) + self.deferred.callback(True) + def cb2(result, *args, **kw): + #print "m2:", result + if not result[0].startswith("m2 = "): + raise Exception("Unexpected m2 response: " + repr(result)) + self.m2 = float(result[0].split("=")[1]) + d = self.send_command("drive m1 %.3f m2 %.3f" % (self.m1, self.m2)) + d.addCallback(cb3) + def cb1(result, *args, **kw): + #print "m1:", result + if not result[0].startswith("m1 = "): + raise Exception("Unexpected m1 response: " + repr(result)) + self.m1 = float(result[0].split("=")[1]) + d = self.send_command("m2") + d.addCallback(cb2) + d = self.send_command("m1") + d.addCallback(cb1) + return self.deferred + test_006_drive.timeout = 10 def test_007_mercury(self): raise unittest.SkipTest("Not doing this test now (borken)") @@ -254,7 +290,8 @@ class Baker(Able): test_007_mercury.timeout = 2 def test_008_mercury_hipadaba(self): - raise unittest.SkipTest("Not doing this test now (borken)") + """Test the hipadaba tree and mechanism + """ global hipadaba debug = False if hipadaba is None: @@ -299,9 +336,10 @@ class Baker(Able): if debug: hipadaba.print_tree(y) text = hipadaba.list_tree(y, props=True, indent=6) - print - for line in text: - print line + if debug: + print "Tree (/sample/tc9/level/helium):" + for line in text: + print line class Zulu(Able): def test_performance(self): diff --git a/site_ansto/instrument/TEST_SICS/unit_tests/test_suite.tcl b/site_ansto/instrument/TEST_SICS/unit_tests/test_suite.tcl new file mode 100644 index 00000000..1f644fb6 --- /dev/null +++ b/site_ansto/instrument/TEST_SICS/unit_tests/test_suite.tcl @@ -0,0 +1,122 @@ +# vim: ft=tcl ts=8 sts=2 sw=2 +# Author Douglas Clowes (dcl@ansto.gov.au) 2014 +# +# TCL utility functions for the SICS Unit Test Suite +# +namespace eval test_suite { + variable version 1.0 +} + +# Send the config dictionary as an ini file image +# +proc test_suite::show_config {the_dict} { + upvar 1 $the_dict my_dict + foreach s [config_reader::get_sections my_dict] { + set section "$s" + clientput "\n\[$section\]" + foreach n [config_reader::get_variables my_dict $s] { + set name "$n" + set value "[config_reader::get_var my_dict $section $n]" + clientput "$name = $value" + } + } +} + +# Send the hipadaba tree as an XML image +# +# Like getgumtreexml except it does the whole tree and does not split values +# +proc test_suite::getdataType {path} { + return [lindex [split [hinfo $path] ,] 0] +} + +proc test_suite::encode {str} { + set result [string map -nocase { + "\"" {"} + {'} {'} + {<} {<} + {>} {>} + {&} {&} + \u0 {} + \u1 {} + \u2 {} + \u3 {} + \u4 {} + \u5 {} + \u6 {} + \u7 {} + \u8 {} + \u9 { } + \ua { } + \ub {} + \uc {} + \ud { } + \ue {} + \uf {} + \u10 {} + \u11 {} + \u12 {} + \u13 {} + \u14 {} + \u15 {} + \u16 {} + \u17 {} + \u18 {} + \u19 {} + \u1a {} + \u1b {} + \u1c {} + \u1d {} + \u1e {} + \u1f {} + } $str] + return $result +} + +proc test_suite::make_nodes {path result indent} { + set nodename [file tail $path]; + set type [test_suite::getdataType $path] + set prefix [string repeat " " $indent] + set newIndent [expr $indent + 2] + + append result "$prefix\n" + if {[string compare -nocase $type "none"] != 0} { + set value [test_suite::encode [hval $path]] + append result "$prefix $value\n" + } + foreach p [test_suite::property_elements $path $newIndent] { + append result $p + } + foreach x [hlist $path] { + set result [test_suite::make_nodes [string map {// /} "$path/$x"] $result $newIndent] + } + append result "$prefix\n" + return $result +} + +proc test_suite::property_elements {path indent} { + set prefix [string repeat " " $indent] + foreach {key rvalue} [string map {= " "} [hlistprop $path tcl]] { + set value [test_suite::encode $rvalue] + lappend proplist "$prefix\n" + lappend proplist "$prefix $value\n" + lappend proplist "$prefix\n" + } + if [info exists proplist] {return $proplist} +} + +proc test_suite::getsicsxml {path} { + append result "\n" + append result "\n" + + if {[string compare $path "/" ] == 0} { + foreach n [hlist $path] { + set result [test_suite::make_nodes $n $result 2] + } + } else { + set result [test_suite::make_nodes $path $result 2] + } + + append result "\n" +} +