def test_GIVEN_one_pending_job_in_the_database_which_has_completed_WHEN_update_dap_client_not_available_THEN_model_run_status_is_not_updated(self):

        self.dap_client_factory.get_dap_client = Mock(side_effect=DapClientException("trouble"))
        self.create_model_run_ready_for_submit()
        model_run_service = ModelRunService()
        model_run = model_run_service.get_model_run_being_created_or_default(self.user)
        with session_scope(Session) as session:
            model_run.change_status(session, constants.MODEL_RUN_STATUS_RUNNING)

        self.running_job_client.get_run_model_statuses = Mock(
            return_value=[{'id': model_run.id,
                           'status': constants.MODEL_RUN_STATUS_COMPLETED,
                           'error_message': ''
                           }])

        self.job_status_updater.update()

        model_run = model_run_service.get_model_by_id(self.user, model_run.id)
        assert_that(model_run.status.name, is_(constants.MODEL_RUN_STATUS_RUNNING), "model status")
        with session_scope() as session:
            datasets = session.query(Dataset)\
                .filter(Dataset.model_run_id == model_run.id)\
                .filter(Dataset.is_input == False)\
                .all()
            assert_that(len(datasets), is_(0), "Number of output datasets")

            datasets = session.query(Dataset)\
                .filter(Dataset.model_run_id == model_run.id)\
                .filter(Dataset.is_input == True)\
                .all()
            assert_that(len(datasets), is_(0), "Number of input datasets")
    def test_GIVEN_model_run_WHEN_view_THEN_parameter_for_code_version_is_shown(self):

        user = self.login()

        model_run_service = ModelRunService()
        model_run_service.update_model_run(user, "test", constants.DEFAULT_SCIENCE_CONFIGURATION)

        response = self.app.get(
            url(controller='model_run', action='parameters'))

        assert_that(response.normal_body, contains_string("timestep_len"))
    def test_GIVEN_model_already_being_created_WHEN_navigate_to_create_run_THEN_model_data_filled_in(self):

        user = self.login()

        model_run_service = ModelRunService()
        model_run_service.update_model_run(user, 'test', constants.DEFAULT_SCIENCE_CONFIGURATION, "description which is unique")

        response = self.app.get(
            url(controller='model_run', action='create'))

        assert_that(response.normal_body, contains_string("test"))
        assert_that(response.normal_body, contains_string(str(constants.DEFAULT_SCIENCE_CONFIGURATION)))
        assert_that(response.normal_body, contains_string("description which is unique"))
    def setUp(self):
        super(TestModelRunOutput, self).setUp()
        self.clean_database()
        self.user = self.login()
        self.valid_params = {
            'submit': u'Next',
            'ov_select_1': 1,
            'ov_yearly_1': 1,
            'ov_monthly_1': 1,
            'ov_select_2': 1,
            'ov_hourly_2': 1,
            'ov_daily_2': 1,
            'ov_select_3': 1,
            'ov_monthly_3': 1
        }
        self.model_run_service = ModelRunService()
        param_run_start = self.model_run_service.get_parameter_by_constant(JULES_PARAM_RUN_START)
        param_run_end = self.model_run_service.get_parameter_by_constant(JULES_PARAM_RUN_END)
        with session_scope(Session) as session:
            self.model_run = self.model_run_service._create_new_model_run(session, self.user)
            self.model_run.name = "MR1"

            pv_run_start = ParameterValue()
            pv_run_start.parameter_id = param_run_start.id
            pv_run_start.value = "'1901-01-01 00:00:00'"

            pv_run_end = ParameterValue()
            pv_run_end.parameter_id = param_run_end.id
            pv_run_end.value = "'1902-01-01 00:00:00'"

            self.model_run.parameter_values = [pv_run_start, pv_run_end]

            session.add(self.model_run)
    def test_GIVEN_valid_driving_data_chosen_WHEN_post_THEN_driving_data_stored_against_model_run(self):
        self._add_model_run_being_created(self.user)
        self.create_two_driving_datasets()

        dataset_service = DatasetService()
        driving_data = dataset_service.get_driving_datasets(self.user)
        ds_id = driving_data[0].id
        self.app.post(
            url(controller='model_run', action='driving_data'),
            params={
                'driving_dataset': ds_id,
                'submit': u'Next'
            })

        model_run_service = ModelRunService()
        model_run = model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        param_val = model_run.get_python_parameter_value(constants.JULES_PARAM_DRIVE_FILE)
        assert_that(param_val, is_('testFileName'))
 def check_valid_user_driving_data_params_stored(self):
     model_run_service = ModelRunService()
     model_run = model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
     data_start = model_run.get_parameter_values(constants.JULES_PARAM_DRIVE_DATA_START)[0].value
     data_end = model_run.get_parameter_values(constants.JULES_PARAM_DRIVE_DATA_END)[0].value
     data_period = model_run.get_parameter_values(constants.JULES_PARAM_DRIVE_DATA_PERIOD)[0].value
     file = model_run.get_parameter_values(constants.JULES_PARAM_DRIVE_FILE)[0].value
     nvars = model_run.get_parameter_values(constants.JULES_PARAM_DRIVE_NVARS)[0].value
     var = model_run.get_parameter_values(constants.JULES_PARAM_DRIVE_VAR)[0].value
     interp = model_run.get_parameter_values(constants.JULES_PARAM_DRIVE_INTERP)[0].value
     assert_that(model_run.driving_data_lat, is_(55))
     assert_that(model_run.driving_data_lon, is_(45))
     assert_that(data_start, is_("'2000-01-01 00:00:00'"))
     assert_that(data_end, is_("'2000-01-01 02:00:00'"))
     assert_that(data_period, is_("3600"))
     assert_that(file, is_("'" + constants.USER_UPLOAD_FILE_NAME + "'"))
     assert_that(nvars, is_("8"))
     assert_that(var, is_("'sw_down'    'lw_down'    'tot_rain'    'tot_snow'    't'    'wind'    'pstar'    'q'"))
     assert_that(interp, is_("'i'    'i'    'i'    'i'    'i'    'i'    'i'    'i'"))
 def setUp(self):
     dap_client_factory = DapClientFactory()
     dap_client_factory.get_land_cover_dap_client = self._mock_get_land_cover_dap_client
     dap_client_factory.get_soil_properties_dap_client = self._mock_get_soil_properties_dap_client
     self.land_cover_service = LandCoverService(dap_client_factory=dap_client_factory)
     self.model_run_service = ModelRunService()
     self.dataset_service = DatasetService()
     self.parameter_service = ParameterService()
     self.clean_database()
     self.user = self.login()
     self.create_model_run_ready_for_submit()
    def test_GIVEN_name_is_duplicate_WHEN_post_THEN_error_thrown(self):

        duplicate_name = u'duplicate name'
        user = self.login()
        model_run_service = ModelRunService()
        model_run_service.update_model_run(user, duplicate_name, constants.DEFAULT_SCIENCE_CONFIGURATION, "description which is unique")
        model_run = model_run_service.get_model_run_being_created_or_default(user)
        with model_run_service.transaction_scope() as session:
            model_run.change_status(session, constants.MODEL_RUN_STATUS_COMPLETED)

        response = self.app.post(
            url=url(controller='model_run', action='create'),
            params={
                'name': duplicate_name,
                'science_configuration': unicode(constants.DEFAULT_SCIENCE_CONFIGURATION),
                'description': u'a description'
            }
        )

        assert_that(response.normal_body, contains_string("Name can not be the same as another model run"))
    def test_GIVEN_name_is_duplicate_but_run_is_owned_by_another_user_WHEN_post_THEN_success(self):

        duplicate_name = u'duplicate name'
        user = self.login("test_different")
        model_run_service = ModelRunService()
        model_run_service.update_model_run(user, duplicate_name, constants.DEFAULT_SCIENCE_CONFIGURATION, "description which is unique")
        model_run = model_run_service.get_model_run_being_created_or_default(user)
        with model_run_service.transaction_scope() as session:
            model_run.change_status(session, constants.MODEL_RUN_STATUS_COMPLETED)

        user = self.login("test")
        response = self.app.post(
            url=url(controller='model_run', action='create'),
            params={
                'name': duplicate_name,
                'science_configuration': unicode(constants.DEFAULT_SCIENCE_CONFIGURATION),
                'description': u'a description'
            }
        )

        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path, is_(url(controller='model_run', action='driving_data')), "url")
    def test_GIVEN_model_already_being_created_WHEN_update_THEN_model_data_overwritten(self):

        user = self.login()
        model_run_service = ModelRunService()
        model_run_service.update_model_run(user, 'not test', 2, "a different description")

        expected_name = u'name'
        expected_science_configuration = constants.DEFAULT_SCIENCE_CONFIGURATION
        expected_description = u'descr'

        response = self.app.post(
            url=url(controller='model_run', action='create'),
            params={
                'name': expected_name,
                'science_configuration': str(expected_science_configuration),
                'description': expected_description
            }
        )

        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path, is_(url(controller='model_run', action='driving_data')), "url")

        self.assert_model_definition(self.login_username, expected_science_configuration, expected_name,expected_description)
    def setUp(self):
        super(TestWithFullModelRun, self).setUp()
        self.running_job_client = JobRunnerClient([])
        self.email_service = EmailService()
        self.email_service.send_email = Mock()

        self.job_status_updater = JobStatusUpdaterService(
            job_runner_client=self.running_job_client,
            config=config,
            email_service=self.email_service,
            dap_client_factory=self.create_mock_dap_factory_client())

        self.clean_database()
        self.user = self.login()
        self.model_run_service = ModelRunService()
    def test_GIVEN_one_pending_job_in_the_database_which_has_completed_WHEN_update_THEN_model_run_data_is_in_datasets(self):

        self.create_model_run_ready_for_submit()
        model_run_service = ModelRunService()
        model_run = model_run_service.get_model_run_being_created_or_default(self.user)
        with session_scope(Session) as session:
            model_run.change_status(session, constants.MODEL_RUN_STATUS_RUNNING)

        self.running_job_client.get_run_model_statuses = Mock(
            return_value=[{'id': model_run.id,
                           'status': constants.MODEL_RUN_STATUS_COMPLETED,
                           'error_message': ''
                           }])

        self.job_status_updater.update()

        with session_scope() as session:
            datasets = session.query(Dataset)\
                .filter(Dataset.model_run_id == model_run.id)\
                .filter(Dataset.is_input == False)\
                .all()
            assert_that(len(datasets), is_(3), "Number of output datasets")
            dataset_names = [dataset.name for dataset in datasets]
            assert_that(dataset_names, contains_inanyorder(
                contains_string('Monthly'), contains_string('Yearly'), contains_string('Hourly')))
            dataset_wms_urls = [dataset.wms_url for dataset in datasets]
            assert_that(dataset_wms_urls, contains_inanyorder(
                contains_string('output/majic.fch4_wetl_yearly.ncml'),
                contains_string('output/majic.fch4_wetl_monthly.ncml'),
                contains_string('output/majic.albedo_land_hourly.ncml')))

            datasets = session.query(Dataset)\
                .filter(Dataset.model_run_id == model_run.id)\
                .filter(Dataset.is_input == True)\
                .all()
            assert_that(len(datasets), is_(2), "Number of input datasets")
Exemple #13
0
    def __init__(self,
                 user_service=UserService(),
                 dataset_service=DatasetService(),
                 account_request_service=AccountRequestService()):
        """
        Constructor for the user controller, takes in any services required
        :param user_service: User service to use within the controller
        :param dataset_service: dataset service
        :param account_request_service: accoun requests service
        :return: nothing
        """
        super(UserController, self).__init__(user_service)

        self._dataset_service = dataset_service
        self._model_run_service = ModelRunService()
        self._account_request_service = account_request_service
class ModelRunServiceTest(BaseTest):

    def setUp(self):

        super(ModelRunServiceTest, self).setUp()

        self._mock_session.query = MagicMock()
        self.model_run_service = ModelRunService(self._mock_session)

    def test_GIVEN_no_model_runs_WHEN_get_model_list_THEN_empty_list_returned(self):

        mock_query_result = MagicMock()
        mock_query_result.all = MagicMock(return_value=[])

        mock_query = MagicMock()
        mock_query.filter = MagicMock()
        mock_query.filter.return_value = mock_query_result
        self._mock_session.query.return_value = mock_query

        user = User()
        models = self.model_run_service.get_models_for_user(user)

        assert_that(len(models), is_(0), "There should be no model for the user")
    def setUp(self):
        super(TestModelRunExtents, self).setUp()
        self.clean_database()
        self.user = self.login()
        self.model_run_service = ModelRunService()
        with session_scope(Session) as session:
            self.driving_data = DrivingDataset()
            self.driving_data.name = "d1"
            self.driving_data.boundary_lat_north = 47.5
            self.driving_data.boundary_lat_south = 13.8
            self.driving_data.boundary_lon_east = 123.1
            self.driving_data.boundary_lon_west = -15.0
            self.driving_data.time_start = datetime.datetime(1901, 1, 1, 0, 0, 0)
            self.driving_data.time_end = datetime.datetime(2001, 1, 1, 0, 0, 0)
            session.add(self.driving_data)
            session.commit()

            self.model_run = ModelRun()
            self.model_run.name = "MR1"
            self.model_run.status = self._status(MODEL_RUN_STATUS_CREATED)
            self.model_run.driving_dataset_id = self.driving_data.id
            self.model_run.user = self.user
            self.model_run.science_configuration_id = 2

            param1 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_INTERP)
            pv1 = ParameterValue()
            pv1.parameter_id = param1.id
            pv1.set_value_from_python(8 * ['nf'])

            param2 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_PERIOD)
            pv2 = ParameterValue()
            pv2.parameter_id = param2.id
            pv2.set_value_from_python(60 * 60)

            self.model_run.parameter_values = [pv1, pv2]
            session.add(self.model_run)
    def setUp(self):
        self.clean_database()
        self.user = self.login()
        self.create_two_driving_datasets()
        dds = DatasetService().get_driving_datasets(self.user)[0]
        with session_scope() as session:
            model_run = ModelRun()
            model_run.name = "model run"
            model_run.change_status(session, MODEL_RUN_STATUS_CREATED)
            model_run.user = self.user
            model_run.driving_dataset_id = dds.id
            session.add(model_run)
            session.commit()

            self.model_run_service = ModelRunService()
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)

            parameter_val = ParameterValue()
            parameter_val.parameter = self.model_run_service.get_parameter_by_constant(JULES_PARAM_LATLON_REGION)
            parameter_val.set_value_from_python(True)
            parameter_val.model_run_id = model_run.id
            session.add(parameter_val)

        self.add_land_cover_region(model_run)
