X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FDropRateSearch.py;h=e87ef95434c4c2612d94267e3739a7b1870bb0b6;hp=2de8e3c174052910a93ed55d32aa7d7e40d82d98;hb=1469b71f48bb4e397ebaa65fbaf0512be691ec49;hpb=4c75804c85ffa7ef236fff24ea8d159ca2dc73b7 diff --git a/resources/libraries/python/DropRateSearch.py b/resources/libraries/python/DropRateSearch.py index 2de8e3c174..e87ef95434 100644 --- a/resources/libraries/python/DropRateSearch.py +++ b/resources/libraries/python/DropRateSearch.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# Copyright (c) 2019 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -109,23 +109,23 @@ class DropRateSearch(object): @abstractmethod def measure_loss(self, rate, frame_size, loss_acceptance, - loss_acceptance_type, traffic_type, skip_warmup=False): + loss_acceptance_type, traffic_profile, skip_warmup=False): """Send traffic from TG and measure count of dropped frames. :param rate: Offered traffic load. :param frame_size: Size of frame. :param loss_acceptance: Permitted drop ratio or frames count. :param loss_acceptance_type: Type of permitted loss. - :param traffic_type: Traffic profile ([2,3]-node-L[2,3], ...). + :param traffic_profile: Module name to use for traffic generation. :param skip_warmup: Start TRex without warmup traffic if true. :type rate: int :type frame_size: str :type loss_acceptance: float :type loss_acceptance_type: LossAcceptanceType - :type traffic_type: str - :type traffic_type: bool + :type traffic_profile: str + :type skip_warmup: bool :returns: Drop threshold exceeded? (True/False) - :rtype bool + :rtype: bool """ pass @@ -137,7 +137,7 @@ class DropRateSearch(object): :type max_rate: float :type min_rate: float :returns: nothing - :raises: ValueError if min rate is lower than 0 and higher than max rate + :raises ValueError: If min rate is lower than 0 or higher than max rate. """ if float(min_rate) <= 0: raise ValueError("min_rate must be higher than 0") @@ -153,7 +153,7 @@ class DropRateSearch(object): :param loss_acceptance: Loss acceptance treshold for PDR search. :type loss_acceptance: str :returns: nothing - :raises: ValueError if loss acceptance is lower than zero + :raises ValueError: If loss acceptance is lower than zero. """ if float(loss_acceptance) < 0: raise ValueError("Loss acceptance must be higher or equal 0") @@ -227,7 +227,7 @@ class DropRateSearch(object): :param rate_type: Type of rate to set. :type rate_type: RateType :returns: nothing - :raises: Exception if rate type is unknown + :raises Exception: If rate type is unknown. """ if rate_type not in RateType: raise Exception("rate_type unknown: {}".format(rate_type)) @@ -282,7 +282,7 @@ class DropRateSearch(object): :returns: String representation of rate type. :rtype: str - :raises: ValueError if rate type is unknown + :raises ValueError: If rate type is unknown. """ if self._rate_type == RateType.PERCENTAGE: return "%" @@ -299,7 +299,7 @@ class DropRateSearch(object): :param max_attempts: Number of traffic runs. :type max_attempts: int :returns: nothing - :raises: ValueError if max attempts is lower than zero + :raises ValueError: If max attempts is lower than zero. """ if int(max_attempts) > 0: self._max_attempts = int(max_attempts) @@ -334,7 +334,7 @@ class DropRateSearch(object): :param search_type: Type of search result evaluation to set. :type search_type: SearchResultType :returns: nothing - :raises: ValueError if search type is unknown + :raises ValueError: If search type is unknown. """ if search_type not in SearchResultType: raise ValueError("search_type unknown: {}".format(search_type)) @@ -372,7 +372,7 @@ class DropRateSearch(object): :type res_list: list :returns: Boolean based on search result type. :rtype: boolean - :raises: ValueError if search result type is unknown + :raises ValueError: If search result type is unknown. """ if self._search_result_type == SearchResultType.BEST_OF_N: return self._get_best_of_n(res_list) @@ -381,15 +381,15 @@ class DropRateSearch(object): else: raise ValueError("Unknown search result type") - def linear_search(self, start_rate, traffic_type): + def linear_search(self, start_rate, traffic_profile): """Linear search of rate with loss below acceptance criteria. :param start_rate: Initial rate. - :param traffic_type: Traffic profile. + :param traffic_profile: Module name to use for traffic generation. :type start_rate: float - :type traffic_type: str + :type traffic_profile: str :returns: nothing - :raises: ValueError if start rate is not in range + :raises ValueError: If start rate is not in range. """ if not self._rate_min <= float(start_rate) <= self._rate_max: @@ -403,44 +403,13 @@ class DropRateSearch(object): while True: res = [] for dummy in range(self._max_attempts): - res.append(self.measure_loss(rate, self._frame_size, - self._loss_acceptance, - self._loss_acceptance_type, - traffic_type)) + res.append(self.measure_loss( + rate, self._frame_size, self._loss_acceptance, + self._loss_acceptance_type, traffic_profile)) res = self._get_res_based_on_search_type(res) - if self._search_linear_direction == SearchDirection.BOTTOM_UP: - # loss occurred and it was above acceptance criteria - if not res: - # if this is first run then we didn't find drop rate - if prev_rate is None: - self._search_result = SearchResults.FAILURE - self._search_result_rate = None - # else we found the rate, which is value from previous run - else: - self._search_result = SearchResults.SUCCESS - self._search_result_rate = prev_rate - return - # there was no loss / loss below acceptance criteria - elif res: - prev_rate = rate - rate += self._rate_linear_step - if rate > self._rate_max: - if prev_rate != self._rate_max: - # one last step with rate set to _rate_max - rate = self._rate_max - continue - else: - self._search_result = SearchResults.SUCCESS - self._search_result_rate = prev_rate - return - else: - continue - else: - raise RuntimeError("Unknown search result") - - elif self._search_linear_direction == SearchDirection.TOP_DOWN: + if self._search_linear_direction == SearchDirection.TOP_DOWN: # loss occurred, decrease rate if not res: prev_rate = rate @@ -466,37 +435,34 @@ class DropRateSearch(object): else: raise Exception("Unknown search direction") - raise Exception("Wrong codepath") - def verify_search_result(self): """Fail if search was not successful. :returns: Result rate and latency stats. :rtype: tuple - :raises: Exception if search failed + :raises Exception: If search failed. """ - if self._search_result == SearchResults.FAILURE: - raise Exception('Search FAILED') - elif self._search_result in [SearchResults.SUCCESS, - SearchResults.SUSPICIOUS]: + if self._search_result in [ + SearchResults.SUCCESS, SearchResults.SUSPICIOUS]: return self._search_result_rate, self.get_latency() + raise Exception('Search FAILED') - def binary_search(self, b_min, b_max, traffic_type, skip_max_rate=False, + def binary_search(self, b_min, b_max, traffic_profile, skip_max_rate=False, skip_warmup=False): """Binary search of rate with loss below acceptance criteria. :param b_min: Min range rate. :param b_max: Max range rate. - :param traffic_type: Traffic profile. + :param traffic_profile: Module name to use for traffic generation. :param skip_max_rate: Start with max rate first :param skip_warmup: Start TRex without warmup traffic if true. :type b_min: float :type b_max: float - :type traffic_type: str + :type traffic_profile: str :type skip_max_rate: bool :type skip_warmup: bool :returns: nothing - :raises: ValueError if input values are not valid + :raises ValueError: If input values are not valid. """ if not self._rate_min <= float(b_min) <= self._rate_max: @@ -523,33 +489,33 @@ class DropRateSearch(object): res = [] for dummy in range(self._max_attempts): - res.append(self.measure_loss(rate, self._frame_size, - self._loss_acceptance, - self._loss_acceptance_type, - traffic_type, skip_warmup=skip_warmup)) + res.append(self.measure_loss( + rate, self._frame_size, self._loss_acceptance, + self._loss_acceptance_type, traffic_profile, + skip_warmup=skip_warmup)) res = self._get_res_based_on_search_type(res) # loss occurred and it was above acceptance criteria if not res: - self.binary_search(b_min, rate, traffic_type, True, True) + self.binary_search(b_min, rate, traffic_profile, True, True) # there was no loss / loss below acceptance criteria else: self._search_result_rate = rate - self.binary_search(rate, b_max, traffic_type, True, True) + self.binary_search(rate, b_max, traffic_profile, True, True) - def combined_search(self, start_rate, traffic_type): + def combined_search(self, start_rate, traffic_profile): """Combined search of rate with loss below acceptance criteria. :param start_rate: Initial rate. - :param traffic_type: Traffic profile. + :param traffic_profile: Module name to use for traffic generation. :type start_rate: float - :type traffic_type: str + :type traffic_profile: str :returns: nothing - :raises: RuntimeError if linear search failed + :raises RuntimeError: If linear search failed. """ - self.linear_search(start_rate, traffic_type) + self.linear_search(start_rate, traffic_profile) if self._search_result in [SearchResults.SUCCESS, SearchResults.SUSPICIOUS]: @@ -569,7 +535,7 @@ class DropRateSearch(object): self._search_result_rate = None # we will use binary search to refine search in one linear step - self.binary_search(b_min, b_max, traffic_type, True) + self.binary_search(b_min, b_max, traffic_profile, True) # linear and binary search succeed if self._search_result == SearchResults.SUCCESS: @@ -596,7 +562,7 @@ class DropRateSearch(object): :returns: Returns True if num_a is close in value to num_b or equal. False otherwise. :rtype: boolean - :raises: ValueError if input values are not valid + :raises ValueError: If input values are not valid. """ if num_a == num_b: