-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #35 from EURODEO/locust
Locust
- Loading branch information
Showing
5 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import time | ||
from typing import Any, Callable | ||
import grpc | ||
import grpc.experimental.gevent as grpc_gevent | ||
from grpc_interceptor import ClientInterceptor | ||
from locust import User | ||
from locust.exception import LocustError | ||
|
||
# patch grpc so that it uses gevent instead of asyncio | ||
grpc_gevent.init_gevent() | ||
|
||
|
||
class LocustInterceptor(ClientInterceptor): | ||
def __init__(self, environment, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
self.env = environment | ||
|
||
def intercept( | ||
self, | ||
method: Callable, | ||
request_or_iterator: Any, | ||
call_details: grpc.ClientCallDetails, | ||
): | ||
response = None | ||
exception = None | ||
start_perf_counter = time.perf_counter() | ||
response_length = 0 | ||
try: | ||
response = method(request_or_iterator, call_details) | ||
response_length = response.result().ByteSize() | ||
except grpc.RpcError as e: | ||
exception = e | ||
|
||
self.env.events.request.fire( | ||
request_type="grpc", | ||
name=call_details.method, | ||
response_time=(time.perf_counter() - start_perf_counter) * 1000, | ||
response_length=response_length, | ||
response=response, | ||
context=None, | ||
exception=exception, | ||
) | ||
return response | ||
|
||
|
||
class GrpcUser(User): | ||
abstract = True | ||
stub_class = None | ||
|
||
def __init__(self, environment): | ||
super().__init__(environment) | ||
for attr_value, attr_name in ((self.host, "host"), (self.stub_class, "stub_class")): | ||
if attr_value is None: | ||
raise LocustError(f"You must specify the {attr_name}.") | ||
|
||
self._channel = grpc.insecure_channel(self.host) | ||
interceptor = LocustInterceptor(environment=environment) | ||
self._channel = grpc.intercept_channel(self._channel, interceptor) | ||
|
||
self.stub = self.stub_class(self._channel) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Use the following command to generate the python protobuf stuff in the correct place (from the root of the repository) | ||
# python -m grpc_tools.protoc --proto_path=datastore/protobuf datastore.proto --python_out=load-test --grpc_python_out=load-test | ||
|
||
import random | ||
from datetime import datetime | ||
|
||
import grpc_user | ||
import datastore_pb2 as dstore | ||
import datastore_pb2_grpc as dstore_grpc | ||
from locust import task | ||
|
||
from google.protobuf.timestamp_pb2 import Timestamp | ||
|
||
|
||
class StoreGrpcUser(grpc_user.GrpcUser): | ||
host = "localhost:50050" | ||
stub_class = dstore_grpc.DatastoreStub | ||
|
||
@task | ||
def find_debilt_humidity(self): | ||
ts_request = dstore.FindTSRequest( | ||
station_ids=["06260"], | ||
param_ids=["rh"] | ||
) | ||
ts_response = self.stub.FindTimeSeries(ts_request) | ||
assert len(ts_response.tseries) == 1 | ||
|
||
@task | ||
def get_data_random_timeserie(self): | ||
ts_id = random.randint(1, 55*44) | ||
|
||
from_time = Timestamp() | ||
from_time.FromDatetime(datetime(2022, 12, 31)) | ||
to_time = Timestamp() | ||
to_time.FromDatetime(datetime(2023, 11, 1)) | ||
request = dstore.GetObsRequest( | ||
tsids=[ts_id], | ||
fromtime=from_time, | ||
totime=to_time, | ||
) | ||
response = self.stub.GetObservations(request) | ||
assert len(response.tsobs[0].obs) == 144 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Generate requirements.txt using: | ||
# pip-compile --upgrade --no-emit-index-url | ||
# Install using: | ||
# pip-sync | ||
|
||
grpcio-tools~=1.56 | ||
grpc-interceptor~=0.15.3 | ||
locust~=2.16 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# | ||
# This file is autogenerated by pip-compile with Python 3.11 | ||
# by the following command: | ||
# | ||
# pip-compile --no-emit-index-url | ||
# | ||
blinker==1.6.2 | ||
# via flask | ||
brotli==1.1.0 | ||
# via geventhttpclient | ||
certifi==2023.7.22 | ||
# via | ||
# geventhttpclient | ||
# requests | ||
charset-normalizer==3.2.0 | ||
# via requests | ||
click==8.1.7 | ||
# via flask | ||
configargparse==1.7 | ||
# via locust | ||
flask==2.3.3 | ||
# via | ||
# flask-basicauth | ||
# flask-cors | ||
# locust | ||
flask-basicauth==0.2.0 | ||
# via locust | ||
flask-cors==4.0.0 | ||
# via locust | ||
gevent==23.9.0.post1 | ||
# via | ||
# geventhttpclient | ||
# locust | ||
geventhttpclient==2.0.10 | ||
# via locust | ||
greenlet==2.0.2 | ||
# via gevent | ||
grpc-interceptor==0.15.3 | ||
# via -r requirements.in | ||
grpcio==1.58.0 | ||
# via | ||
# grpc-interceptor | ||
# grpcio-tools | ||
grpcio-tools==1.58.0 | ||
# via -r requirements.in | ||
idna==3.4 | ||
# via requests | ||
itsdangerous==2.1.2 | ||
# via flask | ||
jinja2==3.1.2 | ||
# via flask | ||
locust==2.16.1 | ||
# via -r requirements.in | ||
markupsafe==2.1.3 | ||
# via | ||
# jinja2 | ||
# werkzeug | ||
msgpack==1.0.5 | ||
# via locust | ||
protobuf==4.24.3 | ||
# via grpcio-tools | ||
psutil==5.9.5 | ||
# via locust | ||
pyzmq==25.1.1 | ||
# via locust | ||
requests==2.31.0 | ||
# via locust | ||
roundrobin==0.0.4 | ||
# via locust | ||
six==1.16.0 | ||
# via geventhttpclient | ||
typing-extensions==4.7.1 | ||
# via locust | ||
urllib3==2.0.4 | ||
# via requests | ||
werkzeug==2.3.7 | ||
# via | ||
# flask | ||
# locust | ||
zope-event==5.0 | ||
# via gevent | ||
zope-interface==6.0 | ||
# via gevent | ||
|
||
# The following packages are considered to be unsafe in a requirements file: | ||
# setuptools |