Exemple #17
0
    def create_run_model(self, storage_in_mb, name, user, status=constants.MODEL_RUN_STATUS_COMPLETED):
        """
        Create a model run
        :param storage_in_mb: storage_in_mb for the model
        :param name: name of the model run
        :param user: user who has created the model run
        :param status: the status, default to complete
        :return:the model run
        """
        model_run_service = ModelRunService()
        with model_run_service.transaction_scope() as session:
            model_run = model_run_service._create_new_model_run(session, user)
            session.add(model_run)
            model_run.name = name
            science_configuration = model_run_service._get_science_configuration(
                constants.DEFAULT_SCIENCE_CONFIGURATION, session)
            model_run.science_configuration_id = science_configuration.id
            model_run.code_version = science_configuration.code_version
            model_run.description = "testing"
            model_run_service._copy_parameter_set_into_model(science_configuration.parameter_values, model_run, session)
            model_run.storage_in_mb = storage_in_mb
            model_run.change_status(session, status)

        return model_run
    def setUp(self):

        super(ModelRunServiceTest, self).setUp()

        self._mock_session.query = MagicMock()
        self.model_run_service = ModelRunService(self._mock_session)
class TestModelRunOutput(TestController):
    def setUp(self):
        super(TestModelRunOutput, self).setUp()
        self.clean_database()
        self.user = self.login()
        self.valid_params = {
            'submit': u'Next',
            'ov_select_1': 1,
            'ov_yearly_1': 1,
            'ov_monthly_1': 1,
            'ov_select_2': 1,
            'ov_hourly_2': 1,
            'ov_daily_2': 1,
            'ov_select_3': 1,
            'ov_monthly_3': 1
        }
        self.model_run_service = ModelRunService()
        param_run_start = self.model_run_service.get_parameter_by_constant(JULES_PARAM_RUN_START)
        param_run_end = self.model_run_service.get_parameter_by_constant(JULES_PARAM_RUN_END)
        with session_scope(Session) as session:
            self.model_run = self.model_run_service._create_new_model_run(session, self.user)
            self.model_run.name = "MR1"

            pv_run_start = ParameterValue()
            pv_run_start.parameter_id = param_run_start.id
            pv_run_start.value = "'1901-01-01 00:00:00'"

            pv_run_end = ParameterValue()
            pv_run_end.parameter_id = param_run_end.id
            pv_run_end.value = "'1902-01-01 00:00:00'"

            self.model_run.parameter_values = [pv_run_start, pv_run_end]

            session.add(self.model_run)

    def test_GIVEN_no_model_being_created_WHEN_page_get_THEN_redirect_to_create_model_run(self):
        self.clean_database()
        self.user = self.login()
        response = self.app.get(
            url(controller='model_run', action='output'))
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path, is_(url(controller='model_run', action='create')), "url")

    def test_GIVEN_model_run_created_WHEN_page_get_THEN_page_loaded(self):
        response = self.app.get(
            url(controller='model_run', action='output'))
        assert_that(response.normal_body, contains_string("Select Output Variables"))
        self.assert_model_run_creation_action(self.user, 'output')

    def test_GIVEN_output_parameters_already_chosen_WHEN_page_get_THEN_parameters_rendered(self):
        self.app.post(
            url(controller='model_run', action='output'),
            params=self.valid_params)
        response = self.app.get(url(controller='model_run', action='output'))
        doc = html.fromstring(response.normal_body)
        
        # Check that the first output variable is displayed, selected and the yearly and monthly period boxes selected:
        output_row_1 = doc.xpath('//div[@id="output_row_1"]/@style')
        assert_that(output_row_1, is_not(contains_string('display:none')))
        ov_select_1 = doc.xpath('//input[@name="ov_select_1"]/@checked')
        ov_yearly_1 = doc.xpath('//input[@name="ov_yearly_1"]/@checked')
        ov_monthly_1 = doc.xpath('//input[@name="ov_monthly_1"]/@checked')
        ov_daily_1 = doc.xpath('//input[@name="ov_daily_1"]/@checked')
        ov_hourly_1 = doc.xpath('//input[@name="ov_hourly_1"]/@checked')
        assert_that(len(ov_select_1), is_(1))
        assert_that(len(ov_yearly_1), is_(1))
        assert_that(len(ov_monthly_1), is_(1))
        assert_that(len(ov_daily_1), is_(0))
        assert_that(len(ov_hourly_1), is_(0))
        
        # For the second we expect the same but with the hourly period box selected
        output_row_2 = doc.xpath('//div[@id="output_row_2"]/@style')
        assert_that(output_row_2, is_not(contains_string('display:none')))
        ov_select_2 = doc.xpath('//input[@name="ov_select_2"]/@checked')
        ov_yearly_2 = doc.xpath('//input[@name="ov_yearly_2"]/@checked')
        ov_monthly_2 = doc.xpath('//input[@name="ov_monthly_2"]/@checked')
        ov_daily_2 = doc.xpath('//input[@name="ov_daily_2"]/@checked')
        ov_hourly_2 = doc.xpath('//input[@name="ov_hourly_2"]/@checked')
        assert_that(len(ov_select_2), is_(1))
        assert_that(len(ov_yearly_2), is_(0))
        assert_that(len(ov_monthly_2), is_(0))
        assert_that(len(ov_daily_2), is_(1))
        assert_that(len(ov_hourly_2), is_(1))
        
        # For the third we expect the monthly box selected
        output_row_3 = doc.xpath('//div[@id="output_row_3"]/@style')
        assert_that(output_row_3, is_not(contains_string('display:none')))
        ov_select_3 = doc.xpath('//input[@name="ov_select_3"]/@checked')
        ov_yearly_3 = doc.xpath('//input[@name="ov_yearly_3"]/@checked')
        ov_monthly_3 = doc.xpath('//input[@name="ov_monthly_3"]/@checked')
        ov_daily_3 = doc.xpath('//input[@name="ov_daily_3"]/@checked')
        ov_hourly_3 = doc.xpath('//input[@name="ov_hourly_3"]/@checked')
        assert_that(len(ov_select_3), is_(1))
        assert_that(len(ov_yearly_3), is_(0))
        assert_that(len(ov_monthly_3), is_(1))
        assert_that(len(ov_daily_3), is_(0))
        assert_that(len(ov_hourly_3), is_(0))
        
        # Finally we check that no other output parameters are selected or visible
        ov_selects = doc.xpath('//input[contains(@name, "ov_select_") and not(@checked)]')
        n_output_params = len(self.model_run_service.get_output_variables(include_depends_on_nsmax=False))
        assert_that(len(ov_selects), is_(n_output_params - 3))

        invisible_rows = doc.xpath('//div[contains(@id, "output_row_") and contains(@style, "display:none")]')
        assert_that(len(invisible_rows), is_(n_output_params - 3))

    def test_GIVEN_selected_outputs_WHEN_post_THEN_redirected_to_next_page(self):
        response = self.app.post(
            url(controller='model_run', action='output'),
            params=self.valid_params)
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='submit')), "url")

    def test_GIVEN_selected_outputs_and_user_over_quota_WHEN_post_THEN_redirected_to_catalogue(self):
        self.create_run_model(storage_in_mb=self.user.storage_quota_in_gb * 1024 + 1, name="big_run", user=self.user)
        response = self.app.post(
            url(controller='model_run', action='output'),
            params=self.valid_params)
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='index')), "url")

    def test_GIVEN_selected_outputs_WHEN_post_THEN_params_stored_in_database(self):
        self.app.post(
            url(controller='model_run', action='output'),
            params=self.valid_params)

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        # Check we have the right number of profiles
        n_expected = 5
        p_output_nprofiles = model_run.get_parameter_values(JULES_PARAM_OUTPUT_NPROFILES)[0].get_value_as_python()
        assert_that(p_output_nprofiles, is_(n_expected))

        pv_var = model_run.get_parameter_values(JULES_PARAM_OUTPUT_VAR)
        pv_nvars = model_run.get_parameter_values(JULES_PARAM_OUTPUT_NVARS)
        pv_profile_name = model_run.get_parameter_values(JULES_PARAM_OUTPUT_PROFILE_NAME)
        pv_output_main_run = model_run.get_parameter_values(JULES_PARAM_OUTPUT_MAIN_RUN)
        pv_output_period = model_run.get_parameter_values(JULES_PARAM_OUTPUT_PERIOD)
        pv_output_types = model_run.get_parameter_values(JULES_PARAM_OUTPUT_TYPE)

        # Check they are all 5
        assert_that(len(pv_var), is_(n_expected))
        assert_that(len(pv_nvars), is_(n_expected))
        assert_that(len(pv_profile_name), is_(n_expected))
        assert_that(len(pv_output_main_run), is_(n_expected))
        assert_that(len(pv_output_period), is_(n_expected))
        assert_that(len(pv_output_types), is_(n_expected))

        # Create list of values so we can check they are correct (easier than checking ParameterValue objects)
        var_vals = [pv.get_value_as_python() for pv in pv_var]
        nvars_vals = [pv.get_value_as_python() for pv in pv_nvars]
        profile_name_vals = [pv.get_value_as_python() for pv in pv_profile_name]
        output_main_run_vals = [pv.get_value_as_python() for pv in pv_output_main_run]
        output_period_vals = [pv.get_value_as_python() for pv in pv_output_period]
        output_types = [pv.get_value_as_python() for pv in pv_output_types]

        # Check that we got the correct values
        # The order is assured consistent by the sort in model_run.get_parameter_values()
        output_var_1 = self.model_run_service.get_output_variable_by_id(1)
        output_var_2 = self.model_run_service.get_output_variable_by_id(2)
        output_var_3 = self.model_run_service.get_output_variable_by_id(3)
        assert_that(var_vals, is_([output_var_1.name, output_var_1.name, output_var_2.name,
                                   output_var_2.name, output_var_3.name]))
        assert_that(nvars_vals, is_([1, 1, 1, 1, 1]))
        assert_that(profile_name_vals, is_([output_var_1.name + '_yearly', output_var_1.name + '_monthly',
                                            output_var_2.name + '_daily', output_var_2.name + '_hourly',
                                            output_var_3.name + '_monthly']))
        assert_that(output_main_run_vals, is_([True, True, True, True, True]))
        assert_that(output_period_vals, is_([-2, -1, JULES_DAILY_PERIOD, JULES_HOURLY_PERIOD, -1]))
        assert_that(output_types, is_(['M', 'M', 'M', 'M', 'M']))

    def test_GIVEN_selected_outputs_WHEN_go_back_THEN_previous_paged_rendered(self):
        params = self.valid_params
        params['submit'] = u'Back'
        response = self.app.post(
            url(controller='model_run', action='output'),
            params=params)
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='land_cover')), "url")

    def test_GIVEN_nsmax_set_zero_WHEN_page_get_THEN_nsmax_parameters_not_available_on_page(self):
        self.model_run_service.save_parameter(JULES_PARAM_NSMAX, 0, self.user)
        response = self.app.get(
            url(controller='model_run', action='output'))
        for output_name in DEPENDS_ON_NSMAX:
            assert_that(response.normal_body, is_not(contains_string(output_name)))

    def test_GIVEN_nsmax_set_three_WHEN_page_get_THEN_nsmax_parameters_shown_on_page(self):
        self.model_run_service.save_parameter(JULES_PARAM_NSMAX, 3, self.user)
        response = self.app.get(
            url(controller='model_run', action='output'))
        output_variables = self.model_run_service.get_output_variables(include_depends_on_nsmax=True)
        for output_variable in output_variables:
            if output_variable.depends_on_nsmax:
                assert_that(response.normal_body, contains_string(str(output_variable.name)))

    def test_GIVEN_page_already_run_once_WHEN_page_post_THEN_new_parameters_overwrite_old_parameters(self):
        self.app.post(
            url(controller='model_run', action='output'),
            params=self.valid_params)
        new_params = {
            'submit': u'Next',
            'ov_select_1': 1,
            'ov_hourly_1': 1,
            'ov_select_10': 1,
            'ov_yearly_10': 1,
            'ov_monthly_10': 1
        }
        self.app.post(
            url(controller='model_run', action='output'),
            params=new_params)

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        # Check we have the right number of profiles
        n_expected = 3
        p_output_nprofiles = model_run.get_parameter_values(JULES_PARAM_OUTPUT_NPROFILES)[0].get_value_as_python()
        assert_that(p_output_nprofiles, is_(n_expected))

        pv_var = model_run.get_parameter_values(JULES_PARAM_OUTPUT_VAR)
        pv_nvars = model_run.get_parameter_values(JULES_PARAM_OUTPUT_NVARS)
        pv_profile_name = model_run.get_parameter_values(JULES_PARAM_OUTPUT_PROFILE_NAME)
        pv_output_main_run = model_run.get_parameter_values(JULES_PARAM_OUTPUT_MAIN_RUN)
        pv_output_period = model_run.get_parameter_values(JULES_PARAM_OUTPUT_PERIOD)
        pv_output_types = model_run.get_parameter_values(JULES_PARAM_OUTPUT_TYPE)

        # Check they are all 3 (not 4 anymore)
        assert_that(len(pv_var), is_(n_expected))
        assert_that(len(pv_nvars), is_(n_expected))
        assert_that(len(pv_profile_name), is_(n_expected))
        assert_that(len(pv_output_main_run), is_(n_expected))
        assert_that(len(pv_output_period), is_(n_expected))
        assert_that(len(pv_output_types), is_(n_expected))

        # Create list of values so we can check they are correct (easier than checking ParameterValue objects)
        var_vals = [pv.get_value_as_python() for pv in pv_var]
        nvars_vals = [pv.get_value_as_python() for pv in pv_nvars]
        profile_name_vals = [pv.get_value_as_python() for pv in pv_profile_name]
        output_main_run_vals = [pv.get_value_as_python() for pv in pv_output_main_run]
        output_period_vals = [pv.get_value_as_python() for pv in pv_output_period]
        output_types = [pv.get_value_as_python() for pv in pv_output_types]

        # Check that we got the correct values
        # The order is assured consistent by the sort in model_run.get_parameter_values()
        output_var_1 = self.model_run_service.get_output_variable_by_id(1)
        output_var_10 = self.model_run_service.get_output_variable_by_id(10)
        assert_that(var_vals, is_([output_var_1.name, output_var_10.name, output_var_10.name]))
        assert_that(nvars_vals, is_([1, 1, 1]))
        assert_that(profile_name_vals, is_([output_var_1.name + '_hourly', output_var_10.name + '_yearly',
                                            output_var_10.name + '_monthly']))
        assert_that(output_main_run_vals, is_([True, True, True]))
        assert_that(output_period_vals, is_([JULES_HOURLY_PERIOD, -2, -1]))
        assert_that(output_types, is_(['M', 'M', 'M']))
