From bb5397fd864c9697c7aaf2867bad66f0be347bff Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 27 Apr 2023 08:55:47 +0000 Subject: [PATCH 1/3] Protos: - extend load generator status with num_released requests --- proto/load_generator.proto | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proto/load_generator.proto b/proto/load_generator.proto index 395afbb88..7d0070c66 100644 --- a/proto/load_generator.proto +++ b/proto/load_generator.proto @@ -64,6 +64,7 @@ message Parameters { message Status { Parameters parameters = 1; uint64 num_generated = 2; - bool infinite_loop = 3; - bool running = 4; + uint64 num_released = 3; + bool infinite_loop = 4; + bool running = 5; } -- GitLab From 21dac16262b96591dea688469e16fe3c7eb7e944 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 27 Apr 2023 08:56:39 +0000 Subject: [PATCH 2/3] Load Generator component: - Added logic to track and report num_released requests --- .../load_gen/RequestGenerator.py | 36 +++++++++++++------ .../load_gen/RequestScheduler.py | 3 ++ .../LoadGeneratorServiceServicerImpl.py | 1 + 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/load_generator/load_gen/RequestGenerator.py b/src/load_generator/load_gen/RequestGenerator.py index ab8f7e30e..3a52b3b32 100644 --- a/src/load_generator/load_gen/RequestGenerator.py +++ b/src/load_generator/load_gen/RequestGenerator.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, json, random, re, threading +import logging, json, random, re, threading, uuid from typing import Dict, Optional, Set, Tuple from common.proto.context_pb2 import Empty, IsolationLevelEnum, TopologyId from common.tools.grpc.Tools import grpc_message_to_json @@ -54,6 +54,7 @@ class RequestGenerator: self._parameters = parameters self._lock = threading.Lock() self._num_generated = 0 + self._num_released = 0 self._available_device_endpoints : Dict[str, Set[str]] = dict() self._used_device_endpoints : Dict[str, Dict[str, str]] = dict() self._endpoint_ids_to_types : Dict[Tuple[str, str], str] = dict() @@ -65,6 +66,9 @@ class RequestGenerator: @property def num_generated(self): return self._num_generated + @property + def num_released(self): return self._num_released + @property def infinite_loop(self): return self._parameters.num_requests == 0 @@ -192,23 +196,18 @@ class RequestGenerator: if not self.infinite_loop and (self._num_generated >= self._parameters.num_requests): LOGGER.info('Generation Done!') return True, None, None # completed - self._num_generated += 1 - num_request = self._num_generated - #request_uuid = str(uuid.uuid4()) - request_uuid = 'svc_{:d}'.format(num_request) - - # choose request type + request_uuid = str(uuid.uuid4()) request_type = random.choice(self._parameters.request_types) if request_type in { RequestType.SERVICE_L2NM, RequestType.SERVICE_L3NM, RequestType.SERVICE_TAPI, RequestType.SERVICE_MW }: - return False, self._compose_service(num_request, request_uuid, request_type), request_type + return False, self._compose_service(request_uuid, request_type), request_type elif request_type in {RequestType.SLICE_L2NM, RequestType.SLICE_L3NM}: - return False, self._compose_slice(num_request, request_uuid, request_type), request_type + return False, self._compose_slice(request_uuid, request_type), request_type - def _compose_service(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: + def _compose_service(self, request_uuid : str, request_type : str) -> Optional[Dict]: # choose source endpoint src_endpoint_types = set(ENDPOINT_COMPATIBILITY.keys()) if request_type in {RequestType.SERVICE_TAPI} else None src = self._use_device_endpoint(request_uuid, request_type, endpoint_types=src_endpoint_types) @@ -237,6 +236,10 @@ class RequestGenerator: self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) return None + with self._lock: + self._num_generated += 1 + num_request = self._num_generated + # compose endpoints dst_device_uuid,dst_endpoint_uuid = dst endpoint_ids = [ @@ -383,7 +386,7 @@ class RequestGenerator: return json_service_l2nm_planned( request_uuid, endpoint_ids=endpoint_ids, constraints=[], config_rules=config_rules) - def _compose_slice(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: + def _compose_slice(self, request_uuid : str, request_type : str) -> Optional[Dict]: # choose source endpoint src = self._use_device_endpoint(request_uuid, request_type) if src is None: @@ -404,6 +407,10 @@ class RequestGenerator: self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) return None + with self._lock: + self._num_generated += 1 + num_request = self._num_generated + # compose endpoints dst_device_uuid,dst_endpoint_uuid = dst endpoint_ids = [ @@ -505,8 +512,15 @@ class RequestGenerator: device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] self._release_device_endpoint(device_uuid, endpoint_uuid) + + with self._lock: + self._num_released += 1 + elif 'slice_id' in json_request: for endpoint_id in json_request['slice_endpoint_ids']: device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] self._release_device_endpoint(device_uuid, endpoint_uuid) + + with self._lock: + self._num_released += 1 diff --git a/src/load_generator/load_gen/RequestScheduler.py b/src/load_generator/load_gen/RequestScheduler.py index 08876e29f..340a5411b 100644 --- a/src/load_generator/load_gen/RequestScheduler.py +++ b/src/load_generator/load_gen/RequestScheduler.py @@ -57,6 +57,9 @@ class RequestScheduler: @property def num_generated(self): return min(self._generator.num_generated, self._parameters.num_requests) + @property + def num_released(self): return min(self._generator.num_released, self._parameters.num_requests) + @property def infinite_loop(self): return self._generator.infinite_loop diff --git a/src/load_generator/service/LoadGeneratorServiceServicerImpl.py b/src/load_generator/service/LoadGeneratorServiceServicerImpl.py index 41c12d8e4..9f12f3492 100644 --- a/src/load_generator/service/LoadGeneratorServiceServicerImpl.py +++ b/src/load_generator/service/LoadGeneratorServiceServicerImpl.py @@ -73,6 +73,7 @@ class LoadGeneratorServiceServicerImpl(LoadGeneratorServiceServicer): status = Status() status.num_generated = self._scheduler.num_generated + status.num_released = self._scheduler.num_released status.infinite_loop = self._scheduler.infinite_loop status.running = self._scheduler.running -- GitLab From a95e7b4f19d23e4aab47269ef74c25edde600730 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Thu, 27 Apr 2023 08:57:10 +0000 Subject: [PATCH 3/3] WebUI component: - Added status field num_released in loadgen tab --- src/webui/service/load_gen/forms.py | 1 + src/webui/service/load_gen/routes.py | 1 + src/webui/service/templates/load_gen/home.html | 15 +++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/src/webui/service/load_gen/forms.py b/src/webui/service/load_gen/forms.py index 8092b3193..e0d11800c 100644 --- a/src/webui/service/load_gen/forms.py +++ b/src/webui/service/load_gen/forms.py @@ -24,6 +24,7 @@ DEFAULT_E2E_LATENCY_MS = '5.0..100.00' class LoadGenForm(FlaskForm): num_requests = IntegerField('Num Requests', default=100, validators=[DataRequired(), NumberRange(min=0)]) num_generated = IntegerField('Num Generated', default=0, render_kw={'readonly': True}) + num_released = IntegerField('Num Released', default=0, render_kw={'readonly': True}) request_type_service_l2nm = BooleanField('Service L2NM', default=False) request_type_service_l3nm = BooleanField('Service L3NM', default=False) diff --git a/src/webui/service/load_gen/routes.py b/src/webui/service/load_gen/routes.py index 1b4f9c6ba..f05f57f6d 100644 --- a/src/webui/service/load_gen/routes.py +++ b/src/webui/service/load_gen/routes.py @@ -80,6 +80,7 @@ def home(): set_properties(form.request_type_slice_l2nm , _request_type_slice_l2nm , disabled=status.running) set_properties(form.request_type_slice_l3nm , _request_type_slice_l3nm , disabled=status.running) set_properties(form.num_generated , status.num_generated , disabled=True) + set_properties(form.num_released , status.num_released , disabled=True) set_properties(form.infinite_loop , status.infinite_loop , disabled=True) set_properties(form.running , status.running , disabled=True) diff --git a/src/webui/service/templates/load_gen/home.html b/src/webui/service/templates/load_gen/home.html index 046459acf..5bedf66fa 100644 --- a/src/webui/service/templates/load_gen/home.html +++ b/src/webui/service/templates/load_gen/home.html @@ -53,6 +53,21 @@
+
+ {{ form.num_released.label(class="col-sm-2 col-form-label") }} +
+ {% if form.num_released.errors %} + {{ form.num_released(class="form-control is-invalid") }} +
+ {% for error in form.num_released.errors %}{{ error }}{% endfor %} +
+ {% else %} + {{ form.num_released(class="form-control") }} + {% endif %} +
+
+
+
Service Types:
-- GitLab