-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert Athena Sample DAG to System Test (#24058)
- Loading branch information
Showing
9 changed files
with
589 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
.. Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
.. http://www.apache.org/licenses/LICENSE-2.0 | ||
.. Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
Example DAGs | ||
============ | ||
|
||
You can learn how to use Amazon AWS integrations by analyzing the source code of the example DAGs: | ||
|
||
* `Amazon AWS <https://github.com/apache/airflow/tree/main/airflow/providers/amazon/aws/example_dags>`__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. |
144 changes: 144 additions & 0 deletions
144
tests/providers/amazon/aws/system/utils/test_helpers.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. | ||
|
||
""" | ||
This module contains the unit tests for the helper methods included in the Amazon System Tests found at | ||
tests/system/providers/amazon/aws/utils/__init__.py | ||
""" | ||
import io | ||
import os | ||
import sys | ||
from unittest.mock import ANY, patch | ||
|
||
import pytest | ||
|
||
from tests.system.providers.amazon.aws import utils | ||
from tests.system.providers.amazon.aws.utils import ( | ||
DEFAULT_ENV_ID_LEN, | ||
DEFAULT_ENV_ID_PREFIX, | ||
ENV_ID_ENVIRON_KEY, | ||
INVALID_ENV_ID_MSG, | ||
LOWERCASE_ENV_ID_MSG, | ||
NO_VALUE_MSG, | ||
_validate_env_id, | ||
set_env_id, | ||
) | ||
|
||
try: | ||
from moto import mock_ssm | ||
except ImportError: | ||
mock_ssm = None | ||
|
||
TEST_NAME: str = 'example_test' | ||
ANY_STR: str = 'any' | ||
|
||
ENV_VALUE: str = 'foo' | ||
SSM_VALUE: str = 'bar' | ||
DEFAULT_VALUE: str = 'baz' | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def provide_test_name(): | ||
with patch.object(utils, '_get_test_name', return_value=TEST_NAME) as name: | ||
yield name | ||
|
||
|
||
@pytest.mark.skipif(mock_ssm is None, reason='mock_ssm package not present') | ||
@mock_ssm | ||
class TestAmazonSystemTestHelpers: | ||
FETCH_VARIABLE_TEST_CASES = [ | ||
# Format is: | ||
# (Environment Variable value, Fetched SSM value, Provided Default value, Expected Result) | ||
(ENV_VALUE, SSM_VALUE, DEFAULT_VALUE, ENV_VALUE), | ||
(ENV_VALUE, SSM_VALUE, None, ENV_VALUE), | ||
(ENV_VALUE, None, DEFAULT_VALUE, ENV_VALUE), | ||
(ENV_VALUE, None, None, ENV_VALUE), | ||
(None, SSM_VALUE, DEFAULT_VALUE, SSM_VALUE), | ||
(None, SSM_VALUE, None, SSM_VALUE), | ||
(None, None, DEFAULT_VALUE, DEFAULT_VALUE), | ||
# For the (None, None, None ) test case, see: test_fetch_variable_no_value_found_raises_exception | ||
] | ||
|
||
@pytest.mark.parametrize( | ||
'env_value, ssm_value, default_value, expected_result', FETCH_VARIABLE_TEST_CASES | ||
) | ||
@patch.object(os, 'getenv') | ||
def test_fetch_variable_success( | ||
self, mock_getenv, env_value, ssm_value, default_value, expected_result | ||
) -> None: | ||
mock_getenv.return_value = env_value if env_value else ssm_value | ||
|
||
result = utils.fetch_variable(ANY, default_value) if default_value else utils.fetch_variable(ANY_STR) | ||
|
||
assert result == expected_result | ||
|
||
def test_fetch_variable_no_value_found_raises_exception(self): | ||
# This would be the (None, None, None) test case from above. | ||
with pytest.raises(ValueError) as raised_exception: | ||
utils.fetch_variable(ANY_STR) | ||
|
||
assert NO_VALUE_MSG.format(key=ANY_STR) in str(raised_exception.value) | ||
|
||
ENV_ID_TEST_CASES = [ | ||
# Happy Cases | ||
('ABCD', True), | ||
('AbCd', True), | ||
('abcd', True), | ||
('ab12', True), | ||
# Failure Cases | ||
# Must be alphanumeric | ||
('not_alphanumeric', False), | ||
# Can not be empty | ||
('', False), | ||
# Must start with a letter | ||
('1234', False), | ||
('12ab', False), | ||
('12AB', False), | ||
('12Ab', False), | ||
] | ||
|
||
@pytest.mark.parametrize('env_id, is_valid', ENV_ID_TEST_CASES) | ||
def test_validate_env_id_success(self, env_id, is_valid): | ||
if is_valid: | ||
captured_output = io.StringIO() | ||
sys.stdout = captured_output | ||
|
||
result = _validate_env_id(env_id) | ||
sys.stdout = sys.__stdout__ | ||
|
||
assert result == env_id.lower() | ||
assert result.isalnum() | ||
if not result == env_id: | ||
assert LOWERCASE_ENV_ID_MSG in captured_output.getvalue() | ||
else: | ||
with pytest.raises(ValueError) as raised_exception: | ||
_validate_env_id(env_id) | ||
|
||
assert INVALID_ENV_ID_MSG in str(raised_exception.value) | ||
|
||
def test_set_env_id_generates_if_required(self): | ||
# No environment variable nor SSM value has been found | ||
result = set_env_id() | ||
|
||
assert len(result) == DEFAULT_ENV_ID_LEN + len(DEFAULT_ENV_ID_PREFIX) | ||
assert result.isalnum() | ||
assert result.islower() | ||
|
||
def test_set_env_id_exports_environment_variable(self): | ||
env_id = set_env_id() | ||
|
||
assert os.environ[ENV_ID_ENVIRON_KEY] == env_id |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
--> | ||
|
||
# Amazon provider system tests | ||
|
||
## Tests structure | ||
|
||
All AWS-related system tests are located inside `tests/system/providers/amazon/aws/`. | ||
In this directory you will find test files in the form of Example DAGs, one DAG per file. | ||
Each test should be self-contained but in the case where additional resources are required, | ||
they can be found in the `resources` directory on the same level as tests or noted in the | ||
test's docstring. Each test file should start with prefix `example_*`. | ||
|
||
Example directory structure: | ||
|
||
``` | ||
tests/system/providers/amazon/aws | ||
├── resources | ||
│ ├── example_athena_data.csv | ||
│ └── example_sagemaker_constants.py | ||
├── example_athena.py | ||
├── example_batch.py | ||
. | ||
├── example_step_functions.py | ||
└── * | ||
``` | ||
|
||
## Initial configuration | ||
|
||
Each test requires some environment variables. Check how to set them up on your | ||
operating system, but on UNIX-based operating systems `export NAME_OF_ENV_VAR=value` | ||
should work. To confirm that it is set up correctly, run `echo $NAME_OF_ENV_VAR` | ||
which will display its value. | ||
|
||
When manually running tests using pytest, you can define them inline with the command. | ||
For example: | ||
|
||
```commandline | ||
NAME_OF_ENV_VAR=value pytest --system amazon tests/system/providers/amazon/aws/example_test.py | ||
``` | ||
|
||
### Required environment variables | ||
|
||
- `SYSTEM_TESTS_ENV_ID` - AWS System Tests will generate and export this value if one does not exist. | ||
|
||
An environment ID is a unique value across different executions of system tests. This | ||
is needed because the CI environment may run the tests on various versions of Airflow | ||
in parallel. If this is the case, the value of this variable ensures that resources | ||
that are created during the tests will not interfere with each other. | ||
|
||
The value is used as part of the name for resources which have different requirements. | ||
For example: an S3 bucket name can not use underscores, but an Athena table name can not | ||
use hyphens. In order to minimize conflicts, this variable should be a randomized value | ||
using only lowercase letters A-Z and digits 0-9, and start with a letter. | ||
|
||
## Settings for specific tests | ||
|
||
Amazon system test files are designed to be as self-contained as possible. They will contain | ||
any sample data and configuration values which are required, and they will create and tear | ||
down any required infrastructure. Some tests will require an IAM Role ARN, and the requirements | ||
for those Roles should be documented inside the docstring of the test file. |
Oops, something went wrong.