diff --git a/.gitignore b/.gitignore index 66f5f93..5f1014e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,7 @@ pkg/ .idea .skaffold-*.yaml .kubernetes-manifests-*/ +env/ + .project -.eclipse.buildship.core.prefs \ No newline at end of file +.eclipse.buildship.core.prefs diff --git a/build.out b/build.out new file mode 100644 index 0000000..5a6bd63 --- /dev/null +++ b/build.out @@ -0,0 +1 @@ +{"builds":[{"imageName":"gcr.io/lesser-weevil/emailservice","tag":"gcr.io/lesser-weevil/emailservice:v0.1.0-74-g468e8dc@sha256:7256c7e27888c37e06c19036032b594c5240d9a80bbe54963fda437346239742"},{"imageName":"gcr.io/lesser-weevil/productcatalogservice","tag":"gcr.io/lesser-weevil/productcatalogservice:v0.1.0-74-g468e8dc@sha256:19b199f0a976a3cebd5cf00d99d040a82c9824506de988d9485fffa828428898"},{"imageName":"gcr.io/lesser-weevil/recommendationservice","tag":"gcr.io/lesser-weevil/recommendationservice:v0.1.0-74-g468e8dc@sha256:3300a437de46c8d2e2144540ce0fe51ec2ea7b728c724021182337fd051bacad"},{"imageName":"gcr.io/lesser-weevil/shippingservice","tag":"gcr.io/lesser-weevil/shippingservice:v0.1.0-74-g468e8dc@sha256:dd8c49052601f9e3873d0c8034e6010645d83768df3526ee99cb43a71ce8344d"},{"imageName":"gcr.io/lesser-weevil/checkoutservice","tag":"gcr.io/lesser-weevil/checkoutservice:v0.1.0-74-g468e8dc@sha256:0955d209db61815892477b6f06b0f7a4c3c3d96e714c8c472faa5a442a2af875"},{"imageName":"gcr.io/lesser-weevil/paymentservice","tag":"gcr.io/lesser-weevil/paymentservice:v0.1.0-74-g468e8dc@sha256:07903a2bddf38920a940a2ab9aaddfbc7c06b0aa27dc07aaf8b9694722b44d92"},{"imageName":"gcr.io/lesser-weevil/currencyservice","tag":"gcr.io/lesser-weevil/currencyservice:v0.1.0-74-g468e8dc@sha256:df6b933e6b42a27035419119f93b471e4f9973b2934c0124da399c64dfc779a9"},{"imageName":"gcr.io/lesser-weevil/cartservice","tag":"gcr.io/lesser-weevil/cartservice:v0.1.0-74-g468e8dc@sha256:538f48876ad2f13603b4992bb3b75cde587333920f0a9f7e4d6d54924d349d3b"},{"imageName":"gcr.io/lesser-weevil/frontend","tag":"gcr.io/lesser-weevil/frontend:v0.1.0-74-g468e8dc@sha256:8b552b7de8dd9c45439d4a334f9d8dfeec0b989075a85e11cb17a81f2e47bab5"},{"imageName":"gcr.io/lesser-weevil/loadgenerator","tag":"gcr.io/lesser-weevil/loadgenerator:v0.1.0-74-g468e8dc@sha256:e874a37782981f587238a8b5ce807f7ce65d4c2f97c6bb847462de5a1aeb74c0"},{"imageName":"gcr.io/lesser-weevil/adservice","tag":"gcr.io/lesser-weevil/adservice:v0.1.0-74-g468e8dc@sha256:446a5743ebf2b7f27758c9d7588742223a42328838e7de222363f170d30e6231"},{"imageName":"gcr.io/lesser-weevil/pingjob","tag":"gcr.io/lesser-weevil/pingjob:v0.1.0-74-g468e8dc@sha256:0ade87236d2d837ca1d9b468497b7d05d729b6420120da35b8a9e64b20ce10a8"}]} \ No newline at end of file diff --git a/kubernetes-manifests/adservice.yaml b/kubernetes-manifests/adservice.yaml index 05dd9bb..d5836c4 100644 --- a/kubernetes-manifests/adservice.yaml +++ b/kubernetes-manifests/adservice.yaml @@ -17,6 +17,8 @@ kind: Deployment metadata: name: adservice spec: + revisionHistoryLimit: 1 + replicas: 5 selector: matchLabels: app: adservice diff --git a/kubernetes-manifests/cartservice.yaml b/kubernetes-manifests/cartservice.yaml index 31175da..196953e 100644 --- a/kubernetes-manifests/cartservice.yaml +++ b/kubernetes-manifests/cartservice.yaml @@ -17,6 +17,8 @@ kind: Deployment metadata: name: cartservice spec: + revisionHistoryLimit: 1 + replicas: 10 selector: matchLabels: app: cartservice @@ -41,10 +43,10 @@ spec: resources: requests: cpu: 200m - memory: 64Mi + memory: 128Mi limits: cpu: 300m - memory: 128Mi + memory: 256Mi readinessProbe: initialDelaySeconds: 15 exec: diff --git a/kubernetes-manifests/checkoutservice.yaml b/kubernetes-manifests/checkoutservice.yaml index 3e244c4..7a34c10 100644 --- a/kubernetes-manifests/checkoutservice.yaml +++ b/kubernetes-manifests/checkoutservice.yaml @@ -17,6 +17,7 @@ kind: Deployment metadata: name: checkoutservice spec: + revisionHistoryLimit: 1 selector: matchLabels: app: checkoutservice diff --git a/kubernetes-manifests/currencyservice.yaml b/kubernetes-manifests/currencyservice.yaml index 5c10ec7..0370416 100644 --- a/kubernetes-manifests/currencyservice.yaml +++ b/kubernetes-manifests/currencyservice.yaml @@ -17,6 +17,7 @@ kind: Deployment metadata: name: currencyservice spec: + revisionHistoryLimit: 1 selector: matchLabels: app: currencyservice @@ -67,3 +68,22 @@ spec: - name: grpc port: 7000 targetPort: 7000 +--- +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: currencyservice + labels: + app: currencyservice +spec: + maxReplicas: 7 + minReplicas: 1 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: currencyservice + metrics: + - type: Resource + resource: + name: cpu + targetAverageUtilization: 19 diff --git a/kubernetes-manifests/emailservice.yaml b/kubernetes-manifests/emailservice.yaml index bc7e6b9..81164e6 100644 --- a/kubernetes-manifests/emailservice.yaml +++ b/kubernetes-manifests/emailservice.yaml @@ -17,6 +17,7 @@ kind: Deployment metadata: name: emailservice spec: + revisionHistoryLimit: 1 selector: matchLabels: app: emailservice diff --git a/kubernetes-manifests/frontend.yaml b/kubernetes-manifests/frontend.yaml index da1c7cc..b44248c 100644 --- a/kubernetes-manifests/frontend.yaml +++ b/kubernetes-manifests/frontend.yaml @@ -15,15 +15,82 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: frontend + name: frontend-a spec: + revisionHistoryLimit: 1 selector: matchLabels: app: frontend + env: a template: metadata: labels: app: frontend + env: a + spec: + containers: + - name: server + image: frontend + ports: + - containerPort: 8080 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + httpHeaders: + - name: "Cookie" + value: "shop_session-id=x-readiness-probe" + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + httpHeaders: + - name: "Cookie" + value: "shop_session-id=x-liveness-probe" + env: + - name: PORT + value: "8080" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "productcatalogservice:3550" + - name: CURRENCY_SERVICE_ADDR + value: "currencyservice:7000" + - name: CART_SERVICE_ADDR + value: "cartservice:7070" + - name: RECOMMENDATION_SERVICE_ADDR + value: "recommendationservice:8080" + - name: SHIPPING_SERVICE_ADDR + value: "shippingservice:50051" + - name: CHECKOUT_SERVICE_ADDR + value: "checkoutservice:5050" + - name: AD_SERVICE_ADDR + value: "adservice:9555" + # - name: JAEGER_SERVICE_ADDR + # value: "jaeger-collector:14268" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: frontend-b +spec: + revisionHistoryLimit: 1 + selector: + matchLabels: + app: frontend + env: b + template: + metadata: + labels: + app: frontend + env: b annotations: sidecar.istio.io/rewriteAppHTTPProbers: "true" spec: @@ -100,6 +167,7 @@ spec: type: LoadBalancer selector: app: frontend + env: b ports: - name: http port: 80 diff --git a/kubernetes-manifests/loadgenerator.yaml b/kubernetes-manifests/loadgenerator.yaml index 53e947e..7c72344 100644 --- a/kubernetes-manifests/loadgenerator.yaml +++ b/kubernetes-manifests/loadgenerator.yaml @@ -16,6 +16,7 @@ kind: Deployment metadata: name: loadgenerator spec: + revisionHistoryLimit: 1 selector: matchLabels: app: loadgenerator @@ -29,6 +30,17 @@ spec: spec: terminationGracePeriodSeconds: 5 restartPolicy: Always + initContainers: + - name: wait-frontend + image: alpine:3.6 + command: ['sh', '-c', 'set -x; apk add --no-cache curl && + until timeout -t 2 curl -f "http://${FRONTEND_ADDR}"; do + echo "waiting for http://${FRONTEND_ADDR}"; + sleep 2; + done;'] + env: + - name: FRONTEND_ADDR + value: "frontend:80" containers: - name: main image: loadgenerator @@ -43,4 +55,4 @@ spec: memory: 256Mi limits: cpu: 500m - memory: 512Mi \ No newline at end of file + memory: 512Mi diff --git a/kubernetes-manifests/paymentservice.yaml b/kubernetes-manifests/paymentservice.yaml index fa62c08..15685b2 100644 --- a/kubernetes-manifests/paymentservice.yaml +++ b/kubernetes-manifests/paymentservice.yaml @@ -17,6 +17,7 @@ kind: Deployment metadata: name: paymentservice spec: + revisionHistoryLimit: 1 selector: matchLabels: app: paymentservice diff --git a/kubernetes-manifests/productcatalogservice.yaml b/kubernetes-manifests/productcatalogservice.yaml index 6949be0..cb143e6 100644 --- a/kubernetes-manifests/productcatalogservice.yaml +++ b/kubernetes-manifests/productcatalogservice.yaml @@ -17,6 +17,7 @@ kind: Deployment metadata: name: productcatalogservice spec: + revisionHistoryLimit: 1 selector: matchLabels: app: productcatalogservice diff --git a/kubernetes-manifests/recommendationservice.yaml b/kubernetes-manifests/recommendationservice.yaml index 0e75f9f..73ac609 100644 --- a/kubernetes-manifests/recommendationservice.yaml +++ b/kubernetes-manifests/recommendationservice.yaml @@ -15,15 +15,18 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: recommendationservice + name: recommendationservice-v1 spec: + revisionHistoryLimit: 1 selector: matchLabels: app: recommendationservice + version: v1 template: metadata: labels: app: recommendationservice + version: v1 spec: terminationGracePeriodSeconds: 5 containers: @@ -58,6 +61,53 @@ spec: cpu: 200m memory: 450Mi --- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: recommendationservice-v2 +spec: + selector: + matchLabels: + app: recommendationservice + version: v2 + template: + metadata: + labels: + app: recommendationservice + version: v2 + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: recommendationservice + ports: + - containerPort: 8080 + readinessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:8080"] + livenessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:8080"] + env: + - name: PORT + value: "8080" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "productcatalogservice:3550" + - name: ENABLE_PROFILER + value: "0" + resources: + requests: + cpu: 100m + memory: 220Mi + limits: + cpu: 200m + memory: 450Mi + revisionHistoryLimit: 1 +--- +#In order for istio to route traffic correctly, it needs a kubernetes service to route traffic to +#the workloads in question. apiVersion: v1 kind: Service metadata: @@ -67,6 +117,38 @@ spec: selector: app: recommendationservice ports: - - name: grpc - port: 8080 - targetPort: 8080 + - name: grpc + port: 8080 + targetPort: 8080 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: recommendationservice +spec: + hosts: + - recommendationservice + http: + - route: + - destination: + host: recommendationservice + subset: v1 + weight: 90 + - destination: + host: recommendationservice + subset: v2 + weight: 10 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: recommendationservice +spec: + host: recommendationservice + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 diff --git a/kubernetes-manifests/redis.yaml b/kubernetes-manifests/redis.yaml index b67649b..bb0d2e4 100644 --- a/kubernetes-manifests/redis.yaml +++ b/kubernetes-manifests/redis.yaml @@ -17,6 +17,7 @@ kind: Deployment metadata: name: redis-cart spec: + revisionHistoryLimit: 1 selector: matchLabels: app: redis-cart diff --git a/kubernetes-manifests/shippingservice.yaml b/kubernetes-manifests/shippingservice.yaml index e3027a1..3876dbf 100644 --- a/kubernetes-manifests/shippingservice.yaml +++ b/kubernetes-manifests/shippingservice.yaml @@ -17,6 +17,7 @@ kind: Deployment metadata: name: shippingservice spec: + revisionHistoryLimit: 1 selector: matchLabels: app: shippingservice @@ -24,6 +25,7 @@ spec: metadata: labels: app: shippingservice + version: deployment spec: containers: - name: server @@ -56,6 +58,47 @@ spec: cpu: 200m memory: 128Mi --- +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + name: shippingservice-rs +spec: + replicas: 2 + selector: + matchLabels: + app: shippingservice + owner: rs + template: + metadata: + labels: + app: shippingservice + owner: rs + spec: + containers: + - name: server + image: shippingservice + ports: + - containerPort: 50051 + env: + - name: PORT + value: "50051" + readinessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:50051"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:50051"] + # env: + # - name: JAEGER_SERVICE_ADDR + # value: "jaeger-collector:14268" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m +--- apiVersion: v1 kind: Service metadata: diff --git a/src/currencyservice/client.js b/src/currencyservice/client.js index 51e7f23..d23aa30 100644 --- a/src/currencyservice/client.js +++ b/src/currencyservice/client.js @@ -46,7 +46,7 @@ const request = { }; function _moneyToString (m) { - return `${m.units}.${m.nanos.toString().padStart(9,'0')} ${m.currency_code}`; + return `${m.units}.${m.nanos.toString().padStart(9, '0')} ${m.currency_code}`; } client.getSupportedCurrencies({}, (err, response) => { diff --git a/src/currencyservice/server.js b/src/currencyservice/server.js index 52ea639..a69869a 100644 --- a/src/currencyservice/server.js +++ b/src/currencyservice/server.js @@ -92,7 +92,13 @@ function _loadProto (path) { */ function _getCurrencyData (callback) { const data = require('./data/currency_conversion.json'); - callback(data); + // Currency conversion API slows down during peak hours. + let delay = 0; + const hour = new Date().getHours(); + if (hour > 8 && hour < 17) { + delay = 100; // add 100ms slowdown + } + setTimeout(() => callback(data), delay); } /** diff --git a/src/frontend/templates/footer.html b/src/frontend/templates/footer.html index 0ca31e1..c98eebb 100644 --- a/src/frontend/templates/footer.html +++ b/src/frontend/templates/footer.html @@ -10,7 +10,9 @@

