Skip to content

Commit 67a5067

Browse files
authored
added formatting, makefile, updated project structure (#15)
* comment resolution * minor fix * removed build on push
1 parent 8763b03 commit 67a5067

File tree

13 files changed

+585
-267
lines changed

13 files changed

+585
-267
lines changed

.github/workflows/main.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ on:
1515
# disabled pipeline for push events, as we want to run the pipeline only on a schedule or manually
1616
# push:
1717
# branches:
18-
# - pytest-plugin-fork
18+
# - pytest-plugin
1919

2020
name: Terraform Tests
2121
jobs:
@@ -27,7 +27,7 @@ jobs:
2727
with:
2828
submodules: 'true'
2929
- id: set-matrix
30-
run: echo "matrix=$(python get-services.py ${{ github.event.inputs.services || 'ls-community' }})" >> $GITHUB_OUTPUT
30+
run: echo "matrix=$(python -m terraform_pytest.get-services ${{ github.event.inputs.services || 'ls-community' }})" >> $GITHUB_OUTPUT
3131
outputs:
3232
matrix: ${{ steps.set-matrix.outputs.matrix }}
3333

@@ -69,16 +69,16 @@ jobs:
6969
run: |
7070
cd terraform-provider-aws && go mod vendor
7171
cd ../
72-
python3 main.py patch
72+
python -m terraform_pytest.main patch
7373
7474
- name: Build ${{ matrix.service }} Binary
7575
run: |
76-
python main.py build -s ${{ matrix.service }}
76+
python -m terraform_pytest.main build -s ${{ matrix.service }}
7777
ls -la terraform-provider-aws/test-bin
7878
7979
- name: Run ${{ matrix.service }} Tests
8080
run: |
81-
pytest --junitxml=target/reports/pytest.xml terraform-provider-aws/internal/service/${{ matrix.service }} -s -v --ls-start --ls-image ${{ github.event.inputs.localstack-image || 'localstack/localstack:latest' }}
81+
python -m pytest --junitxml=target/reports/pytest.xml terraform-provider-aws/internal/service/${{ matrix.service }} -s -v --ls-start --ls-image ${{ github.event.inputs.localstack-image || 'localstack/localstack:latest' }}
8282
8383
- name: Publish ${{ matrix.service }} Test Results
8484
uses: EnricoMi/publish-unit-test-result-action@v2

Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
3+
VENV_BIN ?= python3 -m venv
4+
VENV_DIR ?= .venv
5+
PIP_CMD ?= pip3
6+
7+
ifeq ($(OS), Windows_NT)
8+
VENV_ACTIVATE = $(VENV_DIR)/Scripts/activate
9+
else
10+
VENV_ACTIVATE = $(VENV_DIR)/bin/activate
11+
endif
12+
13+
$(VENV_ACTIVATE):
14+
test -d $(VENV_DIR) || $(VENV_BIN) $(VENV_DIR)
15+
$(VENV_RUN); $(PIP_CMD) install --upgrade pip setuptools wheel plux
16+
touch $(VENV_ACTIVATE)
17+
18+
VENV_RUN = . $(VENV_ACTIVATE)
19+
20+
venv: $(VENV_ACTIVATE) ## Create a new (empty) virtual environment
21+
22+
install:
23+
$(VENV_RUN); $(PIP_CMD) install -r requirements.txt
24+
25+
format:
26+
$(VENV_RUN); python -m isort .; python -m black .

README.md

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,30 @@ This is a test runner for localstack and terraform. It will run a test cases fro
55
Purpose of this project is to externalize the test cases from the localstack repo and run them against localstack to gather parity metrics.
66

77
## Installation
8-
1. Clone the repository
9-
2. Run `python -m virtualenv venv` to create a virtual environment
10-
3. Run `source venv/bin/activate` to activate the virtual environment
11-
4. Run `pip install -r requirements.txt` to install the dependencies
8+
1. Clone the repository with submodules`
9+
2. Run `make venv` to create a virtual environment
10+
3. Run `make install` to install the dependencies
1211

1312
## How to run?
14-
1. Run `python main.py patch` to apply the patch to the terraform provider aws
15-
2. Now you are ready to use `pytest` commands to list and run test cases from golang
13+
1. Run `python -m terraform_pytest.main patch` to apply the patch to the terraform provider aws
14+
2. Run `python -m terraform_pytest.main build -s s3` to build testing binary for the golang module
15+
3Now you are ready to use `python -m pytest` commands to list and run test cases from golang
1616

1717
## How to run test cases?
18-
- To list down all the test case from a specific service, run `pytest terraform-provider-aws/internal/service/<service> --collect-only -q`
19-
- To run a specific test case, run `pytest terraform-provider-aws/internal/service/<service>/<test-file> -k <test-case-name> --ls-start` or `pytest terraform-provider-aws/internal/service/<service>/<test-file>::<test-case-name> --ls-start`
20-
- Additional environment variables can be added by appending it in the start of the command, i.e. `AWS_ALTERNATE_REGION='us-west-2' pytest terraform-provider-aws/internal/service/<service>/<test-file>::<test-case-name> --ls-start`
18+
- To list down all the test case from a specific service, run `python -m pytest terraform-provider-aws/internal/service/<service> --collect-only -q`
19+
- To run a specific test case, run `python -m pytest terraform-provider-aws/internal/service/<service>/<test-file> -k <test-case-name> --ls-start` or `python -m pytest terraform-provider-aws/internal/service/<service>/<test-file>::<test-case-name> --ls-start`
20+
- Additional environment variables can be added by appending it in the start of the command, i.e. `AWS_ALTERNATE_REGION='us-west-2' python -m pytest terraform-provider-aws/internal/service/<service>/<test-file>::<test-case-name> --ls-start`
2121

2222
## Default environment variables
23-
- **TF_LOG**: ``debug``,
24-
- **TF_ACC**: ``1``,
25-
- **AWS_ACCESS_KEY_ID**: ``test``,
26-
- **AWS_SECRET_ACCESS_KEY**: ``test``,
27-
- **AWS_DEFAULT_REGION**: ``'us-east-1``'
23+
- **TF_ACC**: `1`
24+
- **AWS_ACCESS_KEY_ID**: `test`
25+
- **AWS_SECRET_ACCESS_KEY**: `test`
26+
- **AWS_DEFAULT_REGION**: `us-west-1`
27+
- **AWS_ALTERNATE_ACCESS_KEY_ID**: `test`
28+
- **AWS_ALTERNATE_SECRET_ACCESS_KEY**: `test`
29+
- **AWS_ALTERNATE_SECRET_ACCESS_KEY**: `test`
30+
- **AWS_ALTERNATE_REGION**: `us-east-2`
31+
- **AWS_THIRD_REGION**: `eu-west-1`
2832

2933
## Options
3034
- `--ls-start`: Start localstack instance before running the test cases

conftest.py

Lines changed: 74 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,37 @@
1+
import os
12
import re
2-
import pytest
3+
from os.path import dirname, realpath, relpath
4+
from pathlib import Path
5+
36
import docker
7+
import pytest
48
import requests
59
from requests.adapters import HTTPAdapter, Retry
6-
from pathlib import Path
7-
import os
8-
from os.path import realpath, relpath, dirname
9-
from utils import execute_command, build_test_bin
10+
11+
from terraform_pytest.utils import execute_command
1012

1113

1214
def pytest_addoption(parser):
1315
parser.addoption(
14-
'--ls-image', action='store', default='localstack/localstack:latest', help='Base URL for the API tests'
16+
"--ls-image",
17+
action="store",
18+
default="localstack/localstack:latest",
19+
help="Base URL for the API tests",
1520
)
1621
parser.addoption(
17-
'--ls-start', action='store_true', default=False, help='Start localstack service'
22+
"--ls-start", action="store_true", default=False, help="Start localstack service"
1823
)
1924

2025

2126
def pytest_collect_file(parent, file_path):
22-
if file_path.suffix == '.go' and file_path.name.endswith('_test.go'):
27+
if file_path.suffix == ".go" and file_path.name.endswith("_test.go"):
2328
return GoFile.from_parent(parent, path=file_path)
2429

2530

2631
class GoFile(pytest.File):
2732
def collect(self):
2833
raw = self.path.open().read()
29-
fa = re.findall(r'^(func (TestAcc.*))\(.*\).*', raw, re.MULTILINE)
34+
fa = re.findall(r"^(func (TestAcc.*))\(.*\).*", raw, re.MULTILINE)
3035
for _, name in fa:
3136
yield GoItem.from_parent(self, name=name)
3237

@@ -41,41 +46,43 @@ def runtest(self):
4146
service = service_path.split(os.sep)[-1]
4247

4348
env = dict(os.environ)
44-
env.update({
45-
'TF_ACC': '1',
46-
'AWS_ACCESS_KEY_ID': 'test',
47-
'AWS_SECRET_ACCESS_KEY': 'test',
48-
'AWS_DEFAULT_REGION': 'us-west-2',
49-
'AWS_ALTERNATE_ACCESS_KEY_ID': 'test',
50-
'AWS_ALTERNATE_SECRET_ACCESS_KEY': 'test',
51-
'AWS_ALTERNATE_SECRET_ACCESS_KEY': 'test',
52-
'AWS_ALTERNATE_REGION': 'us-east-2',
53-
'AWS_THIRD_REGION': 'eu-west-1',
54-
})
49+
env.update(
50+
{
51+
"TF_ACC": "1",
52+
"AWS_ACCESS_KEY_ID": "test",
53+
"AWS_SECRET_ACCESS_KEY": "test",
54+
"AWS_DEFAULT_REGION": "us-west-1",
55+
"AWS_ALTERNATE_ACCESS_KEY_ID": "test",
56+
"AWS_ALTERNATE_SECRET_ACCESS_KEY": "test",
57+
"AWS_ALTERNATE_SECRET_ACCESS_KEY": "test",
58+
"AWS_ALTERNATE_REGION": "us-east-2",
59+
"AWS_THIRD_REGION": "eu-west-1",
60+
}
61+
)
5562

5663
cmd = [
57-
f'./test-bin/{service}.test',
58-
'-test.v',
59-
'-test.parallel=1',
60-
'-test.count=1',
61-
'-test.timeout=60m',
62-
f'-test.run={self.name}',
64+
f"./test-bin/{service}.test",
65+
"-test.v",
66+
"-test.parallel=1",
67+
"-test.count=1",
68+
"-test.timeout=60m",
69+
f"-test.run={self.name}",
6370
]
6471
return_code, stdout = execute_command(cmd, env, tf_root_path)
6572
if return_code != 0:
6673
raise GoException(returncode=return_code, stderr=stdout)
6774

6875
def repr_failure(self, excinfo, **kwargs):
6976
if isinstance(excinfo.value, GoException):
70-
return '\n'.join(
77+
return "\n".join(
7178
[
72-
f'Execution failed with return code: {excinfo.value.returncode}',
73-
f'Failure Reason:\n{excinfo.value.stderr}',
79+
f"Execution failed with return code: {excinfo.value.returncode}",
80+
f"Failure Reason:\n{excinfo.value.stderr}",
7481
]
7582
)
7683

7784
def reportinfo(self):
78-
return self.path, 0, f'Test Case: {self.name}'
85+
return self.path, 0, f"Test Case: {self.name}"
7986

8087

8188
class ReprCrash:
@@ -97,10 +104,10 @@ def pytest_runtest_makereport(item, call):
97104
outcome = yield
98105
report = outcome.get_result()
99106
if report.failed:
100-
splits = report.longrepr.split('\n', 1)
107+
splits = report.longrepr.split("\n", 1)
101108
longrepr = LongRepr(splits[0], splits[1])
102-
delattr(report, 'longrepr')
103-
setattr(report, 'longrepr', longrepr)
109+
delattr(report, "longrepr")
110+
setattr(report, "longrepr", longrepr)
104111

105112

106113
class GoException(Exception):
@@ -111,58 +118,64 @@ def __init__(self, returncode, stderr):
111118

112119
def _docker_service_health(client):
113120
if not client.ping():
114-
print('\nPlease start docker daemon and try again')
115-
raise Exception('Docker is not running')
121+
print("\nPlease start docker daemon and try again")
122+
raise Exception("Docker is not running")
116123

117124

118125
def _start_docker_container(client, config, localstack_image):
119-
env_vars = ['DEBUG=1', 'PROVIDER_OVERRIDE_S3=asf']
126+
env_vars = ["DEBUG=1", "PROVIDER_OVERRIDE_S3=asf"]
120127
port_mappings = {
121-
'53/tcp': ('127.0.0.1', 53),
122-
'53/udp': ('127.0.0.1', 53),
123-
'443': ('127.0.0.1', 443),
124-
'4566': ('127.0.0.1', 4566),
125-
'4571': ('127.0.0.1', 4571),
128+
"53/tcp": ("127.0.0.1", 53),
129+
"53/udp": ("127.0.0.1", 53),
130+
"443": ("127.0.0.1", 443),
131+
"4566": ("127.0.0.1", 4566),
132+
"4571": ("127.0.0.1", 4571),
126133
}
127-
volumes = ['/var/run/docker.sock:/var/run/docker.sock']
128-
localstack_container = client.containers.run(image=localstack_image, detach=True, ports=port_mappings,
129-
name='localstack_main', volumes=volumes, auto_remove=True,
130-
environment=env_vars)
131-
setattr(config, 'localstack_container_id', localstack_container.id)
134+
volumes = ["/var/run/docker.sock:/var/run/docker.sock"]
135+
localstack_container = client.containers.run(
136+
image=localstack_image,
137+
detach=True,
138+
ports=port_mappings,
139+
name="localstack_main",
140+
volumes=volumes,
141+
auto_remove=True,
142+
environment=env_vars,
143+
)
144+
setattr(config, "localstack_container_id", localstack_container.id)
132145

133146

134147
def _stop_docker_container(client, config):
135-
client.containers.get(getattr(config, 'localstack_container_id')).stop()
136-
print('LocalStack is stopped')
148+
client.containers.get(getattr(config, "localstack_container_id")).stop()
149+
print("LocalStack is stopped")
137150

138151

139152
def _localstack_health_check():
140-
localstack_health_url = 'http://localhost:4566/health'
153+
localstack_health_url = "http://localhost:4566/health"
141154
session = requests.Session()
142155
retry = Retry(connect=3, backoff_factor=2)
143156
adapter = HTTPAdapter(max_retries=retry)
144-
session.mount('http://', adapter)
145-
session.mount('https://', adapter)
157+
session.mount("http://", adapter)
158+
session.mount("https://", adapter)
146159
session.get(localstack_health_url)
147160
session.close()
148161

149162

150163
def _pull_docker_image(client, localstack_image):
151164
docker_image_list = client.images.list(name=localstack_image)
152165
if len(docker_image_list) == 0:
153-
print(f'Pulling image {localstack_image}')
166+
print(f"Pulling image {localstack_image}")
154167
client.images.pull(localstack_image)
155168
docker_image_list = client.images.list(name=localstack_image)
156-
print(f'Using LocalStack image: {docker_image_list[0].id}')
169+
print(f"Using LocalStack image: {docker_image_list[0].id}")
157170

158171

159172
def pytest_configure(config):
160-
is_collect_only = config.getoption(name='--collect-only')
161-
is_localstack_start = config.getoption(name='--ls-start')
162-
localstack_image = config.getoption(name='--ls-image')
173+
is_collect_only = config.getoption(name="--collect-only")
174+
is_localstack_start = config.getoption(name="--ls-start")
175+
localstack_image = config.getoption(name="--ls-image")
163176

164177
if not is_collect_only and is_localstack_start:
165-
print('\nStarting LocalStack...')
178+
print("\nStarting LocalStack...")
166179

167180
client = docker.from_env()
168181
_docker_service_health(client)
@@ -171,15 +184,15 @@ def pytest_configure(config):
171184
_localstack_health_check()
172185
client.close()
173186

174-
print('LocalStack is ready...')
187+
print("LocalStack is ready...")
175188

176189

177190
def pytest_unconfigure(config):
178-
is_collect_only = config.getoption(name='--collect-only')
179-
is_localstack_start = config.getoption(name='--ls-start')
191+
is_collect_only = config.getoption(name="--collect-only")
192+
is_localstack_start = config.getoption(name="--ls-start")
180193

181194
if not is_collect_only and is_localstack_start:
182-
print('\nStopping LocalStack...')
195+
print("\nStopping LocalStack...")
183196
client = docker.from_env()
184197
_stop_docker_container(client, config)
185198
client.close()

docker-compose.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)