buildframework/helium/tools/common/python/lib/cpythontest/test_ats4_aste.py
changeset 179 d8ac696cc51f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildframework/helium/tools/common/python/lib/cpythontest/test_ats4_aste.py	Wed Dec 23 19:29:07 2009 +0200
@@ -0,0 +1,500 @@
+# -*- coding: latin-1 -*-
+
+#============================================================================ 
+#Name        : test_ats4_aste.py 
+#Part of     : Helium 
+
+#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+#All rights reserved.
+#This component and the accompanying materials are made available
+#under the terms of the License "Eclipse Public License v1.0"
+#which accompanies this distribution, and is available
+#at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+#Initial Contributors:
+#Nokia Corporation - initial contribution.
+#
+#Contributors:
+#
+#Description:
+#===============================================================================
+
+""" Testing ATS4 ASTE framework. """
+
+# pylint: disable-msg=E1101
+
+from cStringIO import StringIO
+from pprint import pprint
+from xml.etree.ElementTree import fromstring, tostring
+from xml.etree import ElementTree as et
+import difflib
+import logging
+logging.getLogger().setLevel(logging.ERROR)
+import re
+import tempfile
+import zipfile
+import os
+
+from path import path
+import amara
+import mocker
+
+import ats3.aste
+
+TEST_PATH = None
+TEST_FILES = {}
+TEST_ASSET_FILES = {}
+TSRC = None
+OUTPUT = None
+TEST_ZIP_PATH = None
+
+# Shortcuts
+E = et.Element
+SE = et.SubElement
+
+_logger = logging.getLogger("test.ats4_aste")
+
+class Bunch(object):
+    
+    def __init__(self, **kwargs): 
+        self.__dict__.update(kwargs)
+    
+
+def equal_xml(xml1, xml2):
+    """Check the equality of the given XML snippets.
+    
+    Tag name equality:
+    
+    >>> equal_xml('<a/>', '<a/>')
+    True
+    >>> equal_xml('<a/>', '<b/>')
+    False
+    
+    Attribute equality:
+    
+    >>> equal_xml('<a k="v"/>', '<a k="v"/>')
+    True
+    >>> equal_xml('<a k="v"/>', '<a k="w"/>')
+    False
+    
+    Text content equality:
+    
+    >>> equal_xml('<a>v</a>', '<a>v</a>')
+    True
+    >>> equal_xml('<a>v</a>', '<a>w</a>')
+    False
+    >>> equal_xml('<a>v</a>', '<a></a>')
+    False
+    
+    Text content equality when whitespace differs:
+    >>> equal_xml('<a>v</a>', '<a>v </a>')
+    True
+
+    Equality of child elements:
+    
+    >>> equal_xml('<a><b><c k="v"/></b></a>', '<a><b><c k="v"/></b></a>')
+    True
+    >>> equal_xml('<a><b><c k="v"/></b></a>', '<a><b><c k="w"/></b></a>')
+    False
+    >>> equal_xml('<a><b><c k="v"/>v</b></a>', '<a><b><c k="v"/>w</b></a>')
+    False
+    >>> equal_xml('<a><b><c k="v"/>v</b></a>', '<a><b><c k="v"/>v </b></a>')
+    True
+    
+    """
+    if isinstance(xml1, basestring):
+        xml1 = fromstring(xml1)
+    if isinstance(xml2, basestring):
+        xml2 = fromstring(xml2)
+    if xml1.tag != xml2.tag:
+        return False
+    if xml1.attrib != xml2.attrib:
+        return False
+    if xml1.text:
+        if not xml2.text:
+            return False
+    if xml2.text:
+        if not xml1.text:
+            return False
+    if xml1.text and xml2.text and xml1.text.strip() != xml2.text.strip():
+        return False
+    if xml1.tail is not None and xml2.tail is not None:
+        if xml1.tail.strip() != xml2.tail.strip():
+            return False
+    elif xml1.tail != xml2.tail:
+        return False
+    children1 = list(xml1.getchildren())
+    children2 = list(xml2.getchildren())
+    if len(children1) != len(children2):
+        return False
+    for child1, child2 in zip(children1, children2):
+        return equal_xml(child1, child2)
+    return True        
+
+
+def setup_module():
+    global TEST_PATH, OUTPUT, TEST_ZIP_PATH
+    TEST_PATH = path(tempfile.mkdtemp())
+    OUTPUT = TEST_PATH.joinpath("TestAsset")
+    TEST_ZIP_PATH = TEST_PATH.joinpath("test_zip")
+    asset = TEST_PATH
+    component = TEST_PATH
+    component.joinpath("group").makedirs()
+    for path_parts in (("output", "images", "file1.fpsx"),
+                       ("output", "images", "file2.fpsx")):
+        filename = component.joinpath(*path_parts)
+        if not filename.parent.exists():
+            filename.parent.makedirs()
+        filename.touch()
+        TEST_FILES.setdefault(path_parts[1], []).append(file)
+    for path_parts in (("TestAsset", "Localisation", "S60", "localisation.txt"),
+                       ("TestAsset", "TestCases", "TC_100_Test0", "file1.sis"),
+                       ("TestAsset", "TestCases", "TC_100_Test0", "file2.tcf"),
+                       ("TestAsset", "Tools", "TestCaseCreator", "test_creator.ini"),
+                       ("TestAsset", "testdrop.xml"),):
+        filename = asset.joinpath(*path_parts)
+        if not filename.parent.exists():
+            filename.parent.makedirs()
+        filename.touch()
+        TEST_ASSET_FILES.setdefault(path_parts[1], []).append(file)
+    try:
+        zip_component = TEST_ZIP_PATH
+        filename = zip_component.joinpath("TestAsset.zip")
+        if not filename.parent.exists():
+            filename.parent.makedirs()
+        filename.touch()
+        zfile = zipfile.ZipFile(zip_component.joinpath("TestAsset.zip"), "w", zipfile.ZIP_DEFLATED)
+        for p in TEST_ASSET_FILES:
+            print p
+            zfile.write(p)
+        zfile.close()
+        TEST_ASSET_FILES.setdefault("ZIP", []).append(file)
+    except OSError:
+        print "Got except OSError. Continuing...\n"  
+        
+    
+def teardown_module():
+    path(TEST_PATH).rmtree()
+    
+    
+class TestTestPlan(mocker.MockerTestCase):
+
+    def __init__(self, methodName="runTest"):
+        mocker.MockerTestCase.__init__(self, methodName)
+             
+    def setUp(self):
+        opts = Bunch(testrun_name="testrun", harness="ASTE", 
+                     device_type="product", plan_name="ats3_test_plan", diamonds_build_url="",
+                     software_version="W810", software_release="SPP 51.32", device_language="English",
+                     testasset_location=TEST_PATH.joinpath("TestAsset"), testasset_caseids="100",repeat="1", report_email="",
+                     file_store=path(), test_timeout="60", device_hwid="5425", test_type="smoke")
+        self.tp = ats3.aste.AsteTestPlan(opts)
+        self.image_files = TEST_FILES["images"]
+        self.test_timeout = self.tp["test_timeout"]
+        self.device_hwid = self.tp["device_hwid"]
+        self.test_harness = self.tp["harness"]
+        self.device_language = self.tp["device_language"]
+        self.software_release = self.tp["software_release"]
+        self.software_version = self.tp["software_version"]
+        self.testasset_caseids = self.tp["testasset_caseids"]
+        self.testasset_location = self.tp["testasset_location"]
+        self.test_type = self.tp["test_type"]
+        
+        if self.testasset_location != "":
+            self.test_asset_testcases = [self.testasset_location.joinpath("TestCases", "TC_100_Test0", "file1.sis"), self.testasset_location.joinpath("TestCases", "TC_100_Test0", "file2.tcf")]
+            self.test_asset_tools = [self.testasset_location.joinpath("Tools", "TestCaseCreator", "test_creator.ini")]
+            self.test_asset_localisation = [self.testasset_location.joinpath("Localisation", "S60", "localisation.txt")]
+            self.test_asset_testdrop = self.testasset_location.joinpath("testdrop.xml")
+        else:
+            self.test_asset_testcases = TEST_ASSET_FILES["TestCases"]
+            self.test_asset_tools = TEST_ASSET_FILES["Tools"]
+            self.test_asset_localisation = TEST_ASSET_FILES["Localisation"]
+            self.test_asset_testdrop = TEST_ASSET_FILES["testdrop.xml"]
+
+            
+    def test_creation(self):        
+        assert self.tp["testrun_name"] == "testrun"
+        assert self.tp["harness"] == "ASTE"
+        assert self.tp["device_type"] == "product"
+    
+    def test_insert_set(self):
+        
+        self.tp.insert_set(image_files=self.image_files,
+                           test_timeout=self.test_timeout)
+        
+        assert self.tp.sets[0] == dict(name="set0",
+                                       image_files=self.image_files,
+                                       test_timeout=self.test_timeout,
+                                       test_harness=self.test_harness)
+
+    def test_post_actions_email(self):
+        assert not self.tp.post_actions
+        receiver = "joe.average@example.com"
+        self.tp.report_email = receiver
+        assert len(self.tp.post_actions) == 1
+        action, items = self.tp.post_actions[0]
+        items = dict(items)
+        assert action == "SendEmailAction"
+        assert items["to"] == receiver
+    
+    def test_post_actions_ats3_report_only(self):
+        file_store = path("path/to/files")
+        self.tp.file_store = file_store
+        self.tp.harness = "EUNIT"
+        assert len(self.tp.post_actions) == 2
+        action, items = self.tp.post_actions[0]
+        items = dict(items)
+        assert action == "FileStoreAction"
+        assert items["report-type"] == "ATS_REPORT"
+        assert items["to-folder"].startswith(file_store)
+        assert items["to-folder"].endswith("ATS3_REPORT")
+    
+    def test_post_actions_aste(self):
+        file_store = path("path/to/files")
+        self.tp.file_store = file_store
+        assert len(self.tp.post_actions) == 2
+        action, items = self.tp.post_actions[1]
+        items = dict(items)
+        assert action == "FileStoreAction"
+        assert items["report-type"] == "ASTE_REPORT"
+        assert items["to-folder"].startswith(file_store)
+        assert items["to-folder"].endswith("ASTE_REPORT")
+        
+    def test_post_actions_diamonds(self):
+        self.tp.diamonds_build_url = "http://diamonds.nmp.company.com/diamonds/builds/1234"
+        assert len(self.tp.post_actions) == 1
+        action, items = self.tp.post_actions[0]
+        assert action == "DiamondsAction"
+        assert not items
+
+
+            
+class TestXMLGeneration(mocker.MockerTestCase):
+    """
+    Unit tests for the test.xml generation.
+    """    
+
+    def __init__(self, methodName="runTest"):
+        self.image_files = None
+        self.report_email = None
+        self.diamonds_build_url = None
+        self.test_harness = None
+        self.file_store = None
+        self.testasset_location = None
+        self.test_plan = None
+        self.gen = None
+        mocker.MockerTestCase.__init__(self, methodName)
+        
+        
+    def generate_xml(self):
+        def files(*paths):
+            return [TEST_PATH.joinpath(p) for p in paths]
+        self.image_files = files("output/images/file1.fpsx", "output/images/file2.fpsx")
+        self.report_email = "test.receiver@company.com"
+        self.diamonds_build_url = "http://diamonds.nmp.company.com/diamonds/builds/1234"
+        self.test_harness = "ASTE"
+        self.file_store = path(r"path/to/reports")
+        self.testasset_location = OUTPUT
+        
+        self.mocker.restore()
+        test_plan = self.mocker.mock(count=False)
+        mocker.expect(test_plan["testrun_name"]).result("test")
+        mocker.expect(test_plan["harness"]).result("ASTE")
+        mocker.expect(test_plan["device_type"]).result("product")
+        mocker.expect(test_plan["plan_name"]).result("test plan")
+        mocker.expect(test_plan["diamonds_build_url"]).result(self.diamonds_build_url)
+        mocker.expect(test_plan["test_timeout"]).result("60")
+        mocker.expect(test_plan["device_hwid"]).result("5425")
+        mocker.expect(test_plan["testasset_location"]).result(self.testasset_location)
+        mocker.expect(test_plan["testasset_caseids"]).result("100")
+        mocker.expect(test_plan["report_email"]).result(self.report_email)
+        mocker.expect(test_plan["software_release"]).result("SPP 51.32")
+        mocker.expect(test_plan["software_version"]).result("W810")
+        mocker.expect(test_plan["device_language"]).result("English")
+        mocker.expect(test_plan["test_type"]).result("smoke")
+        mocker.expect(test_plan["temp_directory"]).result(TEST_PATH)
+        mocker.expect(test_plan.sets).result([
+            dict(name="set0", image_files=self.image_files, test_harness="ASTE")])
+        mocker.expect(test_plan.post_actions).result([
+            ("EmailAction", (("subject", "Release testing"),
+                                 ("to", self.report_email))),
+#            ("FileStoreAction", (("to-folder", self.file_store),
+#                                 ("report-type", "ATS_REPORT"),
+#                                 ("date-format", "yyyyMMdd"),
+#                                 ("time-format", "HHmmss"))),
+#            ("FileStoreAction", (("to-folder", self.file_store),
+#                                 ("report-type", "ASTE_REPORT"),
+#                                 ("run-log", "true"),
+#                                 ("date-format", "yyyyMMdd"),
+#                                 ("time-format", "HHmmss"))),
+            ("DiamondsAction", ())
+        ])
+        
+        self.mocker.replay()
+        self.test_plan = test_plan
+        
+        self.gen = ats3.aste.AsteTemplateTestDropGenerator()
+        return self.gen.generate_xml(test_plan)
+
+    def test_basic_structure(self):
+        "Check that the overall test.xml structure is valid."
+        xml = self.generate_xml()
+        # Check basics.
+#        assert xml.find(".").tag == "test"
+#        assert xml.find("./name").text == "test"
+#        assert xml.find("./buildid").text == self.diamonds_build_url
+#        assert xml.find("./target").tag
+#        assert xml.find("./target/device").tag
+#        harness, hardware, device_hwid = xml.findall("./target/device/property")
+#        softwareVersion, softwareRelease, deviceLanguage = xml.findall("./target/device/setting")
+#        assert harness.get("value") == "ASTE"
+#        assert hardware.get("value") == "product"
+#        assert softwareVersion.get("value") == "W810"
+#        assert softwareRelease.get("value") == "SPP 51.32"
+#        assert deviceLanguage.get("value") == "English"
+#        assert device_hwid.get("value") == "5425"
+#        
+#        # Check generation of the test plan.
+#        assert xml.find("./plan").get("name") == "Plan smoke product"
+#        assert xml.find("./plan/session").tag 
+#        sets = xml.findall("./plan/session/set")
+#        assert len(sets) == 1
+#        assert sets[0].get("name") == "set0"
+#        assert sets[0].find("./target/device").tag
+    
+    def test_set_structure(self):
+        "Check that a <set> element's structure is valid."
+        xml = self.generate_xml()
+#        tstset = xml.find("./plan/session/set")
+#        assert tstset.tag
+#        case = tstset.find("./case")
+#        assert case.tag
+#        assert case.get("name") == "set0 case"                
+        
+    def test_case_flash_elems(self):
+        """ Test case flash elems. """
+        xml = self.generate_xml()
+        found = False
+        for case in xml.findall(".//task"):
+            if case.find('type').text == 'FlashTask':
+                found = True
+                flashes = case.findall("./parameters/parameter")
+                assert len(flashes) == len(self.image_files)
+                for i, flash_file in enumerate(self.image_files):
+                    assert flashes[i].get("name") == "image-" + str(i + 1)
+                    assert flashes[i].get("value") == "ATS3Drop\\images\\" + flash_file.name
+        assert found
+    
+    def test_steps(self):
+        xml = self.generate_xml()
+        steps = iter(xml.findall(".//task"))
+        step = steps.next()
+        step = steps.next()
+        self.check_executeasset_step(steps)
+
+    def check_executeasset_step(self, steps):
+        step = steps.next()
+        assert step.findtext("./type") == "SetTestAssetPackageTask"
+        params = step.findall("./parameters/parameter")
+        #assert params[0].get("repeat") == "1"
+        assert params[0].get("value") == "ATS3Drop\\TestAssets\\TestAsset.zip"
+        #assert params[2].get("testcase-ids") == "100"
+
+    def test_post_actions(self):
+        "Post actions are inserted into XML."
+        xml = self.generate_xml()        
+        post_actions = xml.findall(".//action")
+        self.check_send_email_action(post_actions[0])
+#        self.check_ats_report_action(post_actions[1])
+#        self.check_aste_report_action(post_actions[2])
+        self.check_diamonds_action(post_actions[1])
+
+    def check_send_email_action(self, action):
+        assert action.findtext("./type") == "EmailAction"
+        params = action.findall("./parameters/parameter")
+        assert params[0].get("name") == "subject"
+        #assert params[0].get("value") == "email subject"
+        #assert params[1].get("name") == "type"
+        #assert params[1].get("value") == "ATS3_REPORT"
+        #assert params[2].get("name") == "send-files"
+        #assert params[2].get("value") == "true"
+        assert params[1].get("name") == "to"
+        assert params[1].get("value") == self.report_email
+
+    def check_ats_report_action(self, action):
+        assert action.findtext("./type") == "FileStoreAction"
+        params = action.findall("./parameters/parameter")
+        assert params[0].get("name") == "to-folder"
+        assert params[0].get("value") == self.file_store
+        assert params[1].get("name") == "report-type"
+        assert params[1].get("value") == "ATS_REPORT"
+        assert params[2].get("name") == "date-format"
+        assert params[2].get("value") == "yyyyMMdd"
+        assert params[3].get("name") == "time-format"
+        assert params[3].get("value") == "HHmmss"
+
+    def check_aste_report_action(self, action):
+        assert action.findtext("./type") == "FileStoreAction"
+        params = action.findall("./parameters/parameter")
+        assert params[0].get("name") == "to-folder"
+        assert params[0].get("value") == self.file_store
+        assert params[1].get("name") == "report-type"
+        assert params[1].get("value") == "ASTE_REPORT"
+        assert params[2].get("name") == "run-log"
+        assert params[2].get("value") == "true"
+        assert params[3].get("name") == "date-format"
+        assert params[3].get("value") == "yyyyMMdd"
+        assert params[4].get("name") == "time-format"
+        assert params[4].get("value") == "HHmmss"
+        
+    def check_diamonds_action(self, action):
+        assert action.findtext("./type") == "DiamondsAction"
+        assert not action.findall("./parameters/parameter")
+    
+    def test_files(self):
+        xml = self.generate_xml()
+#        files = iter(xml.findall("./files/file"))
+#        assert files.next().text == r"ATS3Drop" + os.sep + "images" + os.sep + "file1.fpsx"
+#        assert files.next().text == r"ATS3Drop" + os.sep + "images" + os.sep + "file2.fpsx"
+#        assert files.next().text == r"ATS3Drop" + os.sep + "TestAssets" + os.sep + "TestAsset.zip"
+#        self.assertRaises(StopIteration, files.next)
+        
+    def test_generate_testasset_zip(self):
+        self.generate_xml()
+        if re.search(r"[.]zip", self.test_plan["testasset_location"]):
+            pass
+        else:
+            strbuffer = StringIO()
+            assert strbuffer == self.gen.generate_testasset_zip(self.test_plan, strbuffer)
+            zfile = zipfile.ZipFile(strbuffer, "r")
+            try:
+                contents = sorted(path(p).normpath() for p in zfile.namelist())
+                expected = sorted(path(p).normpath()
+                               for p in [(r"Localisation" + os.sep + "S60" + os.sep + "localisation.txt"),
+                                         (r"TestCases" + os.sep + "TC_100_Test0" + os.sep + "file1.sis"),
+                                         (r"TestCases" + os.sep + "TC_100_Test0" + os.sep + "file2.tcf"),
+                                         (r"Tools" + os.sep + "TestCaseCreator" + os.sep + "test_creator.ini"),
+                                         (r"testdrop.xml")])
+                diff = difflib.context_diff(expected, contents)
+                assert contents == expected, "\n".join(diff)
+            finally:
+                zfile.close()
+        
+    def test_generate_drop(self):
+        "Manifest for ATS3Drop directory structure is generated."
+        xml = self.generate_xml()
+        strbuffer = StringIO()
+
+        self.gen.generate_drop(self.test_plan, xml, strbuffer)
+        zfile = zipfile.ZipFile(strbuffer, "r")
+        try:
+            contents = sorted(path(p).normpath() for p in zfile.namelist())
+            expected = sorted(path(p).normpath()
+                           for p in [r"ATS3Drop" + os.sep + "images" + os.sep + "file1.fpsx",
+                                     r"ATS3Drop" + os.sep + "images" + os.sep + "file2.fpsx",
+                                     r"ATS3Drop" + os.sep + "TestAssets" + os.sep + "TestAsset.zip",
+                                     r"test.xml"])
+            diff = difflib.context_diff(expected, contents)
+            assert contents == expected, "\n".join(diff)
+        finally:
+            zfile.close()