Skip to content

Add pre-commit and fix issues #327

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

Merged
merged 1 commit into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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']}"