This website is hosted for demo purposes only. It is not an - actual shop. This is not an official Google project. + actual shop. This is not an official Google project. Demo + deployment for Google Cloud & Signals Monitoring + Topology.

diff --git a/src/frontend/templates/home.html b/src/frontend/templates/home.html index 1d97c6a..5d64528 100644 --- a/src/frontend/templates/home.html +++ b/src/frontend/templates/home.html @@ -17,6 +17,9 @@ you catch up with the hipster trend and express your personal style. Start shopping hip and vintage items now!

+

+ Cloud Topology +

diff --git a/src/loadgenerator/Dockerfile b/src/loadgenerator/Dockerfile index cdd89d4..a77fd2c 100644 --- a/src/loadgenerator/Dockerfile +++ b/src/loadgenerator/Dockerfile @@ -14,8 +14,5 @@ FROM base COPY --from=builder /install /usr/local COPY . . -RUN chmod +x ./loadgen.sh -RUN apt-get -qq update \ - && apt-get install -y --no-install-recommends \ - curl -ENTRYPOINT ./loadgen.sh +ENTRYPOINT ["./loadgen.sh"] + diff --git a/src/loadgenerator/loadgen.sh b/src/loadgenerator/loadgen.sh index 4a0f35e..23477fa 100755 --- a/src/loadgenerator/loadgen.sh +++ b/src/loadgenerator/loadgen.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh -eu # # Copyright 2018 Google LLC # @@ -14,22 +14,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +#!/bin/bash set -e trap "exit" TERM -if [[ -z "${FRONTEND_ADDR}" ]]; then +if [ -z "${FRONTEND_ADDR}" ]; then echo >&2 "FRONTEND_ADDR not specified" exit 1 fi set -x - -# if one request to the frontend fails, then exit -STATUSCODE=$(curl --silent --output /dev/stderr --write-out "%{http_code}" http://${FRONTEND_ADDR}) -if test $STATUSCODE -ne 200; then - echo "Error: Could not reach frontend - Status code: ${STATUSCODE}" - exit 1 -fi - -# else, run loadgen -locust --host="http://${FRONTEND_ADDR}" --no-web -c "${USERS:-10}" 2>&1 +locust \ + -f locustfile.py \ + --host="http://${FRONTEND_ADDR}" \ + --no-web \ + -c "${USERS:-10}" \ + -r 1 diff --git a/src/loadgenerator/locustfile.py b/src/loadgenerator/locustfile.py index f1f98ea..2167799 100644 --- a/src/loadgenerator/locustfile.py +++ b/src/loadgenerator/locustfile.py @@ -14,7 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import math import random +import time from locust import HttpLocust, TaskSet products = [ @@ -28,29 +30,39 @@ products = [ 'LS4PSXUNUM', 'OLJCESPC7Z'] + def index(l): l.client.get("/") + def setCurrency(l): currencies = ['EUR', 'USD', 'JPY', 'CAD'] l.client.post("/setCurrency", - {'currency_code': random.choice(currencies)}) + {'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.choice([1,2,3,4,5,10])}) + 'quantity': random.choice([1, 2, 3, 4, 5, 10])}) + def checkout(l): addToCart(l) + # For five minutes every other hour, credit cards passed by the user will be + # invalid and the paymentservice will fail. + now = time.localtime() + expiration_year = '2015' if (now.tm_hour % 2) & (now.tm_min < 5) else '2060' l.client.post("/cart/checkout", { 'email': 'someone@example.com', 'street_address': '1600 Amphitheatre Parkway', @@ -60,23 +72,41 @@ def checkout(l): 'country': 'United States', 'credit_card_number': '4432-8015-6152-0454', 'credit_card_expiration_month': '1', - 'credit_card_expiration_year': '2039', + 'credit_card_expiration_year': expiration_year, 'credit_card_cvv': '672', }) + class UserBehavior(TaskSet): + min_wait = 500 + max_wait = 15000 + + tasks = {index: 1, + setCurrency: 2, + browseProduct: 10, + addToCart: 2, + viewCart: 3, + checkout: 1} def on_start(self): index(self) - tasks = {index: 1, - setCurrency: 2, - browseProduct: 10, - addToCart: 2, - viewCart: 3, - checkout: 1} + def wait_function(self): + """Wait time between user activity is diurnal. + + Compute user's activity rate (wait time between actions) so traffic is + minimum at hrs=0.0|24.0 and maximum at hrs=12.0. + """ + now = time.localtime() + hrs = now.tm_hour + now.tm_min/60.0 + # Compute scale factor is between 0 and 1. + traffic_scaler = -1.0 * math.cos(2.0 * math.pi * hrs / 24) + traffic_scaler = (traffic_scaler + 1) / 2.0 + + # Scale traffic between minimum and maximum wait times. + wait = self.max_wait + (self.min_wait - self.max_wait) * traffic_scaler + return round(wait) + class WebsiteUser(HttpLocust): task_set = UserBehavior - min_wait = 1000 - max_wait = 10000 diff --git a/src/loadgenerator/requirements.in b/src/loadgenerator/requirements.in index 0b66c0a..280aa5f 100644 --- a/src/loadgenerator/requirements.in +++ b/src/loadgenerator/requirements.in @@ -1 +1 @@ -locustio==0.8.1 +locustio==0.9.0 diff --git a/src/loadgenerator/requirements.txt b/src/loadgenerator/requirements.txt index ac69aca..60993cd 100644 --- a/src/loadgenerator/requirements.txt +++ b/src/loadgenerator/requirements.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile # To update, run: # -# pip-compile --output-file requirements.txt requirements.in +# pip-compile --output-file=requirements.txt requirements.in # certifi==2018.11.29 # via requests chardet==3.0.4 # via requests @@ -13,9 +13,9 @@ greenlet==0.4.15 # via gevent idna==2.8 # via requests itsdangerous==1.1.0 # via flask jinja2==2.10 # via flask -locustio==0.8.1 +locustio==0.9.0 markupsafe==1.1.0 # via jinja2 -msgpack-python==0.5.6 # via locustio +msgpack==0.6.1 # via locustio pyzmq==17.0.0 # via locustio requests==2.21.0 # via locustio six==1.12.0 # via locustio diff --git a/src/paymentservice/charge.js b/src/paymentservice/charge.js index ce9674a..fe7b9da 100644 --- a/src/paymentservice/charge.js +++ b/src/paymentservice/charge.js @@ -15,6 +15,7 @@ const cardValidator = require('simple-card-validator'); const uuid = require('uuid/v4'); const pino = require('pino'); +const grpc = require('grpc'); const logger = pino({ name: 'paymentservice-charge', @@ -28,6 +29,7 @@ class CreditCardError extends Error { constructor (message) { super(message); this.code = 400; // Invalid argument error + this.status = grpc.status.INVALID_ARGUMENT; } } diff --git a/src/pingjob/Dockerfile b/src/pingjob/Dockerfile new file mode 100644 index 0000000..4942b0e --- /dev/null +++ b/src/pingjob/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3-slim as base + +FROM base as builder + +RUN apt-get -qq update \ + && apt-get install -y --no-install-recommends \ + g++ + +COPY requirements.txt . + +RUN pip install --install-option="--prefix=/install" -r requirements.txt + +FROM base +COPY --from=builder /install /usr/local + +COPY . . +ENTRYPOINT ["./pinger.sh"] + diff --git a/src/pingjob/pinger.py b/src/pingjob/pinger.py new file mode 100644 index 0000000..915ae85 --- /dev/null +++ b/src/pingjob/pinger.py @@ -0,0 +1,87 @@ +#!/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 + +import requests +import sys + +BASE = sys.argv[1] + +products = [ + '0PUK6V6EV0', + '1YMWWN1N4O', + '2ZYFJ3GM2N', + '66VCHSJNUP', + '6E92ZMYYFZ', + '9SIQT8TOJO', + 'L9ECAV7KIM', + 'LS4PSXUNUM', + 'OLJCESPC7Z'] + + +def index(): + requests.get(BASE + "/") + + +def setCurrency(): + currencies = ['EUR', 'USD', 'JPY', 'CAD'] + requests.post(BASE + "/setCurrency", + {'currency_code': random.choice(currencies)}) + + +def browseProduct(): + requests.get(BASE + "/product/" + random.choice(products)) + + +def viewCart(): + requests.get(BASE + "/cart") + + +def addToCart(): + product = random.choice(products) + requests.get(BASE + "/product/" + product) + requests.post(BASE + "/cart", { + 'product_id': product, + 'quantity': random.choice([1, 2, 3, 4, 5, 10])}) + + +def checkout(): + addToCart() + requests.post(BASE + "/cart/checkout", { + 'email': 'someone@example.com', + 'street_address': '1600 Amphitheatre Parkway', + 'zip_code': '94043', + 'city': 'Mountain View', + 'state': 'CA', + 'country': 'United States', + 'credit_card_number': '4432-8015-6152-0454', + 'credit_card_expiration_month': '1', + 'credit_card_expiration_year': '2039', + 'credit_card_cvv': '672', + }) + + +if not BASE: + print("ERROR: no frontend address") +else: + print("pinging" + BASE) +index() +browseProduct() +addToCart() +viewCart() +checkout() +print("pinging complete") diff --git a/src/pingjob/pinger.sh b/src/pingjob/pinger.sh new file mode 100755 index 0000000..9e799ae --- /dev/null +++ b/src/pingjob/pinger.sh @@ -0,0 +1,27 @@ +#!/bin/sh -eu +# +# 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. + +#!/bin/bash +set -e +trap "exit" TERM + +if [ -z "${FRONTEND_ADDR}" ]; then + echo >&2 "FRONTEND_ADDR not specified" + exit 1 +fi + +set -x +python pinger.py "${FRONTEND_ADDR}" diff --git a/src/pingjob/requirements.in b/src/pingjob/requirements.in new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/src/pingjob/requirements.in @@ -0,0 +1 @@ +requests diff --git a/src/pingjob/requirements.txt b/src/pingjob/requirements.txt new file mode 100644 index 0000000..59b8df2 --- /dev/null +++ b/src/pingjob/requirements.txt @@ -0,0 +1,11 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --output-file=requirements.txt requirements.in +# +certifi==2018.11.29 # via requests +chardet==3.0.4 # via requests +idna==2.8 # via requests +requests==2.21.0 +urllib3==1.24.1 # via requests