def setUp(self):
     super(TestDrivingDataHelper, self).setUp()
     self.mock_job_runner_client = Mock(JobRunnerClient)
     self.mock_job_runner_client.open_file = Mock()
     self.mock_job_runner_client.append_to_file = Mock()
     self.mock_job_runner_client.delete_file = Mock()
     self.mock_job_runner_client.close_file = Mock()
     self.driving_data_helper = DrivingDataControllerHelper(job_runner_client=self.mock_job_runner_client)
     self.start_date = datetime.datetime(2012, 1, 1, 0, 0, 0)
     self.end_date = datetime.datetime(2012, 1, 1, 2, 0, 0)
class TestDrivingDataHelper(BaseTest):
    def setUp(self):
        super(TestDrivingDataHelper, self).setUp()
        self.mock_job_runner_client = Mock(JobRunnerClient)
        self.mock_job_runner_client.open_file = Mock()
        self.mock_job_runner_client.append_to_file = Mock()
        self.mock_job_runner_client.delete_file = Mock()
        self.mock_job_runner_client.close_file = Mock()
        self.driving_data_helper = DrivingDataControllerHelper(job_runner_client=self.mock_job_runner_client)
        self.start_date = datetime.datetime(2012, 1, 1, 0, 0, 0)
        self.end_date = datetime.datetime(2012, 1, 1, 2, 0, 0)

    def test_GIVEN_valid_file_WHEN_parse_THEN_accepted_and_properties_correct(self):
        file_content = ["# solar   long  rain  snow    temp   wind     press      humid\n",
                        "# sw_down   lw_down  tot_rain  tot_snow    t   wind     pstar      q\n",
                        "# i   i  i  i    i   i     i      i\n",
                        "3.3  187.8   0.0   0.0  259.10  3.610  102400.5  1.351E-03\n",
                        "89.5  185.8   0.0   0.0  259.45  3.140  102401.9  1.357E-03\n",
                        "142.3  186.4   0.0   0.0  259.85  2.890  102401.0  1.369E-03\n",
                        "# ----- data for later times ----"]

        self.driving_data_helper._process_driving_data_file(file_content, self.start_date, self.end_date, 1)

        assert_that(self.driving_data_helper.var_list, is_(['sw_down', 'lw_down', 'tot_rain',
                                                            'tot_snow', 't', 'wind', 'pstar', 'q']))
        assert_that(self.driving_data_helper.n_lines, is_(3))
        assert_that(self.driving_data_helper.interp_list, is_(8 * ['i']))

        assert self.driving_data_helper.job_runner_client.start_new_file.called
        assert self.driving_data_helper.job_runner_client.append_to_file.called
        assert self.driving_data_helper.job_runner_client.close_file.called

    def test_GIVEN_file_with_missing_header_WHEN_parse_THEN_raises_DrivingDataParsingException(self):
        with self.assertRaises(DrivingDataParsingException):
            bad_file_content = ["# solar   long  rain  snow    temp   wind     press      humid\n",
                                "3.3  187.8   0.0   0.0  259.10  3.610  102400.5  1.351E-03\n",
                                "89.5  185.8   0.0   0.0  259.45  3.140  102401.9  1.357E-03\n",
                                "142.3  186.4   0.0   0.0  259.85  2.890  102401.0  1.369E-03\n",
                                "# ----- data for later times ----"]
            self.driving_data_helper._process_driving_data_file(bad_file_content, self.start_date, self.end_date, 1)

    def test_GIVEN_file_with_too_few_interps_in_header_WHEN_parse_THEN_raises_DrivingDataParsingException(self):
        with self.assertRaises(DrivingDataParsingException):
            bad_file_content = ["# solar   long  rain  snow    temp   wind     press      humid\n",
                                "# sw_down   lw_down  tot_rain  tot_snow    t   wind     pstar      q\n",
                                "# i   i  i  i    i   i     i\n",
                                "3.3  187.8   0.0   0.0  259.10  3.610  102400.5  1.351E-03\n",
                                "89.5  185.8   0.0   0.0  259.45  3.140  102401.9  1.357E-03\n",
                                "142.3  186.4   0.0   0.0  259.85  2.890  102401.0  1.369E-03\n",
                                "# ----- data for later times ----"]
            self.driving_data_helper._process_driving_data_file(bad_file_content, self.start_date, self.end_date, 1)

    def test_GIVEN_file_with_invalid_interps_in_header_WHEN_parse_THEN_raises_DrivingDataParsingException(self):
        with self.assertRaises(DrivingDataParsingException):
            bad_file_content = ["# solar   long  rain  snow    temp   wind     press      humid\n",
                                "# sw_down   lw_down  tot_rain  tot_snow    t   wind     pstar      q\n",
                                "# i   i  i  i    i   i  x   i\n",
                                "3.3  187.8   0.0   0.0  259.10  3.610  102400.5  1.351E-03\n",
                                "89.5  185.8   0.0   0.0  259.45  3.140  102401.9  1.357E-03\n",
                                "142.3  186.4   0.0   0.0  259.85  2.890  102401.0  1.369E-03\n",
                                "# ----- data for later times ----"]
            self.driving_data_helper._process_driving_data_file(bad_file_content, self.start_date, self.end_date, 1)

    def test_GIVEN_file_with_invalid_vars_in_header_WHEN_parse_THEN_raises_DrivingDataParsingException(self):
        with self.assertRaises(DrivingDataParsingException):
            bad_file_content = ["# solar   long  rain  snow    temp   wind     press      humid\n",
                                "# sw_down   lw_down  xxx  tot_snow    t   wind     pstar      q\n",
                                "# i   i  i  i    i   i   i   i\n",
                                "3.3  187.8   0.0   0.0  259.10  3.610  102400.5  1.351E-03\n",
                                "89.5  185.8   0.0   0.0  259.45  3.140  102401.9  1.357E-03\n",
                                "142.3  186.4   0.0   0.0  259.85  2.890  102401.0  1.369E-03\n",
                                "# ----- data for later times ----"]
            self.driving_data_helper._process_driving_data_file(bad_file_content, self.start_date, self.end_date, 1)

    def test_GIVEN_file_with_two_few_numbers_in_row_WHEN_parse_THEN_raises_DrivingDataParsingException(self):
        with self.assertRaises(DrivingDataParsingException):
            bad_file_content = ["# solar   long  rain  snow    temp   wind     press      humid\n",
                                "# sw_down   lw_down  tot_rain  tot_snow    t   wind     pstar      q\n",
                                "# i   i  i  i    i   i     i      i\n",
                                "3.3  187.8   0.0   0.0  259.10  3.610  102400.5  1.351E-03\n",
                                "89.5  185.8   0.0   0.0  259.45  3.140  102401.9  1.357E-03\n",
                                "142.3  186.4   0.0   0.0  259.85  2.890  1.369E-03\n",
                                "# ----- data for later times ----"]
            self.driving_data_helper._process_driving_data_file(bad_file_content, self.start_date, self.end_date, 1)

    def test_GIVEN_file_with_invalid_number_in_data_WHEN_parse_THEN_raises_DrivingDataParsingException(self):
        with self.assertRaises(DrivingDataParsingException):
            bad_file_content = ["# solar   long  rain  snow    temp   wind     press      humid\n",
                                "# sw_down   lw_down  tot_rain  tot_snow    t   wind     pstar      q\n",
                                "# i   i  i  i    i   i     i      i\n",
                                "3.3  187.8   0.0   0.0  259.10  3.610  102400.5  1.351E-03\n",
                                "89.5  185.8   0.0   0.0  259.45  apple  102401.9  1.357E-03\n",
                                "142.3  186.4   0.0   0.0  259.85  2.890  102401.0  1.369E-03\n",
                                "# ----- data for later times ----"]
            self.driving_data_helper._process_driving_data_file(bad_file_content, self.start_date, self.end_date, 1)