Exemple #20
0
 def _add_model_run_being_created(self, user):
     model_run_service = ModelRunService()
     model_run_service.update_model_run(user, "test", constants.DEFAULT_SCIENCE_CONFIGURATION)
class TestLandCoverService(TestWithFullModelRun):
    def setUp(self):
        dap_client_factory = DapClientFactory()
        dap_client_factory.get_land_cover_dap_client = self._mock_get_land_cover_dap_client
        dap_client_factory.get_soil_properties_dap_client = self._mock_get_soil_properties_dap_client
        self.land_cover_service = LandCoverService(dap_client_factory=dap_client_factory)
        self.model_run_service = ModelRunService()
        self.dataset_service = DatasetService()
        self.parameter_service = ParameterService()
        self.clean_database()
        self.user = self.login()
        self.create_model_run_ready_for_submit()

    @staticmethod
    def _mock_get_land_cover_dap_client(url, key):
        return MockLandCoverDapClient(url, key)

    @staticmethod
    def _mock_get_soil_properties_dap_client(url):
        return MockSoilPropertiesDapClient(url)

    def test_GIVEN_land_cover_regions_exist_WHEN_get_land_cover_region_by_id_THEN_land_cover_region_returned(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        id = land_cover_region.id

        returned_region = self.land_cover_service.get_land_cover_region_by_id(id)
        assert_that(returned_region.id, is_(id))
        assert_that(returned_region.name, is_("Wales"))

    def test_GIVEN_land_cover_categories_WHEN_get_land_cover_region_THEN_returned_region_has_category_loaded(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        id = land_cover_region.id

        with session_scope() as session:
            land_cover_cat = LandCoverRegionCategory()
            land_cover_cat.name = "River Catchments"
            land_cover_cat.driving_dataset_id = model_run.driving_dataset_id
            session.add(land_cover_cat)

        returned_region = self.land_cover_service.get_land_cover_region_by_id(id)
        assert_that(returned_region.category.name, is_("Countries"))

    def test_GIVEN_land_cover_values_WHEN_get_land_cover_values_THEN_land_cover_values_returned(self):
        lc_values = self.land_cover_service.get_land_cover_values(None)
        assert_that(len(lc_values), is_(9))
        names = [lc_value.name for lc_value in lc_values]
        assert 'Urban' in names
        assert constants.FRACTIONAL_ICE_NAME in names

    def test_GIVEN_return_no_ice_WHEN_get_land_cover_values_THEN_land_cover_values_returned(self):
        lc_values = self.land_cover_service.get_land_cover_values(None, return_ice=False)
        assert_that(len(lc_values), is_(8))
        names = [lc_value.name for lc_value in lc_values]
        assert 'Urban' in names
        assert constants.FRACTIONAL_ICE_NAME not in names

    def test_GIVEN_multiple_land_cover_categories_WHEN_get_categories_THEN_correct_categories_returned(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        datasets = self.dataset_service.get_driving_datasets(self.user)

        with session_scope() as session:
            cat1 = LandCoverRegionCategory()
            cat1.name = "Countries"
            cat1.driving_dataset_id = model_run.driving_dataset_id

            region1 = LandCoverRegion()
            region1.mask_file = "filepath"
            region1.name = "Wales"
            region1.category = cat1

            cat2 = LandCoverRegionCategory()
            cat2.name = "Rivers"
            cat2.driving_dataset_id = datasets[1].id

            region2 = LandCoverRegion()
            region2.mask_file = "filepath2"
            region2.name = "Thames"
            region2.category = cat2

            session.add_all([region1, region2])

        categories = self.land_cover_service.get_land_cover_categories(model_run.driving_dataset_id)
        assert_that(len(categories), is_(1))
        assert_that(categories[0].name, is_("Countries"))

    def test_GIVEN_categories_have_land_cover_regions_WHEN_get_categories_THEN_category_has_regions_loaded(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        with session_scope() as session:
            cat1 = LandCoverRegionCategory()
            cat1.name = "Countries"
            cat1.driving_dataset_id = model_run.driving_dataset_id

            region1 = LandCoverRegion()
            region1.mask_file = "filepath"
            region1.name = "Wales"
            region1.category = cat1

            cat2 = LandCoverRegionCategory()
            cat2.name = "Rivers"
            cat2.driving_dataset_id = model_run.driving_dataset_id

            region2 = LandCoverRegion()
            region2.mask_file = "filepath2"
            region2.name = "Thames"
            region2.category = cat2

            session.add_all([region1, region2])

        categories = self.land_cover_service.get_land_cover_categories(model_run.driving_dataset_id)
        assert_that(len(categories[0].regions), is_(1))
        assert_that(categories[0].regions[0].name, is_("Wales"))

    def test_GIVEN_land_cover_actions_WHEN_save_land_cover_actions_THEN_land_cover_actions_saved(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        self.add_land_cover_actions(land_cover_region, model_run, [(1, 1), (2, 3)], self.land_cover_service)

        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
        actions = model_run.land_cover_actions
        assert_that(len(actions), is_(2))

    def test_GIVEN_existing_land_cover_actions_WHEN_save_land_cover_actions_THEN_land_cover_actions_overwritten(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        self.add_land_cover_actions(land_cover_region, model_run, [(1, 1), (2, 3)], self.land_cover_service)

        self.add_land_cover_actions(land_cover_region, model_run, [(2, 4)], self.land_cover_service)

        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
        actions = model_run.land_cover_actions
        assert_that(len(actions), is_(1))
        assert_that(actions[0].value_id, is_(2))
        assert_that(actions[0].order, is_(4))

    def test_GIVEN_no_land_cover_actions_WHEN_save_land_cover_actions_THEN_all_land_cover_actions_removed(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        self.add_land_cover_actions(land_cover_region, model_run, [(1, 1), (2, 3)], self.land_cover_service)

        self.add_land_cover_actions(land_cover_region, model_run, [], self.land_cover_service)

        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
        actions = model_run.land_cover_actions
        assert_that(len(actions), is_(0))

    def test_GIVEN_land_cover_actions_saved_on_model_run_WHEN_get_land_cover_actions_THEN_actions_returned(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        self.add_land_cover_actions(land_cover_region, model_run, [(1, 1), (2, 3)], self.land_cover_service)

        actions = self.land_cover_service.get_land_cover_actions_for_model(model_run)
        assert_that(len(actions), is_(2))
        assert_that(actions[0].value_id, is_(1))
        assert_that(actions[0].order, is_(1))
        assert_that(actions[1].value_id, is_(2))
        assert_that(actions[1].order, is_(3))

    def test_GIVEN_land_cover_actions_saved_WHEN_get_actions_THEN_actions_have_regions_and_categories_loaded(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        self.add_land_cover_actions(land_cover_region, model_run, [(1, 1)], self.land_cover_service)

        action = self.land_cover_service.get_land_cover_actions_for_model(model_run)[0]
        assert_that(action.region.name, is_("Wales"))
        assert_that(action.region.category.name, is_("Countries"))

    def test_GIVEN_land_cover_actions_saved_WHEN_get_actions_THEN_actions_have_values_loaded(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)

        land_cover_region = self.add_land_cover_region(model_run)
        self.add_land_cover_actions(land_cover_region, model_run, [(1, 1)], self.land_cover_service)

        action = self.land_cover_service.get_land_cover_actions_for_model(model_run)[0]
        assert_that(action.value.name, is_("Broad-leaved Tree"))

    def test_GIVEN_fractional_string_WHEN_save_fractional_land_cover_for_model_THEN_fractional_cover_saved(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        assert_that(model_run.land_cover_frac, is_(None))

        fractional_string = "0\t0\t0\t0\t0\t0\t0\t0\t1"
        self.land_cover_service.save_fractional_land_cover_for_model(model_run, fractional_string)

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        assert_that(model_run.land_cover_frac, is_(fractional_string))

    def test_GIVEN_user_uploaded_driving_data_WHEN_get_default_fractional_cover_THEN_fractional_cover_returned(self):
        self.clean_database()
        self.user = self.login()
        self.create_model_run_with_user_uploaded_driving_data()

        model_run = self.set_model_run_latlon(self.user, 70, 0)

        fractional_vals = self.land_cover_service.get_default_fractional_cover(model_run, self.user)
        assert_that(fractional_vals, is_([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]))

    def test_GIVEN_two_matching_datasets_WHEN_get_default_cover_THEN_higher_priority_fractional_cover_returned(self):
        self.clean_database()
        self.user = self.login()
        self.create_model_run_with_user_uploaded_driving_data()

        model_run = self.set_model_run_latlon(self.user, 0, 0)
        fractional_vals = self.land_cover_service.get_default_fractional_cover(model_run, self.user)
        assert_that(fractional_vals, is_([0.02, 0.11, 0.02, 0.05, 0.35, 0.19, 0.22, 0.04, 0.0]))

    def test_GIVEN_no_matching_datasets_WHEN_get_default_cover_THEN_zeros_returned(self):
        self.clean_database()
        self.user = self.login()
        self.create_model_run_with_user_uploaded_driving_data()

        model_run = self.set_model_run_latlon(self.user, 88, 0)
        fractional_vals = self.land_cover_service.get_default_fractional_cover(model_run, self.user)
        assert_that(fractional_vals, is_([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]))

    def test_GIVEN_thredds_not_working_WHEN_get_default_cover_THEN_zeros_returned(self):
        self.clean_database()
        self.user = self.login()
        self.create_model_run_with_user_uploaded_driving_data()

        def _get_broken_dap_client(url, key):
            return MockLandCoverDapClient("broken_url", key)

        dap_client_factory = DapClientFactory()
        dap_client_factory.get_land_cover_dap_client = _get_broken_dap_client
        self.land_cover_service = LandCoverService(dap_client_factory=dap_client_factory)

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        fractional_vals = self.land_cover_service.get_default_fractional_cover(model_run, self.user)
        assert_that(fractional_vals, is_([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]))

    def test_GIVEN_using_provided_driving_data_WHEN_get_default_fractional_cover_THEN_fractional_cover_returned(self):
        self.clean_database()
        self.user = self.login()
        self.create_alternate_model_run()

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        fractional_vals = self.land_cover_service.get_default_fractional_cover(model_run, self.user)
        assert_that(fractional_vals, is_([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]))

    def test_GIVEN_multicell_model_run_WHEN_get_default_fractional_cover_THEN_ServiceException_raised(self):
        self.clean_database()
        self.user = self.login()
        self.create_model_run_ready_for_submit()

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        with self.assertRaises(ServiceException):
            self.land_cover_service.get_default_fractional_cover(model_run, self.user)

    def test_GIVEN_user_uploaded_driving_data_WHEN_set_default_soil_properties_THEN_soil_cover_set(self):
        self.clean_database()
        self.user = self.login()
        self.create_model_run_with_user_uploaded_driving_data()

        model_run = self.set_model_run_latlon(self.user, 51, 0)

        self.land_cover_service.save_default_soil_properties(model_run, self.user)

        #self._land_cover_service.dap_client_factory.get_soil_properties_dap_client = _mock_get_soil_props_client
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        nvars = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_NVARS)
        var = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_VAR, is_list=True)
        use_file = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_USE_FILE, is_list=True)
        const_val = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_CONST_VAL, is_list=True)

        assert_that(nvars, is_(9))
        assert_that(var, is_(['b', 'sathh', 'satcon', 'sm_sat', 'sm_crit', 'sm_wilt', 'hcap', 'hcon', 'albsoil']))
        assert_that(use_file, is_(9 * [False]))
        assert_that(const_val, is_([0.9, 0.0, 0.0, 50.0, 275.0, 278.0, 10.0, 0.0, 0.5]))

    def test_GIVEN_no_appropriate_driving_data_WHEN_set_default_soil_properties_THEN_values_not_set(self):
        self.clean_database()
        self.user = self.login()
        self.create_model_run_with_user_uploaded_driving_data()

        model_run = self.set_model_run_latlon(self.user, 90, 0)

        self.land_cover_service.save_default_soil_properties(model_run, self.user)

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        nvars = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_NVARS)
        var = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_VAR)
        use_file = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_USE_FILE, is_list=True)
        const_val = model_run.get_python_parameter_value(constants.JULES_PARAM_SOIL_PROPS_CONST_VAL, is_list=True)

        assert_that(nvars, is_(None))
        assert_that(var, is_(None))
        assert_that(use_file, is_(None))
        assert_that(const_val, is_(None))

    def set_model_run_latlon(self, user, lat, lon):
        params_to_save = [[constants.JULES_PARAM_POINTS_FILE, [lat, lon]]]
        params_to_del = constants.JULES_PARAM_POINTS_FILE
        self.parameter_service.save_new_parameters(params_to_save, params_to_del, user.id)

        return self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
class ModelRunServiceTest(TestWithFullModelRun):
    def setUp(self):
        super(ModelRunServiceTest, self).setUp()
        self.job_runner_client = JobRunnerClient(config)
        self.model_run_service = ModelRunService(job_runner_client=self.job_runner_client)
        self.clean_database()

    def test_GIVEN_no_model_runs_WHEN_get_model_runs_for_user_THEN_empty_list(self):
        # Add a user who doesn't have any model runs
        with session_scope(Session) as session:
            user = User()
            user.name = 'Has No Model Runs'
            session.add(user)
        # Get the users model runs
        model_runs = self.model_run_service.get_models_for_user(user)
        assert_that(model_runs, is_([]))

    def test_GIVEN_non_existent_user_WHEN_get_model_runs_for_user_THEN_returns_empty_list(self):
        user = User()
        user.id = -100
        user.name = "Doesn't Exist"
        model_runs = self.model_run_service.get_models_for_user(user)
        assert_that(model_runs, is_([]))

    def test_GIVEN_two_users_with_one_model_each_WHEN_get_model_runs_for_user_THEN_returns_correct_model(self):
        # Add two users and give them each one model run
        with session_scope(Session) as session:
            # First add two users
            user1 = User()
            user1.name = 'user1'
            user2 = User()
            user2.name = 'user2'
            session.add_all([user1, user2])
            session.commit()
            # Give them each a model
            model_run1 = ModelRun()
            model_run1.name = "MR1"
            model_run1.user_id = user1.id
            model_run2 = ModelRun()
            model_run2.name = "MR2"
            model_run2.user_id = user2.id
            session.add_all([model_run1, model_run2])
        # Get the users model runs
        model_runs = self.model_run_service.get_models_for_user(user1)
        assert_that(len(model_runs), is_(1))
        assert_that(model_runs[0].name, is_("MR1"))

    def test_GIVEN_user_has_published_model_run_WHEN_get_model_runs_for_user_THEN_published_model_is_returned(self):
        # Add one user and give them a published and unpublished model run
        with session_scope(Session) as session:
            # First add user
            user1 = User()
            user1.name = 'user1'
            session.add(user1)
            session.commit()
            # Give a model
            model_run1 = ModelRun()
            model_run1.name = "MR1"
            model_run1.user_id = user1.id
            model_run1.status = self._status(constants.MODEL_RUN_STATUS_CREATED)
            model_run2 = ModelRun()
            model_run2.name = "MR2"
            model_run2.status = self._status(constants.MODEL_RUN_STATUS_PUBLISHED)
            model_run2.user_id = user1.id
            model_run2.status = self._status(constants.MODEL_RUN_STATUS_COMPLETED)
            session.add_all([model_run1, model_run2])
        # Get the users model runs
        model_runs = self.model_run_service.get_models_for_user(user1)
        assert_that(len(model_runs), is_(2))

    def test_GIVEN_user_has_public_model_run_WHEN_get_model_runs_for_user_THEN_public_model_is_returned(self):
        # Add one user and give them a public and unpublished model run
        with session_scope(Session) as session:
            # First add user
            user1 = User()
            user1.name = 'user1'
            session.add(user1)
            session.commit()
            # Give a model
            model_run1 = ModelRun()
            model_run1.name = "MR1"
            model_run1.user_id = user1.id
            model_run1.status = self._status(constants.MODEL_RUN_STATUS_CREATED)
            model_run2 = ModelRun()
            model_run2.name = "MR2"
            model_run2.status = self._status(constants.MODEL_RUN_STATUS_PUBLIC)
            model_run2.user_id = user1.id
            session.add_all([model_run1, model_run2])
        # Get the users model runs
        model_runs = self.model_run_service.get_models_for_user(user1)
        assert_that(len(model_runs), is_(2))

    def test_GIVEN_user_has_published_model_run_WHEN_get_published_model_runs_THEN_only_published_model_run_returned(self):
        # Add one user and give them a published and unpublished model run
        with session_scope(Session) as session:
            # First add user
            user1 = User()
            user1.name = 'user1'
            session.add(user1)
            session.commit()
            # Give them each a model
            model_run1 = ModelRun()
            model_run1.name = "MR1"
            model_run1.user_id = user1.id
            model_run2 = ModelRun()
            model_run2.name = "MR2"
            model_run2.status = self._status(constants.MODEL_RUN_STATUS_PUBLISHED)
            model_run2.user_id = user1.id
            session.add_all([model_run1, model_run2])
        # Get the published model runs
        model_runs = self.model_run_service.get_published_models()
        assert_that(len(model_runs), is_(1))
        assert_that(model_runs[0].name, is_("MR2"))

    def test_GIVEN_user_has_public_model_run_WHEN_get_published_model_runs_THEN_only_public_model_run_returned(self):
        # Add one user and give them a published and unpublished model run
        with session_scope(Session) as session:
            # First add user
            user1 = User()
            user1.name = 'user1'
            session.add(user1)
            session.commit()
            # Give them each a model
            model_run1 = ModelRun()
            model_run1.name = "MR1"
            model_run1.user_id = user1.id
            model_run2 = ModelRun()
            model_run2.name = "MR2"
            model_run2.status = self._status(constants.MODEL_RUN_STATUS_PUBLIC)
            model_run2.user_id = user1.id
            session.add_all([model_run1, model_run2])
        # Get the published model runs
        model_runs = self.model_run_service.get_published_models()
        assert_that(len(model_runs), is_(1))
        assert_that(model_runs[0].name, is_("MR2"))


    def test_GIVEN_no_published_or_public_runs_WHEN_get_published_model_runs_THEN_empty_list(self):
        model_runs = self.model_run_service.get_published_models()
        assert_that(model_runs, is_([]))

    def test_WHEN_get_user_model_runs_THEN_list_ordered_by_date_created_newest_first(self):
        with session_scope(Session) as session:
            # First add user
            user1 = User()
            user1.name = 'user1'
            session.add(user1)
            session.commit()
            # Create three published models not in datetime order
            model_run1 = ModelRun()
            model_run1.user_id = user1.id
            model_run1.name = "MR1"
            model_run1.date_created = datetime(2013, 12, 7, 17, 15, 30)
            session.add(model_run1)
            session.commit()
            model_run2 = ModelRun()
            model_run2.user_id = user1.id
            model_run2.name = "MR2"
            model_run2.date_created = datetime(2014, 6, 9, 12, 30, 24)
            session.add(model_run2)
            session.commit()
            model_run3 = ModelRun()
            model_run3.user_id = user1.id
            model_run3.name = "MR3"
            model_run3.date_created = datetime(2014, 6, 9, 11, 39, 30)
            session.add_all([model_run1, model_run2, model_run3])
        model_runs = self.model_run_service.get_models_for_user(user1)
        assert_that(model_runs[0].name, is_("MR2"))
        assert_that(model_runs[1].name, is_("MR3"))
        assert_that(model_runs[2].name, is_("MR1"))

    def test_WHEN_get_published_model_runs_THEN_list_ordered_by_date_created_newest_first(self):
        with session_scope(Session) as session:
            # Create three published models not in datetime order
            model_run1 = ModelRun()
            model_run1.name = "MR1"
            model_run1.date_created = datetime(2013, 12, 7, 17, 15, 30)
            model_run1.status = self._status(constants.MODEL_RUN_STATUS_PUBLISHED)
            session.add(model_run1)
            session.commit()
            model_run2 = ModelRun()
            model_run2.name = "MR2"
            model_run2.date_created = datetime(2014, 6, 9, 12, 30, 24)
            model_run2.status = self._status(constants.MODEL_RUN_STATUS_PUBLIC)
            session.add(model_run2)
            session.commit()
            model_run3 = ModelRun()
            model_run3.name = "MR3"
            model_run3.status = self._status(constants.MODEL_RUN_STATUS_PUBLISHED)
            model_run3.date_created = datetime(2014, 6, 9, 11, 39, 30)
            session.add(model_run3)
            session.commit()
        model_runs = self.model_run_service.get_published_models()
        assert_that(model_runs[0].name, is_("MR2"))
        assert_that(model_runs[1].name, is_("MR3"))
        assert_that(model_runs[2].name, is_("MR1"))

    def test_WHEN_get_code_versions_THEN_returns_list_including_default_code_version(self):

        models = self.model_run_service.get_code_versions()

        assert_that(len(models), is_not(0), "There should be at least one code version on the list")
        assert_that([x.name for x in models], has_item(config['default_code_version']), "The list of code versions")

    def test_GIVEN_valid_code_version_id_WHEN_get_code_version_THEN_code_version_returned(self):
        expectedModel = self.model_run_service.get_code_versions()[0]

        model = self.model_run_service.get_code_version_by_id(expectedModel.id)

        assert_that(model.id, is_(expectedModel.id), "Id")
        assert_that(model.name, is_(expectedModel.name), "Name")

    def test_GIVEN_non_existent_code_version_id_WHEN_get_code_version_THEN_raises_NoResultFound_exception(self):
        with self.assertRaises(NoResultFound, msg="Should have thrown a NoResultFound exception"):
            model = self.model_run_service.get_code_version_by_id(-100)

    def test_GIVEN_user_has_model_run_WHEN_get_model_run_by_id_THEN_model_run_returned(self):

        # Add a user and give them a model
        with session_scope(Session) as session:
            # First add user
            user = User()
            user.name = 'user1'
            session.add(user)
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_PUBLIC)
            session.add(model_run)
        # Get the users model runs
        model_run_returned = self.model_run_service.get_model_by_id(user, model_run.id)
        assert_that(model_run_returned.name, is_("MR1"))

    def test_GIVEN_model_run_has_parameters_WHEN_get_model_run_by_id_THEN_model_run_has_parameter_values_loaded(self):
        # Add a user and give them a model
        user = self.login()
        model_run = self.create_run_model(0, "MR1", user)
        with session_scope(Session) as session:
            # Add parameter value
            parameter_value = ParameterValue()
            parameter_value.parameter_id = 1
            parameter_value.set_value_from_python(123)

            parameter = Parameter()
            parameter.name = "Param"
            parameter.parameter_values = [parameter_value]

            # Give them a model
            model_run = session.query(ModelRun).filter(ModelRun.id == model_run.id).one()
            model_run.parameter_values = [parameter_value]
            session.add(model_run)
        with session_scope(Session) as session:
            model_run_id = session.query(ModelRun).filter(ModelRun.name == model_run.name).one().id

        # Get the users model runs
        model_run_returned = self.model_run_service.get_model_by_id(user, model_run_id)
        pv = model_run_returned.parameter_values[0]
        assert_that(pv.value, is_('123'))
        assert_that(pv.parameter.name, is_("Param"))

    def test_GIVEN_model_run_id_belongs_to_another_user_WHEN_get_model_run_by_id_THEN_NoResultFound_exception(self):
        # Add two users and give one a model
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            user2 = User()
            user2.name = 'user2'
            session.add_all([user, user2])
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_COMPLETED)
            session.add(model_run)
        # Get the users model runs
        with self.assertRaises(NoResultFound, msg="Should have thrown a NoResultFound exception"):
            self.model_run_service.get_model_by_id(user2, model_run.id)

    def test_GIVEN_no_defining_model_run_WHEN_get_defining_model_run_THEN_error_returned(self):
        user = self.login()
        with self.assertRaises(NoResultFound, msg="Should have thrown a NoResultFound exception"):self.model_run_service.get_parameters_for_model_being_created(user)

    def test_GIVEN_incomplete_model_WHEN_publish_model_THEN_ServiceException_raised(self):
        # Add a user and give them a model
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            session.add(user)
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_FAILED)
            session.add(model_run)
        # Get the users model runs
        with self.assertRaises(ServiceException, msg="Should have raised a ServiceException"):
            self.model_run_service.publish_model(user, model_run.id)

    def test_GIVEN_model_belongs_to_another_user_WHEN_publish_model_THEN_ServiceException_raised(self):
        # Add two users and give one a model
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            user2 = User()
            user2.name = 'user2'
            session.add_all([user, user2])
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_COMPLETED)
            session.add(model_run)
        # Get the users model runs
        with self.assertRaises(ServiceException, msg="Should have raised a ServiceException"):
            self.model_run_service.publish_model(user2, model_run.id)

    def test_GIVEN_nonexistent_model_id_WHEN_publish_model_THEN_ServiceException_raised(self):
        # Add a user
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            session.add(user)
        with self.assertRaises(ServiceException, msg="Should have raised a ServiceException"):
            self.model_run_service.publish_model(user, -100)

    def test_GIVEN_user_has_completed_model_WHEN_publish_model_THEN_model_published(self):
        # Add a user and give them a model
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            session.add(user)
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_COMPLETED)
            session.add(model_run)
        # Get the users model runs
        self.model_run_service.publish_model(user, model_run.id)
        with session_scope(Session) as session:
            updated_model_run = session.query(ModelRun).join(ModelRunStatus).filter(ModelRun.id == model_run.id).one()
            assert_that(updated_model_run.status.name, is_(constants.MODEL_RUN_STATUS_PUBLISHED))

    def test_GIVEN_complete_model_WHEN_make_public_model_THEN_ServiceException_raised(self):
        # Add a user and give them a model
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            session.add(user)
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_COMPLETED)
            session.add(model_run)
        # Get the users model runs
        with self.assertRaises(ServiceException, msg="Should have raised a ServiceException"):
            self.model_run_service.make_public_model(user, model_run.id)

    def test_GIVEN_model_belongs_to_another_user_WHEN_make_public_model_THEN_ServiceException_raised(self):
        # Add two users and give one a model
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            user2 = User()
            user2.name = 'user2'
            session.add_all([user, user2])
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_PUBLISHED)
            session.add(model_run)
        # Get the users model runs
        with self.assertRaises(ServiceException, msg="Should have raised a ServiceException"):
            self.model_run_service.make_public_model(user2, model_run.id)

    def test_GIVEN_nonexistent_model_id_WHEN_make_public_model_THEN_ServiceException_raised(self):
        # Add a user
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            session.add(user)
        with self.assertRaises(ServiceException, msg="Should have raised a ServiceException"):
            self.model_run_service.make_public_model(user, -100)

    def test_GIVEN_user_has_published_model_WHEN_make_public_model_THEN_model_public(self):
        # Add a user and give them a model
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            session.add(user)
            session.commit()
            # Give them a model
            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_PUBLISHED)
            session.add(model_run)

        # Get the users model runs
        self.model_run_service.make_public_model(user, model_run.id)

        with session_scope(Session) as session:
            updated_model_run = session.query(ModelRun).join(ModelRunStatus).filter(ModelRun.id == model_run.id).one()
            assert_that(updated_model_run.status.name, is_(constants.MODEL_RUN_STATUS_PUBLIC))

    def test_GIVEN_default_science_configurations_THEN_all_configurations_returned(self):

         results = self.model_run_service.get_scientific_configurations()

         assert_that(len(results), greater_than(0), "at least one default configuration")
         assert_that(results[0]['id'], not_none(), "Configuration has an id")
         assert_that(results[0]['name'], not_none(), "Configuration has a name")
         assert_that(results[0]['description'], not_none(), "Configuration has a description")

    def test_GIVEN_model_with_parameters_WHEN_get_parameter_value_THEN_parameter_value_returned(self):
        with session_scope(Session) as session:
            user = User()
            user.name = 'user1'
            session.add(user)
            session.commit()

            param = session.query(Parameter).first()
            param_id = param.id
            param_name = param.name
            param_namelist = param.namelist.name

            model_run = ModelRun()
            model_run.name = "MR1"
            model_run.user_id = user.id
            model_run.status = self._status(constants.MODEL_RUN_STATUS_CREATED)
            session.add(model_run)
            session.commit()

            parameter1 = ParameterValue()
            parameter1.parameter_id = param_id
            parameter1.set_value_from_python("param1 value")
            parameter1.model_run_id = model_run.id
            session.add(parameter1)
        model_run_returned = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        param_value_returned = model_run_returned.get_python_parameter_value([param_namelist, param_name])
        assert_that(param_value_returned, is_("param1 value"))

    def test_GIVEN_no_run_model_WHEN_create_run_model_with_science_config_THEN_model_created_with_parameter_values_copied(self):

        user = self.login()
        expected_name = "model run name"
        expected_description = "some slightly long winded description"

        self.model_run_service.update_model_run(
            user,
            expected_name,
            constants.DEFAULT_SCIENCE_CONFIGURATION,
            expected_description)

        parameter_values_count = self.count_parameter_values_in_model_being_created(user)
        assert_that(parameter_values_count, is_not(0), "parameter values have been set")

    def test_GIVEN_run_model_WHEN_create_run_model_with_same_science_config_THEN_model_updated_with_new_parameter_values_copied(self):

        user = self.login()
        expected_name = "model run name"
        expected_description = "some slightly long winded description"
        self.model_run_service.update_model_run(
            user,
            expected_name,
            constants.DEFAULT_SCIENCE_CONFIGURATION,
            expected_description)
        expected_parameters_count = self.count_parameter_values_in_model_being_created(user)

        self.model_run_service.update_model_run(
            user,
            expected_name,
            constants.DEFAULT_SCIENCE_CONFIGURATION,
            expected_description)

        parameter_values_count = self.count_parameter_values_in_model_being_created(user)
        assert_that(parameter_values_count, is_(expected_parameters_count), "parameter values have been set and old ones removed")

    def test_GIVEN_run_model_with_time_extent_WHEN_create_run_model_with_same_science_config_THEN_model_updated_with_new_parameter_values_copied_and_has_time_extent(self):

        user = self.login()
        expected_name = "model run name"
        expected_description = "some slightly long winded description"
        self.model_run_service.update_model_run(
            user,
            expected_name,
            constants.DEFAULT_SCIENCE_CONFIGURATION,
            expected_description)
        self.model_run_service.save_parameter(constants.JULES_PARAM_LATLON_REGION, True, user)
        expected_parameters_count = self.count_parameter_values_in_model_being_created(user)

        self.model_run_service.update_model_run(
            user,
            expected_name,
            constants.DEFAULT_SCIENCE_CONFIGURATION,
            expected_description)

        parameter_values_count = self.count_parameter_values_in_model_being_created(user)
        assert_that(parameter_values_count, is_(expected_parameters_count), "parameter values have been set and old ones removed")


    def count_parameter_values_in_model_being_created(self, user):
        """
        Count the number of parameter values that this model has
        """
        with session_scope(Session) as session:
            parameter_values = session \
                .query(ParameterValue) \
                .join(ModelRun) \
                .join(ModelRunStatus) \
                .filter(ModelRunStatus.name == constants.MODEL_RUN_STATUS_CREATED) \
                .filter(ModelRun.user == user) \
                .count()
        return parameter_values
