diff --git a/atst/domain/environments.py b/atst/domain/environments.py index e21d4cb9..10ab15f9 100644 --- a/atst/domain/environments.py +++ b/atst/domain/environments.py @@ -1,7 +1,7 @@ from sqlalchemy.orm.exc import NoResultFound from atst.database import db -from atst.models.environment import Environment +from atst.models import Environment, Application, Portfolio, TaskOrder, CLIN from atst.domain.environment_roles import EnvironmentRoles from atst.domain.application_roles import ApplicationRoles @@ -102,3 +102,17 @@ class Environments(object): # TODO: How do we work around environment deletion being a largely manual process in the CSPs return environment + + @classmethod + def get_environments_pending_creation(cls, now) -> [str]: + query = ( + db.session.query(Environment.id) + .join(Application) + .join(Portfolio) + .join(TaskOrder) + .join(CLIN) + .filter(CLIN.start_date <= now) + .filter(CLIN.end_date > now) + .filter(Environment.cloud_id == None) + ) + return [environment_id for (environment_id,) in query.all()] diff --git a/atst/jobs.py b/atst/jobs.py index 8977cd7e..6e983a6c 100644 --- a/atst/jobs.py +++ b/atst/jobs.py @@ -120,21 +120,9 @@ def create_environment_baseline(self, environment_id=None): do_work(do_create_environment_baseline, self, app.csp.cloud, **kwargs) -def environments_to_create(now): - query = ( - db.session.query(Environment.id) - .join(Application) - .join(Portfolio) - .join(TaskOrder) - .join(CLIN) - .filter(CLIN.start_date <= now) - .filter(CLIN.end_date > now) - .filter(Environment.cloud_id == None) - ) - return [environment_id for (environment_id,) in query.all()] - - @celery.task(bind=True) def dispatch_create_environment(self): - for environment_id in environments_to_create(pendulum.now()): + for environment_id in Environments.get_environments_pending_creation( + pendulum.now() + ): create_environment.delay(environment_id=environment_id, atat_user_id="TODO") diff --git a/tests/domain/test_environments.py b/tests/domain/test_environments.py index 4589b179..58ea011b 100644 --- a/tests/domain/test_environments.py +++ b/tests/domain/test_environments.py @@ -1,4 +1,5 @@ import pytest +import pendulum from atst.domain.environments import Environments from atst.domain.environment_roles import EnvironmentRoles @@ -7,11 +8,12 @@ from atst.models.environment_role import CSPRole from tests.factories import ( ApplicationFactory, - UserFactory, PortfolioFactory, EnvironmentFactory, EnvironmentRoleFactory, ApplicationRoleFactory, + TaskOrderFactory, + CLINFactory, ) @@ -132,3 +134,42 @@ def test_update_environment(): assert environment.name is not "name 2" Environments.update(environment, name="name 2") assert environment.name == "name 2" + + +class TestGetEnvironmentsPendingCreate: + NOW = pendulum.now() + YESTERDAY = NOW.subtract(days=1) + TOMORROW = NOW.add(days=1) + + def create_portfolio_with_clins(self, start_and_end_dates): + return PortfolioFactory.create( + applications=[ + { + "name": "Mos Eisley", + "description": "Where Han shot first", + "environments": [{"name": "thebar"}], + } + ], + task_orders=[ + TaskOrderFactory.create( + clins=[ + CLINFactory.create(start_date=start_date, end_date=end_date) + for (start_date, end_date) in start_and_end_dates + ] + ) + ], + ) + + def test_with_expired_clins(self, session): + self.create_portfolio_with_clins([(self.YESTERDAY, self.YESTERDAY)]) + assert len(Environments.get_environments_pending_creation(self.NOW)) == 0 + + def test_with_active_clins(self, session): + portfolio = self.create_portfolio_with_clins([(self.YESTERDAY, self.TOMORROW)]) + Environments.get_environments_pending_creation(self.NOW) == [ + portfolio.applications[0].environments[0].id + ] + + def test_with_future_clins(self, session): + self.create_portfolio_with_clins([(self.TOMORROW, self.TOMORROW)]) + assert len(Environments.get_environments_pending_creation(self.NOW)) == 0 diff --git a/tests/test_jobs.py b/tests/test_jobs.py index 8a2bf19d..409663d1 100644 --- a/tests/test_jobs.py +++ b/tests/test_jobs.py @@ -5,6 +5,8 @@ from atst.jobs import RecordEnvironmentFailure, RecordEnvironmentRoleFailure from tests.factories import EnvironmentFactory, EnvironmentRoleFactory, UserFactory from uuid import uuid4 from unittest.mock import Mock + +from atst.models import Environment from tests.factories import ( UserFactory, PortfolioFactory, @@ -59,6 +61,7 @@ def test_environment_role_job_failure(celery_app, celery_worker): now = pendulum.now() yesterday = now.subtract(days=1) tomorrow = now.add(days=1) +from atst.domain.environments import Environments @pytest.fixture(autouse=True, scope="function") @@ -109,40 +112,3 @@ def test_create_environment_baseline(csp, session): updated_environment = session.query(Environment).get(environment_id) assert updated_environment.baseline_info - - -def create_portfolio_with_clins(start_and_end_dates): - return PortfolioFactory.create( - applications=[ - { - "name": "Mos Eisley", - "description": "Where Han shot first", - "environments": [{"name": "thebar"}], - } - ], - task_orders=[ - TaskOrderFactory.create( - clins=[ - CLINFactory.create(start_date=start_date, end_date=end_date) - for (start_date, end_date) in start_and_end_dates - ] - ) - ], - ) - - -def test_dispatch_query_with_expired_clins(session): - create_portfolio_with_clins([(yesterday, yesterday)]) - assert len(environments_to_create(pendulum.now())) == 0 - - -def test_dispatch_query_with_active_clins(session): - portfolio = create_portfolio_with_clins([(yesterday, tomorrow)]) - environments_to_create(pendulum.now()) == [ - portfolio.applications[0].environments[0].id - ] - - -def test_dispatch_query_with_future_clins(session): - create_portfolio_with_clins([(tomorrow, tomorrow)]) - assert len(environments_to_create(pendulum.now())) == 0