Skip to content

Commit

Permalink
initial e2e smoke test for Role resource
Browse files Browse the repository at this point in the history
Adds a CRUD e2e test for Role resources.

Signed-off-by: Jay Pipes <jaypipes@gmail.com>
  • Loading branch information
jaypipes committed Dec 7, 2021
1 parent 3759a3f commit ad94896
Show file tree
Hide file tree
Showing 14 changed files with 432 additions and 0 deletions.
4 changes: 4 additions & 0 deletions test/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
__pycache__/
*.py[cod]
**/bootstrap.yaml
**/bootstrap.pkl
34 changes: 34 additions & 0 deletions test/e2e/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

import pytest
from typing import Dict, Any
from pathlib import Path

from acktest.resources import load_resource_file

SERVICE_NAME = "iam"
CRD_GROUP = "iam.services.k8s.aws"
CRD_VERSION = "v1alpha1"

# PyTest marker for the current service
service_marker = pytest.mark.service(arg=SERVICE_NAME)

bootstrap_directory = Path(__file__).parent
resource_directory = Path(__file__).parent / "resources"

def load_resource(resource_name: str, additional_replacements: Dict[str, Any] = {}):
"""Overrides the default `load_resource_file` to access the specific resources
directory for the current service.
"""
return load_resource_file(resource_directory, resource_name, additional_replacements=additional_replacements)
32 changes: 32 additions & 0 deletions test/e2e/bootstrap_resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

"""Declares the structure of the bootstrapped resources and provides a loader
for them.
"""

from dataclasses import dataclass
from acktest.bootstrapping import Resources
from e2e import bootstrap_directory

@dataclass
class BootstrapResources(Resources):
pass

_bootstrap_resources = None

def get_bootstrap_resources(bootstrap_file_name: str = "bootstrap.pkl") -> BootstrapResources:
global _bootstrap_resources
if _bootstrap_resources is None:
_bootstrap_resources = BootstrapResources.deserialize(bootstrap_directory, bootstrap_file_name=bootstrap_file_name)
return _bootstrap_resources
Empty file added test/e2e/common/__init__.py
Empty file.
1 change: 1 addition & 0 deletions test/e2e/common/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ROLE_RESOURCE_PLURAL = 'roles'
51 changes: 51 additions & 0 deletions test/e2e/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

import os
import boto3
import pytest

from acktest import k8s


def pytest_addoption(parser):
parser.addoption("--runslow", action="store_true", default=False, help="run slow tests")


def pytest_configure(config):
config.addinivalue_line(
"markers", "canary: mark test to also run in canary tests"
)
config.addinivalue_line(
"markers", "service(arg): mark test associated with a given service"
)
config.addinivalue_line(
"markers", "slow: mark test as slow to run"
)

def pytest_collection_modifyitems(config, items):
if config.getoption("--runslow"):
return
skip_slow = pytest.mark.skip(reason="need --runslow option to run")
for item in items:
if "slow" in item.keywords:
item.add_marker(skip_slow)

# Provide a k8s client to interact with the integration test cluster
@pytest.fixture(scope='class')
def k8s_client():
return k8s._get_k8s_api_client()

@pytest.fixture(scope='module')
def iam_client():
return boto3.client('iam')
22 changes: 22 additions & 0 deletions test/e2e/replacement_values.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

"""Stores the values used by each of the integration tests for replacing the
IAM-specific test variables.
"""

from e2e.bootstrap_resources import get_bootstrap_resources


REPLACEMENT_VALUES = {
}
1 change: 1 addition & 0 deletions test/e2e/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
acktest @ git+https://github.com/aws-controllers-k8s/test-infra.git@8b21fd1a3374f506d35efe7426d5deed8b1bb1bf
9 changes: 9 additions & 0 deletions test/e2e/resources/role_simple.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: iam.services.k8s.aws/v1alpha1
kind: Role
metadata:
name: $ROLE_NAME
spec:
name: $ROLE_NAME
description: $ROLE_DESCRIPTION
maxSessionDuration: $MAX_SESSION_DURATION
assumeRolePolicyDocument: '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":["ec2.amazonaws.com"]},"Action":["sts:AssumeRole"]}]}'
102 changes: 102 additions & 0 deletions test/e2e/role.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