class ModelRunServiceDeleteTest(TestWithFullModelRun):
    def setUp(self):
        super(ModelRunServiceDeleteTest, self).setUp()
        self.job_runner_client = JobRunnerClient(config)
        self.model_run_service = ModelRunService(job_runner_client=self.job_runner_client)
        self.clean_database()

    def test_GIVEN_model_doesnot_exist_WHEN_delete_THEN_not_found(self):
        # Add a user who doesn't have any model runs
        with session_scope(Session) as session:
            user = User()
            user.name = 'Has No Model Runs'
            session.add(user)

        # Get the users model runs
        with self.assertRaises(NoResultFound, msg="Should have thrown a NoResultFound exception"):
            model_runs = self.model_run_service.delete_run_model(10000, user)

    def test_GIVEN_model_belongs_to_someone_else_WHEN_delete_THEN_not_found(self):
        # Add a user who doesn't have any model runs
        other_user = self.login("other_user")
        model = self.create_run_model(10, "test", other_user)

        with session_scope(Session) as session:
            user = User()
            user.name = 'Has No Model Runs'
            session.add(user)

        # Get the users model runs
        with self.assertRaises(NoResultFound, msg="Should have thrown a NoResultFound exception"):
            self.model_run_service.delete_run_model(model.id, user)

    def test_GIVEN_model_WHEN_delete_THEN_model_delete_job_runner_called(self):
        # Add a user who doesn't have any model runs
        user = self.login()
        model = self.create_run_model(10, "test", user)
        self.job_runner_client.delete = Mock()

        self.model_run_service.delete_run_model(model.id, user)

        assert_that(self.job_runner_client.delete.called, is_(True), "Job runner called")
        with self.assertRaises(NoResultFound):
            self.model_run_service.get_model_by_id(user, model.id)

    def test_GIVEN_model_belongs_to_someone_else_and_user_is_an_admin_WHEN_delete_THEN_delete_model(self):
        # Add a user who doesn't have any model runs
        self.job_runner_client.delete = Mock()
        other_user = self.login("other_user")
        model = self.create_run_model(10, "test", other_user)
        user = self.login(access_level=constants.USER_ACCESS_LEVEL_ADMIN)

        self.model_run_service.delete_run_model(model.id, user)

        with self.assertRaises(NoResultFound):
            self.model_run_service.get_model_by_id(user, model.id)

    def test_GIVEN_model_belongs_to_someone_else_and_is_published_and_user_is_an_admin_WHEN_delete_THEN_delete_model(self):
        self.job_runner_client.delete = Mock()
        # Add a user who doesn't have any model runs
        other_user = self.login("other_user")
        model = self.create_run_model(10, "test", other_user, constants.MODEL_RUN_STATUS_PUBLISHED)
        user = self.login(access_level=constants.USER_ACCESS_LEVEL_ADMIN)

        self.model_run_service.delete_run_model(model.id, user)

        with self.assertRaises(NoResultFound):
            self.model_run_service.get_model_by_id(user, model.id)

    def test_GIVEN_model_belongs_to_someone_else_and_is_public_and_user_is_an_admin_WHEN_delete_THEN_delete_model(self):
        self.job_runner_client.delete = Mock()
        # Add a user who doesn't have any model runs
        other_user = self.login("other_user")
        model = self.create_run_model(10, "test", other_user, constants.MODEL_RUN_STATUS_PUBLIC)
        user = self.login(access_level=constants.USER_ACCESS_LEVEL_ADMIN)

        self.model_run_service.delete_run_model(model.id, user)

        with self.assertRaises(NoResultFound):
            self.model_run_service.get_model_by_id(user, model.id)

    def test_GIVEN_model_and_is_public_and_user_is_not_an_admin_WHEN_delete_THEN_raise(self):
        self.job_runner_client.delete = Mock()
        # Add a user who doesn't have any model runs
        user = self.login("user")
        model = self.create_run_model(10, "test", user, constants.MODEL_RUN_STATUS_PUBLIC)

        assert_that(calling(self.model_run_service.delete_run_model).with_args(model.id, user),
                    raises(ModelPublished))

    def test_GIVEN_full_model_WHEN_delete_THEN_model_is_deleted(self):

        user = self.login('')
        self.create_model_run_ready_for_submit()
        with session_scope(Session) as session:
            dataset_count = session.query(Dataset).count()
            model = self.model_run_service.get_models_for_user(user)[0]
            dataset = Dataset()
            dataset.model_run_id = model.id
            session.add(dataset)

            region_count = session.query(LandCoverAction).count()
            session.add(LandCoverAction(model_run_id=model.id))

        model_not_to_delete = self.create_run_model(0, "test", user, constants.MODEL_RUN_STATUS_PUBLISHED)
        self.job_runner_client.delete = Mock()

        self.model_run_service.delete_run_model(model.id, user)

        with session_scope(Session) as session:
            count = session.query(ModelRun).filter(ModelRun.id == model.id).count()
        assert_that(count, is_(0), 'Count(Model)')
        with session_scope(Session) as session:
            count = session.query(ModelRun).filter(ModelRun.id == model_not_to_delete.id).count()
        assert_that(count, is_(1), 'Count(Model)')
        with session_scope(Session) as session:
            count = session.query(Dataset).count()
        assert_that(count, is_(dataset_count), 'Count(Datasets)is same as before creating model')
        with session_scope(Session) as session:
            count = session.query(LandCoverAction).count()
        assert_that(count, is_(region_count), 'Count(LandCoverAction)is same as before creating model')

    def test_GIVEN_full_model_WHEN_delete_THEN_parameter_values_are_deleted(self):

        user = self.login('')
        with session_scope(Session) as session:
            pv_count = session.query(ParameterValue).count()

        self.create_model_run_ready_for_submit()
        with session_scope(Session) as session:
            model = self.model_run_service.get_models_for_user(user)[0]
            assert_that(session.query(ParameterValue).count(), greater_than(pv_count), "Creating model run adds parameters")

        self.job_runner_client.delete = Mock()

        self.model_run_service.delete_run_model(model.id, user)

        with session_scope(Session) as session:
            assert_that(session.query(ParameterValue).count(), is_(pv_count), "Parameter values is same as before model was created")
 def setUp(self):
     self.model_run_service = ModelRunService()
     self.land_cover_service = LandCoverService()
