Skip to content

Commit

Permalink
Add pre-commit and fix issues (#327)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucacome authored May 1, 2023
1 parent 9c3b0ab commit d551469
Show file tree
Hide file tree
Showing 18 changed files with 176 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
build_output
build_output
55 changes: 55 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
args: [--allow-multiple-documents]
- id: check-ast
- id: check-added-large-files
- id: check-merge-conflict
- id: check-shebang-scripts-are-executable
- id: check-executables-have-shebangs
- id: check-symlinks
- id: check-case-conflict
- id: check-vcs-permalinks
- id: mixed-line-ending
args: [--fix=lf]
- id: name-tests-test
args: [--pytest-test-first]
exclude: ^(tests/settings.py)
- id: no-commit-to-branch
- id: requirements-txt-fixer
- id: fix-byte-order-marker
- id: detect-private-key
- repo: local
hooks:
- id: golang-diff
name: create-go-diff
entry: bash -c 'git diff -p origin/main > /tmp/diff.patch'
language: system
types: [go]
pass_filenames: false
- repo: https://github.com/golangci/golangci-lint
rev: v1.52.2
hooks:
- id: golangci-lint
args: [--new-from-patch=/tmp/diff.patch]
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.2
hooks:
- id: pyupgrade
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black

ci:
skip: [golang-diff, golangci-lint]
Empty file modified build/postinstall.sh
100644 → 100755
Empty file.
Empty file modified build/postremove.sh
100644 → 100755
Empty file.
Empty file modified build/preremove.sh
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion examples/azure.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ upstreams:
* `max_conns` – The maximum number of simultaneous active connections to an upstream server. Default value is 0, meaning there is no limit.
* `max_fails` – The number of unsuccessful attempts to communicate with an upstream server that should happen in the duration set by the `fail-timeout` to consider the server unavailable. Default value is 1. The zero value disables the accounting of attempts.
* `fail_timeout` – The time during which the specified number of unsuccessful attempts to communicate with an upstream server should happen to consider the server unavailable. Default value is 10s.
* `slow_start` – The slow start allows an upstream server to gradually recover its weight from 0 to its nominal value after it has been recovered or became available or when the server becomes available after a period of time it was considered unavailable. By default, the slow start is disabled.
* `slow_start` – The slow start allows an upstream server to gradually recover its weight from 0 to its nominal value after it has been recovered or became available or when the server becomes available after a period of time it was considered unavailable. By default, the slow start is disabled.
13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[tool.black]
line-length = 120
target-version = ['py311']
extend-exclude = '.*pb2.*'

[tool.isort]
atomic = true
profile = "black"
line_length = 120
skip_gitignore = true
balanced_wrapping = true
filter_files = true
skip_glob = ['*pb2*']
2 changes: 1 addition & 1 deletion tests/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Ignore pytest cache
.pytest_cache
.pytest_cache
2 changes: 1 addition & 1 deletion tests/.flake8
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
format = pylint
max-complexity = 10
max-line-length = 170
exclude = .git,__pycache__,data,.idea,.pytest_cache
exclude = .git,__pycache__,data,.idea,.pytest_cache
2 changes: 1 addition & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ build:
docker build -t $(PREFIX):$(TAG) -f docker/Dockerfile ..

run-tests: build
docker run --rm -v $(AWS_CREDENTIALS):/root/.aws/credentials $(PREFIX):$(TAG) --nginx-api=$(NGINX_API) --aws-region=$(AWS_REGION) $(PYTEST_ARGS)
docker run --rm -v $(AWS_CREDENTIALS):/root/.aws/credentials $(PREFIX):$(TAG) --nginx-api=$(NGINX_API) --aws-region=$(AWS_REGION) $(PYTEST_ARGS)
8 changes: 4 additions & 4 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ Below you will find the instructions on how to run the tests against a cloud pro

### Prerequisites:

* AWS stack prepared.
* AWS access key and AWS secret access key.
* AWS stack prepared.
* AWS access key and AWS secret access key.
* Python3 or Docker.

#### Step 1 - Set up the environment

* Either create|update ~/.aws/credentials file or set the AWS_SHARED_CREDENTIALS_FILE environment variable pointing to your own location. This file is an INI formatted file with section names corresponding to profiles. Tests use 'default' profile. The file [credentials](data/credentials) is a minimal example of such a file.

#### Step 2 - Run the Tests

Run the tests:
* Use local Python3 installation:
```bash
Expand All @@ -44,4 +44,4 @@ The table below shows various configuration options for the tests. If you use Py
| `--aws-region` | `AWS_REGION` | The AWS stack region. | `us-east-2` |
| `N/A` | `PYTEST_ARGS` | Any additional pytest command-line arguments (i.e `-k TestSmoke`) | `""` |

If you would like to use an IDE (such as PyCharm) to run the tests, use the [pytest.ini](pytest.ini) file to set the command-line arguments.
If you would like to use an IDE (such as PyCharm) to run the tests, use the [pytest.ini](pytest.ini) file to set the command-line arguments.
13 changes: 9 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ def pytest_addoption(parser) -> None:
:return:
"""
parser.addoption("--nginx-api", action="store", default="", help="The NGINX Plus API url.")
parser.addoption("--aws-region", action="store", default=DEFAULT_AWS_REGION, help="The AWS region name.")
parser.addoption(
"--aws-region",
action="store",
default=DEFAULT_AWS_REGION,
help="The AWS region name.",
)


class CLIArguments:
Expand All @@ -24,6 +29,7 @@ class CLIArguments:
nginx_api (str): NGINX Plus API url
aws_region (str): AWS region name
"""

def __init__(self, nginx_api: str, aws_region: str):
self.nginx_api = nginx_api
self.aws_region = aws_region
Expand Down Expand Up @@ -57,6 +63,5 @@ def autoscaling_client(cli_arguments) -> BaseClient:
:param cli_arguments: a set of command-line arguments
:return:
"""
session = Session(profile_name='default',
region_name=cli_arguments.aws_region)
return session.client('autoscaling')
session = Session(profile_name="default", region_name=cli_arguments.aws_region)
return session.client("autoscaling")
2 changes: 1 addition & 1 deletion tests/data/credentials
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[default]
aws_access_key_id=foo
aws_secret_access_key=bar
aws_secret_access_key=bar
2 changes: 1 addition & 1 deletion tests/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ WORKDIR /workspace/tests

RUN pip install -r requirements.txt

ENTRYPOINT [ "python3", "-m", "pytest"]
ENTRYPOINT [ "python3", "-m", "pytest"]
2 changes: 1 addition & 1 deletion tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[pytest]
addopts = --tb=native -r fsxX --disable-warnings
log_cli=true
log_cli=true
4 changes: 2 additions & 2 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
requests==2.29.0
boto3==1.26.5
pytest==7.3.1
pytest==7.3.1
requests==2.29.0
1 change: 0 additions & 1 deletion tests/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""Describe project settings"""
import os

Expand Down
120 changes: 85 additions & 35 deletions tests/suite/test_smoke.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import pytest
import time
import requests
import json
import time

import pytest
import requests
from botocore.waiter import WaiterModel, create_waiter_with_client

from tests.settings import RECONFIGURATION_DELAY, NGINX_API_VERSION
from tests.settings import NGINX_API_VERSION, RECONFIGURATION_DELAY


def wait_for_changes_in_api(req_url, desired_capacity) -> None:
resp = requests.get(req_url)
nginx_upstream = json.loads(resp.text)
counter = 0
while len(nginx_upstream['peers']) != desired_capacity and counter < 10:
while len(nginx_upstream["peers"]) != desired_capacity and counter < 10:
time.sleep(RECONFIGURATION_DELAY)
counter = counter + 1
resp = requests.get(req_url)
nginx_upstream = json.loads(resp.text)


def wait_for_changes_in_aws(autoscaling_client, group_name, desired_capacity) -> None:
waiter_name = 'autoscaling_completed'
argument = f"contains(AutoScalingGroups[?(starts_with(AutoScalingGroupName, `{group_name}`) == `true`)]." \
f"[length(Instances[?LifecycleState=='InService']) == `{desired_capacity}`][], `false`)"
waiter_name = "autoscaling_completed"
argument = (
f"contains(AutoScalingGroups[?(starts_with(AutoScalingGroupName, `{group_name}`) == `true`)]."
f"[length(Instances[?LifecycleState=='InService']) == `{desired_capacity}`][], `false`)"
)
waiter_config = {
"version": 2,
"waiters": {
Expand All @@ -32,20 +34,20 @@ def wait_for_changes_in_aws(autoscaling_client, group_name, desired_capacity) ->
"argument": argument,
"expected": True,
"matcher": "path",
"state": "success"
"state": "success",
},
{
"argument": argument,
"expected": False,
"matcher": "path",
"state": "retry"
}
"state": "retry",
},
],
"delay": 5,
"maxAttempts": 20,
"operation": "DescribeAutoScalingGroups"
"operation": "DescribeAutoScalingGroups",
}
}
},
}
waiter_model = WaiterModel(waiter_config)
custom_waiter = create_waiter_with_client(waiter_name, waiter_model, autoscaling_client)
Expand Down Expand Up @@ -78,41 +80,89 @@ def get_aws_group_name(autoscaling_client, group_name) -> str:
:param group_name:
:return: str
"""
groups = autoscaling_client.describe_auto_scaling_groups()['AutoScalingGroups']
return list(filter(lambda group: group_name in group['AutoScalingGroupName'], groups))[0]['AutoScalingGroupName']
groups = autoscaling_client.describe_auto_scaling_groups()["AutoScalingGroups"]
return list(filter(lambda group: group_name in group["AutoScalingGroupName"], groups))[0]["AutoScalingGroupName"]


class TestSmoke:
@pytest.mark.parametrize("test_data", [
pytest.param({'group_name': 'WebserverGroup1', 'api_url': '/http/upstreams/backend1'}, id="backend1"),
pytest.param({'group_name': 'WebserverGroup2', 'api_url': '/http/upstreams/backend2'}, id="backend2"),
pytest.param({'group_name': 'WebserverGroup3', 'api_url': '/stream/upstreams/tcp-backend'}, id="tcp-backend")
])
@pytest.mark.parametrize(
"test_data",
[
pytest.param(
{
"group_name": "WebserverGroup1",
"api_url": "/http/upstreams/backend1",
},
id="backend1",
),
pytest.param(
{
"group_name": "WebserverGroup2",
"api_url": "/http/upstreams/backend2",
},
id="backend2",
),
pytest.param(
{
"group_name": "WebserverGroup3",
"api_url": "/stream/upstreams/tcp-backend",
},
id="tcp-backend",
),
],
)
def test_aws_scale_up(self, cli_arguments, autoscaling_client, test_data):
desired_capacity = 5
group_name = get_aws_group_name(autoscaling_client, test_data['group_name'])
group_name = get_aws_group_name(autoscaling_client, test_data["group_name"])
scale_aws_group(autoscaling_client, group_name, desired_capacity)
wait_for_changes_in_aws(autoscaling_client, group_name, desired_capacity)
wait_for_changes_in_api(f"{cli_arguments.nginx_api}/{NGINX_API_VERSION}{test_data['api_url']}",
desired_capacity)
wait_for_changes_in_api(
f"{cli_arguments.nginx_api}/{NGINX_API_VERSION}{test_data['api_url']}",
desired_capacity,
)
resp = requests.get(f"{cli_arguments.nginx_api}/{NGINX_API_VERSION}{test_data['api_url']}")
nginx_upstream = json.loads(resp.text)
assert len(nginx_upstream['peers']) == desired_capacity,\
f"Expected {desired_capacity} servers, found: {nginx_upstream['peers']}"
assert (
len(nginx_upstream["peers"]) == desired_capacity
), f"Expected {desired_capacity} servers, found: {nginx_upstream['peers']}"

@pytest.mark.parametrize("test_data", [
pytest.param({'group_name': 'WebserverGroup1', 'api_url': '/http/upstreams/backend1'}, id="backend1"),
pytest.param({'group_name': 'WebserverGroup2', 'api_url': '/http/upstreams/backend2'}, id="backend2"),
pytest.param({'group_name': 'WebserverGroup3', 'api_url': '/stream/upstreams/tcp-backend'}, id="tcp-backend")
])
@pytest.mark.parametrize(
"test_data",
[
pytest.param(
{
"group_name": "WebserverGroup1",
"api_url": "/http/upstreams/backend1",
},
id="backend1",
),
pytest.param(
{
"group_name": "WebserverGroup2",
"api_url": "/http/upstreams/backend2",
},
id="backend2",
),
pytest.param(
{
"group_name": "WebserverGroup3",
"api_url": "/stream/upstreams/tcp-backend",
},
id="tcp-backend",
),
],
)
def test_aws_scale_down(self, cli_arguments, autoscaling_client, test_data):
desired_capacity = 1
group_name = get_aws_group_name(autoscaling_client, test_data['group_name'])
group_name = get_aws_group_name(autoscaling_client, test_data["group_name"])
scale_aws_group(autoscaling_client, group_name, desired_capacity)
wait_for_changes_in_aws(autoscaling_client, group_name, desired_capacity)
wait_for_changes_in_api(f"{cli_arguments.nginx_api}/{NGINX_API_VERSION}{test_data['api_url']}",
desired_capacity)
wait_for_changes_in_api(
f"{cli_arguments.nginx_api}/{NGINX_API_VERSION}{test_data['api_url']}",
desired_capacity,
)
resp = requests.get(f"{cli_arguments.nginx_api}/{NGINX_API_VERSION}{test_data['api_url']}")
nginx_upstream = json.loads(resp.text)
assert len(nginx_upstream['peers']) == desired_capacity,\
f"Expected {desired_capacity} servers, found: {nginx_upstream['peers']}"
assert (
len(nginx_upstream["peers"]) == desired_capacity
), f"Expected {desired_capacity} servers, found: {nginx_upstream['peers']}"

0 comments on commit d551469

Please sign in to comment.