722 lines
24 KiB
Python
722 lines
24 KiB
Python
import json
|
|
from copy import deepcopy
|
|
from datetime import datetime
|
|
|
|
import boto3
|
|
import pytest
|
|
from botocore.exceptions import ClientError
|
|
|
|
from moto import mock_aws
|
|
|
|
expected_pipeline_details = {
|
|
"name": "test-pipeline",
|
|
"roleArn": "arn:aws:iam::123456789012:role/test-role",
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"runOrder": 1,
|
|
"configuration": {
|
|
"S3Bucket": "test-bucket",
|
|
"S3ObjectKey": "test-object",
|
|
},
|
|
"outputArtifacts": [{"name": "artifact"}],
|
|
"inputArtifacts": [],
|
|
}
|
|
],
|
|
},
|
|
{
|
|
"name": "Stage-2",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Approval",
|
|
"owner": "AWS",
|
|
"provider": "Manual",
|
|
"version": "1",
|
|
},
|
|
"runOrder": 1,
|
|
"configuration": {},
|
|
"outputArtifacts": [],
|
|
"inputArtifacts": [],
|
|
}
|
|
],
|
|
},
|
|
],
|
|
"version": 1,
|
|
}
|
|
|
|
|
|
@mock_aws
|
|
def test_create_pipeline():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
|
|
response = create_basic_codepipeline(client, "test-pipeline")
|
|
|
|
assert response["pipeline"] == expected_pipeline_details
|
|
assert response["tags"] == [{"key": "key", "value": "value"}]
|
|
|
|
|
|
@mock_aws
|
|
def test_create_pipeline_errors():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
client_iam = boto3.client("iam", region_name="us-east-1")
|
|
create_basic_codepipeline(client, "test-pipeline")
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
create_basic_codepipeline(client, "test-pipeline")
|
|
ex = e.value
|
|
assert ex.operation_name == "CreatePipeline"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "InvalidStructureException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "A pipeline with the name 'test-pipeline' already exists in account '123456789012'"
|
|
)
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_pipeline(
|
|
pipeline={
|
|
"name": "invalid-pipeline",
|
|
"roleArn": "arn:aws:iam::123456789012:role/not-existing",
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"runOrder": 1,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "CreatePipeline"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "InvalidStructureException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/not-existing"
|
|
)
|
|
|
|
wrong_role_arn = client_iam.create_role(
|
|
RoleName="wrong-role",
|
|
AssumeRolePolicyDocument=json.dumps(
|
|
{
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Effect": "Allow",
|
|
"Principal": {"Service": "s3.amazonaws.com"},
|
|
"Action": "sts:AssumeRole",
|
|
}
|
|
],
|
|
}
|
|
),
|
|
)["Role"]["Arn"]
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_pipeline(
|
|
pipeline={
|
|
"name": "invalid-pipeline",
|
|
"roleArn": wrong_role_arn,
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"runOrder": 1,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "CreatePipeline"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "InvalidStructureException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/wrong-role"
|
|
)
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.create_pipeline(
|
|
pipeline={
|
|
"name": "invalid-pipeline",
|
|
"roleArn": get_role_arn(),
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"runOrder": 1,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "CreatePipeline"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "InvalidStructureException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "Pipeline has only 1 stage(s). There should be a minimum of 2 stages in a pipeline"
|
|
)
|
|
|
|
|
|
@mock_aws
|
|
def test_get_pipeline():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
create_basic_codepipeline(client, "test-pipeline")
|
|
|
|
response = client.get_pipeline(name="test-pipeline")
|
|
|
|
assert response["pipeline"] == expected_pipeline_details
|
|
assert (
|
|
response["metadata"]["pipelineArn"]
|
|
== "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline"
|
|
)
|
|
assert isinstance(response["metadata"]["created"], datetime)
|
|
assert isinstance(response["metadata"]["updated"], datetime)
|
|
|
|
|
|
@mock_aws
|
|
def test_get_pipeline_errors():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.get_pipeline(name="not-existing")
|
|
ex = e.value
|
|
assert ex.operation_name == "GetPipeline"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "PipelineNotFoundException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "Account '123456789012' does not have a pipeline with name 'not-existing'"
|
|
)
|
|
|
|
|
|
@mock_aws
|
|
def test_update_pipeline():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
create_basic_codepipeline(client, "test-pipeline")
|
|
|
|
response = client.get_pipeline(name="test-pipeline")
|
|
created_time = response["metadata"]["created"]
|
|
updated_time = response["metadata"]["updated"]
|
|
|
|
response = client.update_pipeline(
|
|
pipeline={
|
|
"name": "test-pipeline",
|
|
"roleArn": get_role_arn(),
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"configuration": {
|
|
"S3Bucket": "different-bucket",
|
|
"S3ObjectKey": "test-object",
|
|
},
|
|
"outputArtifacts": [{"name": "artifact"}],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
"name": "Stage-2",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Approval",
|
|
"owner": "AWS",
|
|
"provider": "Manual",
|
|
"version": "1",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
)
|
|
|
|
assert response["pipeline"] == {
|
|
"name": "test-pipeline",
|
|
"roleArn": "arn:aws:iam::123456789012:role/test-role",
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"runOrder": 1,
|
|
"configuration": {
|
|
"S3Bucket": "different-bucket",
|
|
"S3ObjectKey": "test-object",
|
|
},
|
|
"outputArtifacts": [{"name": "artifact"}],
|
|
"inputArtifacts": [],
|
|
}
|
|
],
|
|
},
|
|
{
|
|
"name": "Stage-2",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Approval",
|
|
"owner": "AWS",
|
|
"provider": "Manual",
|
|
"version": "1",
|
|
},
|
|
"runOrder": 1,
|
|
"configuration": {},
|
|
"outputArtifacts": [],
|
|
"inputArtifacts": [],
|
|
}
|
|
],
|
|
},
|
|
],
|
|
"version": 2,
|
|
}
|
|
|
|
metadata = client.get_pipeline(name="test-pipeline")["metadata"]
|
|
assert metadata["created"] == created_time
|
|
assert metadata["updated"] > updated_time
|
|
|
|
|
|
@mock_aws
|
|
def test_update_pipeline_errors():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.update_pipeline(
|
|
pipeline={
|
|
"name": "not-existing",
|
|
"roleArn": get_role_arn(),
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"configuration": {
|
|
"S3Bucket": "test-bucket",
|
|
"S3ObjectKey": "test-object",
|
|
},
|
|
"outputArtifacts": [{"name": "artifact"}],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
"name": "Stage-2",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Approval",
|
|
"owner": "AWS",
|
|
"provider": "Manual",
|
|
"version": "1",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "UpdatePipeline"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "The account with id '123456789012' does not include a pipeline with the name 'not-existing'"
|
|
)
|
|
|
|
|
|
@mock_aws
|
|
def test_list_pipelines():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
name_1 = "test-pipeline-1"
|
|
create_basic_codepipeline(client, name_1)
|
|
name_2 = "test-pipeline-2"
|
|
create_basic_codepipeline(client, name_2)
|
|
|
|
response = client.list_pipelines()
|
|
|
|
assert len(response["pipelines"]) == 2
|
|
assert response["pipelines"][0]["name"] == name_1
|
|
assert response["pipelines"][0]["version"] == 1
|
|
assert isinstance(response["pipelines"][0]["created"], datetime)
|
|
assert isinstance(response["pipelines"][0]["updated"], datetime)
|
|
assert response["pipelines"][1]["name"] == name_2
|
|
assert response["pipelines"][1]["version"] == 1
|
|
assert isinstance(response["pipelines"][1]["created"], datetime)
|
|
assert isinstance(response["pipelines"][1]["updated"], datetime)
|
|
|
|
|
|
@mock_aws
|
|
def test_delete_pipeline():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
name = "test-pipeline"
|
|
create_basic_codepipeline(client, name)
|
|
assert len(client.list_pipelines()["pipelines"]) == 1
|
|
|
|
client.delete_pipeline(name=name)
|
|
|
|
assert len(client.list_pipelines()["pipelines"]) == 0
|
|
|
|
# deleting a not existing pipeline, should raise no exception
|
|
client.delete_pipeline(name=name)
|
|
|
|
|
|
@mock_aws
|
|
def test_list_tags_for_resource():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
name = "test-pipeline"
|
|
create_basic_codepipeline(client, name)
|
|
|
|
response = client.list_tags_for_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}"
|
|
)
|
|
assert response["tags"] == [{"key": "key", "value": "value"}]
|
|
|
|
|
|
@mock_aws
|
|
def test_list_tags_for_resource_errors():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.list_tags_for_resource(
|
|
resourceArn="arn:aws:codepipeline:us-east-1:123456789012:not-existing"
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "ListTagsForResource"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "The account with id '123456789012' does not include a pipeline with the name 'not-existing'"
|
|
)
|
|
|
|
|
|
@mock_aws
|
|
def test_tag_resource():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
name = "test-pipeline"
|
|
create_basic_codepipeline(client, name)
|
|
|
|
client.tag_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}",
|
|
tags=[{"key": "key-2", "value": "value-2"}],
|
|
)
|
|
|
|
response = client.list_tags_for_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}"
|
|
)
|
|
assert response["tags"] == [
|
|
{"key": "key", "value": "value"},
|
|
{"key": "key-2", "value": "value-2"},
|
|
]
|
|
|
|
|
|
@mock_aws
|
|
def test_tag_resource_errors():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
name = "test-pipeline"
|
|
create_basic_codepipeline(client, name)
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.tag_resource(
|
|
resourceArn="arn:aws:codepipeline:us-east-1:123456789012:not-existing",
|
|
tags=[{"key": "key-2", "value": "value-2"}],
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "TagResource"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "The account with id '123456789012' does not include a pipeline with the name 'not-existing'"
|
|
)
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.tag_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}",
|
|
tags=[{"key": "aws:key", "value": "value"}],
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "TagResource"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "InvalidTagsException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "Not allowed to modify system tags. System tags start with 'aws:'. msg=[Caller is an end user and not allowed to mutate system tags]"
|
|
)
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.tag_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}",
|
|
tags=[{"key": f"key-{i}", "value": f"value-{i}"} for i in range(50)],
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "TagResource"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "TooManyTagsException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== f"Tag limit exceeded for resource [arn:aws:codepipeline:us-east-1:123456789012:{name}]."
|
|
)
|
|
|
|
|
|
@mock_aws
|
|
def test_untag_resource():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
name = "test-pipeline"
|
|
create_basic_codepipeline(client, name)
|
|
|
|
response = client.list_tags_for_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}"
|
|
)
|
|
assert response["tags"] == [{"key": "key", "value": "value"}]
|
|
|
|
client.untag_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}",
|
|
tagKeys=["key"],
|
|
)
|
|
|
|
response = client.list_tags_for_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}"
|
|
)
|
|
assert len(response["tags"]) == 0
|
|
|
|
# removing a not existing tag should raise no exception
|
|
client.untag_resource(
|
|
resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}",
|
|
tagKeys=["key"],
|
|
)
|
|
|
|
|
|
@mock_aws
|
|
def test_untag_resource_errors():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
|
|
with pytest.raises(ClientError) as e:
|
|
client.untag_resource(
|
|
resourceArn="arn:aws:codepipeline:us-east-1:123456789012:not-existing",
|
|
tagKeys=["key"],
|
|
)
|
|
ex = e.value
|
|
assert ex.operation_name == "UntagResource"
|
|
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
|
assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
|
|
assert (
|
|
ex.response["Error"]["Message"]
|
|
== "The account with id '123456789012' does not include a pipeline with the name 'not-existing'"
|
|
)
|
|
|
|
|
|
simple_trust_policy = {
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Effect": "Allow",
|
|
"Principal": {"Service": "codepipeline.amazonaws.com"},
|
|
"Action": "sts:AssumeRole",
|
|
}
|
|
],
|
|
}
|
|
|
|
|
|
def get_role_arn(name="test-role", trust_policy=None):
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
try:
|
|
return client.get_role(RoleName=name)["Role"]["Arn"]
|
|
except ClientError:
|
|
if trust_policy is None:
|
|
trust_policy = simple_trust_policy
|
|
return client.create_role(
|
|
RoleName=name,
|
|
AssumeRolePolicyDocument=json.dumps(trust_policy),
|
|
)["Role"]["Arn"]
|
|
|
|
|
|
def create_basic_codepipeline(client, name, role_arn=None, tags=None):
|
|
if role_arn is None:
|
|
role_arn = get_role_arn()
|
|
if tags is None:
|
|
tags = [{"key": "key", "value": "value"}]
|
|
return client.create_pipeline(
|
|
pipeline={
|
|
"name": name,
|
|
"roleArn": role_arn,
|
|
"artifactStore": {
|
|
"type": "S3",
|
|
"location": "codepipeline-us-east-1-123456789012",
|
|
},
|
|
"stages": [
|
|
{
|
|
"name": "Stage-1",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Source",
|
|
"owner": "AWS",
|
|
"provider": "S3",
|
|
"version": "1",
|
|
},
|
|
"configuration": {
|
|
"S3Bucket": "test-bucket",
|
|
"S3ObjectKey": "test-object",
|
|
},
|
|
"outputArtifacts": [{"name": "artifact"}],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
"name": "Stage-2",
|
|
"actions": [
|
|
{
|
|
"name": "Action-1",
|
|
"actionTypeId": {
|
|
"category": "Approval",
|
|
"owner": "AWS",
|
|
"provider": "Manual",
|
|
"version": "1",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
tags=tags,
|
|
)
|
|
|
|
|
|
extended_trust_policy = {
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Effect": "Allow",
|
|
"Principal": {"Service": "codebuild.amazonaws.com"},
|
|
"Action": "sts:AssumeRole",
|
|
},
|
|
{
|
|
"Effect": "Allow",
|
|
"Principal": {"Service": "codepipeline.amazonaws.com"},
|
|
"Action": "sts:AssumeRole",
|
|
},
|
|
],
|
|
}
|
|
|
|
|
|
@mock_aws
|
|
def test_create_pipeline_with_extended_trust_policy():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
|
|
role_arn = get_role_arn(
|
|
name="test-role-extended", trust_policy=extended_trust_policy
|
|
)
|
|
response = create_basic_codepipeline(client, "test-pipeline", role_arn=role_arn)
|
|
|
|
extended_pipeline_details = deepcopy(expected_pipeline_details)
|
|
extended_pipeline_details["roleArn"] = role_arn
|
|
|
|
assert response["pipeline"] == extended_pipeline_details
|
|
assert response["tags"] == [{"key": "key", "value": "value"}]
|
|
|
|
|
|
@mock_aws
|
|
def test_create_pipeline_without_tags():
|
|
client = boto3.client("codepipeline", region_name="us-east-1")
|
|
|
|
response = create_basic_codepipeline(client, "test-pipeline", tags=[])
|
|
|
|
assert response["pipeline"] == expected_pipeline_details
|
|
assert response["tags"] == []
|