Exemple #25
0
class UserController(BaseController):
    """Provides operations for user page actions"""

    _user_service = None
    _dataset_service = None

    def __init__(self,
                 user_service=UserService(),
                 dataset_service=DatasetService(),
                 account_request_service=AccountRequestService()):
        """
        Constructor for the user controller, takes in any services required
        :param user_service: User service to use within the controller
        :param dataset_service: dataset service
        :param account_request_service: accoun requests service
        :return: nothing
        """
        super(UserController, self).__init__(user_service)

        self._dataset_service = dataset_service
        self._model_run_service = ModelRunService()
        self._account_request_service = account_request_service

    def index(self):
        """Allow admin-user to see all users of the system. If user is non-admin, redirect to page not found.
        """

        if self.current_user is not None and self.current_user.is_admin():
            c.all_users = self._user_service.get_all_users()
            user_map = {}
            for user in c.all_users:
                user_map[user.id] = user
                user.storage_in_mb = 0
                user.published_storage_in_mb = 0

            c.storage_total_used_in_gb = 0
            for user_id, status, storage_mb in self._model_run_service.get_storage_used():
                c.storage_total_used_in_gb += int(storage_mb)
                if status == constants.MODEL_RUN_STATUS_PUBLISHED or status == constants.MODEL_RUN_STATUS_PUBLIC:
                    user_map[user_id].published_storage_in_mb += int(storage_mb)
                else:
                    user_map[user_id].storage_in_mb += int(storage_mb)
            c.storage_total_used_in_gb = utils.convert_mb_to_gb_and_round(c.storage_total_used_in_gb)

            c.core_user = None
            for user in c.all_users:
                if user.username == constants.CORE_USERNAME:
                    c.core_user = user

                user.quota_status = ''
                percentage = round(utils.convert_mb_to_gb_and_round(user.storage_in_mb)
                                   / user.storage_quota_in_gb * 100.0, 1)
                if percentage >= constants.QUOTA_ABSOLUTE_LIMIT_PERCENT:
                    user.quota_status = 'error'
                elif percentage >= constants.QUOTA_WARNING_LIMIT_PERCENT:
                    user.quota_status = 'warning'

            c.core_user.quota_status = 'info'

            c.total_storage_percent_used = c.storage_total_used_in_gb / c.core_user.storage_quota_in_gb * 100.0
            c.bar_class = helpers.get_progress_bar_class_name(c.total_storage_percent_used)

            return render('user/list_of_users.html')

        else:

            return render('not_found.html')

    def create(self):
        """Create a new user
        """

        if not self.current_user.access_level == constants.USER_ACCESS_LEVEL_ADMIN:
            return render('not_found.html')

        if not request.POST:
            return render('new_user.html')

        schema = CreateUserForm()
        c.form_errors = {}

        if request.POST:

            try:
                c.form_result = schema.to_python(request.params)

            except formencode.Invalid, error:

                c.form_result = error.value
                c.form_errors = error.error_dict or {}

            user_email = str(c.form_result.get('email'))

            # Username of the user will be set as the user's email address
            # Generate an error if the email address (and hence username) is already taken
            if self._user_service.get_user_by_email_address(user_email):
                c.form_errors = dict(c.form_errors.items() + {
                    'email': 'Email address is already taken - please choose another.'
                }.items())

            if c.form_errors:
                html = render('new_user.html')
                return htmlfill.render(html,
                                       defaults=c.form_result,
                                       errors=c.form_errors,
                                       prefix_error=False,
                                       auto_error_formatter=BaseController.error_formatter)
            else:

                # By default a user will be an external user
                self._user_service.create(c.form_result.get('user_name'),
                                          c.form_result.get('first_name'),
                                          c.form_result.get('last_name'),
                                          user_email,
                                          constants.USER_ACCESS_LEVEL_ADMIN if c.form_result.get('is_admin')
                                          else constants.USER_ACCESS_LEVEL_CEH)
                return redirect(url(controller="user"))
 def setUp(self):
     super(ModelRunServiceDuplicateTest, self).setUp()
     self.job_runner_client = JobRunnerClient(config)
     self.model_run_service = ModelRunService(job_runner_client=self.job_runner_client)
     self.clean_database()
