From 54e2596d9f370609013a69680e940dbb161528f5 Mon Sep 17 00:00:00 2001 From: dent50cent <35925962+dent50cent@users.noreply.github.com> Date: Thu, 29 Nov 2018 15:10:38 +0000 Subject: [PATCH] Fix kubernetes mode (#906) * fixed default port not being given in dockerfile for games * Changed simulation runner to make use of asyncio * changed parallel_map to async_map * Waiting for workers pt. 1 * aimmo now works in kubernetes mode again * aimmo now works in kubernetes mode again (tests fails though) * Merge remote-tracking branch 'origin/fix_kubernetes_mode' into fix_kubernetes_mode * fixed broken tests * pep8 * removed temporary logging * moved get loop into setUp for tests * bump version++ * make runner last build stage * remove broken coverage tool * removed broken coverage tool++ * change docker build target in tester * docker now uses buildkit (requires docker 18.09) * create build hook for docker cloud * fix syntax error * add image tag to build hook * fix image name on build hook * add build hook for worker and game-creator * remove pwd from build hooks * remove broken coverage tool from travis.yml * change env variable to be str not int * force setup.py version * Revert "force setup.py version" This reverts commit 306bee841a0f76d4a34295400c2a223574f2e86d. * review changes * add dockerbuildkit env variable to travis * change the way docker is installed for travis test * removed docker addon from travis.yml (installing older version) * changed logic in docker scripts --- .travis.yml | 17 +- aimmo-game-creator/Dockerfile | 10 -- aimmo-game-creator/Pipfile | 1 - aimmo-game-creator/Pipfile.lock | 79 +++------- aimmo-game-creator/hooks/build | 2 + aimmo-game-creator/setup.py | 13 -- aimmo-game-worker/Dockerfile | 9 -- aimmo-game-worker/Pipfile.lock | 40 ++--- aimmo-game-worker/hooks/build | 2 + aimmo-game-worker/setup.py | 12 -- aimmo-game/Dockerfile | 14 +- aimmo-game/Pipfile | 3 +- aimmo-game/Pipfile.lock | 149 +++++++----------- aimmo-game/hooks/build | 2 + aimmo-game/setup.py | 13 -- aimmo-game/simulation/game_runner.py | 3 +- aimmo-game/simulation/simulation_runner.py | 35 ++-- .../kubernetes_worker_manager.py | 2 +- .../worker_managers/worker_manager.py | 2 +- .../test_damage_pickups_and_effects.py | 12 +- .../tests/functional/test_effect_expiry.py | 49 +++--- .../test_health_pickups_and_effects.py | 10 +- ...est_invulnerability_pickups_and_effects.py | 9 +- .../tests/functional/test_movements_in_map.py | 22 +-- .../test_simulation/test_simulation_runner.py | 4 +- aimmo_runner/docker_scripts.py | 34 ++-- all_tests.py | 5 +- version.txt | 2 +- 28 files changed, 205 insertions(+), 350 deletions(-) create mode 100755 aimmo-game-creator/hooks/build create mode 100755 aimmo-game-worker/hooks/build create mode 100755 aimmo-game/hooks/build diff --git a/.travis.yml b/.travis.yml index 58e1c8359..cbc1a6997 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ services: - docker env: global: + - DOCKER_BUILDKIT=1 - secure: "TNhj8oXrtBzCkkJDA8qbDmqUggK9Kbsy8Itgi0+VmXB+3bVRornZMS38ppaFz+BVOTdL80ZvN2s/OPV106QjFv0Hx1MmWAw4kNST2QBtxFXBHRKYtr7NtBN0jr11el1fG83YdpeZYQbc5aqbJ4OPz2GpfhGfDVhVGPjMFMKXI5XbTbbl+HCEL67ywozt964LhpuuXTaX7jgYFiJUtcwkYRUaDYY3ryJvMSOx95AjKyRMNC5JlgAqbJuYsOTm1eVZtfQ1jYVvd/NuAHOMDNpZWvcIaxTuc3k4XZh4UPryuRJWfjgjIq6kua7Q6ho6W2GbDgN2b/9lIldkTR8QfLSnCNLJIg6KJZ2gmIQg7u+nZHemdugo9XkvfmKXfB/t3HChFX1HNtS4gSeIn874IynLHx3UJ1lxm7BdDbF4Jjijffj5uWDGqVj3/Myd2jdFTJCoLJXvYI7la6ouMzXW5aDFhy2UXK2A3q7aBbaD64+U1R7YPGIyvfAd7NCF11vtRvJGI/fNjO5S1EuSacrQm7CiXu0rd0L5EOSU85XNTQsWN6xxJKEcc8Hx9YLRXkmR7gK9LoEPTUwFbfVXBUvnOsZav3MOBBxzj4+eLxkx2B1vbY2Lx5yPAqyWwi3vet46NEZUIKgqK+xRYQKj6dj3OF1gx7LOcyhpyevdpTZotiEx0C4=" # SNAP_API_AUTH git: depth: 9999999 # Building untagged builds needs enough depth to get the latest tag @@ -45,39 +46,31 @@ jobs: - node djangoBundler.js - popd script: - - python all_tests.py --no-docker-container-tests --coverage - after_success: - - coveralls + - python all_tests.py --no-docker-container-tests - name: "aimmo-game" before_install: - cd aimmo-game - - docker build -t ocadotechnology/aimmo-game:test . + - docker build --target tester -t ocadotechnology/aimmo-game:test . install: - pip install coveralls script: - docker run -it -p 5000:5000 ocadotechnology/aimmo-game:test - after_success: - - coveralls - name: "aimmo-game-creator" before_install: - cd aimmo-game-creator - - docker build -t ocadotechnology/aimmo-game-creator:test . + - docker build --target tester -t ocadotechnology/aimmo-game-creator:test . install: - pip install coveralls script: - docker run -it -p 5000:5000 ocadotechnology/aimmo-game-creator:test - after_success: - - coveralls - name: "aimmo-game-worker" before_install: - cd aimmo-game-worker - - docker build -t ocadotechnology/aimmo-game-worker:test . + - docker build --target tester -t ocadotechnology/aimmo-game-worker:test . install: - pip install coveralls script: - docker run -it -p 5000:5000 ocadotechnology/aimmo-game-worker:test - after_success: - - coveralls - name: "Javascript Tests" before_install: - nvm install node diff --git a/aimmo-game-creator/Dockerfile b/aimmo-game-creator/Dockerfile index 135413cda..ebceaede1 100644 --- a/aimmo-game-creator/Dockerfile +++ b/aimmo-game-creator/Dockerfile @@ -3,26 +3,16 @@ MAINTAINER code@ocado.com # RUN apk add --no-cache gcc musl-dev python-dev libffi-dev openssl-dev RUN pip install pipenv COPY ["Pipfile", "Pipfile.lock", "setup.py", "./"] -RUN pipenv install coverage RUN pipenv install --system --deploy FROM python:3.6-alpine as base COPY --from=builder /usr/local/lib/python3.6/site-packages /usr/local/lib/python3.6/site-packages COPY . . - FROM base as runner ENV WORKER_MANAGER=kubernetes CMD ["python", "./service.py", "0.0.0.0"] - FROM base as tester ENV WORKER_MANAGER=kubernetes CMD ["python", "setup.py", "test"] - -FROM base as coverage_tester -ENV WORKER_MANAGER=kubernetes -ENV WITH_COVERAGE='True' -RUN apk add bash -COPY --from=builder /usr/local/bin/coverage /usr/local/bin/coverage -CMD python setup.py test \ No newline at end of file diff --git a/aimmo-game-creator/Pipfile b/aimmo-game-creator/Pipfile index 6da8ef065..5f8617ff1 100644 --- a/aimmo-game-creator/Pipfile +++ b/aimmo-game-creator/Pipfile @@ -7,7 +7,6 @@ name = "pypi" kubernetes = "*" aimmo-game-creator = {editable = true, path = "."} docker = "*" -coverage = "*" [requires] python_version = "3.6.7" diff --git a/aimmo-game-creator/Pipfile.lock b/aimmo-game-creator/Pipfile.lock index ed6b9fcf5..ba5aeabf5 100644 --- a/aimmo-game-creator/Pipfile.lock +++ b/aimmo-game-creator/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0a9a9775ea69c8dd572b73cad7cdb6f7460a87bd98956a74b0cbe70d800a98ae" + "sha256": "d98688ef01ef4dd26698c8ed47bd8ccda0c299d2205648133c6c226a69c7fa62" }, "pipfile-spec": 6, "requires": { @@ -92,66 +92,29 @@ ], "version": "==3.0.4" }, - "coverage": { - "hashes": [ - "sha256:09e47c529ff77bf042ecfe858fb55c3e3eb97aac2c87f0349ab5a7efd6b3939f", - "sha256:0a1f9b0eb3aa15c990c328535655847b3420231af299386cfe5efc98f9c250fe", - "sha256:0cc941b37b8c2ececfed341444a456912e740ecf515d560de58b9a76562d966d", - "sha256:10e8af18d1315de936d67775d3a814cc81d0747a1a0312d84e27ae5610e313b0", - "sha256:1b4276550b86caa60606bd3572b52769860a81a70754a54acc8ba789ce74d607", - "sha256:1e8a2627c48266c7b813975335cfdea58c706fe36f607c97d9392e61502dc79d", - "sha256:2b224052bfd801beb7478b03e8a66f3f25ea56ea488922e98903914ac9ac930b", - "sha256:447c450a093766744ab53bf1e7063ec82866f27bcb4f4c907da25ad293bba7e3", - "sha256:46101fc20c6f6568561cdd15a54018bb42980954b79aa46da8ae6f008066a30e", - "sha256:4710dc676bb4b779c4361b54eb308bc84d64a2fa3d78e5f7228921eccce5d815", - "sha256:510986f9a280cd05189b42eee2b69fecdf5bf9651d4cd315ea21d24a964a3c36", - "sha256:5535dda5739257effef56e49a1c51c71f1d37a6e5607bb25a5eee507c59580d1", - "sha256:5a7524042014642b39b1fcae85fb37556c200e64ec90824ae9ecf7b667ccfc14", - "sha256:5f55028169ef85e1fa8e4b8b1b91c0b3b0fa3297c4fb22990d46ff01d22c2d6c", - "sha256:6694d5573e7790a0e8d3d177d7a416ca5f5c150742ee703f3c18df76260de794", - "sha256:6831e1ac20ac52634da606b658b0b2712d26984999c9d93f0c6e59fe62ca741b", - "sha256:77f0d9fa5e10d03aa4528436e33423bfa3718b86c646615f04616294c935f840", - "sha256:828ad813c7cdc2e71dcf141912c685bfe4b548c0e6d9540db6418b807c345ddd", - "sha256:85a06c61598b14b015d4df233d249cd5abfa61084ef5b9f64a48e997fd829a82", - "sha256:8cb4febad0f0b26c6f62e1628f2053954ad2c555d67660f28dfb1b0496711952", - "sha256:a5c58664b23b248b16b96253880b2868fb34358911400a7ba39d7f6399935389", - "sha256:aaa0f296e503cda4bc07566f592cd7a28779d433f3a23c48082af425d6d5a78f", - "sha256:ab235d9fe64833f12d1334d29b558aacedfbca2356dfb9691f2d0d38a8a7bfb4", - "sha256:b3b0c8f660fae65eac74fbf003f3103769b90012ae7a460863010539bb7a80da", - "sha256:bab8e6d510d2ea0f1d14f12642e3f35cefa47a9b2e4c7cea1852b52bc9c49647", - "sha256:c45297bbdbc8bb79b02cf41417d63352b70bcb76f1bbb1ee7d47b3e89e42f95d", - "sha256:d19bca47c8a01b92640c614a9147b081a1974f69168ecd494687c827109e8f42", - "sha256:d64b4340a0c488a9e79b66ec9f9d77d02b99b772c8b8afd46c1294c1d39ca478", - "sha256:da969da069a82bbb5300b59161d8d7c8d423bc4ccd3b410a9b4d8932aeefc14b", - "sha256:ed02c7539705696ecb7dc9d476d861f3904a8d2b7e894bd418994920935d36bb", - "sha256:ee5b8abc35b549012e03a7b1e86c09491457dba6c94112a2482b18589cc2bdb9" - ], - "index": "pypi", - "version": "==4.5.2" - }, "cryptography": { "hashes": [ - "sha256:02915ee546b42ce513e8167140e9937fc4c81a06a82216e086ccce51f347948a", - "sha256:03cc8bc5a69ae3d44acf1a03facdb7c10a94c67907862c563e10efe72b737977", - "sha256:07f76bde6815c55195f3b3812d35769cc7c765144c0bb71ae45e02535d078591", - "sha256:13eac1c477b9af7e9a9024369468d08aead6ad78ed599d163ad046684474364b", - "sha256:179bfb585c5efc87ae0e665770e4896727b92dbc1f810c761b1ebf8363e2fec8", - "sha256:414af0ba308e74c1f8bc5b11befc86cb66b10be8959547786f64258830d2096f", - "sha256:41a1ca14f255df8c44dd22c6006441d631d1589104045ec7263cc47e9772f41a", - "sha256:54947eb98bc4eef99ddf49f45d2694ea5a3929ab3edc9806ad01967368594d82", - "sha256:5bac7a2abda07d0c3c8429210349bb54149ad8940dc7bcffedcd56519b410a3c", - "sha256:7f41af8c586bed9f59cfe8832d818b3b75c860d7025da9cd2db76875a72ff785", - "sha256:8004fae1b3cb2dbd90a011ad972e49a7e78a871b89c70cc7213cf4ebd2532bcb", - "sha256:8e0eccadc3b465e12c50a5b8fb4d39cf401b44d7bb9936c70fddb5e5aaf740d5", - "sha256:95b4741722269cfdc134fec23b7ae6503ee2aea83d0924cfee6d6ec54cd42d8e", - "sha256:a06f5aa6d7a94531dfe82eb2972e669258c452fe9cf88f76116610de4c789785", - "sha256:b0833d27c7eb536bc27323a1e8e22cb39ebac78c4ef3be0167ba40f447344808", - "sha256:b72dec675bc59a01edc96616cd48ec465b714481caa0938c8bbca5d18f17d5df", - "sha256:c800ddc23b5206ce025f23225fdde89cdc0e64016ad914d5be32d1f602ce9495", - "sha256:c980c8c313a5e014ae12e2245e89e7b30427e5a98cbb88afe478ecae85f3abaa", - "sha256:e85b410885addaeb31a867eabcefc9ef4a7e904ad45eac9e60a763a54b244626" + "sha256:05a6052c6a9f17ff78ba78f8e6eb1d777d25db3b763343a1ae89a7a8670386dd", + "sha256:0eb83a24c650a36f68e31a6d0a70f7ad9c358fa2506dc7b683398b92e354a038", + "sha256:0ff4a3d6ea86aa0c9e06e92a9f986de7ee8231f36c4da1b31c61a7e692ef3378", + "sha256:1699f3e916981df32afdd014fb3164db28cdb61c757029f502cb0a8c29b2fdb3", + "sha256:1b1f136d74f411f587b07c076149c4436a169dc19532e587460d9ced24adcc13", + "sha256:21e63dd20f5e5455e8b34179ac43d95b3fb1ffa54d071fd2ed5d67da82cfe6dc", + "sha256:2454ada8209bbde97065453a6ca488884bbb263e623d35ba183821317a58b46f", + "sha256:3cdc5f7ca057b2214ce4569e01b0f368b3de9d8ee01887557755ccd1c15d9427", + "sha256:418e7a5ec02a7056d3a4f0c0e7ea81df374205f25f4720bb0e84189aa5fd2515", + "sha256:471a097076a7c4ab85561d7fa9a1239bd2ae1f9fd0047520f13d8b340bf3210b", + "sha256:5ecaf9e7db3ca582c6de6229525d35db8a4e59dc3e8a40a331674ed90e658cbf", + "sha256:63b064a074f8dc61be81449796e2c3f4e308b6eba04a241a5c9f2d05e882c681", + "sha256:6afe324dfe6074822ccd56d80420df750e19ac30a4e56c925746c735cf22ae8b", + "sha256:70596e90398574b77929cd87e1ac6e43edd0e29ba01e1365fed9c26bde295aa5", + "sha256:70c2b04e905d3f72e2ba12c58a590817128dfca08949173faa19a42c824efa0b", + "sha256:8908f1db90be48b060888e9c96a0dee9d842765ce9594ff6a23da61086116bb6", + "sha256:af12dfc9874ac27ebe57fc28c8df0e8afa11f2a1025566476b0d50cdb8884f70", + "sha256:b4fc04326b2d259ddd59ed8ea20405d2e695486ab4c5e1e49b025c484845206e", + "sha256:da5b5dda4aa0d5e2b758cc8dfc67f8d4212e88ea9caad5f61ba132f948bab859" ], - "version": "==2.4.1" + "version": "==2.4.2" }, "dnspython": { "hashes": [ diff --git a/aimmo-game-creator/hooks/build b/aimmo-game-creator/hooks/build new file mode 100755 index 000000000..77b270dcb --- /dev/null +++ b/aimmo-game-creator/hooks/build @@ -0,0 +1,2 @@ +#!/bin/bash +docker build --target runner -t $IMAGE_NAME . diff --git a/aimmo-game-creator/setup.py b/aimmo-game-creator/setup.py index dbda8e559..fff0bf0f4 100644 --- a/aimmo-game-creator/setup.py +++ b/aimmo-game-creator/setup.py @@ -1,19 +1,11 @@ # -*- coding: utf-8 -*- from setuptools import find_packages, setup -import coverage import sys import os withcoverage = os.environ.get('WITH_COVERAGE') -if withcoverage == 'True': - print("starting code coverage engine") - coveragedatafile = ".coverage" - cov = coverage.Coverage(config_file=False) - cov.start() - - setup( name='aimmo-game-creator', packages=find_packages(), @@ -28,8 +20,3 @@ test_suite='tests', zip_safe=False, ) - -if withcoverage == 'True': - print("saving coverage stats") - cov.save() - print("exiting program") diff --git a/aimmo-game-worker/Dockerfile b/aimmo-game-worker/Dockerfile index b58c307bd..ac85aea5d 100644 --- a/aimmo-game-worker/Dockerfile +++ b/aimmo-game-worker/Dockerfile @@ -3,7 +3,6 @@ MAINTAINER code@ocado.com RUN pip install pipenv COPY ["Pipfile", "Pipfile.lock", "setup.py", "./"] -RUN pipenv install coverage RUN pipenv install --system --deploy FROM python:3.6-alpine as base @@ -13,16 +12,8 @@ COPY . . FROM base as runner ENV WORKER_MANAGER=kubernetes ENV FLASK_ENV='development' -RUN apk add --no-cache bash CMD python ./service.py 0.0.0.0 $PORT $DATA_URL FROM base as tester ENV WORKER_MANAGER=kubernetes CMD python setup.py test - -FROM base as coverage_tester -ENV WORKER_MANAGER=kubernetes -ENV WITH_COVERAGE='True' -RUN apk add bash -COPY --from=builder /usr/local/bin/coverage /usr/local/bin/coverage -CMD python setup.py test \ No newline at end of file diff --git a/aimmo-game-worker/Pipfile.lock b/aimmo-game-worker/Pipfile.lock index 4eb0d38f2..762ada83c 100644 --- a/aimmo-game-worker/Pipfile.lock +++ b/aimmo-game-worker/Pipfile.lock @@ -138,27 +138,27 @@ }, "cryptography": { "hashes": [ - "sha256:02915ee546b42ce513e8167140e9937fc4c81a06a82216e086ccce51f347948a", - "sha256:03cc8bc5a69ae3d44acf1a03facdb7c10a94c67907862c563e10efe72b737977", - "sha256:07f76bde6815c55195f3b3812d35769cc7c765144c0bb71ae45e02535d078591", - "sha256:13eac1c477b9af7e9a9024369468d08aead6ad78ed599d163ad046684474364b", - "sha256:179bfb585c5efc87ae0e665770e4896727b92dbc1f810c761b1ebf8363e2fec8", - "sha256:414af0ba308e74c1f8bc5b11befc86cb66b10be8959547786f64258830d2096f", - "sha256:41a1ca14f255df8c44dd22c6006441d631d1589104045ec7263cc47e9772f41a", - "sha256:54947eb98bc4eef99ddf49f45d2694ea5a3929ab3edc9806ad01967368594d82", - "sha256:5bac7a2abda07d0c3c8429210349bb54149ad8940dc7bcffedcd56519b410a3c", - "sha256:7f41af8c586bed9f59cfe8832d818b3b75c860d7025da9cd2db76875a72ff785", - "sha256:8004fae1b3cb2dbd90a011ad972e49a7e78a871b89c70cc7213cf4ebd2532bcb", - "sha256:8e0eccadc3b465e12c50a5b8fb4d39cf401b44d7bb9936c70fddb5e5aaf740d5", - "sha256:95b4741722269cfdc134fec23b7ae6503ee2aea83d0924cfee6d6ec54cd42d8e", - "sha256:a06f5aa6d7a94531dfe82eb2972e669258c452fe9cf88f76116610de4c789785", - "sha256:b0833d27c7eb536bc27323a1e8e22cb39ebac78c4ef3be0167ba40f447344808", - "sha256:b72dec675bc59a01edc96616cd48ec465b714481caa0938c8bbca5d18f17d5df", - "sha256:c800ddc23b5206ce025f23225fdde89cdc0e64016ad914d5be32d1f602ce9495", - "sha256:c980c8c313a5e014ae12e2245e89e7b30427e5a98cbb88afe478ecae85f3abaa", - "sha256:e85b410885addaeb31a867eabcefc9ef4a7e904ad45eac9e60a763a54b244626" + "sha256:05a6052c6a9f17ff78ba78f8e6eb1d777d25db3b763343a1ae89a7a8670386dd", + "sha256:0eb83a24c650a36f68e31a6d0a70f7ad9c358fa2506dc7b683398b92e354a038", + "sha256:0ff4a3d6ea86aa0c9e06e92a9f986de7ee8231f36c4da1b31c61a7e692ef3378", + "sha256:1699f3e916981df32afdd014fb3164db28cdb61c757029f502cb0a8c29b2fdb3", + "sha256:1b1f136d74f411f587b07c076149c4436a169dc19532e587460d9ced24adcc13", + "sha256:21e63dd20f5e5455e8b34179ac43d95b3fb1ffa54d071fd2ed5d67da82cfe6dc", + "sha256:2454ada8209bbde97065453a6ca488884bbb263e623d35ba183821317a58b46f", + "sha256:3cdc5f7ca057b2214ce4569e01b0f368b3de9d8ee01887557755ccd1c15d9427", + "sha256:418e7a5ec02a7056d3a4f0c0e7ea81df374205f25f4720bb0e84189aa5fd2515", + "sha256:471a097076a7c4ab85561d7fa9a1239bd2ae1f9fd0047520f13d8b340bf3210b", + "sha256:5ecaf9e7db3ca582c6de6229525d35db8a4e59dc3e8a40a331674ed90e658cbf", + "sha256:63b064a074f8dc61be81449796e2c3f4e308b6eba04a241a5c9f2d05e882c681", + "sha256:6afe324dfe6074822ccd56d80420df750e19ac30a4e56c925746c735cf22ae8b", + "sha256:70596e90398574b77929cd87e1ac6e43edd0e29ba01e1365fed9c26bde295aa5", + "sha256:70c2b04e905d3f72e2ba12c58a590817128dfca08949173faa19a42c824efa0b", + "sha256:8908f1db90be48b060888e9c96a0dee9d842765ce9594ff6a23da61086116bb6", + "sha256:af12dfc9874ac27ebe57fc28c8df0e8afa11f2a1025566476b0d50cdb8884f70", + "sha256:b4fc04326b2d259ddd59ed8ea20405d2e695486ab4c5e1e49b025c484845206e", + "sha256:da5b5dda4aa0d5e2b758cc8dfc67f8d4212e88ea9caad5f61ba132f948bab859" ], - "version": "==2.4.1" + "version": "==2.4.2" }, "flask": { "hashes": [ diff --git a/aimmo-game-worker/hooks/build b/aimmo-game-worker/hooks/build new file mode 100755 index 000000000..77b270dcb --- /dev/null +++ b/aimmo-game-worker/hooks/build @@ -0,0 +1,2 @@ +#!/bin/bash +docker build --target runner -t $IMAGE_NAME . diff --git a/aimmo-game-worker/setup.py b/aimmo-game-worker/setup.py index d85ff229a..7738b4352 100644 --- a/aimmo-game-worker/setup.py +++ b/aimmo-game-worker/setup.py @@ -1,18 +1,11 @@ # -*- coding: utf-8 -*- from setuptools import find_packages, setup -import coverage import sys import os withcoverage = os.environ.get('WITH_COVERAGE') -if withcoverage == 'True': - print("starting code coverage engine") - coveragedatafile = ".coverage" - cov = coverage.Coverage(config_file=False) - cov.start() - setup( name='aimmo-game-worker', packages=find_packages(), @@ -28,8 +21,3 @@ test_suite='tests', zip_safe=False, ) - -if withcoverage == 'True': - print("saving coverage stats") - cov.save() - print("exiting program") diff --git a/aimmo-game/Dockerfile b/aimmo-game/Dockerfile index 8df291525..12a490b91 100644 --- a/aimmo-game/Dockerfile +++ b/aimmo-game/Dockerfile @@ -1,27 +1,17 @@ FROM python:3.6 as builder MAINTAINER code@ocado.com - RUN pip install pipenv COPY ["Pipfile", "Pipfile.lock", "setup.py", "./"] -RUN pipenv install coverage RUN pipenv install --system --deploy FROM python:3.6-alpine as base COPY --from=builder /usr/local/lib/python3.6/site-packages /usr/local/lib/python3.6/site-packages COPY . . -FROM base as runner -RUN apk add --no-cache bash -ENV WORKER_MANAGER=kubernetes -CMD python ./service.py 0.0.0.0 - FROM base as tester ENV WORKER_MANAGER=kubernetes CMD python setup.py test -FROM base as coverage_tester +FROM base as runner ENV WORKER_MANAGER=kubernetes -ENV WITH_COVERAGE='True' -RUN apk add bash -COPY --from=builder /usr/local/bin/coverage /usr/local/bin/coverage -CMD python setup.py test +CMD python ./service.py 0.0.0.0 5000 diff --git a/aimmo-game/Pipfile b/aimmo-game/Pipfile index 08ef209b9..6a4bfb80c 100644 --- a/aimmo-game/Pipfile +++ b/aimmo-game/Pipfile @@ -4,13 +4,12 @@ verify_ssl = true name = "pypi" [packages] -aimmo-game = {path = ".", editable = true} +aimmo-game = {editable = true, path = "."} docker = "*" kubernetes = "*" prometheus-client = "*" aiohttp = "*" aiohttp-cors = "*" -coverage = "*" [requires] python_version = "3.6.7" diff --git a/aimmo-game/Pipfile.lock b/aimmo-game/Pipfile.lock index b563235c2..6ddfdf0cb 100644 --- a/aimmo-game/Pipfile.lock +++ b/aimmo-game/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "360ec685cdd165953b512dfb38da651d3dae70c6c907966cd6eb186d0a4e69e5" + "sha256": "319154631fa8e0db89b50fa53c68ac0b76c54eac54551381f08965a902bd75ed" }, "pipfile-spec": 6, "requires": { @@ -149,66 +149,29 @@ ], "version": "==7.0" }, - "coverage": { - "hashes": [ - "sha256:09e47c529ff77bf042ecfe858fb55c3e3eb97aac2c87f0349ab5a7efd6b3939f", - "sha256:0a1f9b0eb3aa15c990c328535655847b3420231af299386cfe5efc98f9c250fe", - "sha256:0cc941b37b8c2ececfed341444a456912e740ecf515d560de58b9a76562d966d", - "sha256:10e8af18d1315de936d67775d3a814cc81d0747a1a0312d84e27ae5610e313b0", - "sha256:1b4276550b86caa60606bd3572b52769860a81a70754a54acc8ba789ce74d607", - "sha256:1e8a2627c48266c7b813975335cfdea58c706fe36f607c97d9392e61502dc79d", - "sha256:2b224052bfd801beb7478b03e8a66f3f25ea56ea488922e98903914ac9ac930b", - "sha256:447c450a093766744ab53bf1e7063ec82866f27bcb4f4c907da25ad293bba7e3", - "sha256:46101fc20c6f6568561cdd15a54018bb42980954b79aa46da8ae6f008066a30e", - "sha256:4710dc676bb4b779c4361b54eb308bc84d64a2fa3d78e5f7228921eccce5d815", - "sha256:510986f9a280cd05189b42eee2b69fecdf5bf9651d4cd315ea21d24a964a3c36", - "sha256:5535dda5739257effef56e49a1c51c71f1d37a6e5607bb25a5eee507c59580d1", - "sha256:5a7524042014642b39b1fcae85fb37556c200e64ec90824ae9ecf7b667ccfc14", - "sha256:5f55028169ef85e1fa8e4b8b1b91c0b3b0fa3297c4fb22990d46ff01d22c2d6c", - "sha256:6694d5573e7790a0e8d3d177d7a416ca5f5c150742ee703f3c18df76260de794", - "sha256:6831e1ac20ac52634da606b658b0b2712d26984999c9d93f0c6e59fe62ca741b", - "sha256:77f0d9fa5e10d03aa4528436e33423bfa3718b86c646615f04616294c935f840", - "sha256:828ad813c7cdc2e71dcf141912c685bfe4b548c0e6d9540db6418b807c345ddd", - "sha256:85a06c61598b14b015d4df233d249cd5abfa61084ef5b9f64a48e997fd829a82", - "sha256:8cb4febad0f0b26c6f62e1628f2053954ad2c555d67660f28dfb1b0496711952", - "sha256:a5c58664b23b248b16b96253880b2868fb34358911400a7ba39d7f6399935389", - "sha256:aaa0f296e503cda4bc07566f592cd7a28779d433f3a23c48082af425d6d5a78f", - "sha256:ab235d9fe64833f12d1334d29b558aacedfbca2356dfb9691f2d0d38a8a7bfb4", - "sha256:b3b0c8f660fae65eac74fbf003f3103769b90012ae7a460863010539bb7a80da", - "sha256:bab8e6d510d2ea0f1d14f12642e3f35cefa47a9b2e4c7cea1852b52bc9c49647", - "sha256:c45297bbdbc8bb79b02cf41417d63352b70bcb76f1bbb1ee7d47b3e89e42f95d", - "sha256:d19bca47c8a01b92640c614a9147b081a1974f69168ecd494687c827109e8f42", - "sha256:d64b4340a0c488a9e79b66ec9f9d77d02b99b772c8b8afd46c1294c1d39ca478", - "sha256:da969da069a82bbb5300b59161d8d7c8d423bc4ccd3b410a9b4d8932aeefc14b", - "sha256:ed02c7539705696ecb7dc9d476d861f3904a8d2b7e894bd418994920935d36bb", - "sha256:ee5b8abc35b549012e03a7b1e86c09491457dba6c94112a2482b18589cc2bdb9" - ], - "index": "pypi", - "version": "==4.5.2" - }, "cryptography": { "hashes": [ - "sha256:02915ee546b42ce513e8167140e9937fc4c81a06a82216e086ccce51f347948a", - "sha256:03cc8bc5a69ae3d44acf1a03facdb7c10a94c67907862c563e10efe72b737977", - "sha256:07f76bde6815c55195f3b3812d35769cc7c765144c0bb71ae45e02535d078591", - "sha256:13eac1c477b9af7e9a9024369468d08aead6ad78ed599d163ad046684474364b", - "sha256:179bfb585c5efc87ae0e665770e4896727b92dbc1f810c761b1ebf8363e2fec8", - "sha256:414af0ba308e74c1f8bc5b11befc86cb66b10be8959547786f64258830d2096f", - "sha256:41a1ca14f255df8c44dd22c6006441d631d1589104045ec7263cc47e9772f41a", - "sha256:54947eb98bc4eef99ddf49f45d2694ea5a3929ab3edc9806ad01967368594d82", - "sha256:5bac7a2abda07d0c3c8429210349bb54149ad8940dc7bcffedcd56519b410a3c", - "sha256:7f41af8c586bed9f59cfe8832d818b3b75c860d7025da9cd2db76875a72ff785", - "sha256:8004fae1b3cb2dbd90a011ad972e49a7e78a871b89c70cc7213cf4ebd2532bcb", - "sha256:8e0eccadc3b465e12c50a5b8fb4d39cf401b44d7bb9936c70fddb5e5aaf740d5", - "sha256:95b4741722269cfdc134fec23b7ae6503ee2aea83d0924cfee6d6ec54cd42d8e", - "sha256:a06f5aa6d7a94531dfe82eb2972e669258c452fe9cf88f76116610de4c789785", - "sha256:b0833d27c7eb536bc27323a1e8e22cb39ebac78c4ef3be0167ba40f447344808", - "sha256:b72dec675bc59a01edc96616cd48ec465b714481caa0938c8bbca5d18f17d5df", - "sha256:c800ddc23b5206ce025f23225fdde89cdc0e64016ad914d5be32d1f602ce9495", - "sha256:c980c8c313a5e014ae12e2245e89e7b30427e5a98cbb88afe478ecae85f3abaa", - "sha256:e85b410885addaeb31a867eabcefc9ef4a7e904ad45eac9e60a763a54b244626" - ], - "version": "==2.4.1" + "sha256:05a6052c6a9f17ff78ba78f8e6eb1d777d25db3b763343a1ae89a7a8670386dd", + "sha256:0eb83a24c650a36f68e31a6d0a70f7ad9c358fa2506dc7b683398b92e354a038", + "sha256:0ff4a3d6ea86aa0c9e06e92a9f986de7ee8231f36c4da1b31c61a7e692ef3378", + "sha256:1699f3e916981df32afdd014fb3164db28cdb61c757029f502cb0a8c29b2fdb3", + "sha256:1b1f136d74f411f587b07c076149c4436a169dc19532e587460d9ced24adcc13", + "sha256:21e63dd20f5e5455e8b34179ac43d95b3fb1ffa54d071fd2ed5d67da82cfe6dc", + "sha256:2454ada8209bbde97065453a6ca488884bbb263e623d35ba183821317a58b46f", + "sha256:3cdc5f7ca057b2214ce4569e01b0f368b3de9d8ee01887557755ccd1c15d9427", + "sha256:418e7a5ec02a7056d3a4f0c0e7ea81df374205f25f4720bb0e84189aa5fd2515", + "sha256:471a097076a7c4ab85561d7fa9a1239bd2ae1f9fd0047520f13d8b340bf3210b", + "sha256:5ecaf9e7db3ca582c6de6229525d35db8a4e59dc3e8a40a331674ed90e658cbf", + "sha256:63b064a074f8dc61be81449796e2c3f4e308b6eba04a241a5c9f2d05e882c681", + "sha256:6afe324dfe6074822ccd56d80420df750e19ac30a4e56c925746c735cf22ae8b", + "sha256:70596e90398574b77929cd87e1ac6e43edd0e29ba01e1365fed9c26bde295aa5", + "sha256:70c2b04e905d3f72e2ba12c58a590817128dfca08949173faa19a42c824efa0b", + "sha256:8908f1db90be48b060888e9c96a0dee9d842765ce9594ff6a23da61086116bb6", + "sha256:af12dfc9874ac27ebe57fc28c8df0e8afa11f2a1025566476b0d50cdb8884f70", + "sha256:b4fc04326b2d259ddd59ed8ea20405d2e695486ab4c5e1e49b025c484845206e", + "sha256:da5b5dda4aa0d5e2b758cc8dfc67f8d4212e88ea9caad5f61ba132f948bab859" + ], + "version": "==2.4.2" }, "dnspython": { "hashes": [ @@ -362,37 +325,37 @@ }, "multidict": { "hashes": [ - "sha256:05eeab69bf2b0664644c62bd92fabb045163e5b8d4376a31dfb52ce0210ced7b", - "sha256:0c85880efa7cadb18e3b5eef0aa075dc9c0a3064cbbaef2e20be264b9cf47a64", - "sha256:136f5a4a6a4adeacc4dc820b8b22f0a378fb74f326e259c54d1817639d1d40a0", - "sha256:14906ad3347c7d03e9101749b16611cf2028547716d0840838d3c5e2b3b0f2d3", - "sha256:1ade4a3b71b1bf9e90c5f3d034a87fe4949c087ef1f6cd727fdd766fe8bbd121", - "sha256:22939a00a511a59f9ecc0158b8db728afef57975ce3782b3a265a319d05b9b12", - "sha256:2b86b02d872bc5ba5b3a4530f6a7ba0b541458ab4f7c1429a12ac326231203f7", - "sha256:3c11e92c3dfc321014e22fb442bc9eb70e01af30d6ce442026b0c35723448c66", - "sha256:4ba3bd26f282b201fdbce351f1c5d17ceb224cbedb73d6e96e6ce391b354aacc", - "sha256:4c6e78d042e93751f60672989efbd6a6bc54213ed7ff695fff82784bbb9ea035", - "sha256:4d80d1901b89cc935a6cf5b9fd89df66565272722fe2e5473168927a9937e0ca", - "sha256:4fcf71d33178a00cc34a57b29f5dab1734b9ce0f1c97fb34666deefac6f92037", - "sha256:52f7670b41d4b4d97866ebc38121de8bcb9813128b7c4942b07794d08193c0ab", - "sha256:5368e2b7649a26b7253c6c9e53241248aab9da49099442f5be238fde436f18c9", - "sha256:5bb65fbb48999044938f0c0508e929b14a9b8bf4939d8263e9ea6691f7b54663", - "sha256:60672bb5577472800fcca1ac9dae232d1461db9f20f055184be8ce54b0052572", - "sha256:669e9be6d148fc0283f53e17dd140cde4dc7c87edac8319147edd5aa2a830771", - "sha256:6a0b7a804e8d1716aa2c72e73210b48be83d25ba9ec5cf52cf91122285707bb1", - "sha256:79034ea3da3cf2a815e3e52afdc1f6c1894468c98bdce5d2546fa2342585497f", - "sha256:79247feeef6abcc11137ad17922e865052f23447152059402fc320f99ff544bb", - "sha256:81671c2049e6bf42c7fd11a060f8bc58f58b7b3d6f3f951fc0b15e376a6a5a98", - "sha256:82ac4a5cb56cc9280d4ae52c2d2ebcd6e0668dd0f9ef17f0a9d7c82bd61e24fa", - "sha256:9436267dbbaa49dad18fbbb54f85386b0f5818d055e7b8e01d219661b6745279", - "sha256:94e4140bb1343115a1afd6d84ebf8fca5fb7bfb50e1c2cbd6f2fb5d3117ef102", - "sha256:a2cab366eae8a0ffe0813fd8e335cf0d6b9bb6c5227315f53bb457519b811537", - "sha256:a596019c3eafb1b0ae07db9f55a08578b43c79adb1fe1ab1fd818430ae59ee6f", - "sha256:e8848ae3cd6a784c29fae5055028bee9bffcc704d8bcad09bd46b42b44a833e2", - "sha256:e8a048bfd7d5a280f27527d11449a509ddedf08b58a09a24314828631c099306", - "sha256:f6dd28a0ac60e2426a6918f36f1b4e2620fc785a0de7654cd206ba842eee57fd" - ], - "version": "==4.4.2" + "sha256:013eb6591ab95173fd3deb7667d80951abac80100335b3e97b5fa778c1bb4b91", + "sha256:0bffbbbb48db35f57dfb4733e943ac8178efb31aab5601cb7b303ee228ce96af", + "sha256:1a34aab1dfba492407c757532f665ba3282ec4a40b0d2f678bda828ef422ebb7", + "sha256:1b4b46a33f459a2951b0fd26c2d80639810631eb99b3d846d298b02d28a3e31d", + "sha256:1d616d80c37a388891bf760d64bc50cac7c61dbb7d7013f2373aa4b44936e9f0", + "sha256:225aefa7befbe05bd0116ef87e8cd76cbf4ac39457a66faf7fb5f3c2d7bea19a", + "sha256:2c9b28985ef7c830d5c7ea344d068bcdee22f8b6c251369dea98c3a814713d44", + "sha256:39e0600f8dd72acb011d09960da560ba3451b1eca8de5557c15705afc9d35f0e", + "sha256:3c642c40ea1ca074397698446893a45cd6059d5d071fc3ba3915c430c125320f", + "sha256:42357c90b488fac38852bcd7b31dcd36b1e2325413960304c28b8d98e6ff5fd4", + "sha256:6ac668f27dbdf8a69c31252f501e128a69a60b43a44e43d712fb58ce3e5dfcca", + "sha256:713683da2e3f1dd81a920c995df5dda51f1fff2b3995f5864c3ee782fcdcb96c", + "sha256:73b6e7853b6d3bc0eac795044e700467631dff37a5a33d3230122b03076ac2f9", + "sha256:77534c1b9f4a5d0962392cad3f668d1a04036b807618e3357eb2c50d8b05f7f7", + "sha256:77b579ef57e27457064bb6bb4c8e5ede866af071af60fe3576226136048c6dfa", + "sha256:82cf28f18c935d66c15a6f82fda766a4138d21e78532a1946b8ec603019ba0b8", + "sha256:937e8f12f9edc0d2e351c09fc3e7335a65eefb75406339d488ee46ef241f75d8", + "sha256:985dbf59e92f475573a04598f9a00f92b4fdb64fc41f1df2ea6f33b689319537", + "sha256:9c4fab7599ba8c0dbf829272c48c519625c2b7f5630b49925802f1af3a77f1f4", + "sha256:9e8772be8455b49a85ad6dbf6ce433da7856ba481d6db36f53507ae540823b15", + "sha256:a06d6d88ce3be4b54deabd078810e3c077a8b2e20f0ce541c979b5dd49337031", + "sha256:a1da0cdc3bc45315d313af976dab900888dbb477d812997ee0e6e4ea43d325e5", + "sha256:a6652466a4800e9fde04bf0252e914fff5f05e2a40ee1453db898149624dfe04", + "sha256:a7f23523ea6a01f77e0c6da8aae37ab7943e35630a8d2eda7e49502f36b51b46", + "sha256:a87429da49f4c9fb37a6a171fa38b59a99efdeabffb34b4255a7a849ffd74a20", + "sha256:c26bb81d0d19619367a96593a097baec2d5a7b3a0cfd1e3a9470277505a465c2", + "sha256:d4f4545edb4987f00fde44241cef436bf6471aaac7d21c6bbd497cca6049f613", + "sha256:daabc2766a2b76b3bec2086954c48d5f215f75a335eaee1e89c8357922a3c4d5", + "sha256:f08c1dcac70b558183b3b755b92f1135a76fd1caa04009b89ddea57a815599aa" + ], + "version": "==4.5.1" }, "oauthlib": { "hashes": [ @@ -444,10 +407,10 @@ }, "python-engineio": { "hashes": [ - "sha256:306a91fda59e3678b34755f475ff6b5b3dc0deb0272a23e213f2f259b5602c4c", - "sha256:871f4d022eb9171e380281266ba2aef0759b264ba862350bc94e7a597a98a443" + "sha256:a437bda348b8325a1a09bc2e04c5fff8bb8cbe674b5ba41adbb2a8eeacc98457", + "sha256:bb8b5888adb852614b4b1861586ee7d89145cbd2ebba03ed7043e64c029bbb3b" ], - "version": "==2.3.2" + "version": "==3.0.0" }, "python-socketio": { "hashes": [ diff --git a/aimmo-game/hooks/build b/aimmo-game/hooks/build new file mode 100755 index 000000000..77b270dcb --- /dev/null +++ b/aimmo-game/hooks/build @@ -0,0 +1,2 @@ +#!/bin/bash +docker build --target runner -t $IMAGE_NAME . diff --git a/aimmo-game/setup.py b/aimmo-game/setup.py index 7b0e89209..c6ccd3ba3 100644 --- a/aimmo-game/setup.py +++ b/aimmo-game/setup.py @@ -1,19 +1,11 @@ # -*- coding: utf-8 -*- from setuptools import find_packages, setup -import coverage import sys import os withcoverage = os.environ.get('WITH_COVERAGE') -if withcoverage == 'True': - print("starting code coverage engine") - coveragedatafile = ".coverage" - cov = coverage.Coverage(config_file=False) - cov.start() - - setup( name='aimmo-game', packages=find_packages(), @@ -41,8 +33,3 @@ test_suite='tests', zip_safe=False, ) - -if withcoverage == 'True': - print("saving coverage stats") - cov.save() - print("exiting program") diff --git a/aimmo-game/simulation/game_runner.py b/aimmo-game/simulation/game_runner.py index 3ea6d5d39..c6e6ca2f1 100644 --- a/aimmo-game/simulation/game_runner.py +++ b/aimmo-game/simulation/game_runner.py @@ -48,7 +48,6 @@ def update_workers(self): game_metadata = self.communicator.get_game_metadata()['main'] users_to_add = self.get_users_to_add(game_metadata) - LOGGER.info(users_to_add) users_to_delete = self.get_users_to_delete(game_metadata) self.worker_manager.add_workers(users_to_add) @@ -61,7 +60,7 @@ def update_workers(self): self.worker_manager.fetch_all_worker_data(self.game_state.get_serialised_game_states_for_workers()) async def update_simulation(self, player_id_to_serialised_actions): - self.simulation_runner.run_single_turn(player_id_to_serialised_actions) + await self.simulation_runner.run_single_turn(player_id_to_serialised_actions) await self._end_turn_callback() async def update(self): diff --git a/aimmo-game/simulation/simulation_runner.py b/aimmo-game/simulation/simulation_runner.py index 008ee085d..39151ecb8 100644 --- a/aimmo-game/simulation/simulation_runner.py +++ b/aimmo-game/simulation/simulation_runner.py @@ -1,8 +1,8 @@ import logging +import asyncio from abc import ABCMeta, abstractmethod -from concurrent import futures -from concurrent.futures import ALL_COMPLETED -from simulation.action import PRIORITIES +from concurrent.futures import ALL_COMPLETED, ThreadPoolExecutor +from simulation.action import PRIORITIES, WaitAction from threading import Thread LOGGER = logging.getLogger(__name__) @@ -22,10 +22,10 @@ def __init__(self, game_state, communicator): self.communicator = communicator @abstractmethod - def run_turn(self, player_id_to_serialised_actions): + async def run_turn(self, player_id_to_serialised_actions): pass - def _run_turn_for_avatar(self, avatar, serialised_action): + async def _run_turn_for_avatar(self, avatar, serialised_action): """ Send an avatar its view of the game state and register its chosen action & logs. @@ -50,44 +50,39 @@ def _update_environment(self, game_state): def _mark_complete(self): self.communicator.mark_game_complete(data=self.game_state.serialise()) - def run_single_turn(self, player_id_to_serialised_actions): - self.run_turn(player_id_to_serialised_actions) + async def run_single_turn(self, player_id_to_serialised_actions): + await self.run_turn(player_id_to_serialised_actions) self.game_state.update_environment() class SequentialSimulationRunner(SimulationRunner): - def run_turn(self, player_id_to_serialised_actions): + async def run_turn(self, player_id_to_serialised_actions): """ Get and apply each avatar's action in turn. """ avatars = self.game_state.avatar_manager.active_avatars for avatar in avatars: - self._run_turn_for_avatar(avatar, player_id_to_serialised_actions[avatar.player_id]) + await self._run_turn_for_avatar(avatar, player_id_to_serialised_actions[avatar.player_id]) location_to_clear = avatar.action.target_location avatar.action.process(self.game_state.world_map) self.game_state.world_map.clear_cell_actions(location_to_clear) class ConcurrentSimulationRunner(SimulationRunner): - def _parallel_map(self, func, iterable_args): - with futures.ThreadPoolExecutor() as executor: - results = executor.map(func, iterable_args) - futures.wait(results, timeout=2, return_when=ALL_COMPLETED) - return [results] + async def async_map(self, func, iterable_args): + futures = [func(*arg) for arg in iterable_args] + await asyncio.gather(*futures) - def run_turn(self, player_id_to_serialised_actions): + async def run_turn(self, player_id_to_serialised_actions): """ Concurrently get the intended actions from all avatars and register them on the world map. Then apply actions in order of priority. """ avatars = self.game_state.avatar_manager.active_avatars - threads = [Thread(target=self._run_turn_for_avatar, - args=(avatar, player_id_to_serialised_actions[avatar.player_id])) for avatar in avatars] - - [thread.start() for thread in threads] - [thread.join() for thread in threads] + args = [(avatar, player_id_to_serialised_actions[avatar.player_id]) for avatar in avatars] + await self.async_map(self._run_turn_for_avatar, args) # Waits applied first, then attacks, then moves. avatars.sort(key=lambda a: PRIORITIES[type(a.action)]) diff --git a/aimmo-game/simulation/worker_managers/kubernetes_worker_manager.py b/aimmo-game/simulation/worker_managers/kubernetes_worker_manager.py index 0c0a846aa..943326a92 100644 --- a/aimmo-game/simulation/worker_managers/kubernetes_worker_manager.py +++ b/aimmo-game/simulation/worker_managers/kubernetes_worker_manager.py @@ -46,7 +46,7 @@ def _make_container(self, player_id): env=[client.V1EnvVar( name='DATA_URL', value='%s/player/%d' % (self.game_url, player_id)), - kubernetes.client.V1EnvVar( + client.V1EnvVar( name='PORT', value='5000')], name='aimmo-game-worker', diff --git a/aimmo-game/simulation/worker_managers/worker_manager.py b/aimmo-game/simulation/worker_managers/worker_manager.py index f1d61480e..735e2e133 100644 --- a/aimmo-game/simulation/worker_managers/worker_manager.py +++ b/aimmo-game/simulation/worker_managers/worker_manager.py @@ -73,7 +73,7 @@ def update_code(self, player): def add_new_worker(self, player_id): worker_url_base = self.create_worker(player_id) - self.player_id_to_worker[player_id] = Worker('{}/turn/'.format(worker_url_base)) + self.player_id_to_worker[player_id] = Worker(f'{worker_url_base}/turn/') def _parallel_map(self, func, iterable_args): with futures.ThreadPoolExecutor() as executor: diff --git a/aimmo-game/tests/functional/test_damage_pickups_and_effects.py b/aimmo-game/tests/functional/test_damage_pickups_and_effects.py index f524e582b..d609807ac 100644 --- a/aimmo-game/tests/functional/test_damage_pickups_and_effects.py +++ b/aimmo-game/tests/functional/test_damage_pickups_and_effects.py @@ -2,6 +2,7 @@ from hypothesis import given, assume from hypothesis import strategies as st import math +import asyncio from .mock_world import MockWorld from simulation.location import Location @@ -19,12 +20,13 @@ def setUp(self): _avatar_spawn_cell = self.game.game_state.world_map.get_cell(Location(0, 0)) self.initial_attack_strength = _avatar_spawn_cell.avatar.attack_strength self.cell = self.game.game_state.world_map.get_cell(Location(1, 0)) + self.loop = asyncio.get_event_loop() def test_damage_boost_pickup_can_be_picked_up_default(self): pickup_created = DamageBoostPickup(self.cell) self.cell.pickup = pickup_created - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) self.assertEqual(len(self.game.avatar_manager.get_avatar(1).effects), 1) @@ -37,7 +39,7 @@ def test_damage_boost_pickup_can_be_picked_up_custom_integer(self, boost_value): pickup_created = DamageBoostPickup(self.cell, boost_value) self.cell.pickup = pickup_created - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) self.assertEqual(len(self.game.avatar_manager.get_avatar(1).effects), 1) @@ -51,7 +53,7 @@ def test_damage_boost_pickup_can_be_picked_up_custom_floats(self, boost_value): pickup_created = DamageBoostPickup(self.cell, boost_value) self.cell.pickup = pickup_created - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) self.assertEqual(len(self.game.avatar_manager.get_avatar(1).effects), 1) @@ -65,7 +67,7 @@ def test_damage_boost_increases_attack_strength_with_default_integer(self): pickup_created = DamageBoostPickup(self.cell) self.cell.pickup = pickup_created - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertTrue(self.cell.avatar.attack_strength, self.initial_attack_strength + DAMAGE_BOOST_DEFAULT) @@ -78,6 +80,6 @@ def test_damage_boost_increases_attack_strength_with_custom_integers(self, boost pickup_created = DamageBoostPickup(self.cell, boost_value) self.cell.pickup = pickup_created - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertTrue(self.cell.avatar.attack_strength, self.initial_attack_strength + boost_value) diff --git a/aimmo-game/tests/functional/test_effect_expiry.py b/aimmo-game/tests/functional/test_effect_expiry.py index 37f034453..1145625f7 100644 --- a/aimmo-game/tests/functional/test_effect_expiry.py +++ b/aimmo-game/tests/functional/test_effect_expiry.py @@ -1,4 +1,5 @@ from unittest import TestCase +import asyncio from .mock_world import MockWorld @@ -39,10 +40,11 @@ def test_single_damage_boost_pickup_expiry(self): self.assertEqual(self.avatar.attack_strength, 1) # Avatar moves EAST to (1,0) where pickup is located, then repeats it 5 times. + loop = asyncio.get_event_loop() for i in range(6): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertTrue(isinstance(list(self.avatar.effects)[0], pickup_created.EFFECT)) self.assertEqual(list(self.avatar.effects)[0]._time_remaining, 5) @@ -50,9 +52,9 @@ def test_single_damage_boost_pickup_expiry(self): # Run 5 more turns and expect the effect to expire. for i in range(5): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertEqual(len(self.avatar.effects), 0) self.assertEqual(self.avatar.attack_strength, 1) @@ -67,8 +69,9 @@ def test_single_invulnerability_pickup_pickup_expiry(self): self.assertEqual(self.avatar.resistance, 0) # Avatar moves EAST to (1,0) where pickup is located, then repeats it 5 times. + loop = asyncio.get_event_loop() for i in range(6): - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertTrue(isinstance(list(self.avatar.effects)[0], pickup_created.EFFECT)) self.assertEqual(list(self.avatar.effects)[0]._time_remaining, 5) @@ -76,7 +79,7 @@ def test_single_invulnerability_pickup_pickup_expiry(self): # Run 5 more turns and expect the effect to expire. for i in range(5): - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(len(self.avatar.effects), 0) self.assertEqual(self.avatar.resistance, 0) @@ -97,9 +100,10 @@ def test_multiple_damage_boost_pickup_expiry(self): self.assertEqual(self.avatar.attack_strength, 1) # Avatar moves EAST to (1,0) where pickup one is located. - self.game.simulation_runner.run_single_turn( + loop = asyncio.get_event_loop() + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertTrue(isinstance(list(self.avatar.effects)[0], pickup_created_one.EFFECT)) self.assertEqual(len(self.avatar.effects), 1) @@ -108,9 +112,9 @@ def test_multiple_damage_boost_pickup_expiry(self): # Move twice to the second pickup. for i in range(2): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertTrue(isinstance(list(self.avatar.effects)[1], pickup_created_two.EFFECT)) self.assertEqual(len(self.avatar.effects), 2) @@ -118,9 +122,9 @@ def test_multiple_damage_boost_pickup_expiry(self): # Eight turns later, we expect the first effect to expire. for i in range(8): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertEqual(len(self.avatar.effects), 1) self.assertEqual(list(self.avatar.effects)[0]._time_remaining, 2) @@ -128,9 +132,9 @@ def test_multiple_damage_boost_pickup_expiry(self): # Two turns later, the second pickup expires too. for i in range(2): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertEqual(len(self.avatar.effects), 0) self.assertEqual(self.avatar.attack_strength, 1) @@ -151,9 +155,10 @@ def test_multiple_invulnerability_boost_pickup_expiry(self): self.assertEqual(self.avatar.resistance, 0) # Avatar moves EAST to (1,0) where pickup one is located. - self.game.simulation_runner.run_single_turn( + loop = asyncio.get_event_loop() + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertTrue(isinstance(list(self.avatar.effects)[0], pickup_created_one.EFFECT)) self.assertEqual(len(self.avatar.effects), 1) @@ -162,9 +167,9 @@ def test_multiple_invulnerability_boost_pickup_expiry(self): # Move twice to the second pickup. for i in range(2): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertTrue(isinstance(list(self.avatar.effects)[1], pickup_created_two.EFFECT)) self.assertEqual(len(self.avatar.effects), 2) @@ -172,9 +177,9 @@ def test_multiple_invulnerability_boost_pickup_expiry(self): # Eight turns later, we expect the first effect to expire. for i in range(8): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertEqual(len(self.avatar.effects), 1) self.assertEqual(list(self.avatar.effects)[0]._time_remaining, 2) @@ -182,9 +187,9 @@ def test_multiple_invulnerability_boost_pickup_expiry(self): # Two turns later, the second pickup expires too. for i in range(2): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) self.assertEqual(len(self.avatar.effects), 0) self.assertEqual(self.avatar.resistance, 0) diff --git a/aimmo-game/tests/functional/test_health_pickups_and_effects.py b/aimmo-game/tests/functional/test_health_pickups_and_effects.py index fdf0e7ef4..aef269325 100644 --- a/aimmo-game/tests/functional/test_health_pickups_and_effects.py +++ b/aimmo-game/tests/functional/test_health_pickups_and_effects.py @@ -1,5 +1,6 @@ import random from unittest import TestCase +import asyncio from hypothesis import given import hypothesis.strategies as st @@ -22,6 +23,7 @@ def setUp(self): self.game.game_state.add_avatar(1, Location(0, 0)) self.cell = self.game.game_state.world_map.get_cell(Location(1, 0)) self.initial_health = self.game.avatar_manager.get_avatar(1).health + self.loop = asyncio.get_event_loop() def test_health_pickups_and_effects_apply_default(self): """ @@ -29,7 +31,7 @@ def test_health_pickups_and_effects_apply_default(self): """ self.cell.pickup = HealthPickup(self.cell) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) self.assertEqual(self.cell.avatar.health, self.initial_health + @@ -43,7 +45,7 @@ def test_health_pickups_and_effects_apply_custom_integers(self, restore_value): self.setUp() self.cell.pickup = HealthPickup(self.cell, restore_value) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) if self.initial_health + restore_value > HEALTH_RESTORE_MAX: @@ -61,7 +63,7 @@ def test_health_pickups_and_effects_apply_custom_floats(self, restore_value): self.setUp() self.cell.pickup = HealthPickup(self.cell, restore_value) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) if self.initial_health + restore_value > HEALTH_RESTORE_MAX: @@ -81,7 +83,7 @@ def test_health_effect_is_capped_at_HEALTH_RESTORE_MAX(self, restore_value): self.setUp() self.cell.pickup = HealthPickup(self.cell, restore_value) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + self.loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) self.assertEqual(self.cell.avatar.health, AVATAR_HEALTH_MAX) diff --git a/aimmo-game/tests/functional/test_invulnerability_pickups_and_effects.py b/aimmo-game/tests/functional/test_invulnerability_pickups_and_effects.py index e6b990412..f85a8c982 100644 --- a/aimmo-game/tests/functional/test_invulnerability_pickups_and_effects.py +++ b/aimmo-game/tests/functional/test_invulnerability_pickups_and_effects.py @@ -1,4 +1,5 @@ from unittest import TestCase +import asyncio from .mock_world import MockWorld @@ -25,7 +26,8 @@ def test_invulnerability_pickups_increase_resistance_of_avatar(self): self.cell.pickup = InvulnerabilityPickup(self.cell) self.assertEqual(self.game.avatar_manager.get_avatar(1).resistance, 0) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop = asyncio.get_event_loop() + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) self.assertEqual(self.cell.avatar.resistance, 1000) @@ -36,14 +38,15 @@ def test_invulnerability_pickups_can_increase_resistance_to_2000(self): Checks if the pickup can be applied twice. First moved from ORIGIN to 1,0 -> then picks up the pickup, and moves to 2,0 to do the same. """ + loop = asyncio.get_event_loop() self.cell.pickup = InvulnerabilityPickup(self.cell) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) self.assertEqual(self.cell.avatar.resistance, 1000) self.cell = self.game.game_state.world_map.get_cell(Location(2, 0)) self.cell.pickup = InvulnerabilityPickup(self.cell) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.cell.avatar.resistance, 2000) self.assertEqual(self.cell.avatar, self.game.avatar_manager.get_avatar(1)) diff --git a/aimmo-game/tests/functional/test_movements_in_map.py b/aimmo-game/tests/functional/test_movements_in_map.py index e1d9ad3d7..47e6bfa8f 100644 --- a/aimmo-game/tests/functional/test_movements_in_map.py +++ b/aimmo-game/tests/functional/test_movements_in_map.py @@ -1,4 +1,5 @@ from unittest import TestCase +import asyncio from .mock_world import MockWorld from simulation.location import Location @@ -36,8 +37,9 @@ def set_up_and_make_movements_in_a_single_direction(self, dummy_list, self.set_up_environment(dummy_list, spawn) self.assertEqual(self.avatar.location, spawn) + loop = asyncio.get_event_loop() for i in range(number_of_movements): - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) def test_movement_five_times_in_all_directions(self): """ @@ -105,8 +107,9 @@ def test_avatar_cannot_move_into_obstacle(self): obstacle_cell.habitable = False self.assertTrue(self.avatar.location, Location(0, 0)) + loop = asyncio.get_event_loop() for i in range(2): - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertTrue(self.avatar.location, Location(1, 0)) @@ -121,11 +124,11 @@ def test_avatars_cannot_go_into_each_other(self): self.assertEqual(self.avatar.location, Location(0, 0)) self.assertEqual(avatar_two.location, Location(3, 0)) - + loop = asyncio.get_event_loop() for i in range(2): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) # Avatar 1 & Avatar 2 only managed to move once. self.assertEqual(self.avatar.location, Location(1, 0)) @@ -140,9 +143,9 @@ def test_avatars_cannot_go_into_each_other(self): self.assertEqual(avatar_two.location, Location(4, 0)) for i in range(2): - self.game.simulation_runner.run_single_turn( + loop.run_until_complete(self.game.simulation_runner.run_single_turn( self.game.avatar_manager.get_player_id_to_serialised_action() - ) + )) # Avatar 1 & Avatar 2 managed to only move only once. self.assertEqual(self.avatar.location, Location(1, 0)) @@ -155,7 +158,7 @@ def test_avatars_cannot_go_into_each_other(self): self.assertEqual(self.avatar.location, Location(0, 0)) self.assertEqual(avatar_two.location, Location(1, 0)) - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.avatar.location, Location(0, 0)) self.assertEqual(avatar_two.location, Location(1, 0)) @@ -167,7 +170,8 @@ def test_wait_action_on_a_single_avatar(self): self.set_up_environment(dummy_list=[WaitDummy]) self.assertEqual(self.avatar.location, Location(0, 0)) + loop = asyncio.get_event_loop() for i in range(5): - self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action()) + loop.run_until_complete(self.game.simulation_runner.run_single_turn(self.game.avatar_manager.get_player_id_to_serialised_action())) self.assertEqual(self.avatar.location, Location(0, 0)) diff --git a/aimmo-game/tests/test_simulation/test_simulation_runner.py b/aimmo-game/tests/test_simulation/test_simulation_runner.py index b2ef223e8..4d7b01f28 100644 --- a/aimmo-game/tests/test_simulation/test_simulation_runner.py +++ b/aimmo-game/tests/test_simulation/test_simulation_runner.py @@ -1,6 +1,7 @@ from __future__ import absolute_import import unittest +import asyncio from simulation.avatar.avatar_appearance import AvatarAppearance from simulation.game_state import GameState @@ -57,7 +58,8 @@ def get_avatar(self, player_id): return self.avatar_manager.get_avatar(player_id) def run_turn(self): - self.simulation_runner.run_turn(self.avatar_manager.avatars_by_id) + loop = asyncio.get_event_loop() + loop.run_until_complete(self.simulation_runner.run_turn(self.avatar_manager.avatars_by_id)) def test_run_turn(self): """ diff --git a/aimmo_runner/docker_scripts.py b/aimmo_runner/docker_scripts.py index aeed9267b..591ea037e 100644 --- a/aimmo_runner/docker_scripts.py +++ b/aimmo_runner/docker_scripts.py @@ -6,36 +6,27 @@ import os -def vm_none_enabled(raw_env_settings): - """ - Check if the VM driver is enabled or not. This is important to see where the environment variables live. - - :param raw_env_settings: String that is returned by the 'minikube docker-env' command. - :return: Boolean value indicating if enabled or not. - """ - return False if 'driver does not support' in raw_env_settings else True - - -def create_docker_client(raw_env_settings): +def create_docker_client(use_raw_env=False, minikube=None): """ Create a docker client using the python SDK. :param raw_env_settings: String that is returned by the 'minikube docker-env' command. :return: """ - if vm_none_enabled(raw_env_settings): + if use_raw_env: + raw_env_settings = run_command([minikube, 'docker-env', '--shell="bash"'], True) matches = re.finditer(r'^export (.+)="(.+)"$', raw_env_settings, re.MULTILINE) env_variables = dict([(m.group(1), m.group(2)) for m in matches]) + + else: + # VM driver is set + env_variables = os.environ - return docker.from_env( + env_variables['DOCKER_BUILDKIT'] = "1" + return docker.from_env( environment=env_variables, version='auto', - ) - else: - # VM driver is set - return docker.from_env( - version='auto' - ) + ) def build_docker_images(minikube=None, build_target=None): @@ -46,10 +37,9 @@ def build_docker_images(minikube=None, build_target=None): """ print('Building docker images') if minikube: - raw_env_settings = run_command([minikube, 'docker-env', '--shell="bash"'], True) - client = create_docker_client(raw_env_settings) + client = create_docker_client(use_raw_env=True, minikube=minikube) else: - client = docker.from_env(version='auto') + client = create_docker_client(use_raw_env=False, minikube=minikube) directories = ('aimmo-game', 'aimmo-game-creator', 'aimmo-game-worker') for dir in directories: diff --git a/all_tests.py b/all_tests.py index 357aafcac..7446445f4 100755 --- a/all_tests.py +++ b/all_tests.py @@ -40,10 +40,7 @@ def run_tests(compute_coverage, use_docker=True): if use_docker: docker_scripts.delete_containers() client = docker.from_env() - if compute_coverage: - docker_scripts.build_docker_images(build_target='coverage_tester') - else: - docker_scripts.build_docker_images(build_target='tester') + docker_scripts.build_docker_images(build_target='tester') print('Docker containers built, running tests now...') run_game_creator_tests(client) run_game_tests(client) diff --git a/version.txt b/version.txt index 44bb5d1f7..f7abe273d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.4.1 \ No newline at end of file +0.4.2 \ No newline at end of file