# -*- coding: latin-1 -*-
#============================================================================
#Name : test_ats3_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 ATS3 ASTE framework. """
# pylint: disable-msg=E1101,W0603,W0142
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_ast3_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["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([
("SendEmailAction", (("subject", "email subject"),
("type", "ATS3_REPORT"),
("send-files", "true"),
("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.AsteTestDropGenerator()
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):
xml = self.generate_xml()
case = xml.find("./plan/session/set/case")
flashes = case.findall("./flash")
assert len(flashes) == len(self.image_files)
for i, flash_file in enumerate(self.image_files):
assert flashes[i].get("target-alias") == "DEFAULT"
assert flashes[i].get("images") == path(r"ATS3Drop" + os.sep + "images") / flash_file.name
def test_steps(self):
xml = self.generate_xml()
steps = iter(xml.findall("./plan/session/set/case/step"))
self.check_executeasset_step(steps)
def check_executeasset_step(self, steps):
step = steps.next()
assert step.get("name") == "Execute asset zip step"
assert step.findtext("./command") == "execute-asset"
params = step.findall("./params/param")
assert params[0].get("repeat") == "1"
assert params[1].get("asset-source") == "ATS3Drop" + os.sep + "TestAssets" + os.sep + "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("./postAction")
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[3])
def check_send_email_action(self, action):
assert action.findtext("./type") == "SendEmailAction"
params = action.findall("./params/param")
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[3].get("name") == "to"
assert params[3].get("value") == self.report_email
def check_ats_report_action(self, action):
assert action.findtext("./type") == "FileStoreAction"
params = action.findall("./params/param")
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("./params/param")
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("./params/param")
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()