class ModelRunServiceDuplicateTest(TestWithFullModelRun):
    def setUp(self):
        super(ModelRunServiceDuplicateTest, self).setUp()
        self.job_runner_client = JobRunnerClient(config)
        self.model_run_service = ModelRunService(job_runner_client=self.job_runner_client)
        self.clean_database()

    def test_GIVEN_model_doesnot_exist_WHEN_duplicate_THEN_not_found(self):
        # Add a user who doesn't have any model runs
        with session_scope(Session) as session:
            user = User()
            user.name = 'Has No Model Runs'
            session.add(user)

        # Get the users model runs
        with self.assertRaises(NoResultFound, msg="Should have thrown a NoResultFound exception"):
            model_runs = self.model_run_service.duplicate_run_model(10000, user)

    def test_GIVEN_model_belongs_to_someone_else_WHEN_duplicate_THEN_not_found(self):
        # Add a user who doesn't have any model runs
        other_user = self.login("other_user")
        model = self.create_run_model(10, "test", other_user)

        with session_scope(Session) as session:
            user = User()
            user.name = 'Has No Model Runs'
            session.add(user)

        # Get the users model runs
        with self.assertRaises(NoResultFound, msg="Should have thrown a NoResultFound exception"):
            self.model_run_service.duplicate_run_model(model.id, user)

    def test_GIVEN_model_WHEN_duplicate_THEN_model_is_duplicated(self):
        # Add a user who doesn't have any model runs
        user = self.login()
        model = self.create_run_model(10, "test", user)
        model = self.model_run_service.get_model_by_id(user, model.id)
        self.job_runner_client.duplicate = Mock()

        self.model_run_service.duplicate_run_model(model.id, user)

        assert_that(self.job_runner_client.duplicate.called, is_(False), "Job runner not called")
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        assert_that(model_run.name, is_(model.name + " (Copy)"), "names are the same")
        assert_that(model_run.description, is_(model.description), "description are the same")
        assert_that(model_run.driving_dataset_id, is_(model.driving_dataset_id), "driving_dataset_id are the same")
        assert_that(len(model_run.parameter_values), is_(len(model.parameter_values)), "names are the same")
        assert_that(model_run.parameter_values[0].parameter_id, is_(model.parameter_values[0].parameter_id), "first parameter value is for same paramerer")
        assert_that(model_run.parameter_values[0].value, is_(model.parameter_values[0].value), "first parameter value is for same value")

    def test_GIVEN_model_with_land_cover_actions_WHEN_duplicate_THEN_model_is_duplicated(self):
        # Add a user who doesn't have any model runs
        user = self.login()
        model = self.create_run_model(10, "test", user)
        model = self.model_run_service.get_model_by_id(user, model.id)
        with session_scope() as session:
            region1 = LandCoverRegion()
            region2 = LandCoverRegion()
            session.add(region1)
            session.add(region2)
            session.add(LandCoverAction(model_run_id=model.id, order=1, value_id=1, region=region1))
            session.add(LandCoverAction(model_run_id=model.id, order=2, value_id=2, region=region2))
        self.job_runner_client.duplicate = Mock()

        self.model_run_service.duplicate_run_model(model.id, user)

        assert_that(self.job_runner_client.duplicate.called, is_(False), "Job runner not called")
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        with session_scope() as session:
            regions = session.query(LandCoverAction).filter(LandCoverAction.model_run_id == model_run.id).all()

        assert_that(len(regions), is_(2), "regions")
        assert_that(regions[0].value_id, is_(1), "value id")
        assert_that(regions[0].order, is_(1), "order id")
        assert_that(regions[0].region_id, is_(region1.id), "region id")
        assert_that(regions[1].value_id, is_(2), "value id")
        assert_that(regions[1].order, is_(2), "order id")
        assert_that(regions[1].region_id, is_(region2.id), "region id")

    def test_GIVEN_model_belongs_to_someone_else_and_is_published_WHEN_duplicate_THEN_duplicate_model(self):
        self.job_runner_client.delete = Mock()
        # Add a user who doesn't have any model runs
        other_user = self.login("other_user")
        model = self.create_run_model(10, "test", other_user, constants.MODEL_RUN_STATUS_PUBLISHED)
        user = self.login(access_level=constants.USER_ACCESS_LEVEL_ADMIN)

        self.model_run_service.duplicate_run_model(model.id, user)

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        assert_that(model_run.name, is_(model.name), "model name")

    def test_GIVEN_model_belongs_to_someone_else_and_is_public_WHEN_duplicate_THEN_duplicate_model(self):
        self.job_runner_client.delete = Mock()
        # Add a user who doesn't have any model runs
        other_user = self.login("other_user")
        model = self.create_run_model(10, "test", other_user, constants.MODEL_RUN_STATUS_PUBLIC)
        user = self.login()

        self.model_run_service.duplicate_run_model(model.id, user)

        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        assert_that(model_run.name, is_(model.name), "model name")

    def test_GIVEN_model_WHEN_duplicate_and_name_is_same_as_owner_THEN_model_is_duplicated_name_is_changed(self):

        # Add a user who doesn't have any model runs
        user = self.login()
        model = self.create_run_model(10, "test", user)
        self.create_run_model(10, "test (Copy)", user)
        model = self.model_run_service.get_model_by_id(user, model.id)
        self.job_runner_client.duplicate = Mock()

        self.model_run_service.duplicate_run_model(model.id, user)

        assert_that(self.job_runner_client.duplicate.called, is_(False), "Job runner not called")
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        assert_that(model_run.name, is_(model.name + " (Copy 2)"), "names are the same")

    def test_GIVEN_model_run_already_being_created_WHEN_duplicate_THEN_model_is_duplicated_and_created_is_overwritten(self):

        # Add a user who doesn't have any model runs
        user = self.login()
        model_being_created = self.create_run_model(10, "test", user, status=constants.MODEL_RUN_STATUS_CREATED)
        model = self.create_run_model(10, "test", user)
        model = self.model_run_service.get_model_by_id(user, model.id)
        self.job_runner_client.duplicate = Mock()
        self.job_runner_client.delete = Mock()

        self.model_run_service.duplicate_run_model(model.id, user)

        assert_that(self.job_runner_client.duplicate.called, is_(False), "Job runner not called")
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        assert_that(model_run.name, is_(model.name + " (Copy)"), "names are the same")
        with self.assertRaises(NoResultFound):
            self.model_run_service.get_model_by_id(user, model_being_created.id)

    def test_GIVEN_uploaded_driving_data_model_run_WHEN_duplicate_THEN_uploaded_driving_data_is_duplicated(self):

        # Add a user who doesn't have any model runs
        user = self.login()
        model = self.create_run_model(10, "test", user)
        model = self.model_run_service.get_model_by_id(user, model.id)
        id_for_user_upload_driving_dataset = DatasetService().get_id_for_user_upload_driving_dataset()
        with session_scope() as session:
            model = session.query(ModelRun).filter(ModelRun.id == model.id).one()
            model.driving_dataset_id = id_for_user_upload_driving_dataset

        self.job_runner_client.duplicate_uploaded_driving_data = Mock()
        self.job_runner_client.delete = Mock()

        self.model_run_service.duplicate_run_model(model.id, user)

        assert_that(self.job_runner_client.duplicate_uploaded_driving_data.called, is_(True), "Job runner duplicate called")
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
        assert_that(model_run.name, is_(model.name + " (Copy)"), "names are the same")

    def test_GIVEN_uploaded_driving_data_model_run_WHEN_duplicate_and_job_runner_duplicate_fails_THEN_model_is_not_duplicated_exception_is_thrown(self):

        # Add a user who doesn't have any model runs
        error_message = "error"
        user = self.login()
        model = self.create_run_model(10, "test", user)
        model = self.model_run_service.get_model_by_id(user, model.id)
        id_for_user_upload_driving_dataset = DatasetService().get_id_for_user_upload_driving_dataset()
        with session_scope() as session:
            model = session.query(ModelRun).filter(ModelRun.id == model.id).one()
            model.driving_dataset_id = id_for_user_upload_driving_dataset

        self.job_runner_client.duplicate_uploaded_driving_data = Mock(side_effect=ServiceException(error_message))
        self.job_runner_client.delete = Mock()

        with self.assertRaises(ServiceException):
            self.model_run_service.duplicate_run_model(model.id, user)

        with self.assertRaises(NoResultFound):
            self.model_run_service.get_model_being_created_with_non_default_parameter_values(user)
class TestModelRunLandCover(TestController):
    def setUp(self):
        self.clean_database()
        self.user = self.login()
        self.create_two_driving_datasets()
        dds = DatasetService().get_driving_datasets(self.user)[0]
        with session_scope() as session:
            model_run = ModelRun()
            model_run.name = "model run"
            model_run.change_status(session, MODEL_RUN_STATUS_CREATED)
            model_run.user = self.user
            model_run.driving_dataset_id = dds.id
            session.add(model_run)
            session.commit()

            self.model_run_service = ModelRunService()
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)

            parameter_val = ParameterValue()
            parameter_val.parameter = self.model_run_service.get_parameter_by_constant(JULES_PARAM_LATLON_REGION)
            parameter_val.set_value_from_python(True)
            parameter_val.model_run_id = model_run.id
            session.add(parameter_val)

        self.add_land_cover_region(model_run)

    def test_GIVEN_land_cover_actions_WHEN_post_THEN_land_cover_action_saved_in_database(self):
        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
            dds = model_run.driving_dataset
        categories = LandCoverService().get_land_cover_categories(dds.id)
        # Need to know the region IDs
        self.app.post(
            url(controller='model_run', action='land_cover'),
            params={
                'submit': u'Next',
                'action_1_region': str(categories[0].regions[0].id),
                'action_1_value': u'8',
                'action_1_order': u'1',
                'action_2_region': str(categories[0].regions[0].id),
                'action_2_value': u'7',
                'action_2_order': u'2'
            })
        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)

        actions = model_run.land_cover_actions
        assert_that(len(actions), is_(2))
        for action in actions:
            if action.value_id == 8:
                assert_that(action.order, is_(1))
            elif action.value_id == 7:
                assert_that(action.order, is_(2))
            else:
                assert False

    def test_GIVEN_invalid_land_cover_actions_WHEN_post_THEN_error_shown_and_stay_on_page(self):
        # Add some regions to another driving dataset
        dds = DatasetService().get_driving_datasets(self.user)[1]
        with session_scope() as session:
            land_cat = LandCoverRegionCategory()
            land_cat.driving_dataset = dds
            land_cat.name = "Category2"

            land_region = LandCoverRegion()
            land_region.name = "Region1"
            land_region.category = land_cat
            session.add(land_region)

        response = self.app.post(
            url(controller='model_run', action='land_cover'),
            params={
                'submit': u'Next',
                'action_1_region': str(land_region.id),
                'action_1_value': u'8',
                'action_1_order': u'1'
            })
        assert_that(response.normal_body, contains_string("Land Cover"))  # Check still on page
        assert_that(response.normal_body, contains_string("Land Cover Region not valid for the chosen driving data"))

    def test_GIVEN_land_cover_values_and_regions_exist_WHEN_get_THEN_regions_and_categories_rendered(self):
        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
            dds = model_run.driving_dataset
            session.add_all(self.generate_categories_with_regions(dds))

        response = self.app.get(url(controller='model_run', action='land_cover'))

        assert_that(response.normal_body, contains_string("Rivers"))
        assert_that(response.normal_body, contains_string("Thames"))
        assert_that(response.normal_body, contains_string("Itchen"))
        assert_that(response.normal_body, contains_string("Counties"))
        assert_that(response.normal_body, contains_string("Hampshire"))
        assert_that(response.normal_body, contains_string("Oxfordshire"))

    def test_GIVEN_nothing_WHEN_get_THEN_values_rendered(self):
        response = self.app.get(url(controller='model_run', action='land_cover'))

        values = LandCoverService().get_land_cover_values(None, return_ice=False)
        for value in values:
            assert_that(response.normal_body, contains_string(str(value.name)))

    def test_GIVEN_land_cover_action_already_saved_WHEN_get_THEN_action_rendered(self):
        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
            dds = model_run.driving_dataset
            session.add_all(self.generate_categories_with_regions(dds))

            action = LandCoverAction()
            action.model_run = model_run
            action.region_id = 1  # Thames
            action.value_id = 5  # Shrub

        response = self.app.get(url(controller='model_run', action='land_cover'))
        assert_that(response.normal_body, contains_string("Change <b>Thames (Rivers)</b> to <b>Shrub</b>"))

    def test_GIVEN_invalid_land_cover_actions_already_saved_WHEN_get_THEN_errors_returned_no_actions_rendered(self):
        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
            dds = model_run.driving_dataset
            session.add_all(self.generate_categories_with_regions(dds))

            action = LandCoverAction()
            action.model_run = model_run
            action.region_id = 1  # Thames
            action.value_id = 9  # Ice
            session.add(action)
            session.commit()

            # Set the model run to have a different driving dataset - this should result in an error
            model_run.driving_dataset = session.query(DrivingDataset).filter(DrivingDataset.name == "driving2").one()

        response = self.app.get(url(controller='model_run', action='land_cover'))
        assert_that(response.normal_body, contains_string("Your saved Land Cover edits are not valid for the "
                                                          "chosen driving data"))
        assert_that(response.normal_body, is_not(contains_string("Change <b>")))  # Actions start with this

    def test_GIVEN_multiple_land_cover_actions_saved_out_of_order_WHEN_get_THEN_order_rendered_correctly(self):
        with session_scope() as session:
            model_run = self.model_run_service._get_model_run_being_created(session, self.user)
            dds = model_run.driving_dataset
            session.add_all(self.generate_categories_with_regions(dds))

            action = LandCoverAction()
            action.model_run = model_run
            action.region_id = 1  # Thames
            action.value_id = 5  # Shrub
            action.order = 5
            session.add(action)
            session.commit()

            action2 = LandCoverAction()
            action2.model_run = model_run
            action2.region_id = 2  # Itchen
            action2.value_id = 1  # Broad-leaved Tree
            action2.order = 1
            session.add(action2)
            session.commit()

            action3 = LandCoverAction()
            action3.model_run = model_run
            action3.region_id = 3  # Hampshire
            action3.value_id = 6  # Urban
            action3.order = 2
            session.add(action3)
            session.commit()

        response = self.app.get(url(controller='model_run', action='land_cover'))
        order1 = response.normal_body.index("Change <b>Itchen (Rivers)</b> to <b>Broad-leaved Tree</b>")
        order2 = response.normal_body.index("Change <b>Hampshire (Counties)</b> to <b>Urban</b>")
        order5 = response.normal_body.index("Change <b>Thames (Rivers)</b> to <b>Shrub</b>")
        assert (order1 < order2 < order5)

    def generate_categories_with_regions(self, driving_dataset):
        # Add categories
        cat1 = LandCoverRegionCategory()
        cat1.driving_dataset_id = driving_dataset.id
        cat1.name = "Rivers"
        cat1.id = 1

        region1 = LandCoverRegion()
        region1.id = 1
        region1.name = "Thames"
        region1.category_id = 1
        region1.category = cat1

        region2 = LandCoverRegion()
        region2.id = 2
        region2.name = "Itchen"
        region2.category_id = 1
        region2.category = cat1

        cat1.regions = [region1, region2]

        cat2 = LandCoverRegionCategory()
        cat2.driving_dataset_id = driving_dataset.id
        cat2.name = "Counties"
        cat2.id = 2

        region3 = LandCoverRegion()
        region3.id = 3
        region3.name = "Hampshire"
        region3.category_id = 2
        region3.category = cat2

        region4 = LandCoverRegion()
        region4.id = 4
        region4.name = "Oxfordshire"
        region4.category_id = 2
        region4.category = cat2

        cat2.regions = [region3, region4]

        return [cat1, cat2]
