Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added load test to generate traffic for green check API tests in Gree… #591

Open
wants to merge 1 commit into
base: sl-gmt
Choose a base branch
from

Conversation

jcamilleri-scottlogic
Copy link
Collaborator

…n Metric Tool

@jcamilleri-scottlogic
Copy link
Collaborator Author

When I try to run the GMT tool locally, even without these changes, I get the following error output - I'm sure this is a local config issue:

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 0_o >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Traceback (most recent call last):
File "/home/james/repos/green-metrics-tool/runner.py", line 1662, in
run_id = runner.run() # Start main code
File "/home/james/repos/green-metrics-tool/runner.py", line 1540, in run
raise exc
File "/home/james/repos/green-metrics-tool/runner.py", line 1499, in run
self.setup_services()
File "/home/james/repos/green-metrics-tool/runner.py", line 972, in setup_services
ps = subprocess.run(
File "/usr/lib/python3.10/subprocess.py", line 526, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['docker', 'exec', 'django', 'python', 'manage.py', 'migrate']' returned non-zero exit status 1.

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 0_o >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Error: Command failed

Stdout (<class 'str'>):
Stderr (<class 'str'>): WARNING No valid path found for the GeoIp binary database. We will not be able to serve ip-to-co2-intensity lookups.
Traceback (most recent call last):
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 275, in ensure_connection
self.connect()
File "/app/.venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
self.connection = self.get_new_connection(conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
connection = Database.connect(**conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/MySQLdb/init.py", line 123, in Connect
return Connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/MySQLdb/connections.py", line 185, in init
super().init(*args, **kwargs2)
MySQLdb.OperationalError: (2002, "Can't connect to server on 'mariadb' (115)")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/app/manage.py", line 20, in
main()
File "/app/manage.py", line 16, in main
execute_from_command_line(sys.argv)
File "/app/.venv/lib/python3.11/site-packages/django/core/management/init.py", line 442, in execute_from_command_line
utility.execute()
File "/app/.venv/lib/python3.11/site-packages/django/core/management/init.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/app/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 413, in run_from_argv
self.execute(*args, **cmd_options)
File "/app/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 459, in execute
output = self.handle(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 107, in wrapper
res = handle_func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 100, in handle
self.check(databases=[database])
File "/app/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 486, in check
all_issues = checks.run_checks(
^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/core/checks/registry.py", line 88, in run_checks
new_errors = check(app_configs=app_configs, databases=databases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django_mysql/checks.py", line 30, in check_variables
with connection.temporary_connection() as cursor:
File "/usr/local/lib/python3.11/contextlib.py", line 137, in enter
return next(self.gen)
^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 691, in temporary_connection
with self.cursor() as cursor:
^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 316, in cursor
return self._cursor()
^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 292, in _cursor
self.ensure_connection()
File "/app/.venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 274, in ensure_connection
with self.wrap_database_errors:
File "/app/.venv/lib/python3.11/site-packages/django/db/utils.py", line 91, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 275, in ensure_connection
self.connect()
File "/app/.venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/base/base.py", line 256, in connect
self.connection = self.get_new_connection(conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 256, in get_new_connection
connection = Database.connect(**conn_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/MySQLdb/init.py", line 123, in Connect
return Connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/.venv/lib/python3.11/site-packages/MySQLdb/connections.py", line 185, in init
super().init(*args, **kwargs2)
django.db.utils.OperationalError: (2002, "Can't connect to server on 'mariadb' (115)")

Run_id (<class 'uuid.UUID'>): 02946e27-6a96-4245-9198-0b48e5f7dbc8

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 0_o >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

@mrchrisadams
Copy link
Member

mrchrisadams commented May 24, 2024

I @jcamilleri-scottlogic - I've had a look at this I'm unable to reproduce the database connection issues but I did come across a different issue that I think would stop this working.

Previously the load testing script looked like this:

export default function () {
  // define URL and request body
  const url = "https://django:9000/api/v3/greencheck/climateaction.tech";
  const params = {
    headers: {
      "Content-Type": "application/json",
    },
  };

  // send a post request and save response as a variable
  const res = http.get(url, params);

  // check that response is 200
  check(res, {
    "response code was 200": (res) => res.status == 200,
  });
}

I'll the changes I've made to my usage scenario do you can sanity check against yours. It's a big long, do I've hidden it inside a expandable details block

Details

the main change I have from yours is that I am using a volume mount for copying the green_metric_tests into the k6 container, instead of copying. I was doing this largely for convenience when inspecting the container to debug.

---
name: Greencheck Test
author: James Camilleri <[email protected]>, Chris Adams <[email protected]>
description: Scenario to test the Greencheck endpoint of the Green Web Foundation Greencheck API

version: "3.5"

networks:
  greencheck-network:

services:
  mariadb:
    image: mariadb:10.11
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=deploy
      - MYSQL_DATABASE=greencheck
      - MYSQL_USER=deploy
      - MYSQL_PASSWORD=deploy
    networks:
      - greencheck-network

  rabbitmq:
    image: rabbitmq:3.11
    restart: always
    ports:
      - 5672:5672
    options: '--hostname "rmq" --health-cmd "rabbitmqctl status" --health-interval 10s --health-timeout 10s --health-retries 3 --health-start-period 60s'
    networks:
      - greencheck-network

  django:
    image: greenweb-app
    depends_on:
      - mariadb
      - rabbitmq
    # if we have the greenweb-app container built, commenting out the lines below
    # means we can use the image we've already built rather than needing to take a
    # few minutes each time to build it fresh again
    # build:
    #   context: .
    #   dockerfile: Dockerfile

    # if we need to inspect the container, and make changes between runs
    # mounting the volumes below allows for change to the most commonly
    # changed files without needing to rebuild the container
    # volumes:
    #   - ./apps:/app/apps
    #   - ./greenweb:/app/greenweb
    # we use sleep 5 as a hack to wait for the database to be ready
    setup-commands:
      - sleep 5
      - python manage.py migrate
      - python manage.py collectstatic --noinput
    environment:
      - PORT=9000
      - GUNICORN_BIND_IP=0.0.0.0
      - PYTHONDONTWRITEBYTECODE=1
      - PYTHONUNBUFFERED=1
      - DATABASE_URL=mysql://deploy:deploy@mariadb:3306/greencheck
      - DATABASE_URL_READ_ONLY=mysql://deploy:deploy@mariadb:3306/greencheck
      - RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672/
      - DJANGO_SETTINGS_MODULE=greenweb.settings.development
    ports:
      - 9000:9000
    # uncomment this be able to send requests to the django container
    # from outside the docker network
    # expose:
    #   - 9000
    # restart: on-failure
    log-stdout: true
    log-stderr: true
    networks:
      - greencheck-network

  # test-container:
  #   container_name: test-container
  #   image: node
  #   log-stdout: true
  #   log-stderr: true
  #   depends_on:
  #     - django
  #   setup-commands:
  #     - cp /tmp/repo/green_metric_tests/greencheck_test.spec.js .
  #     - cp /tmp/repo/green_metric_tests/package.json .
  #     - npm install
  #   networks:
  #     - greencheck-network

  load-test-container:
    container_name: load-test-container
    log-stdout: true
    log-stderr: true
    image: grafana/k6
    depends_on:
      - django
    # setup-commands:
    #   - cp /tmp/repo/green_metric_tests/greencheck_api_loadtest.js /src/greencheck_api_loadtest.js
    networks:
      - greencheck-network
    volumes:
      - ./green_metric_tests:/src

flow:
  # this should trigger a http request to an API endpoint
  # of http://django:9000, simulating a greencheck lookup
  # - name: Greencheck API Test
  #   container: test-container
  #   commands:
  #     - type: console
  #       command: npm test
  #       note: Starting test
  #       read-notes-stdout: true
  #       log-stdout: true
  #       log-stderr: true
  #     - type: console
  #       note: Idling
  #       command: sleep 30
  #     - type: console
  #       command: npm test
  #       note: Starting test again
  - name: Greencheck API Load Test
    container: load-test-container
    commands:
      - type: console
        note: Starting load test
        log-stdout: true
        log-stderr: true
        read-notes-stdout: true
        command: k6 run --iterations 11 /src/greencheck_api_loadtest.js

Anyway, a key thing I saw was that the load test was trying to connect to https://django:9000/api/v3/greencheck/climateaction.tech, but we terminate TLS at the reverse proxy server, and use HTTP inside the docker network. So, we should be connecting via HTTP instead for this test like so: http://django:9000/api/v3/greencheck/climateaction.tech

When I shell into the load testing container like so once all the containers are booted:

docker run -it --rm \
  --name load-test-container-<UNIQUE_SLUG>  \
  --entrypoint /bin/sh \
  -v /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal:/tmp/repo:ro \
  -v /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal/green_metric_tests:/src \
  --net greencheck-network grafanak6_gmt_run_tmp

Then I can manually run the following command, and see the output:

~ $ k6 run --iterations 11 /src/greencheck_api_loadtest.js

          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: /src/greencheck_api_loadtest.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 11 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)


     ✓ response code was 200

     checks.........................: 100.00% ✓ 11        ✗ 0 
     data_received..................: 4.1 kB  7.1 kB/s
     data_sent......................: 1.6 kB  2.7 kB/s
     http_req_blocked...............: avg=414.47µs min=76.67µs med=200.85µs max=1.55ms   p(90)=856.81µs p(95)=1.2ms   
     http_req_connecting............: avg=328.5µs  min=51.38µs med=169.02µs max=956.61µs p(90)=823.35µs p(95)=889.98µs
   ✓ http_req_duration..............: avg=52.47ms  min=6.42ms  med=6.84ms   max=176.25ms p(90)=168.59ms p(95)=172.42ms
       { expected_response:true }...: avg=52.47ms  min=6.42ms  med=6.84ms   max=176.25ms p(90)=168.59ms p(95)=172.42ms
   ✓ http_req_failed................: 0.00%   ✓ 0         ✗ 11
     http_req_receiving.............: avg=71.22µs  min=44.29µs med=64.96µs  max=109.34µs p(90)=109.18µs p(95)=109.26µs
     http_req_sending...............: avg=28.64µs  min=21.08µs med=27.46µs  max=46.38µs  p(90)=34.37µs  p(95)=40.37µs 
     http_req_tls_handshaking.......: avg=0s       min=0s      med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=52.37ms  min=6.33ms  med=6.74ms   max=176.14ms p(90)=168.49ms p(95)=172.32ms
     http_reqs......................: 11      18.868796/s
     iteration_duration.............: avg=52.98ms  min=6.69ms  med=7.09ms   max=177.16ms p(90)=169.53ms p(95)=173.35ms
     iterations.....................: 11      18.868796/s


running (00m00.6s), 0/1 VUs, 11 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m00.6s/10m0s  11/11 shared iters

To get a shell, I had to override the entrypoint with --entrypoint /bin/sh, as I think the container defaults to calling k6, and presumably passing any extra CMD params along.

I've linked what I think is the dockerfile for k6 - this is where I figured out what the entry point might be:

https://hub.docker.com/layers/grafana/k6/master/images/sha256-7d6f221698069f59aab8b85af2bfff592d447a2424841aab77a53b0e809c1742?context=explore

I'll share the annotated output from running this usage scenario, as I think there may be something up with the actual command used to run the load test from that file.

Details

bash run-test.sh 

This is calling the following command from the Green Metric Repo inside run-test.sh. Basically it's running GMT without building or any of the slow steps to ensure accurate measurements (--dev-no-metrics, --dev-no-sleeps and --dev-no-build ), and allowing external connections (allow-unsafe), and dumping logs for us to see (--print-logs)

python3 runner.py \
  --uri /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal \
  --name testing-fresh-greenweb  \
  --allow-unsafe \
  --print-logs \
  --dev-no-metrics \
  --dev-no-sleeps \
  --dev-no-build \
  --skip-system-checks

The rest is what I would expect

Detected supplied folder:  /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal
System check skipped
 
Checking out repository 
 
Having Usage Scenario  Greencheck Test 
From:  James Camilleri <[email protected]>, Chris Adams <[email protected]>
Description:  Scenario to test the Greencheck endpoint of the Green Web Foundation Greencheck API 

 

>>>> Warning: Runner is running in unsafe mode <<<<

 
 
Skipping import of metric providers 
 
Skipping downloading dependencies 
 
Starting phase [BASELINE]. 

Force-sleeping for 1s
 
Starting phase [INSTALLATION]. 

Force-sleeping for 1s
 
Building Docker images 
Image mariadb:10.11 exists in build cache. Skipping build ...
Image rabbitmq:3.11 exists in build cache. Skipping build ...
Image greenweb-app exists in build cache. Skipping build ...
Image grafana/k6 exists in build cache. Skipping build ...
 
Starting phase [BOOT]. 

Force-sleeping for 1s
 
Setting up networks 
Creating network:  greencheck-network
9a65e87a89f656a1247d4503e6aa79df60725235a39e52c078403aa39d781627
 
Setting up services 
Startup order:  ['mariadb', 'rabbitmq', 'django', 'load-test-container']
 
Setting up container:  mariadb 
Resetting container
Creating container
Setting ports:  ['3306:3306']
Running docker run with: docker run -it -d --name mariadb -v /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal:/tmp/repo:ro -p 3306:3306 -e MYSQL_ROOT_PASSWORD=deploy -e MYSQL_DATABASE=greencheck -e MYSQL_USER=deploy -e MYSQL_PASSWORD=deploy --net greencheck-network mariadb1011_gmt_run_tmp
Stdout: dbf7a19264956aba86843b781b7d8bf4658b3570f7ae798ba8ba119770db007c
 
Setting up container:  rabbitmq 
Resetting container
Creating container
Setting ports:  ['5672:5672']
Running docker run with: docker run -it -d --name rabbitmq -v /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal:/tmp/repo:ro -p 5672:5672 --net greencheck-network rabbitmq311_gmt_run_tmp
Stdout: 3b20f88c66a6e6c6f55105031d05e56bd63f2d1fba4730ec03b727fbb3b13585
 
Setting up container:  django 
Resetting container
Creating container
Setting ports:  ['9000:9000']
Waiting for dependent container mariadb
State of container 'mariadb': running
Waiting for dependent container rabbitmq
State of container 'rabbitmq': running
Running docker run with: docker run -it -d --name django -v /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal:/tmp/repo:ro -p 9000:9000 -e PORT=9000 -e GUNICORN_BIND_IP=0.0.0.0 -e PYTHONDONTWRITEBYTECODE=1 -e PYTHONUNBUFFERED=1 -e DATABASE_URL=mysql://deploy:deploy@mariadb:3306/greencheck -e DATABASE_URL_READ_ONLY=mysql://deploy:deploy@mariadb:3306/greencheck -e RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672/ -e DJANGO_SETTINGS_MODULE=greenweb.settings.development --net greencheck-network greenwebapp_gmt_run_tmp
Stdout: c0ac3718744a8a21bfbdc43f1a2da0f7f8b03a40829d968ef170cdc4c3850d9d
Running commands
Running command:  docker exec django sleep 5
Stdout: 
Stderr: 
Running command:  docker exec django python manage.py migrate
Stdout: Operations to perform:
  Apply all migrations: accounts, admin, auth, authtoken, contenttypes, django_dramatiq, django_registration, drf_api_logger, explorer, greencheck, guardian, sessions, taggit, waffle
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying accounts.0001_initial... OK
  Applying guardian.0001_initial... OK
  Applying guardian.0002_generic_permissions_index... OK
  Applying taggit.0001_initial... OK
  Applying taggit.0002_auto_20150616_2121... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying taggit.0003_taggeditem_add_unique_index... OK
  Applying taggit.0004_alter_taggeditem_content_type_alter_taggeditem_tag... OK
  Applying taggit.0005_auto_20220424_2025... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying accounts.0002_add_django_user_fields... OK
  Applying accounts.0003_index_on_name_for_hp_and_dc... OK
  Applying accounts.0004_default_values_for_boolean_fields... OK
  Applying accounts.0005_default_fields_for_hostingprovider... OK
  Applying accounts.0006_auto_20191114_1548... OK
  Applying accounts.0007_auto_20200206_1105... OK
  Applying accounts.0008_auto_20200206_1737... OK
  Applying accounts.0009_auto_20200603_1109... OK
  Applying accounts.0010_add_date_joined_values... OK
  Applying accounts.0011_auto_20210107_1245... OK
  Applying accounts.0012_auto_20210201_2230... OK
  Applying accounts.0013_datacentresupportingdocument_hostingprovidersupportingdocument... OK
  Applying accounts.0014_auto_20210314_2305... OK
  Applying accounts.0015_use_dc_locations... OK
  Applying accounts.0016_auto_20210424_1603... OK
  Applying accounts.0017_rename_datacentresupportingdocument_datacentersupportingdocument... OK
  Applying accounts.0018_datacenternote_hostingprovidernote... OK
  Applying accounts.0019_auto_20210708_1340... OK
  Applying accounts.0020_auto_20210809_1525... OK
  Applying accounts.0021_add_starting_templates... OK
  Applying accounts.0022_auto_20210809_1534... OK
  Applying accounts.0023_auto_20210809_1536... OK
  Applying accounts.0024_hostingcommunication_message_content... OK
  Applying accounts.0025_add_template_messages... OK
  Applying accounts.0026_auto_20210917_1012... OK
  Applying accounts.0027_alter_label_slug... OK
  Applying accounts.0028_auto_20220708_1237... OK
  Applying accounts.0029_alter_user_hostingprovider... OK
  Applying accounts.0030_auto_20220711_0848... OK
  Applying accounts.0031_auto_20220804_1502... OK
  Applying accounts.0032_providerrequest... OK
  Applying accounts.0033_remove_providerrequestsupplier... OK
  Applying accounts.0034_refactor_providerrequest_location... OK
  Applying accounts.0035_private_public_evidence... OK
  Applying accounts.0036_provider_request_evidence_changes... OK
  Applying accounts.0037_authorised_by_org... OK
  Applying accounts.0038_provider_request_consent... OK
  Applying accounts.0039_hostingprovider_city_squashed_0041_remove_providerrequestlocation_description... OK
  Applying accounts.0040_hostingprovider_providerrequest_link... OK
  Applying accounts.0041_alter_providerrequest_status... OK
  Applying accounts.0042_providerrequest_missing_network_explanation... OK
  Applying accounts.0043_providerrequest_location_import_required... OK
  Applying accounts.0044_provider_request_evidence_upload_location... OK
  Applying accounts.0045_alter_providerrequestevidence_public... OK
  Applying accounts.0046_providersharedsecret... OK
  Applying accounts.0047_provider_request_approved_date... OK
  Applying accounts.0048_rename_services_hostingprovider_service_tags... OK
  Applying accounts.0049_auto_20230507_2146... OK
  Applying accounts.0050_alter_providerrequest_services... OK
  Applying accounts.0051_auto_20230508_1317... OK
  Applying accounts.0048_disallow_adding_hp_and_dc... OK
  Applying accounts.0052_merge_20230510_1057... OK
  Applying accounts.0053_alter_providerrequest_status... OK
  Applying accounts.0054_provider_permissions... OK
  Applying accounts.0055_hostingprovider_datacenter_created_by... OK
  Applying accounts.0056_populate_existing_permissions... OK
  Applying accounts.0057_remove_user_hostingprovider_fk... OK
  Applying accounts.0054_providerrequest_network_import_required... OK
  Applying accounts.0055_alter_providerrequest_missing_network_explanation... OK
  Applying accounts.0058_merge_20230712_1143... OK
  Applying accounts.0058_alter_user_is_staff... OK
  Applying accounts.0059_merge_20230712_1415... OK
  Applying accounts.0060_provider_request_consent... OK
  Applying accounts.0061_providerrequest_rename_open_status... OK
  Applying accounts.0060_alter_hostingprovider_website... OK
  Applying accounts.0062_merge_20230921_1230... OK
  Applying accounts.0063_provider_request_related_provider... OK
  Applying accounts.0064_auto_20231025_1541... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying authtoken.0001_initial... OK
  Applying authtoken.0002_auto_20160226_1747... OK
  Applying authtoken.0003_tokenproxy... OK
  Applying authtoken.0004_alter_tokenproxy_options... OK
  Applying django_dramatiq.0001_initial... OK
  Applying django_dramatiq.0002_auto_20191104_1354... OK
  Applying django_dramatiq.0003_auto_20200204_0842... OK
  Applying django_registration.0001_initial... OK
  Applying drf_api_logger.0001_initial... OK
  Applying drf_api_logger.0002_auto_20211221_2155... OK
  Applying explorer.0001_initial... OK
  Applying explorer.0002_auto_20150501_1515... OK
  Applying explorer.0003_query_snapshot... OK
  Applying explorer.0004_querylog_duration... OK
  Applying explorer.0005_auto_20160105_2052... OK
  Applying explorer.0006_query_connection... OK
  Applying explorer.0007_querylog_connection... OK
  Applying explorer.0008_auto_20190308_1642... OK
  Applying explorer.0009_auto_20201009_0547... OK
  Applying explorer.0010_sql_required... OK
  Applying explorer.0011_query_favorites... OK
  Applying explorer.0012_alter_queryfavorite_query_alter_queryfavorite_user... OK
  Applying explorer.0013_querylog_error_querylog_success... OK
  Applying explorer.0014_promptlog... OK
  Applying explorer.0015_explorervalue... OK
  Applying greencheck.0001_initial... OK
  Applying greencheck.0002_approval_original_id_nullable... OK
  Applying greencheck.0003_timestamped_ranges_approvals... OK
  Applying greencheck.0004_auto_20200603_1109... OK
  Applying greencheck.0005_auto_20200604_1037... OK
  Applying greencheck.0006_auto_20210120_0751... OK
  Applying greencheck.0007_auto_20210120_0805... OK
  Applying greencheck.0008_auto_20210120_0916... OK
  Applying greencheck.0009_auto_20210120_1029... OK
  Applying greencheck.0010_auto_20210120_1107... OK
  Applying greencheck.0011_auto_20210120_1418... OK
  Applying greencheck.0012_auto_20210120_1433... OK
  Applying greencheck.0013_auto_20210215_1809... OK
  Applying greencheck.0014_auto_20210314_1704... OK
  Applying greencheck.0015_auto_20210320_1728... OK
  Applying greencheck.0016_auto_20210424_1603... OK
  Applying greencheck.0017_create_dailystat... OK
  Applying greencheck.0018_auto_20210917_1012... OK
  Applying greencheck.0019_auto_20220515_1835... OK
  Applying greencheck.0020_auto_20240223_2122... OK
  Applying sessions.0001_initial... OK
  Applying taggit.0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx... OK
  Applying waffle.0001_initial... OK
  Applying waffle.0002_auto_20161201_0958... OK
  Applying waffle.0003_update_strings_for_i18n... OK
  Applying waffle.0004_update_everyone_nullbooleanfield... OK

Stderr: WARNING No valid path found for the GeoIp binary database. We will not be able to serve ip-to-co2-intensity lookups.

Running command:  docker exec django python manage.py collectstatic --noinput
Stdout: Found another file with the destination path 'fonts/TWKEverett-Regular-web.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'fonts/TWKEverett-RegularItalic-web.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'fonts/twkeverett-regular.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'fonts/twkeverett-regularitalic.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-lightning--black.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-lightning--purple.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-plant--black.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-plant--orange.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-sunburst--black.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-sunburst--green.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-sunburst--yellow.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-logo-white.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/TGWF-logo.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/icon-external-link-white.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/icon-external-link.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'js/dist/app.bundle.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'js/dist/app.bundle.min.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/dist/styles.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.

0 static files copied to '/app/staticfiles', 575 unmodified.

So far, this is ok. We are setting up rabbit mq, our mariadb database server, and the django server, then running migrations to set up the desired database state, and collect all the static files so they can be served from a single directory.

The next bit is the load-test-container using k6. this is what I based the command above to log into a comparable container and troubleshoot. The key difference was removing the -d section so I had a terminal, and adding an --rm to remove the container after I log out to clear up after myself.

Stderr: 
 
Setting up container:  load-test-container 
Resetting container
Creating container
Waiting for dependent container django
State of container 'django': running
Running docker run with: docker run -it -d --name load-test-container -v /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal:/tmp/repo:ro -v /Users/chrisadams/Code/tgwf/gmt-testing-admin-portal/green_metric_tests:/src --net greencheck-network grafanak6_gmt_run_tmp
Stdout: f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384

The next steps are carrying out the steps in the flow. For clarity I commented out the other test-container, and the flow steps it used, so we can look at just the k6 container.


Current known containers:  {'dbf7a19264956aba86843b781b7d8bf4658b3570f7ae798ba8ba119770db007c': {'name': 'mariadb', 'log-stdout': False, 'log-stderr': True, 'read-notes-stdout': False, 'read-sci-stdout': False}, '3b20f88c66a6e6c6f55105031d05e56bd63f2d1fba4730ec03b727fbb3b13585': {'name': 'rabbitmq', 'log-stdout': False, 'log-stderr': True, 'read-notes-stdout': False, 'read-sci-stdout': False}, 'c0ac3718744a8a21bfbdc43f1a2da0f7f8b03a40829d968ef170cdc4c3850d9d': {'name': 'django', 'log-stdout': True, 'log-stderr': True, 'read-notes-stdout': False, 'read-sci-stdout': False}, 'f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384': {'name': 'load-test-container', 'log-stdout': True, 'log-stderr': True, 'read-notes-stdout': False, 'read-sci-stdout': False}} 
 
Starting phase [IDLE]. 

Force-sleeping for 1s
 
Starting phase [RUNTIME]. 

Force-sleeping for 1s
 
Running flow:  Greencheck API Load Test 
 
Starting phase Greencheck API Load Test. 
 
Console command k6 run --iterations 11 /src/greencheck_api_loadtest.js on container load-test-container 
Process should be synchronous. Alloting 3800s runtime ...
 
Checking process return codes 
 
Capturing container logs 
 
Reading process stdout/stderr (if selected) and cleaning them up 
stderr from process: ['docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js'] Error response from daemon: container f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384 is not running
 
Saving notes:   [{'note': 'Start of measurement', 'detail_name': '[NOTES]', 'timestamp': 1716536701759465}, {'note': 'Starting phase [BASELINE]', 'detail_name': '[NOTES]', 'timestamp': 1716536701759515}, {'note': 'Ending phase [BASELINE]', 'detail_name': '[NOTES]', 'timestamp': 1716536701759519}, {'note': 'Starting phase [INSTALLATION]', 'detail_name': '[NOTES]', 'timestamp': 1716536701759530}, {'note': 'Ending phase [INSTALLATION]', 'detail_name': '[NOTES]', 'timestamp': 1716536701907431}, {'note': 'Starting phase [BOOT]', 'detail_name': '[NOTES]', 'timestamp': 1716536701907482}, {'note': 'Ending phase [BOOT]', 'detail_name': '[NOTES]', 'timestamp': 1716536717464672}, {'note': 'Starting phase [IDLE]', 'detail_name': '[NOTES]', 'timestamp': 1716536717464752}, {'note': 'Ending phase [IDLE]', 'detail_name': '[NOTES]', 'timestamp': 1716536717464760}, {'note': 'Starting phase [RUNTIME]', 'detail_name': '[NOTES]', 'timestamp': 1716536717464780}, {'note': 'Starting phase Greencheck API Load Test', 'detail_name': '[NOTES]', 'timestamp': 1716536717464820}, {'note': 'Starting load test', 'detail_name': 'load-test-container', 'timestamp': 1716536717464831}, {'note': 'Ending phase Greencheck API Load Test', 'detail_name': '[NOTES]', 'timestamp': 1716536717564206}]
 
Saving logs to DB 
 
Starting cleanup routine 
Stopping metric providers
Stopping containers
dbf7a19264956aba86843b781b7d8bf4658b3570f7ae798ba8ba119770db007c
3b20f88c66a6e6c6f55105031d05e56bd63f2d1fba4730ec03b727fbb3b13585
c0ac3718744a8a21bfbdc43f1a2da0f7f8b03a40829d968ef170cdc4c3850d9d
f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384
Removing network
greencheck-network
 -Cleanup gracefully completed 
 -Cleanup gracefully completed 
 

Here's where we are seeing errors - on boot, calling 'docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js'] is not working. I'm not sure why:


<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 0_o >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Traceback (most recent call last):
  File "/Users/chrisadams/Code/tgwf/green-metrics-tool/runner.py", line 2350, in <module>
    run_id = runner.run()  # Start main code
             ^^^^^^^^^^^^
  File "/Users/chrisadams/Code/tgwf/green-metrics-tool/runner.py", line 2114, in run
    raise exc
  File "/Users/chrisadams/Code/tgwf/green-metrics-tool/runner.py", line 2088, in run
    self.run_flows()  # can trigger debug breakpoints;
    ^^^^^^^^^^^^^^^^
  File "/Users/chrisadams/Code/tgwf/green-metrics-tool/runner.py", line 1635, in run_flows
    raise flow_exc
  File "/Users/chrisadams/Code/tgwf/green-metrics-tool/runner.py", line 1627, in run_flows
    self.check_process_returncodes()
  File "/Users/chrisadams/Code/tgwf/green-metrics-tool/runner.py", line 1811, in check_process_returncodes
    raise RuntimeError(
RuntimeError: Process '['docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js']' had bad returncode: 1. Stderr: Error response from daemon: container f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384 is not running
; Detached process: False. Please also check the stdout in the logs and / or enable stdout logging to debug further.


<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 0_o >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Error: RuntimeError occured in runner.py

Exception (<class 'RuntimeError'>): Process '['docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js']' had bad returncode: 1. Stderr: Error response from daemon: container f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384 is not running
; Detached process: False. Please also check the stdout in the logs and / or enable stdout logging to debug further.
Run_id (<class 'uuid.UUID'>): 8dc92f61-dde1-4cc9-9fec-17c14ef4e3c7

The logs below are not errors but they are output sent to STDERR. It might make sense to pass a --quiet tag to the django commands in future, as they are working as intended.


<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 0_o >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

     
Container logs of 'django_['docker', 'exec', 'django', 'python', 'manage.py', 'migrate']':

stdout Operations to perform:
  Apply all migrations: accounts, admin, auth, authtoken, contenttypes, django_dramatiq, django_registration, drf_api_logger, explorer, greencheck, guardian, sessions, taggit, waffle
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying accounts.0001_initial... OK
  Applying guardian.0001_initial... OK
  Applying guardian.0002_generic_permissions_index... OK
  Applying taggit.0001_initial... OK
  Applying taggit.0002_auto_20150616_2121... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying taggit.0003_taggeditem_add_unique_index... OK
  Applying taggit.0004_alter_taggeditem_content_type_alter_taggeditem_tag... OK
  Applying taggit.0005_auto_20220424_2025... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying accounts.0002_add_django_user_fields... OK
  Applying accounts.0003_index_on_name_for_hp_and_dc... OK
  Applying accounts.0004_default_values_for_boolean_fields... OK
  Applying accounts.0005_default_fields_for_hostingprovider... OK
  Applying accounts.0006_auto_20191114_1548... OK
  Applying accounts.0007_auto_20200206_1105... OK
  Applying accounts.0008_auto_20200206_1737... OK
  Applying accounts.0009_auto_20200603_1109... OK
  Applying accounts.0010_add_date_joined_values... OK
  Applying accounts.0011_auto_20210107_1245... OK
  Applying accounts.0012_auto_20210201_2230... OK
  Applying accounts.0013_datacentresupportingdocument_hostingprovidersupportingdocument... OK
  Applying accounts.0014_auto_20210314_2305... OK
  Applying accounts.0015_use_dc_locations... OK
  Applying accounts.0016_auto_20210424_1603... OK
  Applying accounts.0017_rename_datacentresupportingdocument_datacentersupportingdocument... OK
  Applying accounts.0018_datacenternote_hostingprovidernote... OK
  Applying accounts.0019_auto_20210708_1340... OK
  Applying accounts.0020_auto_20210809_1525... OK
  Applying accounts.0021_add_starting_templates... OK
  Applying accounts.0022_auto_20210809_1534... OK
  Applying accounts.0023_auto_20210809_1536... OK
  Applying accounts.0024_hostingcommunication_message_content... OK
  Applying accounts.0025_add_template_messages... OK
  Applying accounts.0026_auto_20210917_1012... OK
  Applying accounts.0027_alter_label_slug... OK
  Applying accounts.0028_auto_20220708_1237... OK
  Applying accounts.0029_alter_user_hostingprovider... OK
  Applying accounts.0030_auto_20220711_0848... OK
  Applying accounts.0031_auto_20220804_1502... OK
  Applying accounts.0032_providerrequest... OK
  Applying accounts.0033_remove_providerrequestsupplier... OK
  Applying accounts.0034_refactor_providerrequest_location... OK
  Applying accounts.0035_private_public_evidence... OK
  Applying accounts.0036_provider_request_evidence_changes... OK
  Applying accounts.0037_authorised_by_org... OK
  Applying accounts.0038_provider_request_consent... OK
  Applying accounts.0039_hostingprovider_city_squashed_0041_remove_providerrequestlocation_description... OK
  Applying accounts.0040_hostingprovider_providerrequest_link... OK
  Applying accounts.0041_alter_providerrequest_status... OK
  Applying accounts.0042_providerrequest_missing_network_explanation... OK
  Applying accounts.0043_providerrequest_location_import_required... OK
  Applying accounts.0044_provider_request_evidence_upload_location... OK
  Applying accounts.0045_alter_providerrequestevidence_public... OK
  Applying accounts.0046_providersharedsecret... OK
  Applying accounts.0047_provider_request_approved_date... OK
  Applying accounts.0048_rename_services_hostingprovider_service_tags... OK
  Applying accounts.0049_auto_20230507_2146... OK
  Applying accounts.0050_alter_providerrequest_services... OK
  Applying accounts.0051_auto_20230508_1317... OK
  Applying accounts.0048_disallow_adding_hp_and_dc... OK
  Applying accounts.0052_merge_20230510_1057... OK
  Applying accounts.0053_alter_providerrequest_status... OK
  Applying accounts.0054_provider_permissions... OK
  Applying accounts.0055_hostingprovider_datacenter_created_by... OK
  Applying accounts.0056_populate_existing_permissions... OK
  Applying accounts.0057_remove_user_hostingprovider_fk... OK
  Applying accounts.0054_providerrequest_network_import_required... OK
  Applying accounts.0055_alter_providerrequest_missing_network_explanation... OK
  Applying accounts.0058_merge_20230712_1143... OK
  Applying accounts.0058_alter_user_is_staff... OK
  Applying accounts.0059_merge_20230712_1415... OK
  Applying accounts.0060_provider_request_consent... OK
  Applying accounts.0061_providerrequest_rename_open_status... OK
  Applying accounts.0060_alter_hostingprovider_website... OK
  Applying accounts.0062_merge_20230921_1230... OK
  Applying accounts.0063_provider_request_related_provider... OK
  Applying accounts.0064_auto_20231025_1541... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying authtoken.0001_initial... OK
  Applying authtoken.0002_auto_20160226_1747... OK
  Applying authtoken.0003_tokenproxy... OK
  Applying authtoken.0004_alter_tokenproxy_options... OK
  Applying django_dramatiq.0001_initial... OK
  Applying django_dramatiq.0002_auto_20191104_1354... OK
  Applying django_dramatiq.0003_auto_20200204_0842... OK
  Applying django_registration.0001_initial... OK
  Applying drf_api_logger.0001_initial... OK
  Applying drf_api_logger.0002_auto_20211221_2155... OK
  Applying explorer.0001_initial... OK
  Applying explorer.0002_auto_20150501_1515... OK
  Applying explorer.0003_query_snapshot... OK
  Applying explorer.0004_querylog_duration... OK
  Applying explorer.0005_auto_20160105_2052... OK
  Applying explorer.0006_query_connection... OK
  Applying explorer.0007_querylog_connection... OK
  Applying explorer.0008_auto_20190308_1642... OK
  Applying explorer.0009_auto_20201009_0547... OK
  Applying explorer.0010_sql_required... OK
  Applying explorer.0011_query_favorites... OK
  Applying explorer.0012_alter_queryfavorite_query_alter_queryfavorite_user... OK
  Applying explorer.0013_querylog_error_querylog_success... OK
  Applying explorer.0014_promptlog... OK
  Applying explorer.0015_explorervalue... OK
  Applying greencheck.0001_initial... OK
  Applying greencheck.0002_approval_original_id_nullable... OK
  Applying greencheck.0003_timestamped_ranges_approvals... OK
  Applying greencheck.0004_auto_20200603_1109... OK
  Applying greencheck.0005_auto_20200604_1037... OK
  Applying greencheck.0006_auto_20210120_0751... OK
  Applying greencheck.0007_auto_20210120_0805... OK
  Applying greencheck.0008_auto_20210120_0916... OK
  Applying greencheck.0009_auto_20210120_1029... OK
  Applying greencheck.0010_auto_20210120_1107... OK
  Applying greencheck.0011_auto_20210120_1418... OK
  Applying greencheck.0012_auto_20210120_1433... OK
  Applying greencheck.0013_auto_20210215_1809... OK
  Applying greencheck.0014_auto_20210314_1704... OK
  Applying greencheck.0015_auto_20210320_1728... OK
  Applying greencheck.0016_auto_20210424_1603... OK
  Applying greencheck.0017_create_dailystat... OK
  Applying greencheck.0018_auto_20210917_1012... OK
  Applying greencheck.0019_auto_20220515_1835... OK
  Applying greencheck.0020_auto_20240223_2122... OK
  Applying sessions.0001_initial... OK
  Applying taggit.0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx... OK
  Applying waffle.0001_initial... OK
  Applying waffle.0002_auto_20161201_0958... OK
  Applying waffle.0003_update_strings_for_i18n... OK
  Applying waffle.0004_update_everyone_nullbooleanfield... OK

stderr WARNING No valid path found for the GeoIp binary database. We will not be able to serve ip-to-co2-intensity lookups.


-----------------------------

Container logs of 'django_['docker', 'exec', 'django', 'python', 'manage.py', 'collectstatic', '--noinput']':

stdout Found another file with the destination path 'fonts/TWKEverett-Regular-web.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'fonts/TWKEverett-RegularItalic-web.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'fonts/twkeverett-regular.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'fonts/twkeverett-regularitalic.woff2'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-lightning--black.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-lightning--purple.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-plant--black.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-plant--orange.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-sunburst--black.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-sunburst--green.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-icon-sunburst--yellow.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/GWF-logo-white.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/TGWF-logo.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/icon-external-link-white.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'img/icon-external-link.svg'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'js/dist/app.bundle.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'js/dist/app.bundle.min.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'css/dist/styles.css'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.

0 static files copied to '/app/staticfiles', 575 unmodified.


Here is the output from calling '['docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js']'.

From what I can see, it looks like load-test-container is not calling k6 to run the load test like we saw above when I run it manually.

I'm not sure why that's happening because I assumed that

'['docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js']'

And this command inside would be functionally the same:

k6 run --iterations 11 /src/greencheck_api_loadtest.js

Instead we're seeing the output from the django server ready to receive requests, and then the output from k6 when you run k6 with no other arguments:


-----------------------------

Container logs of 'RuntimeError_':

Process '['docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js']' had bad returncode: 1. Stderr: Error response from daemon: container f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384 is not running
; Detached process: False. Please also check the stdout in the logs and / or enable stdout logging to debug further.

-----------------------------

Container logs of 'c0ac3718744a8a21bfbdc43f1a2da0f7f8b03a40829d968ef170cdc4c3850d9d_':

stdout: [2024-05-24 07:45:03 +0000] [7] [INFO] Starting gunicorn 22.0.0
[2024-05-24 07:45:03 +0000] [7] [INFO] Listening at: http://0.0.0.0:9000 (7)
[2024-05-24 07:45:03 +0000] [7] [INFO] Using worker: sync
[2024-05-24 07:45:03 +0000] [14] [INFO] Booting worker with pid: 14
[2024-05-24 07:45:03 +0000] [15] [INFO] Booting worker with pid: 15
[2024-05-24 07:45:03 +0000] [16] [INFO] Booting worker with pid: 16
[2024-05-24 07:45:03 +0000] [17] [INFO] Booting worker with pid: 17
[2024-05-24 07:45:03 +0000] [18] [INFO] Booting worker with pid: 18
[2024-05-24 07:45:03 +0000] [19] [INFO] Booting worker with pid: 19
[2024-05-24 07:45:03 +0000] [20] [INFO] Booting worker with pid: 20
[2024-05-24 07:45:03 +0000] [21] [INFO] Booting worker with pid: 21


-----------------------------

Container logs of 'f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384_':

stdout: 
          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

Usage:
  k6 [command]

Available Commands:
  archive     Create an archive
  cloud       Run a test on the cloud
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  inspect     Inspect a script or archive
  login       Authenticate with a service
  new         Create and initialize a new k6 script
  pause       Pause a running test
  resume      Resume a paused test
  run         Start a test
  scale       Scale a running test
  stats       Show test metrics
  status      Show test status
  version     Show application version

Flags:
  -a, --address string      address for the REST API server (default "localhost:6565")
  -c, --config string       JSON config file (default "/home/k6/.config/loadimpact/k6/config.json")
  -h, --help                help for k6
      --log-format string   log output format
      --log-output string   change the output for k6 logs, possible values are stderr,stdout,none,loki[=host:port],file[=./path.fileformat] (default "stderr")
      --no-color            disable colored output
      --profiling-enabled   enable profiling (pprof) endpoints, k6's REST API should be enabled as well
  -q, --quiet               disable progress updates
  -v, --verbose             enable verbose logging
      --version             version for k6

Use "k6 [command] --help" for more information about a command.


-----------------------------

Container logs of 'load-test-container_['docker', 'exec', 'load-test-container', 'k6', 'run', '--iterations', '11', '/src/greencheck_api_loadtest.js']':

stderr: Error response from daemon: container f645e9342e97ea679bf6d70fb632a52b964371bc9b994472e0122d30f019b384 is not running

-----------------------------

We have some time booked today anyway, but hopefully this provides a bit more context, and helps along the way.

@mrchrisadams
Copy link
Member

Hi @ArneTR - just quick one before we go further on this.

GMT doesn't have any native load testing tooling inside it, right? @jcamilleri-scottlogic is working trying to recreate conditions of hitting an endpoint multiple times a second, a bit like how the app works in production, and we're not sure if this a sensible way to use GMT.

We're not trying to recreate production exactly, obvs, but at least have a scenario that's more representative of a just single HTTP request in isolation

@ArneTR
Copy link
Contributor

ArneTR commented May 25, 2024

Hey @mrchrisadams , no GMT does not have an integrated load testing tool. But it is designed to support any tool that you have.

We have many people using GMT in that fashion. A typical tool in the java world is for instance jMeter and in essence you would just start a container alongside your others on the system and stress your API.

See an example here: https://github.com/green-coding-solutions/example-applications/tree/main/jmeter

I do not know which load tester you have in mind but for a simple HTTP(S) API I would probalby go for a CLI based one like ab

Happy to support more and do not hesitate to follow up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants