Implement list jobs (#4610)

This commit is contained in:
Dan Aronson 2021-11-22 18:46:17 +02:00 committed by GitHub
parent 7122f4f890
commit 3d6d8c27fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 129 additions and 4 deletions

View File

@ -16,9 +16,19 @@ from .exceptions import (
PartitionNotFoundException,
VersionNotFoundException,
)
from ..utilities.paginator import paginate
class GlueBackend(BaseBackend):
PAGINATION_MODEL = {
"list_jobs": {
"input_token": "next_token",
"limit_key": "max_results",
"limit_default": 100,
"page_ending_range_keys": ["name"],
},
}
def __init__(self):
self.databases = OrderedDict()
self.crawlers = OrderedDict()
@ -183,6 +193,10 @@ class GlueBackend(BaseBackend):
)
return name
@paginate(pagination_model=PAGINATION_MODEL)
def list_jobs(self):
return [job for _, job in self.jobs.items()]
class FakeDatabase(BaseModel):
def __init__(self, database_name, database_input):
@ -448,5 +462,8 @@ class FakeJob:
self.created_on = datetime.utcnow()
self.last_modified_on = datetime.utcnow()
def get_name(self):
return self.name
glue_backend = GlueBackend()

View File

@ -360,3 +360,31 @@ class GlueResponse(BaseResponse):
worker_type=worker_type,
)
return json.dumps(dict(Name=name))
def list_jobs(self):
next_token = self._get_param("NextToken")
max_results = self._get_int_param("MaxResults")
tags = self._get_param("Tags")
jobs, next_token = self.glue_backend.list_jobs(
next_token=next_token, max_results=max_results
)
filtered_job_names = self.filter_jobs_by_tags(jobs, tags)
return json.dumps(
dict(
JobNames=[job_name for job_name in filtered_job_names],
NextToken=next_token,
)
)
def filter_jobs_by_tags(self, jobs, tags):
if not tags:
return [job.get_name() for job in jobs]
return [job.get_name() for job in jobs if self.is_tags_match(job.tags, tags)]
@staticmethod
def is_tags_match(job_tags, tags):
mutual_keys = set(job_tags).intersection(tags)
for key in mutual_keys:
if job_tags[key] == tags[key]:
return True
return False

View File

@ -1,4 +1,7 @@
"""Unit tests for glue-supported APIs."""
from random import randint
from uuid import uuid4
import boto3
import pytest
import sure # noqa # pylint: disable=unused-import
@ -9,19 +12,96 @@ from moto import mock_glue
@mock_glue
def test_create_job():
client = boto3.client("glue", region_name="us-east-1")
client = create_glue_client()
job_name = str(uuid4())
response = client.create_job(
Name="test_name", Role="test_role", Command=dict(Name="test_command")
Name=job_name, Role="test_role", Command=dict(Name="test_command")
)
assert response["Name"] == "test_name"
assert response["Name"] == job_name
@mock_glue
def test_create_job_default_argument_not_provided():
client = boto3.client("glue", region_name="us-east-1")
client = create_glue_client()
with pytest.raises(ParamValidationError) as exc:
client.create_job(Role="test_role", Command=dict(Name="test_command"))
exc.value.kwargs["report"].should.equal(
'Missing required parameter in input: "Name"'
)
@mock_glue
def test_list_jobs():
client = create_glue_client()
expected_jobs = randint(1, 15)
create_test_jobs(client, expected_jobs)
response = client.list_jobs()
response["JobNames"].should.have.length_of(expected_jobs)
response.shouldnt.have.key("NextToken")
@mock_glue
def test_list_jobs_with_max_results():
client = create_glue_client()
create_test_jobs(client, 4)
response = client.list_jobs(MaxResults=2)
response["JobNames"].should.have.length_of(2)
response.should.have.key("NextToken")
@mock_glue
def test_list_jobs_from_next_token():
client = create_glue_client()
create_test_jobs(client, 10)
first_response = client.list_jobs(MaxResults=3)
response = client.list_jobs(NextToken=first_response["NextToken"])
response["JobNames"].should.have.length_of(7)
@mock_glue
def test_list_jobs_with_max_results_greater_than_actual_results():
client = create_glue_client()
create_test_jobs(client, 4)
response = client.list_jobs(MaxResults=10)
response["JobNames"].should.have.length_of(4)
@mock_glue
def test_list_jobs_with_tags():
client = create_glue_client()
create_test_job(client)
create_test_job(client, {"string": "string"})
response = client.list_jobs(Tags={"string": "string"})
response["JobNames"].should.have.length_of(1)
@mock_glue
def test_next_token_logic_does_not_create_infinite_loop():
client = create_glue_client()
create_test_jobs(client, 4)
first_response = client.list_jobs(MaxResults=1)
next_token = first_response["NextToken"]
while next_token:
response = client.list_jobs(NextToken=next_token)
next_token = response.get("NextToken")
assert not next_token
def create_glue_client():
return boto3.client("glue", region_name="us-east-1")
def create_test_job(client, tags=None):
job_name = str(uuid4())
client.create_job(
Name=job_name,
Role="test_role",
Command=dict(Name="test_command"),
Tags=tags or {},
)
def create_test_jobs(client, number_of_jobs):
for _ in range(number_of_jobs):
create_test_job(client)