class TestModelRunExtents(TestController):
    def setUp(self):
        super(TestModelRunExtents, self).setUp()
        self.clean_database()
        self.user = self.login()
        self.model_run_service = ModelRunService()
        with session_scope(Session) as session:
            self.driving_data = DrivingDataset()
            self.driving_data.name = "d1"
            self.driving_data.boundary_lat_north = 47.5
            self.driving_data.boundary_lat_south = 13.8
            self.driving_data.boundary_lon_east = 123.1
            self.driving_data.boundary_lon_west = -15.0
            self.driving_data.time_start = datetime.datetime(1901, 1, 1, 0, 0, 0)
            self.driving_data.time_end = datetime.datetime(2001, 1, 1, 0, 0, 0)
            session.add(self.driving_data)
            session.commit()

            self.model_run = ModelRun()
            self.model_run.name = "MR1"
            self.model_run.status = self._status(MODEL_RUN_STATUS_CREATED)
            self.model_run.driving_dataset_id = self.driving_data.id
            self.model_run.user = self.user
            self.model_run.science_configuration_id = 2

            param1 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_INTERP)
            pv1 = ParameterValue()
            pv1.parameter_id = param1.id
            pv1.set_value_from_python(8 * ['nf'])

            param2 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_PERIOD)
            pv2 = ParameterValue()
            pv2.parameter_id = param2.id
            pv2.set_value_from_python(60 * 60)

            self.model_run.parameter_values = [pv1, pv2]
            session.add(self.model_run)

    def set_up_single_cell_user_driving_data(self):
        self.clean_database()
        del self.driving_data
        self.user = self.login()
        user_upload_id = DatasetService().get_id_for_user_upload_driving_dataset()
        with session_scope(Session) as session:
            self.model_run = ModelRun()
            self.model_run.name = "MR1"
            self.model_run.status = self._status(MODEL_RUN_STATUS_CREATED)
            self.model_run.driving_dataset_id = user_upload_id
            self.model_run.user = self.user
            self.model_run.driving_data_lat = 25
            self.model_run.driving_data_lon = 40
            self.model_run.driving_data_rows = 248
            self.model_run.science_configuration_id = 2

            param1 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_INTERP)
            pv1 = ParameterValue()
            pv1.parameter_id = param1.id
            pv1.set_value_from_python(8 * ['nf'])

            param2 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_PERIOD)
            pv2 = ParameterValue()
            pv2.parameter_id = param2.id
            pv2.set_value_from_python(60 * 60)

            param3 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_START)
            pv3 = ParameterValue()
            pv3.parameter_id = param3.id
            pv3.value = "'1901-01-01 00:00:00'"

            param4 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_END)
            pv4 = ParameterValue()
            pv4.parameter_id = param4.id
            pv4.value = "'1901-01-31 21:00:00'"

            self.model_run.parameter_values = [pv1, pv2, pv3, pv4]
            session.add(self.model_run)

    def test_GIVEN_no_created_model_WHEN_page_get_THEN_redirect_to_create(self):
        self.clean_database()
        self.login()
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path, is_(url(controller='model_run', action='create')), "url")

    def test_GIVEN_no_driving_dataset_selected_for_model_WHEN_page_get_THEN_redirect_to_driving_data(self):
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        with session_scope(Session) as session:
            model_run.driving_dataset_id = None
            session.add(model_run)
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='driving_data')), "url")

    def test_GIVEN_nothing_WHEN_page_get_THEN_extents_page_rendered(self):
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string("Specify Model Run Extents"))
        self.assert_model_run_creation_action(self.user, 'extents')

    def test_GIVEN_driving_dataset_selected_for_model_WHEN_page_get_THEN_driving_data_spatial_extents_rendered(self):
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string(str(self.driving_data.boundary_lat_north)))
        assert_that(response.normal_body, contains_string(str(self.driving_data.boundary_lat_south)))
        assert_that(response.normal_body, contains_string(str(self.driving_data.boundary_lon_east)))
        assert_that(response.normal_body, contains_string(str(self.driving_data.boundary_lon_west)))

    def test_GIVEN_driving_dataset_selected_for_model_WHEN_page_get_THEN_driving_data_temporal_extents_rendered(self):
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string("1901-01-01"))
        assert_that(response.normal_body, contains_string("1911-01-01"))

    def test_GIVEN_multi_cell_spatial_extents_already_chosen_WHEN_page_get_THEN_existing_extents_rendered(self):
        self.model_run_service.save_parameter(JULES_PARAM_LON_BOUNDS, [12.3, 35.5], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LAT_BOUNDS, [50, 70], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_USE_SUBGRID, True, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LATLON_REGION, True, self.user)
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string("12.3"))
        assert_that(response.normal_body, contains_string("35.5"))
        assert_that(response.normal_body, contains_string("50"))
        assert_that(response.normal_body, contains_string("70"))

    def test_GIVEN_single_cell_spatial_extents_already_chosen_WHEN_page_get_THEN_existing_extents_rendered(self):
        self.model_run_service.save_parameter(JULES_PARAM_USE_SUBGRID, True, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LATLON_REGION, False, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_NPOINTS, 1, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_POINTS_FILE, [55, 12.3], self.user)
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string("55"))
        assert_that(response.normal_body, contains_string("12.3"))

    def test_GIVEN_temporal_extents_already_chosen_WHEN_page_get_THEN_existing_extents_rendered(self):
        self.model_run_service.save_parameter(JULES_PARAM_LON_BOUNDS, [12.3, 35.5], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LAT_BOUNDS, [50, 70], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_USE_SUBGRID, True, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LATLON_REGION, True, self.user)
        start_time = datetime.datetime(1935, 3, 5, 17, 12, 11)
        end_time = datetime.datetime(1969, 7, 21, 20, 17, 00)
        self.model_run_service.save_parameter(JULES_PARAM_RUN_START, start_time, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_RUN_END, end_time, self.user)
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string(start_time.strftime("%Y-%m-%d")))
        assert_that(response.normal_body, contains_string(end_time.strftime("%Y-%m-%d")))

    def test_GIVEN_invalid_multi_cell_spatial_extents_already_chosen_WHEN_page_get_THEN_errors_shown(self):
        self.model_run_service.save_parameter(JULES_PARAM_LON_BOUNDS, [40, 500], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LAT_BOUNDS, [20, 25], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_USE_SUBGRID, True, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LATLON_REGION, True, self.user)
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string("Longitude must be between -180 and 180"))

    def test_GIVEN_invalid_single_cell_spatial_extents_already_chosen_WHEN_page_get_THEN_errors_shown(self):
        self.model_run_service.save_parameter(JULES_PARAM_USE_SUBGRID, True, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LATLON_REGION, False, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_NPOINTS, 1, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_POINTS_FILE, [55, 593], self.user)
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string("Longitude must be between -180 and 180"))

    def test_GIVEN_invalid_temporal_extents_already_chosen_WHEN_page_get_THEN_errors_shown(self):
        self.model_run_service.save_parameter(JULES_PARAM_LON_BOUNDS, [12.3, 35.5], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LAT_BOUNDS, [50, 70], self.user)
        self.model_run_service.save_parameter(JULES_PARAM_USE_SUBGRID, True, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_LATLON_REGION, True, self.user)
        start_time = datetime.datetime(1900, 10, 14, 17, 12, 11)
        end_time = datetime.datetime(1969, 7, 21, 20, 17, 00)
        self.model_run_service.save_parameter(JULES_PARAM_RUN_START, start_time, self.user)
        self.model_run_service.save_parameter(JULES_PARAM_RUN_END, end_time, self.user)
        response = self.app.get(
            url(controller='model_run', action='extents'))
        assert_that(response.normal_body, contains_string("Start date cannot be earlier than 1901-01-01"))

    def test_GIVEN_invalid_multi_cell_spatial_extents_WHEN_post_THEN_errors_rendered(self):
        response = self.app.post(
            url(controller='model_run', action='extents'),
            params={
                'submit': u'Next',
                'site': u'multi',
                'lat_n': 25,
                'lat_s': 20,
                'lon_e': 40,
                'lon_w': 500,
                'start_date': '1940-10-13',
                'end_date': '1950-10-13'
            })
        assert_that(response.normal_body, contains_string("Longitude must be between -180 and 180"))

    def test_GIVEN_invalid_single_cell_spatial_extents_WHEN_post_THEN_errors_rendered(self):
        response = self.app.post(
            url(controller='model_run', action='extents'),
            params={
                'submit': u'Next',
                'site': u'single',
                'lat': -88,
                'lon': 40,
                'start_date': '1940-10-13',
                'end_date': '1950-10-13'
            })
        assert_that(response.normal_body, contains_string("Latitude (-88 deg N) cannot be south of 13.8 deg N"))

    def test_GIVEN_invalid_temporal_extents_WHEN_post_THEN_errors_rendered(self):
        response = self.app.post(
            url(controller='model_run', action='extents'),
            params={
                'submit': u'Next',
                'site': u'multi',
                'lat_n': 25,
                'lat_s': 20,
                'lon_e': 40,
                'lon_w': 35,
                'start_date': '1900-10-14',
                'end_date': '1950-10-13'
            })
        assert_that(response.normal_body, contains_string("Start date cannot be earlier than 1901-01-01"))

    def test_GIVEN_valid_multi_cell_extents_WHEN_post_THEN_extents_saved(self):
        self.app.post(
            url(controller='model_run', action='extents'),
            params={
                'submit': u'Next',
                'site': u'multi',
                'lat_n': 25,
                'lat_s': 20,
                'lon_e': 40,
                'lon_w': 35,
                'start_date': '1940-10-13',
                'end_date': '1950-10-13'
            })
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        lat_bounds = model_run.get_parameter_values(JULES_PARAM_LAT_BOUNDS)[0].value
        lon_bounds = model_run.get_parameter_values(JULES_PARAM_LON_BOUNDS)[0].value
        use_subgrid = model_run.get_parameter_values(JULES_PARAM_USE_SUBGRID)[0].value
        latlon_region = model_run.get_parameter_values(JULES_PARAM_LATLON_REGION)[0].value
        start_run = model_run.get_parameter_values(JULES_PARAM_RUN_START)[0].value
        end_run = model_run.get_parameter_values(JULES_PARAM_RUN_END)[0].value
        assert_that(lat_bounds, is_("20    25"))
        assert_that(lon_bounds, is_("35    40"))
        assert_that(use_subgrid, is_(".true."))
        assert_that(latlon_region, is_(".true."))
        assert_that(str(start_run), is_("'1940-10-13 00:00:00'"))
        assert_that(str(end_run), is_("'1950-10-13 23:00:00'"))  # Time is moved forward to match the acceptable end

    def test_GIVEN_valid_single_cell_extents_WHEN_post_THEN_extents_saved(self):
        self.set_up_single_cell_user_driving_data()
        self.app.post(
            url(controller='model_run', action='extents'),
            params={
                'submit': u'Next',
                'site': u'single',
                'lat': 25,
                'lon': 40,
                'start_date': '1901-01-4',
                'end_date': '1901-01-13',
                'average_over_cell': 1
            })
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        pointfile = model_run.get_parameter_values(JULES_PARAM_POINTS_FILE)[0].value
        n_points = model_run.get_parameter_values(JULES_PARAM_NPOINTS)[0].value
        use_subgrid = model_run.get_parameter_values(JULES_PARAM_USE_SUBGRID)[0].value
        latlon_region = model_run.get_parameter_values(JULES_PARAM_LATLON_REGION)[0].value
        l_point_data = model_run.get_parameter_values(JULES_PARAM_SWITCHES_L_POINT_DATA)[0].value
        start_run = model_run.get_parameter_values(JULES_PARAM_RUN_START)[0].value
        end_run = model_run.get_parameter_values(JULES_PARAM_RUN_END)[0].value
        assert_that(pointfile, is_("25    40"))
        assert_that(n_points, is_("1"))
        assert_that(use_subgrid, is_(".true."))
        assert_that(latlon_region, is_(".false."))
        assert_that(l_point_data, is_(".false."))
        assert_that(str(start_run), is_("'1901-01-04 00:00:00'"))
        assert_that(str(end_run), is_("'1901-01-13 20:00:00'"))  # Interpolation flag brings us forward an hour

    def test_GIVEN_valid_extents_WHEN_post_THEN_redirect_to_output(self):
        response = self.app.post(
            url(controller='model_run', action='extents'),
            params={
                'submit': u'Next',
                'site': u'multi',
                'lat_n': 25,
                'lat_s': 20,
                'lon_e': 40,
                'lon_w': 35,
                'start_date': '1940-10-13',
                'end_date': '1950-10-13'
            })
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='land_cover')), "url")

    def test_GIVEN_valid_extents_and_user_over_quota_WHEN_post_THEN_redirect_to_catalogue(self):
        self.create_run_model(storage_in_mb=self.user.storage_quota_in_gb * 1024 + 1, name="big_run", user=self.user)

        response = self.app.post(
            url(controller='model_run', action='extents'),
            params={
                'submit': u'Next',
                'site': u'multi',
                'lat_n': 25,
                'lat_s': 20,
                'lon_e': 40,
                'lon_w': 35,
                'start_date': '1940-10-13',
                'end_date': '1950-10-13'
            })
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='index')), "url")

    def test_GIVEN_bng_WHEN_bng_to_latlon_service_called_THEN_correct_latlon_returned(self):
        # BNG test values are from http://www.bgs.ac.uk/data/webservices/convertForm.cfm
        bng_easting = 429157
        bng_northing = 623009
        lat = 55.5
        lon = -1.54
        delta = 0.00001
        response = self.app.post(
            url(controller='model_run', action='bng_to_latlon'),
            params={
                'bng_easting': bng_easting,
                'bng_northing': bng_northing
            })
        json = response.json_body
        assert_that(json['lat'], is_(close_to(lat, delta)))
        assert_that(json['lon'], is_(close_to(lon, delta)))

    def test_GIVEN_invalid_bng_WHEN_bng_to_latlon_service_called_THEN_error_returned(self):
        response = self.app.post(
            url(controller='model_run', action='bng_to_latlon'),
            params={
                'bng_easting': u'asd',
                'bng_northing': u'1.1,23413'
            })
        json = response.json_body
        assert_that(json['is_error'], is_(True))