Esempio n. 3
0
    def driving_data(self):
        """
        Select a driving data set
        """
        driving_data_controller_helper = DrivingDataControllerHelper()

        model_run = None
        try:
            model_run = \
                self._model_run_service.get_model_being_created_with_non_default_parameter_values(self.current_user)
        except NoResultFound:
            helpers.error_flash(u"You must create a model run before you can choose a driving data set")
            redirect(url(controller='model_run', action='create'))

        driving_datasets = self._dataset_service.get_driving_datasets(self.current_user)
        user_upload_ds_id = self._dataset_service.get_id_for_user_upload_driving_dataset()
        errors = {}

        c.driving_datasets = driving_datasets
        c.user_upload_ds_id = user_upload_ds_id
        c.driving_data_rows = model_run.driving_data_rows

        if not request.POST:
            self._user_service.set_current_model_run_creation_action(self.current_user, "driving_data")

            values = driving_data_controller_helper.create_values_dict_from_database(model_run)

            if len(driving_datasets) == 0:
                abort_with_error("There are no driving datasets available - cannot create a new model run")

            # If the chosen driving dataset value is None, set it to the first in the list
            if values['driving_dataset'] is None:
                values['driving_dataset'] = driving_datasets[0].id

            c.errors = errors
            html = render('model_run/driving_data.html')
            return htmlfill.render(
                html,
                defaults=values,
                errors=errors,
                auto_error_formatter=BaseController.error_formatter)
        else:
            # This is a post
            values = dict(request.params)

            # Get the action to perform and remove it from the dictionary
            action = values['submit']
            del values['submit']

            old_driving_dataset = None
            if model_run.driving_dataset_id is not None:
                old_driving_dataset = find_by_id(driving_datasets, model_run.driving_dataset_id)

            if action == u'Upload':
                # This is a request to to upload a driving data file
                try:
                    driving_data_controller_helper.save_uploaded_driving_data(values, errors,
                                                                              self._model_run_service,
                                                                              old_driving_dataset,
                                                                              self.current_user)
                    if len(errors) == 0:
                        # Reload the current page
                        helpers.success_flash("Your driving data file has been successfully uploaded.")
                        redirect(url(controller='model_run', action='driving_data'))
                        return
                    else:
                        c.errors = errors
                        helpers.error_flash("Errors were present in the upload information: please check below.")
                        html = render('model_run/driving_data.html')
                        return htmlfill.render(
                            html,
                            defaults=values,
                            errors=errors,
                            auto_error_formatter=BaseController.error_formatter)
                except ServiceException as e:
                    helpers.error_flash(e.message)
                    redirect(url(controller='model_run', action='driving_data'))
            elif action == u'Download':
                # This is a request to to download driving data
                try:
                    file_generator = driving_data_controller_helper.download_driving_data(values, errors, response)

                    if len(errors) > 0:
                        c.errors = errors
                        helpers.error_flash("Errors were present in the download information: please check below.")
                        return htmlfill.render(
                            render('model_run/driving_data.html'),
                            defaults=values,
                            errors=errors,
                            auto_error_formatter=BaseController.error_formatter)
                    # This will stream the file to the browser without loading it all in memory
                    # BUT only if the .ini file does not have 'debug=true' enabled
                    return file_generator
                except (DapClientException, ServiceException) as e:
                    helpers.error_flash("Couldn't download data: %s." % e.message)
                    redirect(url(controller='model_run', action='driving_data'))
            else:

                try:
                    driving_dataset = find_by_id(driving_datasets, int(values['driving_dataset']))
                except (KeyNotFound, KeyError):
                    errors['driving_dataset'] = 'Driving data not recognised'
                    html = render('model_run/driving_data.html')
                    return htmlfill.render(
                        html,
                        defaults=values,
                        errors=errors,
                        auto_error_formatter=BaseController.error_formatter)
                # If the new selected driving dataset is NOT a user uploaded dataset:
                if driving_dataset.id != user_upload_ds_id:
                    # If the previous driving dataset was a user uploaded driving dataset we need to create an uploaded
                    # driving dataset so that the parameters are removed:
                    if old_driving_dataset is not None:
                        if old_driving_dataset.id == user_upload_ds_id:
                            old_driving_dataset = driving_data_controller_helper. \
                                _create_uploaded_driving_dataset(None, None, None, None, self._model_run_service)
                    self._model_run_service.save_driving_dataset_for_new_model(
                        driving_dataset,
                        old_driving_dataset,
                        self.current_user)
                else:
                    # If the selected driving dataset is the user uploaded dataset we can't proceed if the driving
                    # data has not already been uploaded:
                    if not model_run.driving_data_rows:
                        errors['driving-file'] = 'You must upload a driving data file'
                        c.errors = errors
                        html = render('model_run/driving_data.html')
                        return htmlfill.render(
                            html,
                            defaults=values,
                            errors=errors,
                            auto_error_formatter=BaseController.error_formatter)

                        # If the chosen ds_id is 'upload' and they have already uploaded data then we need do nothing

                self._model_run_controller_helper.check_user_quota(self.current_user)

                if action == u'Next':
                    redirect(url(controller='model_run', action='extents'))
                else:
                    redirect(url(controller='model_run', action='create'))