Merge pull request #9 from DavidSouther/fluctuating-errors
Diurnal user load (for real)
This commit is contained in:
commit
a32631d717
8 changed files with 43 additions and 24 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,3 +9,4 @@ pkg/
|
||||||
.idea
|
.idea
|
||||||
.skaffold-*.yaml
|
.skaffold-*.yaml
|
||||||
.kubernetes-manifests-*/
|
.kubernetes-manifests-*/
|
||||||
|
env/
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"builds":[{"imageName":"gcr.io/lesser-weevil/emailservice","tag":"gcr.io/lesser-weevil/emailservice:v0.1.0-26-gff80ed8@sha256:b5642298862ce0852e6038cf029ed75df6a08530c3ca9b86cd2ad4b50d5cff00"},{"imageName":"gcr.io/lesser-weevil/productcatalogservice","tag":"gcr.io/lesser-weevil/productcatalogservice:v0.1.0-26-gff80ed8@sha256:74288be0207731ee0f846273da3486638777cf8d4077bddd45e0aeac75bb3559"},{"imageName":"gcr.io/lesser-weevil/recommendationservice","tag":"gcr.io/lesser-weevil/recommendationservice:v0.1.0-26-gff80ed8@sha256:41f79b358ddf3d22f2f317caab5585fbaccf9ce75052f57a2e3da03a29b4a65e"},{"imageName":"gcr.io/lesser-weevil/shippingservice","tag":"gcr.io/lesser-weevil/shippingservice:v0.1.0-26-gff80ed8@sha256:6625a1e45b63c32585248a51d32b1b5137c16c7fb0f622ee9efbd08ef0cfed42"},{"imageName":"gcr.io/lesser-weevil/checkoutservice","tag":"gcr.io/lesser-weevil/checkoutservice:v0.1.0-26-gff80ed8@sha256:cab8d517f524609837c7c70d357d7ba4aeb836dc417414d726079ed811928804"},{"imageName":"gcr.io/lesser-weevil/paymentservice","tag":"gcr.io/lesser-weevil/paymentservice:v0.1.0-26-gff80ed8@sha256:1d65c32c95fbf5fe7348e8d4975bf15a305279f78264f342734afc3d1273a7cb"},{"imageName":"gcr.io/lesser-weevil/currencyservice","tag":"gcr.io/lesser-weevil/currencyservice:v0.1.0-26-gff80ed8@sha256:e6a17c4d41d5e95d5182dfea2bbac392dee5ac5d965e0a35af70ef11edc7c0a1"},{"imageName":"gcr.io/lesser-weevil/cartservice","tag":"gcr.io/lesser-weevil/cartservice:v0.1.0-26-gff80ed8@sha256:2d6b7b6422669a0850f3743c734d300cbcf247fe850127ea99f695e831e32374"},{"imageName":"gcr.io/lesser-weevil/frontend","tag":"gcr.io/lesser-weevil/frontend:v0.1.0-26-gff80ed8@sha256:119a11554f457f3a4df05672de4f51050f305fba67482b242543ec6fb4ed1f05"},{"imageName":"gcr.io/lesser-weevil/loadgenerator","tag":"gcr.io/lesser-weevil/loadgenerator:v0.1.0-26-gff80ed8@sha256:dcd70533d44517a2c5460e20b7e001c79e54e009f5c42ebcb52474bcd1610fa9"},{"imageName":"gcr.io/lesser-weevil/adservice","tag":"gcr.io/lesser-weevil/adservice:v0.1.0-26-gff80ed8@sha256:39a383bafca249864cd67a8eac66e67a19dc107b46566d7e16501c4f15ee0935"}]}
|
{"builds":[{"imageName":"gcr.io/lesser-weevil/emailservice","tag":"gcr.io/lesser-weevil/emailservice:v0.1.0-33-g6e6db3b@sha256:593de0cc94b95fa033838a3d3f3dc0168cc35f736b01ace2954b3648771e1027"},{"imageName":"gcr.io/lesser-weevil/productcatalogservice","tag":"gcr.io/lesser-weevil/productcatalogservice:v0.1.0-33-g6e6db3b@sha256:29dc89ac7aa66dcb70fd1c9e84f422a5e0c4bcb117ed0cb29c7cd6282ab13bbe"},{"imageName":"gcr.io/lesser-weevil/recommendationservice","tag":"gcr.io/lesser-weevil/recommendationservice:v0.1.0-33-g6e6db3b@sha256:de6cddba59ea40a879baf25b2ae58dd06b64532d0ca52dda4c4b6d22e577f0d6"},{"imageName":"gcr.io/lesser-weevil/shippingservice","tag":"gcr.io/lesser-weevil/shippingservice:v0.1.0-33-g6e6db3b@sha256:0ee734d45b10760c0d01bf3ca27a85b56296337adfe540f344860b2de1eb0277"},{"imageName":"gcr.io/lesser-weevil/checkoutservice","tag":"gcr.io/lesser-weevil/checkoutservice:v0.1.0-33-g6e6db3b@sha256:d9b7a695508b8df8d894d4b1ea24ebc8f651c069daab64df4acb2556c72ace1d"},{"imageName":"gcr.io/lesser-weevil/paymentservice","tag":"gcr.io/lesser-weevil/paymentservice:v0.1.0-33-g6e6db3b@sha256:93d422fe681b9ac2aed353b5b22f447dcd305bb297980edb0dfd68719e9dde65"},{"imageName":"gcr.io/lesser-weevil/currencyservice","tag":"gcr.io/lesser-weevil/currencyservice:v0.1.0-33-g6e6db3b@sha256:5dd9f85c65b0ab000f759ea37d78ff06643ea800220e9e34c251f3c1e33ab2b9"},{"imageName":"gcr.io/lesser-weevil/cartservice","tag":"gcr.io/lesser-weevil/cartservice:v0.1.0-33-g6e6db3b@sha256:6cc3baab0bdf2eda1ec9da076a102007c851a665c9fd8ee99d741c734c8a85fe"},{"imageName":"gcr.io/lesser-weevil/frontend","tag":"gcr.io/lesser-weevil/frontend:v0.1.0-33-g6e6db3b@sha256:43d6cbbfb02cb9a4435063c63127f1f4e22a8954f38cc78159c1ae7e44700bdd"},{"imageName":"gcr.io/lesser-weevil/loadgenerator","tag":"gcr.io/lesser-weevil/loadgenerator:v0.1.0-33-g6e6db3b@sha256:88ece337b51771e0a10cc09d8db31dd474d93fcbc47b145a9d9f6a27e24a5fb4"},{"imageName":"gcr.io/lesser-weevil/adservice","tag":"gcr.io/lesser-weevil/adservice:v0.1.0-33-g6e6db3b@sha256:dcb2c1644648b9c18c6fc48ad7fc1a15f4dc890ad3fca531b9892d6cfdf1a305"}]}
|
|
@ -14,4 +14,5 @@ FROM base
|
||||||
COPY --from=builder /install /usr/local
|
COPY --from=builder /install /usr/local
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
ENTRYPOINT ./loadgen.sh
|
ENTRYPOINT ["./loadgen.sh"]
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,15 @@
|
||||||
set -e
|
set -e
|
||||||
trap "exit" TERM
|
trap "exit" TERM
|
||||||
|
|
||||||
if [[ -z "${FRONTEND_ADDR}" ]]; then
|
if [ -z "${FRONTEND_ADDR}" ]; then
|
||||||
echo >&2 "FRONTEND_ADDR not specified"
|
echo >&2 "FRONTEND_ADDR not specified"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
locust --host="http://${FRONTEND_ADDR}" --no-web -c "${USERS:-10}"
|
locust \
|
||||||
|
-f locustfile.py \
|
||||||
|
--host="http://${FRONTEND_ADDR}" \
|
||||||
|
--no-web \
|
||||||
|
-c "${USERS:-10}" \
|
||||||
|
-r 1
|
||||||
|
|
|
@ -30,26 +30,32 @@ products = [
|
||||||
'LS4PSXUNUM',
|
'LS4PSXUNUM',
|
||||||
'OLJCESPC7Z']
|
'OLJCESPC7Z']
|
||||||
|
|
||||||
|
|
||||||
def index(l):
|
def index(l):
|
||||||
l.client.get("/")
|
l.client.get("/")
|
||||||
|
|
||||||
|
|
||||||
def setCurrency(l):
|
def setCurrency(l):
|
||||||
currencies = ['EUR', 'USD', 'JPY', 'CAD']
|
currencies = ['EUR', 'USD', 'JPY', 'CAD']
|
||||||
l.client.post("/setCurrency",
|
l.client.post("/setCurrency",
|
||||||
{'currency_code': random.choice(currencies)})
|
{'currency_code': random.choice(currencies)})
|
||||||
|
|
||||||
|
|
||||||
def browseProduct(l):
|
def browseProduct(l):
|
||||||
l.client.get("/product/" + random.choice(products))
|
l.client.get("/product/" + random.choice(products))
|
||||||
|
|
||||||
|
|
||||||
def viewCart(l):
|
def viewCart(l):
|
||||||
l.client.get("/cart")
|
l.client.get("/cart")
|
||||||
|
|
||||||
|
|
||||||
def addToCart(l):
|
def addToCart(l):
|
||||||
product = random.choice(products)
|
product = random.choice(products)
|
||||||
l.client.get("/product/" + product)
|
l.client.get("/product/" + product)
|
||||||
l.client.post("/cart", {
|
l.client.post("/cart", {
|
||||||
'product_id': product,
|
'product_id': product,
|
||||||
'quantity': random.choice([1,2,3,4,5,10])})
|
'quantity': random.choice([1, 2, 3, 4, 5, 10])})
|
||||||
|
|
||||||
|
|
||||||
def checkout(l):
|
def checkout(l):
|
||||||
addToCart(l)
|
addToCart(l)
|
||||||
|
@ -66,16 +72,27 @@ def checkout(l):
|
||||||
'credit_card_cvv': '672',
|
'credit_card_cvv': '672',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class UserBehavior(TaskSet):
|
class UserBehavior(TaskSet):
|
||||||
min_wait = 1000
|
min_wait = 500
|
||||||
max_wait = 20000
|
max_wait = 15000
|
||||||
|
|
||||||
|
tasks = {index: 1,
|
||||||
|
setCurrency: 2,
|
||||||
|
browseProduct: 10,
|
||||||
|
addToCart: 2,
|
||||||
|
viewCart: 3,
|
||||||
|
checkout: 1}
|
||||||
|
|
||||||
def on_start(self):
|
def on_start(self):
|
||||||
index(self)
|
index(self)
|
||||||
|
|
||||||
def wait_function(self):
|
def wait_function(self):
|
||||||
# Compute user's activity rate (wait time between actions) so traffic is
|
"""Wait time between user activity is diurnal.
|
||||||
# diurnal; minimum at hrs=0.0|24.0 and maximum at hrs=12.0.
|
|
||||||
|
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()
|
now = time.localtime()
|
||||||
hrs = now.tm_hour + now.tm_min/60.0
|
hrs = now.tm_hour + now.tm_min/60.0
|
||||||
# Compute scale factor is between 0 and 1.
|
# Compute scale factor is between 0 and 1.
|
||||||
|
@ -83,14 +100,9 @@ class UserBehavior(TaskSet):
|
||||||
traffic_scaler = (traffic_scaler + 1) / 2.0
|
traffic_scaler = (traffic_scaler + 1) / 2.0
|
||||||
|
|
||||||
# Scale traffic between minimum and maximum wait times.
|
# Scale traffic between minimum and maximum wait times.
|
||||||
return self.max_wait + (self.min_wait - self.max_wait) * traffic_scaler
|
wait = self.max_wait + (self.min_wait - self.max_wait) * traffic_scaler
|
||||||
|
return round(wait)
|
||||||
|
|
||||||
tasks = {index: 1,
|
|
||||||
setCurrency: 2,
|
|
||||||
browseProduct: 10,
|
|
||||||
addToCart: 2,
|
|
||||||
viewCart: 3,
|
|
||||||
checkout: 1}
|
|
||||||
|
|
||||||
class WebsiteUser(HttpLocust):
|
class WebsiteUser(HttpLocust):
|
||||||
task_set = UserBehavior
|
task_set = UserBehavior
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
locustio==0.8.1
|
locustio==0.9.0
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# This file is autogenerated by pip-compile
|
# This file is autogenerated by pip-compile
|
||||||
# To update, run:
|
# 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
|
certifi==2018.11.29 # via requests
|
||||||
chardet==3.0.4 # via requests
|
chardet==3.0.4 # via requests
|
||||||
|
@ -13,9 +13,9 @@ greenlet==0.4.15 # via gevent
|
||||||
idna==2.8 # via requests
|
idna==2.8 # via requests
|
||||||
itsdangerous==1.1.0 # via flask
|
itsdangerous==1.1.0 # via flask
|
||||||
jinja2==2.10 # via flask
|
jinja2==2.10 # via flask
|
||||||
locustio==0.8.1
|
locustio==0.9.0
|
||||||
markupsafe==1.1.0 # via jinja2
|
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
|
pyzmq==17.0.0 # via locustio
|
||||||
requests==2.21.0 # via locustio
|
requests==2.21.0 # via locustio
|
||||||
six==1.12.0 # via locustio
|
six==1.12.0 # via locustio
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue