1#! python2.7 2# Copyright (c) 2015, Intel Corporation 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without modification, 6# are permitted provided that the following conditions are met: 7# 8# 1. Redistributions of source code must retain the above copyright notice, this 9# list of conditions and the following disclaimer. 10# 11# 2. Redistributions in binary form must reproduce the above copyright notice, 12# this list of conditions and the following disclaimer in the documentation and/or 13# other materials provided with the distribution. 14# 15# 3. Neither the name of the copyright holder nor the names of its contributors 16# may be used to endorse or promote products derived from this software without 17# specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30import sys 31import os 32import subprocess 33import difflib 34import unittest 35import copy 36 37class PfConfig: 38 def __init__(self, toplevel, criteria, schemas): 39 self.toplevel = toplevel 40 self.criteria = criteria 41 self.schemas = schemas 42 43class TestVector: 44 def __init__(self, initialSettings=None, edds=[], domains=[]): 45 self.initialSettings = initialSettings 46 self.edds = edds 47 self.domains = domains 48 49class Tester(object): 50 def __init__(self, pfConfig, testVector): 51 self.command = [sys.executable, "domainGenerator.py", 52 "--validate", 53 "--verbose", 54 "--toplevel-config", pfConfig.toplevel, 55 "--criteria", pfConfig.criteria, 56 "--schemas-dir", pfConfig.schemas] 57 58 if testVector.initialSettings: 59 self.command += ["--initial-settings", testVector.initialSettings] 60 if testVector.edds: 61 self.command += ["--add-edds"] + testVector.edds 62 if testVector.domains: 63 self.command += ["--add-domains"] + testVector.domains 64 65 def check(self, reference=None, expectedErrors=0): 66 process = subprocess.Popen(self.command, stdout=subprocess.PIPE) 67 actual = process.stdout.read().splitlines() 68 69 if process.wait() != expectedErrors: 70 raise AssertionError("Expected {} errors, found {}".format( 71 expectedErrors, 72 process.returncode)) 73 74 if not reference: 75 # The caller only wants to check the number of errors 76 return 77 78 # The generation has succeeded as expected - let's compare with the reference. 79 if reference != actual: 80 unified = difflib.unified_diff(reference, 81 actual, 82 fromfile="reference.xml", 83 tofile="-", 84 lineterm="") 85 raise AssertionError("The result and the reference don't match:" + "\n".join(unified)) 86 87 88basedir = os.path.dirname(sys.argv[0]) 89 90config_dir = os.path.join(basedir, "PFConfig") 91vector_dir = os.path.join(basedir, "testVector") 92class TestCase(unittest.TestCase): 93 def setUp(self): 94 self.nominal_reference = open(os.path.join(vector_dir, "reference.xml")).read().splitlines() 95 self.nominal_pfconfig = PfConfig(os.path.join(config_dir, "configuration.xml"), 96 os.path.join(config_dir, "criteria.txt"), 97 os.path.join(basedir, "../../schemas")) 98 self.nominal_vector = TestVector(os.path.join(vector_dir, "initialSettings.xml"), 99 [os.path.join(vector_dir, "first.pfw"), 100 os.path.join(vector_dir, "second.pfw"), 101 os.path.join(vector_dir, "complex.pfw")], 102 [os.path.join(vector_dir, "third.xml"), 103 os.path.join(vector_dir, "fourth.xml")]) 104 105 def test_nominal(self): 106 tester = Tester(self.nominal_pfconfig, self.nominal_vector) 107 tester.check(self.nominal_reference) 108 109 def test_nonfatalError(self): 110 self.nominal_vector.edds.append(os.path.join(vector_dir, "duplicate.pfw")) 111 112 tester = Tester(self.nominal_pfconfig, self.nominal_vector) 113 tester.check(self.nominal_reference, expectedErrors=1) 114 115 def test_conflicting(self): 116 vector = TestVector(edds=[os.path.join(vector_dir, "conflicting.pfw")]) 117 118 tester = Tester(self.nominal_pfconfig, vector) 119 tester.check(expectedErrors=1) 120 121 def test_fail_criteria(self): 122 self.nominal_pfconfig.criteria = os.path.join(config_dir, "duplicate_criterion_value.txt") 123 # Empty test vector: we want to make sure that the erroneous criterion 124 # is the only source of error 125 empty_vector = TestVector() 126 127 tester = Tester(self.nominal_pfconfig, empty_vector) 128 tester.check(expectedErrors=1) 129 130if __name__ == "__main__": 131 unittest.main() 132