Home | History | Annotate | Download | only in userInteraction
      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 
     29 from clientsimulator.criterion.InclusiveCriterion import InclusiveCriterion
     30 from clientsimulator.testGenerator.TestLauncher import TestLauncher
     31 from clientsimulator.userInteraction.DynamicCallHelper import DynamicCallHelper
     32 
     33 
     34 class 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