-
Notifications
You must be signed in to change notification settings - Fork 6
add Loadgen #90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
add Loadgen #90
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure when the deploy-app.yaml is moved from frontend to loadgen. Did you mean to copy-paste? |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The k8s folder needs to be structured to work with skaffold and kustomize as the deployments are different for workload clusters (where the archetype based workload is deployed) and other clusters (where just the virutal service and namespace) definitions are applied. If you look at the structure of any other k8s folder such as frontend/app-repo/k8s, it'll become apparent |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| # Copyright 2018 Google LLC | ||
| # | ||
| # 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 | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| apiVersion: apps/v1 | ||
| kind: Deployment | ||
| metadata: | ||
| name: loadgenerator | ||
| labels: | ||
| app: loadgenerator | ||
| spec: | ||
| selector: | ||
| matchLabels: | ||
| app: loadgenerator | ||
| replicas: 1 | ||
| template: | ||
| metadata: | ||
| labels: | ||
| app: loadgenerator | ||
| annotations: | ||
| sidecar.istio.io/rewriteAppHTTPProbers: "true" | ||
| spec: | ||
| serviceAccountName: loadgenerator | ||
| terminationGracePeriodSeconds: 5 | ||
| restartPolicy: Always | ||
| securityContext: | ||
| fsGroup: 1000 | ||
| runAsGroup: 1000 | ||
| runAsNonRoot: true | ||
| runAsUser: 1000 | ||
| initContainers: | ||
| - command: | ||
| - /bin/sh | ||
| - -exc | ||
| - | | ||
| MAX_RETRIES=12 | ||
| RETRY_INTERVAL=10 | ||
| for i in $(seq 1 $MAX_RETRIES); do | ||
| echo "Attempt $i: Pinging frontend: ${FRONTEND_ADDR}..." | ||
| STATUSCODE=$(wget --server-response http://${FRONTEND_ADDR} 2>&1 | awk '/^ HTTP/{print $2}') | ||
| if [ $STATUSCODE -eq 200 ]; then | ||
| echo "Frontend is reachable." | ||
| exit 0 | ||
| fi | ||
| echo "Error: Could not reach frontend - Status code: ${STATUSCODE}" | ||
| sleep $RETRY_INTERVAL | ||
| done | ||
| echo "Failed to reach frontend after $MAX_RETRIES attempts." | ||
| exit 1 | ||
| name: frontend-check | ||
| securityContext: | ||
| allowPrivilegeEscalation: false | ||
| capabilities: | ||
| drop: | ||
| - ALL | ||
| privileged: false | ||
| readOnlyRootFilesystem: true | ||
| image: busybox:latest | ||
| env: | ||
| - name: FRONTEND_ADDR | ||
| value: "frontend:80" | ||
| containers: | ||
| - name: main | ||
| securityContext: | ||
| allowPrivilegeEscalation: false | ||
| capabilities: | ||
| drop: | ||
| - ALL | ||
| privileged: false | ||
| readOnlyRootFilesystem: true | ||
| image: loadgenerator | ||
| env: | ||
| - name: FRONTEND_ADDR | ||
| value: "frontend:80" | ||
| - name: USERS | ||
| value: "10" | ||
| resources: | ||
| requests: | ||
| cpu: 300m | ||
| memory: 256Mi | ||
| limits: | ||
| cpu: 500m | ||
| memory: 512Mi | ||
| --- | ||
| apiVersion: v1 | ||
| kind: ServiceAccount | ||
| metadata: | ||
| name: loadgenerator |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be copy-paste instead of move? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Copyright 2020 Google LLC | ||
| # | ||
| # 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 | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| FROM python:3.12.3-slim@sha256:afc139a0a640942491ec481ad8dda10f2c5b753f5c969393b12480155fe15a63 as base | ||
|
|
||
| FROM base as builder | ||
|
|
||
| COPY requirements.txt . | ||
|
|
||
| RUN pip install --prefix="/install" -r requirements.txt | ||
|
|
||
| FROM base | ||
|
|
||
| WORKDIR /loadgen | ||
|
|
||
| COPY --from=builder /install /usr/local | ||
|
|
||
| # Add application code. | ||
| COPY locustfile.py . | ||
|
|
||
| # enable gevent support in debugger | ||
| ENV GEVENT_SUPPORT=True | ||
|
|
||
| ENTRYPOINT locust --host="http://${FRONTEND_ADDR}" --headless -u "${USERS:-10}" 2>&1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| #!/usr/bin/python | ||
| # | ||
| # Copyright 2018 Google LLC | ||
| # | ||
| # 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 | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| import random | ||
| from locust import FastHttpUser, TaskSet, between | ||
| from faker import Faker | ||
| import datetime | ||
| fake = Faker() | ||
|
|
||
| products = [ | ||
| '0PUK6V6EV0', | ||
| '1YMWWN1N4O', | ||
| '2ZYFJ3GM2N', | ||
| '66VCHSJNUP', | ||
| '6E92ZMYYFZ', | ||
| '9SIQT8TOJO', | ||
| 'L9ECAV7KIM', | ||
| 'LS4PSXUNUM', | ||
| 'OLJCESPC7Z'] | ||
|
|
||
| def index(l): | ||
| l.client.get("/") | ||
|
|
||
| def setCurrency(l): | ||
| currencies = ['EUR', 'USD', 'JPY', 'CAD', 'GBP', 'TRY'] | ||
| l.client.post("/setCurrency", | ||
| {'currency_code': random.choice(currencies)}) | ||
|
|
||
| def browseProduct(l): | ||
| l.client.get("/product/" + random.choice(products)) | ||
|
|
||
| def viewCart(l): | ||
| l.client.get("/cart") | ||
|
|
||
| def addToCart(l): | ||
| product = random.choice(products) | ||
| l.client.get("/product/" + product) | ||
| l.client.post("/cart", { | ||
| 'product_id': product, | ||
| 'quantity': random.randint(1,10)}) | ||
|
|
||
| def empty_cart(l): | ||
| l.client.post('/cart/empty') | ||
|
|
||
| def checkout(l): | ||
| addToCart(l) | ||
| current_year = datetime.datetime.now().year+1 | ||
| l.client.post("/cart/checkout", { | ||
| 'email': fake.email(), | ||
| 'street_address': fake.street_address(), | ||
| 'zip_code': fake.zipcode(), | ||
| 'city': fake.city(), | ||
| 'state': fake.state_abbr(), | ||
| 'country': fake.country(), | ||
| 'credit_card_number': fake.credit_card_number(card_type="visa"), | ||
| 'credit_card_expiration_month': random.randint(1, 12), | ||
| 'credit_card_expiration_year': random.randint(current_year, current_year + 70), | ||
| 'credit_card_cvv': f"{random.randint(100, 999)}", | ||
| }) | ||
|
|
||
| def logout(l): | ||
| l.client.get('/logout') | ||
|
|
||
|
|
||
| class UserBehavior(TaskSet): | ||
|
|
||
| def on_start(self): | ||
| index(self) | ||
|
|
||
| tasks = {index: 1, | ||
| setCurrency: 2, | ||
| browseProduct: 10, | ||
| addToCart: 2, | ||
| viewCart: 3, | ||
| checkout: 1} | ||
|
|
||
| class WebsiteUser(FastHttpUser): | ||
| tasks = [UserBehavior] | ||
| wait_time = between(1, 10) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| locust==2.29.0 | ||
| faker==25.8.0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| # | ||
| # This file is autogenerated by pip-compile with Python 3.11 | ||
| # by the following command: | ||
| # | ||
| # pip-compile --output-file=requirements.txt requirements.in | ||
| # | ||
| blinker==1.8.2 | ||
| # via flask | ||
| brotli==1.1.0 | ||
| # via geventhttpclient | ||
| certifi==2024.6.2 | ||
| # via | ||
| # geventhttpclient | ||
| # requests | ||
| charset-normalizer==3.3.2 | ||
| # via requests | ||
| click==8.1.7 | ||
| # via flask | ||
| configargparse==1.7 | ||
| # via locust | ||
| faker==25.8.0 | ||
| # via -r requirements.in | ||
| flask==3.0.3 | ||
| # via | ||
| # flask-cors | ||
| # flask-login | ||
| # locust | ||
| flask-cors==4.0.1 | ||
| # via locust | ||
| flask-login==0.6.3 | ||
| # via locust | ||
| gevent==24.2.1 | ||
| # via | ||
| # geventhttpclient | ||
| # locust | ||
| geventhttpclient==2.3.1 | ||
| # via locust | ||
| greenlet==3.0.3 | ||
| # via gevent | ||
| idna==3.7 | ||
| # via requests | ||
| itsdangerous==2.2.0 | ||
| # via flask | ||
| jinja2==3.1.4 | ||
| # via flask | ||
| locust==2.29.0 | ||
| # via -r requirements.in | ||
| markupsafe==2.1.5 | ||
| # via | ||
| # jinja2 | ||
| # werkzeug | ||
| msgpack==1.0.8 | ||
| # via locust | ||
| psutil==5.9.8 | ||
| # via locust | ||
| python-dateutil==2.9.0.post0 | ||
| # via faker | ||
| pyzmq==26.0.3 | ||
| # via locust | ||
| requests==2.32.3 | ||
| # via locust | ||
| six==1.16.0 | ||
| # via python-dateutil | ||
| urllib3==2.2.2 | ||
| # via | ||
| # geventhttpclient | ||
| # requests | ||
| werkzeug==3.0.3 | ||
| # via | ||
| # flask | ||
| # flask-login | ||
| # locust | ||
| zope-event==5.0 | ||
| # via gevent | ||
| zope-interface==6.4.post2 | ||
| # via gevent | ||
|
|
||
| # The following packages are considered to be unsafe in a requirements file: | ||
| # setuptools |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure when the build.yaml is moved from frontend to loadgen. Did you mean to copy-paste?