Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize Django module for one-off management commands #2

Merged
merged 27 commits into from
Apr 8, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7a7d1ab
Scaffold Python package and move over source code
Feb 27, 2019
3dd7116
Add PR template and test artifacts
Feb 27, 2019
a35b00e
Adjust ecsmanage command to read configuration values
Feb 27, 2019
dbe4a70
Get ecsmanage command working
Feb 28, 2019
159e654
Make management command installable
Feb 28, 2019
a46dc8d
Initialize tests
Feb 28, 2019
b2e542c
Draft simple README
Feb 28, 2019
4096b3f
Add Travis config and drop support for py2.7 + py3.5
Feb 28, 2019
f42609d
Clean up Travis config
Feb 28, 2019
f929023
Document workarounds in .travis.yml
jeancochrane Mar 2, 2019
80c3ba5
Clean up README
jeancochrane Mar 2, 2019
0aff8d3
Specify Python 3.6+ support
jeancochrane Mar 2, 2019
6c031a8
Use AWS region name for Boto3 clients
jeancochrane Mar 2, 2019
cc8ecbb
Update setup.py to reflect Python 3.6+ requirement
jeancochrane Mar 2, 2019
1aeac5d
Make sure scripts/update can run in one pass
rbreslow Mar 13, 2019
004ebee
Satisfy linter requirements
rbreslow Mar 13, 2019
8ab47fa
Only pass networkConfiguration for awsvpc network mode
rbreslow Mar 14, 2019
0156d2d
fixup! Only pass networkConfiguration for awsvpc network mode
rbreslow Mar 14, 2019
0dfcaf7
Use setuptools_scm to manage Python package version
rbreslow Mar 14, 2019
94a7ccb
Fix README
hectcastro Apr 6, 2019
0433873
Add support for Black
hectcastro Apr 6, 2019
aa4e0d9
Relax all Black version constraints
hectcastro Apr 6, 2019
cfb5714
Publish to PyPi using azavea user
rbreslow Apr 8, 2019
df23ccb
Single self.stdout.write() call
rbreslow Apr 8, 2019
88b5dfa
Remove moto
rbreslow Apr 8, 2019
e7ac83c
Update MANIFEST.in
rbreslow Apr 8, 2019
fa21255
Remove deploys on develop because untagged scm version violates PEP 4…
rbreslow Apr 8, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Initialize tests
Set up some simple tests for the package configuration.
  • Loading branch information
Jean Cochrane committed Feb 28, 2019
commit a46dc8d93acfab5050e99dc7483f9f48944cc333
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -115,4 +113,7 @@ venv.bak/
dmypy.json

# Pyre type checker
pyre/
pyre/

# Editors
.vscode
14 changes: 11 additions & 3 deletions ecsmanage/management/commands/ecsmanage.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ def add_arguments(self, parser):
'-e', '--env',
type=str,
default='default',
help="Environment to run the task in, as defined in ECSMANAGE_ENVIRONMENTS."
help=(
'Environment to run the task in, as defined in'
'ECSMANAGE_ENVIRONMENTS.'
)
)

parser.add_argument(
Expand Down Expand Up @@ -74,7 +77,7 @@ def parse_config(self):
'ECSMANAGE_ENVIRONMENTS (environments include: '
f'{settings.ECSMANAGE_ENVIRONMENTS.keys()})'
)