"""Utilities for working with Role resources"""

import datetime
import time

import boto3
import pytest

DEFAULT_WAIT_UNTIL_EXISTS_TIMEOUT_SECONDS = 60*10
DEFAULT_WAIT_UNTIL_EXISTS_INTERVAL_SECONDS = 15
DEFAULT_WAIT_UNTIL_DELETED_TIMEOUT_SECONDS = 60*10
DEFAULT_WAIT_UNTIL_DELETED_INTERVAL_SECONDS = 15


def wait_until_exists(
role_name: str,
timeout_seconds: int = DEFAULT_WAIT_UNTIL_EXISTS_TIMEOUT_SECONDS,
interval_seconds: int = DEFAULT_WAIT_UNTIL_EXISTS_INTERVAL_SECONDS,
) -> None:
"""Waits until a Role with a supplied name is returned from IAM GetRole
API.
Usage:
from e2e.role import wait_until_exists
wait_until_exists(role_name)
Raises:
pytest.fail upon timeout
"""
now = datetime.datetime.now()
timeout = now + datetime.timedelta(seconds=timeout_seconds)

while True:
if datetime.datetime.now() >= timeout:
pytest.fail(
"Timed out waiting for Role to exist "
"in IAM API"
)
time.sleep(interval_seconds)

latest = get(role_name)
if latest is not None:
break


def wait_until_deleted(
role_name: str,
timeout_seconds: int = DEFAULT_WAIT_UNTIL_DELETED_TIMEOUT_SECONDS,
interval_seconds: int = DEFAULT_WAIT_UNTIL_DELETED_INTERVAL_SECONDS,
) -> None:
"""Waits until a Role with a supplied ID is no longer returned from
the IAM API.
Usage:
from e2e.role import wait_until_deleted
wait_until_deleted(role_name)
Raises:
pytest.fail upon timeout
"""
now = datetime.datetime.now()
timeout = now + datetime.timedelta(seconds=timeout_seconds)

while True:
if datetime.datetime.now() >= timeout:
pytest.fail(
"Timed out waiting for Role to be "
"deleted in IAM API"
)
time.sleep(interval_seconds)

latest = get(role_name)
if latest is None:
break


def get(role_name):
"""Returns a dict containing the Role record from the IAM API.
If no such Role exists, returns None.
"""
c = boto3.client('iam')
try:
resp = c.get_role(RoleName=role_name)
return resp['Role']
except c.exceptions.NoSuchEntityException:
return None
39 changes: 39 additions & 0 deletions test/e2e/service_bootstrap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

"""Bootstraps the resources required to run the IAM integration tests.
"""

import logging

from acktest.bootstrapping import Resources, BootstrapFailureException
from acktest.bootstrapping.iam import Role
from acktest.bootstrapping.vpc import VPC
from e2e import bootstrap_directory
from e2e.bootstrap_resources import BootstrapResources

def service_bootstrap() -> Resources:
logging.getLogger().setLevel(logging.INFO)
resources = BootstrapResources()

try:
resources.bootstrap()
except BootstrapFailureException as ex:
exit(254)

return resources

if __name__ == "__main__":
config = service_bootstrap()
# Write config to current directory by default
config.serialize(bootstrap_directory)
30 changes: 30 additions & 0 deletions test/e2e/service_cleanup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

"""Cleans up the resources created by the bootstrapping process.
"""

import logging

from acktest.bootstrapping import Resources

from e2e import bootstrap_directory

def service_cleanup():
logging.getLogger().setLevel(logging.INFO)

resources = Resources.deserialize(bootstrap_directory)
resources.cleanup()

if __name__ == "__main__":
service_cleanup()
12 changes: 12 additions & 0 deletions test/e2e/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may
# not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.

0 comments on commit ad94896

Please sign in to comment.