• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2014-2015, Intel Corporation
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without modification,
5# are permitted provided that the following conditions are met:
6#
7# 1. Redistributions of source code must retain the above copyright notice, this
8# list of conditions and the following disclaimer.
9#
10# 2. Redistributions in binary form must reproduce the above copyright notice,
11# this list of conditions and the following disclaimer in the documentation and/or
12# other materials provided with the distribution.
13#
14# 3. Neither the name of the copyright holder nor the names of its contributors
15# may be used to endorse or promote products derived from this software without
16# specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29import json
30import logging
31
32
33class Scenario:
34
35    """
36        Class which can handle several TestVectors and script
37        to play a complete scenario.
38    """
39
40    def __init__(self,
41                 consoleLogger,
42                 scenarioFileName,
43                 actionGathererFileName,
44                 testFactory,
45                 testLauncher):
46        """
47            Init function
48
49            :param consoleLogger: console log handler
50            :type consoleLogger: Handler
51            :param scenarioFileName: name of file containing scenario description
52            :type scenarioFileName: string
53            :param actionGathererFileName: conf file which allows to reduce action repetition
54            :type actionGathererFileName: string
55            :param testFactory: the factory used to generate tests from setCriterion actions
56            :type testFactory: TestVectorFactory
57            :param testLauncher: object used to execute actions from scenarios
58            :type testLauncher: TestLauncher
59        """
60        self.__logger = logging.getLogger(__name__)
61        self.__logger.addHandler(consoleLogger)
62
63        self.__testFactory = testFactory
64        self.__testLauncher = testLauncher
65
66        # Simplify the way to get an action behaviour
67        # Python way to replace switch statement but keeping the possibility
68        # to get keys (usefull in __parseScenarioActions)
69        self.__actionTypeBehaviour = {
70            "setCriterion":
71                lambda rawCriterions:
72                    self.__testLauncher.executeTestVector(
73                        self.__testFactory.generateTestVector(rawCriterions)),
74            "script":
75                self.__testLauncher.executeScript
76        }
77
78        self.__scenarioActions = self.__parseScenarioActions(
79            scenarioFileName,
80            actionGathererFileName)
81
82    def __parseScenarioActions(self, scenarioFileName, actionGathererFileName):
83        """
84            Parse actions from a scenario.
85            Convert user-defined actions in system-known actions.
86
87            :param scenarioFileName: name of file containing scenario description
88            :type scenarioFileName: string
89            :param actionGathererFileName: conf file which allows to reduce action repetition
90            :type actionGathererFileName: string
91
92            :return: parsed scenario's actions with system-known types
93            :rtype: dict
94        """
95
96        # Parsing of Json test file
97        with open(scenarioFileName, "r") as scenarioFile:
98            scenarioActions = json.load(scenarioFile)
99
100        # Parsing the action Gatherer file which allows defining new
101        # actions types
102        scenarioGatheredActions = {}
103        if actionGathererFileName:
104            with open(actionGathererFileName, "r") as actionGathererFile:
105                scenarioGatheredActions = json.load(actionGathererFile)
106
107        for action in scenarioActions:
108            actionDefinedType = self.__getActionType(action)
109            if actionDefinedType in self.__actionTypeBehaviour.keys():
110                continue
111
112            try:
113                actionValue = action.pop(actionDefinedType)
114                actionGatherer = scenarioGatheredActions[actionDefinedType]
115            except KeyError as e:
116                self.__logger.error(
117                    "Actions {} from {} file is not valid".format(
118                        actionDefinedType,
119                        scenarioFileName))
120                raise e
121
122            if self.__getActionType(actionGatherer) == "script":
123                raise UngatherableTypeException(
124                    "Unable to redefine {} type, please edit your {} file".format(
125                        self.__getActionType(actionGatherer),
126                        actionGathererFileName))
127
128            # Fusion of gathered Actions and other desired actions which
129            # are directly writed in the scenario's file
130            actionValue.update(self.__getActionValue(actionGatherer))
131
132            # Change the user defined key which was previously popped
133            # by the known one
134            action[self.__getActionType(actionGatherer)] = actionValue
135
136        return scenarioActions
137
138    def __getActionType(self, action):
139        """
140            Return the type of an action (the key)
141            An action is a dictionary with only one element
142
143            :param action: the action you want to get the type
144            :type action: dict
145
146            :return: the type of the desired action
147            :rtype: string
148        """
149        return list(action.keys())[0]
150
151    def __getActionValue(self, action):
152        """
153            Return the Value of an action
154            An action is a dictionary with only one element
155
156            :param action: the action you want to get the type
157            :type action: dict
158
159            :return: the value of the desired action
160            :rtype: string or dict
161        """
162        return list(action.values())[0]
163
164    def play(self):
165        """
166            Execute a Scenario
167        """
168
169        for action in self.__scenarioActions:
170            # Launch the adequate behaviour depending on the key of the action dict
171            # No need to try KeyError as it would have been raised during init
172            # process
173            self.__actionTypeBehaviour[self.__getActionType(action)](
174                self.__getActionValue(action))
175
176
177class UngatherableTypeException(Exception):
178
179    """
180        Exception raised in case of problem with a type that the
181        user try to personalize
182    """
183
184    def __init__(self, msg):
185        self.__msg = msg
186
187    def __str__(self):
188        return "Ungatherable type Error : " + self.__msg
189