• 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
29from clientsimulator.criterion.InclusiveCriterion import InclusiveCriterion
30from clientsimulator.testGenerator.TestLauncher import TestLauncher
31from clientsimulator.userInteraction.DynamicCallHelper import DynamicCallHelper
32
33
34class UserInteractor:
35
36    """
37        Define all user interactions the program can have.
38
39        Allows to run the interactive mode and dynamics menus.
40    """
41
42    def __init__(self, testLauncher, criterions):
43        """
44            Init function of user interactor
45
46            :param testLauncher: object which allows to run tests
47            :type testLauncher: TestLauncher
48        """
49
50        self.__testLauncher = testLauncher
51        self.__criterions = criterions
52
53    @classmethod
54    def getMenu(cls, options, cancelSentence="Go Back"):
55        """
56            Dynamic Menu Generator :
57
58            :param options: list containing tuples of a) the invite string and
59            b) the function to launch
60            :type options: list
61            :param cancelSentence: title of the menu entry that will be
62            appended after the provided options, in order to exit the menu. For
63            top-level menus, it is advised to pass "Quit" as argument.
64            :type cancelSentence: string
65        """
66
67        while True:
68            print("\nPlease Make a choice : ")
69            for numMenu, (sentenceMenu, fonc) in enumerate(options):
70                print("\t{}. {}".format(numMenu, sentenceMenu))
71
72            # Lastly, append an option to go to the previous menu/quit
73            print("\t{}. {}".format(len(options), cancelSentence))
74
75            choice = input("Your Choice : ")
76            try:
77                choice = int(choice)
78                if choice == len(options):
79                    # The user has selected the "cancel" option
80                    break
81                if choice < 0:
82                    # Negative values make no sense
83                    raise KeyError(choice)
84
85                options[choice][1]()
86            except (KeyError, ValueError) as e:
87                print("Invalid Choice : {}".format(e))
88
89    def launchInteractiveMode(self):
90        """
91            Interactive Mode : Set up a menu which allow
92            users to personnalize a Test and to Launch it
93        """
94        optionsMenu = [
95            ("Edit Vector", self.__editVector),
96            ("Apply Configuration", self.__applyConfiguration),
97            ("Launch Script", self.__launchScript)
98        ]
99
100        UserInteractor.getMenu(optionsMenu, "Quit")
101
102    def __applyConfiguration(self):
103        """
104            Apply the configuration described in the
105            current criterions state.
106        """
107
108        self.__testLauncher.executeTestVector(self.__criterions)
109
110        return True
111
112    def __launchScript(self):
113        """
114            Display the menu which let the user choose an available
115            script to run.
116        """
117
118        optionScript = [
119            ("Execute {}".format(script),
120                  DynamicCallHelper(self.__testLauncher.executeScript, script))
121            for script in self.__testLauncher.scripts
122        ]
123
124        UserInteractor.getMenu(optionScript)
125
126        return True
127
128    def __setCriterion(self, criterion, value):
129        criterion.currentValue = value
130
131    def __removeCriterionValue(self, criterion, value):
132        criterion.removeValue(value)
133
134    def __editCriterion(self, criterion):
135        """
136            Allow to change the value of a criterion through a menu.
137
138            :param criterion: the criterion to edit
139            :type criterion: Criterion
140        """
141
142        optionEditCriterion = []
143        for possibleValue in [x for x in criterion.allowedValues()
144                              if not x in criterion.currentValue
145                              and not x == criterion.noValue]:
146            optionEditCriterion.append(
147                ("Set {}".format(possibleValue),
148                 DynamicCallHelper(
149                     self.__setCriterion,
150                     criterion,
151                     possibleValue)))
152
153        if InclusiveCriterion in criterion.__class__.__bases__:
154            # Inclusive criterion : display unset value (default when empty)
155            for possibleValue in criterion.currentValue:
156                optionEditCriterion.append(
157                    ("Unset {}".format(possibleValue),
158                     DynamicCallHelper(
159                         self.__removeCriterionValue,
160                         criterion,
161                         possibleValue)))
162        else:
163            # Exclusive criterion : display default value
164            optionEditCriterion.append(
165                ("Set Default",
166                 DynamicCallHelper(
167                     self.__setCriterion,
168                     criterion,
169                     criterion.noValue)))
170
171        UserInteractor.getMenu(optionEditCriterion)
172
173        return True
174
175    def __editVector(self):
176        """
177            Allow to change the value of several criterions through a menu.
178        """
179
180        optionEdit = [
181            ("Edit {}".format(cri.__class__.__name__),
182                  DynamicCallHelper(self.__editCriterion, cri))
183            for cri in self.__criterions
184        ]
185
186        UserInteractor.getMenu(optionEdit)
187
188        return True
189