config = {
'TASK_DEFINITION_NAME': '',
'CLUSTER_NAME': '',
Expand Down Expand Up @@ -164,7 +167,12 @@ def get_subnet(self, subnet_tags):
subnet = self.parse_response(subnet_response, 'Subnets', 0)
return subnet['SubnetId']

def run_task(self, config, task_def_arn, security_group_id, subnet_id, cmd):
def run_task(self,
config,
task_def_arn,
security_group_id,
subnet_id,
cmd):
"""
Run a task for a given task definition ARN using the given security
group and subnets, and return the task ID.
Expand Down
9 changes: 4 additions & 5 deletions scripts/test
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Options:
--lint Run shell and Python linters.
--app Run app tests.
"
}

function run_linters() {
# Lint Bash scripts.
Expand All @@ -25,14 +26,12 @@ function run_linters() {
fi

# Lint Python scripts.
# Lint Python scripts.
docker-compose run --rm --no-deps \
--entrypoint flake8 app \
--exclude *.pyc
./.venv/bin/flake8 --exclude ./*.pyc,./.venv
}

function run_tests() {
docker-compose run --rm --entrypoint python app manage.py test --noinput
PYTHONPATH="./tests/" DJANGO_SETTINGS_MODULE='settings_test' \
./.venv/bin/django-admin test --noinput
}

if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
Expand Down
35 changes: 35 additions & 0 deletions scripts/update
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

set -e

if [[ -n "${ECSMANAGE_DEBUG}" ]]; then
set -x
fi

function usage() {
echo -n \
"Usage: $(basename "$0")

Install the package for testing.
"
}

if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
if [ "${1:-}" = "--help" ]; then
usage
else
if ! [ -x "$(command -v python3)" ]; then
echo "Error: python3 is not installed."
exit 1j
elif ! [ -x "$(command -v pip3)" ]; then
echo "Error: pip3 is not installed."
exit 1
else
if ! [ -d ".venv" ]; then
python3 -m venv .venv
else
./.venv/bin/pip3 install -e ".[tests]"
fi
fi
fi
fi
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
README = readme.read()

description = (
'Run any Django management command on an AWS Elastic Container Service (ECS)'
'cluster.'
'Run any Django management command on an AWS Elastic Container Service'
'(ECS) cluster.'
)

# allow setup.py to be run from any path
Expand All @@ -29,6 +29,7 @@
'Django >=1.11, <=2.1',
'boto3 >=1.9.0'
],
extras_require={'tests': ['moto >= 1.3.3', 'flake8 >= 3.7.7']},
rbreslow marked this conversation as resolved.
Show resolved Hide resolved
classifiers=[
'Environment :: Web Environment',
'Framework :: Django',
Expand All @@ -43,4 +44,4 @@
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
],
)
)
File renamed without changes.
4 changes: 4 additions & 0 deletions tests/settings_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
Django settings for testing purposes.
"""
SECRET_KEY = 'testing!'
93 changes: 93 additions & 0 deletions tests/test_configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test import SimpleTestCase


class ConfigurationTestCase(SimpleTestCase):
"""
Test the configuration of settings for the management command.
"""
def test_failure_when_no_settings(self):
"""
Test that the command throws an error when the ECSMANAGE_ENVIRONMENTS
setting does not exist.
"""
with self.assertRaises(CommandError):
call_command('ecsmanage', 'help')

def test_failure_when_missing_environment(self):
"""
Test that the command throws an error when the environment passed to
the CLI does not exist in ECSMANAGE_ENVIRONMENTS.
"""
ECSMANAGE_ENVIRONMENTS = {
'staging': {},
'production': {}
}
with self.assertRaises(CommandError):
with self.settings(ECSMANAGE_ENVIRONMENTS=ECSMANAGE_ENVIRONMENTS):
call_command('ecsmanage', 'help', env='foobar')

def test_failure_when_no_task_def_name(self):
"""
Test that the command throws an error when the configuration is missing
a task definition name.
"""
ECSMANAGE_ENVIRONMENTS = {
'staging': {
'CLUSTER_NAME': 'foo',
'SECURITY_GROUP_TAGS': {},
'SUBNET_TAGS': {},
},
}
with self.assertRaises(CommandError):
with self.settings(ECSMANAGE_ENVIRONMENTS=ECSMANAGE_ENVIRONMENTS):
call_command('ecsmanage', 'help', env='staging')

def test_failure_when_no_cluster_name(self):
"""
Test that the command throws an error when the configuration is missing
a cluster name.
"""
ECSMANAGE_ENVIRONMENTS = {
'staging': {
'TASK_DEFINITION_NAME': 'foo',
'SECURITY_GROUP_TAGS': {},
'SUBNET_TAGS': {},
},
}
with self.assertRaises(CommandError):
with self.settings(ECSMANAGE_ENVIRONMENTS=ECSMANAGE_ENVIRONMENTS):
call_command('ecsmanage', 'help', env='staging')

def test_failure_when_no_security_group_tags(self):
"""
Test that the command throws an error when the configuration is missing
security group tags.
"""
ECSMANAGE_ENVIRONMENTS = {
'staging': {
'TASK_DEFINITION_NAME': 'foo',
'CLUSTER_NAME': 'bar',
'SUBNET_TAGS': {},
},
}
with self.assertRaises(CommandError):
with self.settings(ECSMANAGE_ENVIRONMENTS=ECSMANAGE_ENVIRONMENTS):
call_command('ecsmanage', 'help', env='staging')

def test_failure_when_no_subnet_tags(self):
"""
Test that the command throws an error when the configuration is missing
subnet tags.
"""
ECSMANAGE_ENVIRONMENTS = {
'staging': {
'TASK_DEFINITION_NAME': 'foo',
'CLUSTER_NAME': 'bar',
'SECURITY_GROUP_TAGS': {},
},
}
with self.assertRaises(CommandError):
with self.settings(ECSMANAGE_ENVIRONMENTS=ECSMANAGE_ENVIRONMENTS):
call_command('ecsmanage', 'help', env='staging')