Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit d631fdf

Browse files
Implementado alguns cenários de testes de unidade e mocks de serviços e recursos como SQS, boto, redis, Mysql
1 parent 236db4b commit d631fdf

File tree

34 files changed

+1127
-87
lines changed

34 files changed

+1127
-87
lines changed

examples/lambda_api/app.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ def alive():
7070
application/json:
7171
schema: HealthCheckSchema
7272
"""
73-
# body = {"app": "I'm alive!"}
74-
# return http_helper.create_response(body=body, status_code=200)
7573
service = HealthCheckService()
7674
service.add_check("self", SelfConnectionHealthCheck(logger, config), [])
7775
service.add_check("mysql", MysqlConnectionHealthCheck(logger, config), ["db"])

examples/lambda_api/env/development.env

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ LOCAL_API_SERVER=http://localhost:5000
1212
LOCAL_API_SERVER_DESCRIPTION=Development server
1313
REDIS_HOST=redis
1414
REDIS_PORT=6379
15-
DB_HOST = mysql
16-
DB_USER = root
17-
DB_PASSWORD = store
18-
DB = store
15+
DB_HOST=mysql
16+
DB_USER=root
17+
DB_PASSWORD=store
18+
DB=store
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import os
2+
from time import sleep
3+
4+
import boto3
5+
6+
from chalicelib.logging import get_logger
7+
8+
logger = get_logger()
9+
10+
_CONNECTION = False
11+
_RETRY_COUNT = 0
12+
_MAX_RETRY_ATTEMPTS = 3
13+
14+
15+
def reset():
16+
global _CONNECTION
17+
_CONNECTION = False
18+
19+
20+
def get_connection(connect=True, retry=False):
21+
global _CONNECTION, _RETRY_COUNT, _MAX_RETRY_ATTEMPTS
22+
if not _CONNECTION:
23+
connection = None
24+
try:
25+
profile = os.environ['AWS_PROFILE'] if 'AWS_PROFILE' in os.environ else None
26+
logger.info('profile: {}'.format(profile))
27+
if profile:
28+
session = boto3.session.Session(profile_name=profile)
29+
connection = session.resource(
30+
'dynamodb',
31+
region_name="sa-east-1"
32+
)
33+
else:
34+
connection = boto3.resource(
35+
'dynamodb',
36+
region_name="sa-east-1"
37+
)
38+
39+
_CONNECTION = connection
40+
_RETRY_COUNT = 0
41+
logger.info('Connected')
42+
43+
except Exception as err:
44+
if _RETRY_COUNT == _MAX_RETRY_ATTEMPTS:
45+
_RETRY_COUNT = 0
46+
logger.error(err)
47+
return connection
48+
else:
49+
logger.error(err)
50+
logger.info('Trying to reconnect... {}'.format(_RETRY_COUNT))
51+
52+
sleep(0.1)
53+
# retry
54+
if not retry:
55+
_RETRY_COUNT += 1
56+
return get_connection(True)
57+
else:
58+
connection = _CONNECTION
59+
60+
return connection

examples/lambda_api/lambda_app/events/aws/sqs.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
_RETRY_COUNT = 0
1010
_MAX_RETRY_ATTEMPTS = 3
1111

12+
1213
class SQSEvents:
1314

1415
def __init__(self, logger=None, config=None):
@@ -18,21 +19,24 @@ def __init__(self, logger=None, config=None):
1819
self.config = config if config is not None else get_config()
1920
# last_exception
2021
self.exception = None
22+
# session
23+
self.profile = os.environ['AWS_PROFILE'] if 'AWS_PROFILE' in os.environ else None
24+
self.session = boto3.session.Session(profile_name=self.profile)
2125

2226
def connect(self, retry=False):
2327
global _RETRY_COUNT, _MAX_RETRY_ATTEMPTS
2428
connection = None
2529
try:
2630
endpoint_url = self.config.SQS_ENDPOINT
27-
profile = os.environ['AWS_PROFILE'] if 'AWS_PROFILE' in os.environ else None
31+
2832
queue_name = os.path.basename(os.environ['APP_QUEUE']) if 'APP_QUEUE' in os.environ else None
29-
self.logger.info('SQSEvents - profile: {}'.format(profile))
33+
self.logger.info('SQSEvents - profile: {}'.format(self.profile))
3034
self.logger.info('SQSEvents - endpoint_url: {}'.format(endpoint_url))
3135
self.logger.info('SQSEvents - queue_name: {}'.format(queue_name))
3236
self.logger.info('SQSEvents - self.config.REGION_NAME: {}'.format(self.config.REGION_NAME))
3337

34-
if profile:
35-
session = boto3.session.Session(profile_name=profile)
38+
if self.profile:
39+
session = self.session
3640
connection = session.resource(
3741
'sqs',
3842
endpoint_url=endpoint_url,
@@ -70,10 +74,12 @@ def connect(self, retry=False):
7074
if not retry:
7175
_RETRY_COUNT += 1
7276
# Fix para tratar diff entre docker/local
73-
if self.config.SQS_ENDPOINT == 'http://0.0.0.0:4566' or self.config.SQS_ENDPOINT == 'http://localstack:4566':
77+
if self.config.SQS_ENDPOINT == 'http://0.0.0.0:4566' or \
78+
self.config.SQS_ENDPOINT == 'http://localstack:4566':
7479
old_value = self.config.SQS_ENDPOINT
7580
self.config.SQS_ENDPOINT = 'http://localhost:4566'
76-
self.logger.info('Changing the endpoint from {} to {}'.format(old_value, self.config.SQS_ENDPOINT))
81+
self.logger.info(
82+
'Changing the endpoint from {} to {}'.format(old_value, self.config.SQS_ENDPOINT))
7783
connection = self.connect(retry=True)
7884
return connection
7985

@@ -166,7 +172,3 @@ def delete_queue(self, queue_name):
166172
result = False
167173

168174
return result
169-
170-
171-
172-

examples/lambda_api/requirements-tests.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
serverless-wsgi
12
unittest-data-provider
23
coverage
34
coverage2clover

examples/lambda_api/server.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from gevent.pywsgi import WSGIServer
2+
from app import app
3+
4+
http_server = WSGIServer(('0.0.0.0', 5000), app)
5+
http_server.serve_forever()

examples/lambda_api/tests/component/helpers/events/aws/sqs_helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22

3-
from flask_app.events.aws.sqs import SQSEvents
3+
from lambda_app.events.aws.sqs import SQSEvents
44

55

66
class SQSHelper:

examples/lambda_api/tests/component/test_app.py

Lines changed: 89 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
import os
22
import unittest
33

4-
from tests.component.componenttestutils import BaseComponentTestCase
4+
import serverless_wsgi
5+
56
from unittest_data_provider import data_provider
6-
from flask_app.config import get_config
7-
from flask_app.logging import get_logger
7+
from lambda_app import APP_NAME, APP_VERSION
8+
from lambda_app.repositories.mysql.product_repository import ProductRepository
9+
from tests import ROOT_DIR
10+
from tests.component.componenttestutils import BaseComponentTestCase
11+
from lambda_app.config import get_config
12+
from lambda_app.logging import get_logger
13+
14+
from tests.component.helpers.database.mysql_helper import MySQLHelper
815
from tests.component.helpers.events.aws.sqs_helper import SQSHelper
916
from tests.unit.helpers.aws.sqs_helper import get_sqs_event_sample
1017
from tests.unit.mocks.aws_mocks.aws_lambda_mock import FakeLambdaContext
18+
from tests.unit.mocks.lambda_event_mocks.request_event import create_aws_api_gateway_proxy_request_event
1119
from tests.unit.testutils import get_function_name
1220
import app
1321
import json
@@ -25,49 +33,92 @@ class AppTestCase(BaseComponentTestCase):
2533

2634
@classmethod
2735
def setUpClass(cls):
36+
BaseComponentTestCase.setUpClass()
2837
cls.CONFIG = get_config()
2938
cls.CONFIG.SQS_ENDPOINT = cls.SQS_LOCALSTACK
3039

3140
# fixture
3241
if cls.EXECUTE_FIXTURE:
3342
logger = get_logger()
43+
44+
logger.info("Fixture: MYSQL Database connection")
45+
logger.info("Fixture: drop table")
46+
47+
mysql_connection = MySQLHelper.get_connection()
48+
table_name = ProductRepository.BASE_TABLE
49+
cls.fixture_table(logger, mysql_connection, table_name)
50+
3451
logger.info('Fixture: create sqs queue')
3552

36-
# queue_url = cls.CONFIG.APP_QUEUE
37-
# cls.fixture_sqs(logger, queue_url)
38-
#
39-
# @classmethod
40-
# def fixture_sqs(cls, logger, queue_url):
41-
# queue_name = SQSHelper.get_queue_name(queue_url)
42-
# deleted = SQSHelper.delete_queue(queue_url)
43-
# if deleted:
44-
# logger.info(f'Deleting queue name: {queue_name}')
45-
#
46-
# attributes = {'DelaySeconds': '1'}
47-
# result = SQSHelper.create_queue(queue_url, attributes)
48-
# if result is not None:
49-
# logger.info(f'queue {queue_name} created')
50-
# else:
51-
# logger.error(f'queue {queue_name} not created')
52-
#
53-
# event = get_sqs_event_sample()
54-
# message = event['Records'][0]
55-
# SQSHelper.create_message(message, queue_url)
56-
# logger.info('created message: {}'.format(message))
57-
#
58-
# @data_provider(get_queue_message)
59-
# def test_sqs_handler(self, event):
60-
# self.logger.info('Running test: %s', get_function_name(__name__))
61-
# self.logger.info('Event: {}'.format(event))
62-
#
63-
# lambda_context = FakeLambdaContext()
64-
# try:
65-
# response = app.sqs_handler(event=event, context=lambda_context)
66-
# except Exception as err:
67-
# self.logger.error(err)
68-
# # response = app.sqs_handler(event=event)
69-
#
70-
# self.assertTrue(response)
53+
queue_url = cls.CONFIG.APP_QUEUE
54+
cls.fixture_sqs(logger, queue_url)
55+
56+
@classmethod
57+
def fixture_sqs(cls, logger, queue_url):
58+
queue_name = SQSHelper.get_queue_name(queue_url)
59+
deleted = SQSHelper.delete_queue(queue_url)
60+
if deleted:
61+
logger.info(f'Deleting queue name: {queue_name}')
62+
63+
attributes = {'DelaySeconds': '1'}
64+
result = SQSHelper.create_queue(queue_url, attributes)
65+
if result is not None:
66+
logger.info(f'queue {queue_name} created')
67+
else:
68+
logger.error(f'queue {queue_name} not created')
69+
70+
event = get_sqs_event_sample()
71+
message = event['Records'][0]
72+
SQSHelper.create_message(message, queue_url)
73+
logger.info('created message: {}'.format(message))
74+
75+
@classmethod
76+
def fixture_table(cls, logger, mysql_connection, table_name):
77+
dropped = MySQLHelper.drop_table(mysql_connection, table_name)
78+
if dropped:
79+
logger.info(f"Table dropped:: {table_name}")
80+
file_name = ROOT_DIR + f"tests/datasets/database/structure/mysql/create.table.store.{table_name}.sql"
81+
created = MySQLHelper.create_table(mysql_connection, table_name, file_name)
82+
if created:
83+
logger.info(f"Table created:: {table_name}")
84+
file_name = ROOT_DIR + f"tests/datasets/database/seeders/mysql/seeder.table.store.{table_name}.sql"
85+
populated = MySQLHelper.sow_table(mysql_connection, table_name, file_name)
86+
if populated:
87+
logger.info(f"Table populated:: {table_name}")
88+
89+
def test_index(self):
90+
self.logger.info('Running test: %s', get_function_name(__name__))
91+
92+
event = create_aws_api_gateway_proxy_request_event('GET', '/')
93+
context = FakeLambdaContext()
94+
95+
response = serverless_wsgi.handle_request(app.app, event, context)
96+
97+
self.assertTrue('statusCode' in response)
98+
self.assertTrue('body' in response)
99+
100+
body = json.loads(response['body'])
101+
self.logger.info(body)
102+
103+
self.assertTrue('app' in body)
104+
self.assertEqual(body['app'], "%s:%s" % (APP_NAME, APP_VERSION))
105+
106+
def test_alive(self):
107+
self.logger.info('Running test: %s', get_function_name(__name__))
108+
109+
event = create_aws_api_gateway_proxy_request_event('GET', '/alive')
110+
context = FakeLambdaContext()
111+
112+
response = serverless_wsgi.handle_request(app.app, event, context)
113+
114+
self.assertTrue('statusCode' in response)
115+
self.assertTrue('body' in response)
116+
117+
body = json.loads(response['body'])
118+
self.logger.info(body)
119+
120+
self.assertTrue('status' in body)
121+
self.assertTrue('entries' in body)
71122

72123

73124
if __name__ == '__main__':

examples/lambda_api/tests/component/test_lambda_app/events/aws/test_sqs.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import os
21
import unittest
32

43
from unittest_data_provider import data_provider
@@ -9,7 +8,6 @@
98
from tests.component.componenttestutils import BaseComponentTestCase
109
from tests.component.helpers.events.aws.sqs_helper import SQSHelper
1110
from tests.unit.helpers.events_helper import get_cancelamento_event
12-
from tests.unit.helpers.ocoren_helper import get_ocoren_cancelamento_sample
1311
from tests.unit.testutils import get_function_name
1412

1513

@@ -57,18 +55,22 @@ def fixture_sqs(cls, logger, queue_url):
5755
SQSHelper.create_message(message, queue_url)
5856
logger.info('created message: {}'.format(message))
5957

58+
def setUp(self):
59+
super().setUp()
60+
self.sqs = SQSEvents()
61+
6062
def test_connect(self):
6163
self.logger.info('Running test: %s', get_function_name(__name__))
62-
sqs = SQSEvents()
63-
connection = sqs.connect()
64+
connection = self.sqs.connect()
6465
self.assertIsNotNone(connection)
6566

6667
@data_provider(get_sqs_event_sample)
6768
def test_send_message(self, message):
6869
self.logger.info('Running test: %s', get_function_name(__name__))
69-
sqs = SQSEvents()
7070
queue_url = self.CONFIG.APP_QUEUE
71-
response = sqs.send_message(message, queue_url)
71+
response = self.sqs.send_message(message, queue_url)
72+
73+
self.logger.info(response)
7274

7375
self.assertIsNotNone(response)
7476
self.assertIsInstance(response, dict)

0 commit comments

Comments
 (0)