class TestModelRunLandCoverSingleCell(TestController):
    def setUp(self):
        self.model_run_service = ModelRunService()
        self.land_cover_service = LandCoverService()

    def set_up_single_cell_model_run(self):
        self.clean_database()
        self.user = self.login()
        self.create_two_driving_datasets()
        user_upload_id = DatasetService().get_id_for_user_upload_driving_dataset()
        with session_scope(Session) as session:
            self.model_run = ModelRun()
            self.model_run.name = "MR1"
            self.model_run.status = self._status(MODEL_RUN_STATUS_CREATED)
            self.model_run.driving_dataset_id = user_upload_id
            self.model_run.user = self.user
            self.model_run.driving_data_lat = 51.75
            self.model_run.driving_data_lon = -0.25
            self.model_run.driving_data_rows = 248

            param1 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_INTERP)
            pv1 = ParameterValue()
            pv1.parameter_id = param1.id
            pv1.set_value_from_python(8 * ['nf'])

            param2 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_PERIOD)
            pv2 = ParameterValue()
            pv2.parameter_id = param2.id
            pv2.set_value_from_python(60 * 60)

            param3 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_START)
            pv3 = ParameterValue()
            pv3.parameter_id = param3.id
            pv3.value = "'1901-01-01 00:00:00'"

            param4 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_DRIVE_DATA_END)
            pv4 = ParameterValue()
            pv4.parameter_id = param4.id
            pv4.value = "'1901-01-31 21:00:00'"

            param5 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_LATLON_REGION)
            pv5 = ParameterValue()
            pv5.parameter_id = param5.id
            pv5.value = ".false."

            param6 = self.model_run_service.get_parameter_by_constant(JULES_PARAM_POINTS_FILE)
            pv6 = ParameterValue()
            pv6.parameter_id = param6.id
            pv6.value = "51.75 -0.25"

            self.model_run.parameter_values = [pv1, pv2, pv3, pv4, pv5, pv6]
            session.add(self.model_run)

    def test_GIVEN_single_cell_run_WHEN_page_get_THEN_fractional_cover_page_shown(self):
        self.set_up_single_cell_model_run()
        response = self.app.get(url(controller='model_run', action='land_cover'))
        assert_that(response.normal_body, contains_string("Fractional Land Cover"))

    def test_GIVEN_land_cover_values_WHEN_page_get_THEN_land_cover_type_names_rendered(self):
        self.set_up_single_cell_model_run()
        response = self.app.get(url(controller='model_run', action='land_cover'))
        lc_vals = self.land_cover_service.get_land_cover_values(None)
        del lc_vals[-1]  # Remove the ice
        names = [str(val.name) for val in lc_vals]
        assert_that(response.normal_body, string_contains_in_order(*names))

    def test_GIVEN_available_driving_datasets_WHEN_page_get_THEN_default_fractional_cover_rendered(self):
        self.set_up_single_cell_model_run()
        response = self.app.get(url(controller='model_run', action='land_cover'))
        lc_vals = self.land_cover_service.get_land_cover_values(None)
        del lc_vals[-1]  # Remove the ice
        string_names_values = []
        for val in lc_vals:
            string_names_values.append(str(val.name))
            string_names_values.append('12.5')
        assert_that(response.normal_body, string_contains_in_order(*string_names_values))

    def test_GIVEN_saved_land_cover_frac_WHEN_page_get_THEN_saved_values_rendered(self):
        self.set_up_single_cell_model_run()
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        frac_string = "0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.72 0.0"
        self.land_cover_service.save_fractional_land_cover_for_model(model_run, frac_string)

        response = self.app.get(url(controller='model_run', action='land_cover'))

        lc_vals = self.land_cover_service.get_land_cover_values(None)
        del lc_vals[-1]  # Remove the ice

        string_names_values = []
        for i in range(len(lc_vals)):
            string_names_values.append(str(lc_vals[i].name))
            string_names_values.append(str(100 * float(frac_string.split()[i])))
        assert_that(response.normal_body, string_contains_in_order(*string_names_values))

    def test_GIVEN_saved_land_cover_with_too_few_types_WHEN_page_get_THEN_available_values_rendered(self):
        self.set_up_single_cell_model_run()
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        frac_string = "0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.72"
        self.land_cover_service.save_fractional_land_cover_for_model(model_run, frac_string)

        response = self.app.get(url(controller='model_run', action='land_cover'))

        lc_vals = self.land_cover_service.get_land_cover_values(None)
        del lc_vals[-1]  # Remove the ice

        string_names_values = []
        for i in range(len(lc_vals)):
            string_names_values.append(str(lc_vals[i].name))
            string_names_values.append(str(100 * float(frac_string.split()[i])))
        assert_that(response.normal_body, string_contains_in_order(*string_names_values))

    def test_GIVEN_saved_land_cover_with_too_many_types_WHEN_page_get_THEN_some_values_rendered(self):
        self.set_up_single_cell_model_run()
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        frac_string = "0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.72 0.0 0.0"
        self.land_cover_service.save_fractional_land_cover_for_model(model_run, frac_string)

        response = self.app.get(url(controller='model_run', action='land_cover'))

        lc_vals = self.land_cover_service.get_land_cover_values(None)
        del lc_vals[-1]  # Remove the ice

        string_names_values = []
        for i in range(len(lc_vals)):
            string_names_values.append(str(lc_vals[i].name))
            string_names_values.append(str(100 * float(frac_string.split()[i])))
        assert_that(response.normal_body, string_contains_in_order(*string_names_values))

    def test_GIVEN_valid_fractional_cover_WHEN_post_THEN_values_saved(self):
        self.set_up_single_cell_model_run()
        self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'submit': u'Next',
                    'fractional_cover': u'1',
                    'land_cover_value_1': u'20',
                    'land_cover_value_2': u'25',
                    'land_cover_value_3': u'5',
                    'land_cover_value_4': u'10',
                    'land_cover_value_5': u'10',
                    'land_cover_value_6': u'5',
                    'land_cover_value_7': u'10',
                    'land_cover_value_8': u'15'})
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        assert_that(model_run.land_cover_frac, is_("0.2\t0.25\t0.05\t0.1\t0.1\t0.05\t0.1\t0.15\t0"))

    def test_GIVEN_valid_fractional_cover_WHEN_post_THEN_default_soil_props_saved(self):
        self.set_up_single_cell_model_run()
        self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'submit': u'Next',
                    'fractional_cover': u'1',
                    'land_cover_value_1': u'20',
                    'land_cover_value_2': u'25',
                    'land_cover_value_3': u'5',
                    'land_cover_value_4': u'10',
                    'land_cover_value_5': u'10',
                    'land_cover_value_6': u'5',
                    'land_cover_value_7': u'10',
                    'land_cover_value_8': u'15'})
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        soil_props = model_run.get_python_parameter_value(JULES_PARAM_SOIL_PROPS_CONST_VAL, is_list=True)
        assert_that(soil_props, is_([0.9, 0.0, 0.0, 50.0, 275.0, 300.0, 10.0, 0.0, 0.5]))

    def test_GIVEN_ice_fractional_cover_WHEN_post_THEN_values_saved(self):
        self.set_up_single_cell_model_run()
        self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'submit': u'Next',
                    'fractional_cover': u'1',
                    'land_cover_ice': u'1'})
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        assert_that(model_run.land_cover_frac, is_("0\t0\t0\t0\t0\t0\t0\t0\t1"))

    def test_GIVEN_valid_fractional_cover_WHEN_post_THEN_moved_to_next_page(self):
        self.set_up_single_cell_model_run()
        response = self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'submit': u'Next',
                    'fractional_cover': u'1',
                    'land_cover_value_1': u'20',
                    'land_cover_value_2': u'25',
                    'land_cover_value_3': u'5',
                    'land_cover_value_4': u'10',
                    'land_cover_value_5': u'10',
                    'land_cover_value_6': u'5',
                    'land_cover_value_7': u'10',
                    'land_cover_value_8': u'15'})
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='output')), "url")

    def test_GIVEN_fractional_cover_saved_WHEN_reset_THEN_cover_reset(self):
        self.set_up_single_cell_model_run()
        self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'submit': u'Next',
                    'fractional_cover': u'1',
                    'land_cover_value_1': u'20',
                    'land_cover_value_2': u'25',
                    'land_cover_value_3': u'5',
                    'land_cover_value_4': u'10',
                    'land_cover_value_5': u'10',
                    'land_cover_value_6': u'5',
                    'land_cover_value_7': u'10',
                    'land_cover_value_8': u'15'})
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        initial_cover = model_run.land_cover_frac
        assert initial_cover is not None
        response = self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'reset_fractional_cover': u'1'})
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='land_cover')), "url")
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        final_cover = model_run.land_cover_frac
        assert_that(final_cover, is_(None))

    def test_GIVEN_values_dont_add_up_WHEN_post_THEN_errors_returned_and_values_not_saved(self):
        self.set_up_single_cell_model_run()
        response = self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'submit': u'Next',
                    'fractional_cover': u'1',
                    'land_cover_value_1': u'40',
                    'land_cover_value_2': u'25',
                    'land_cover_value_3': u'5',
                    'land_cover_value_4': u'10',
                    'land_cover_value_5': u'10',
                    'land_cover_value_6': u'5',
                    'land_cover_value_7': u'10',
                    'land_cover_value_8': u'15'})
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        assert_that(model_run.land_cover_frac, is_(None))
        assert_that(response.normal_body, contains_string("The sum of all the land cover fractions must be 100%"))
        assert_that(response.normal_body, contains_string("Fractional Land Cover"))

    def test_GIVEN_values_dont_add_up_WHEN_post_THEN_values_still_present_on_page(self):
        self.set_up_single_cell_model_run()
        response = self.app.post(
            url(controller='model_run', action='land_cover'),
            params={'submit': u'Next',
                    'fractional_cover': u'1',
                    'land_cover_value_1': u'40',
                    'land_cover_value_2': u'25',
                    'land_cover_value_3': u'5',
                    'land_cover_value_4': u'10',
                    'land_cover_value_5': u'10',
                    'land_cover_value_6': u'5',
                    'land_cover_value_7': u'10',
                    'land_cover_value_8': u'15'})

        lc_vals = self.land_cover_service.get_land_cover_values(None)
        del lc_vals[-1]  # Remove the ice
        frac_vals = ['40', '25', '5', '10', '10', '5', '10', '15']
        string_names_values = []
        for i in range(len(lc_vals)):
            string_names_values.append(str(lc_vals[i].name))
            string_names_values.append(str(frac_vals[i]))
        assert_that(response.normal_body, string_contains_in_order(*string_names_values))

    def test_GIVEN_no_extents_selected_WHEN_page_get_THEN_redirect(self):
        self.set_up_single_cell_model_run()
        param = self.model_run_service.get_parameter_by_constant(JULES_PARAM_POINTS_FILE)
        model_run = self.model_run_service.get_model_being_created_with_non_default_parameter_values(self.user)
        with session_scope() as session:
            session.query(ParameterValue) \
                .filter(ParameterValue.parameter_id == param.id) \
                .filter(ParameterValue.model_run_id == model_run.id) \
                .delete()

        response = self.app.get(url(controller='model_run', action='land_cover'))
        assert_that(response.status_code, is_(302), "Response is redirect")
        assert_that(urlparse(response.response.location).path,
                    is_(url(controller='model_run', action='extents')), "url")