def test_list_field_from_db_value(self, mock_tp): ret = ListField() ret.from_db_value(value='foo', expression='exp', connection='con', context='ctx') mock_tp.assert_called_with('foo')
def test_list_field_clean(self, mock_sc, mock_gpv): ret = ListField() input_value = 'foo' input_model_instance = mock.MagicMock() output = mock_sc.return_value ret.clean(value=input_value, model_instance=input_model_instance) mock_sc.assert_called_with(input_value, input_model_instance) mock_gpv.assert_called_with(output)
def test_list_field_value_to_string(self, mock_gpvo, mock_gpv): ret = ListField() output = mock_gpvo.return_value mock_obj = mock.MagicMock() ret.value_to_string(obj=mock_obj) mock_gpvo.assert_called_with(mock_obj) mock_gpv.assert_called_with(output)
class TethysApp(models.Model): """ DB Model for Tethys Apps """ # The package is enforced to be unique by the file system package = models.CharField(max_length=200, unique=True, default='') # Portal admin first attributes name = models.CharField(max_length=200, default='') description = models.TextField(max_length=1000, blank=True, default='') enable_feedback = models.BooleanField(default=False) feedback_emails = ListField(default='', blank=True) tags = models.CharField(max_length=200, blank=True, default='') # Developer first attributes index = models.CharField(max_length=200, default='') icon = models.CharField(max_length=200, default='') root_url = models.CharField(max_length=200, default='') color = models.CharField(max_length=10, default='') # Portal admin only attributes enabled = models.BooleanField(default=True) show_in_apps_library = models.BooleanField(default=True) class Meta: permissions = ( ('view_app', 'Can see app in library'), ('access_app', 'Can access app'), ) verbose_name = 'Tethys App' verbose_name_plural = 'Installed Apps' def __unicode__(self): return unicode(self.name)
def test_tethys_apps_context_feedback(self, mock_get_active_app): mock_args = mock.MagicMock() app = TethysApp() app.id = 'foo.id' app.name = models.CharField(max_length=200, default='') app.name.value = 'foo.name' app.icon = models.CharField(max_length=200, default='') app.icon.value = 'foo.icon' app.color = models.CharField(max_length=10, default='') app.color.value = '#foobar' app.tags = models.CharField(max_length=200, blank=True, default='') app.tags.value = 'tags' app.description = models.TextField(max_length=1000, blank=True, default='') app.description.value = 'foo.description' app.enable_feedback = models.BooleanField(default=True) app.enable_feedback.value = True app.feedback_emails = ListField(default='', blank=True) app.feedback_emails.append('foo.feedback') mock_get_active_app.return_value = app context = tethys_apps_context(mock_args) mock_get_active_app.assert_called_once() self.assertEqual('foo.id', context['tethys_app']['id']) self.assertEqual('foo.name', context['tethys_app']['name'].value) self.assertEqual('foo.icon', context['tethys_app']['icon'].value) self.assertEqual('#foobar', context['tethys_app']['color'].value) self.assertEqual('tags', context['tethys_app']['tags'].value) self.assertEqual('foo.description', context['tethys_app']['description'].value) self.assertTrue('enable_feedback' in context['tethys_app']) self.assertTrue('feedback_emails' in context['tethys_app']) self.assertEqual(True, context['tethys_app']['enable_feedback'].value) self.assertEqual(['foo.feedback'], context['tethys_app']['feedback_emails'])
def test_ListField(self): ret = ListField() self.assertEqual('List object', ret.description)
def test_list_field_formfield(self, mock_ff): ret = ListField() ret.formfield(additional='test2') mock_ff.assert_called_once()
def test_list_field_get_internal_type(self): ret = ListField() self.assertEqual('TextField', ret.get_internal_type())
def test_list_field_get_prep_value_list(self, mock_jd): ret = ListField() input_value = ['foo', 'bar'] ret.get_prep_value(value=input_value) mock_jd.assert_called_with(input_value)
def test_list_field_to_python_empty_str(self): ret = ListField() self.assertListEqual([], ret.to_python(value=""))
def test_list_field_to_python_dict(self): ret = ListField() input_value = {'name': 'bar'} output = ret.to_python(value=input_value) self.assertListEqual([], output)
def test_list_field_to_python_str_ValueError(self, mock_jl): ret = ListField() mock_jl.side_effect = ValueError self.assertRaises(ValueError, ret.to_python, value='foo')
def test_list_field_to_python_list(self): ret = ListField() input_value = ['foo', 'bar'] output = ret.to_python(value=input_value) self.assertListEqual(input_value, output)
def test_list_field_to_python_str(self, mock_jl): ret = ListField() ret.to_python(value='foo') mock_jl.assert_called_with('foo')
def test_list_field_to_python_none(self): ret = ListField() self.assertIsNone(ret.to_python(value=None))
class CondorJob(TethysJob): """ Condor job type """ executable = models.CharField(max_length=1024) condorpy_template_name = models.CharField(max_length=1024, blank=True, null=True) attributes = DictionaryField(default='') remote_input_files = ListField(default='') cluster_id = models.IntegerField(blank=True, default=0) num_jobs = models.IntegerField(default=1) remote_id = models.CharField(max_length=32, blank=True, null=True) tethys_job = models.OneToOneField(TethysJob) scheduler = models.ForeignKey(Scheduler, blank=True, null=True) STATUS_MAP = { 'Unexpanded': 'PEN', 'Idle': 'SUB', 'Running': 'RUN', 'Removed': 'ABT', 'Completed': 'COM', 'Held': 'ERR', 'Submission_err': 'ERR', 'Various': 'VAR', 'Various-Complete': 'VCP', } def __init__(self, *args, **kwargs): kwargs.update({'_subclass': self.__class__.__name__.lower()}) super(self.__class__, self).__init__(*args, **kwargs) @property def condorpy_template(self): if self.condorpy_template_name: template = getattr(Templates, self.condorpy_template_name) else: template = Templates.base return template @property def condorpy_job(self): if not hasattr(self, '_condorpy_job'): if 'executable' in self.attributes.keys(): del self.attributes['executable'] if self.scheduler: host = self.scheduler.host username = self.scheduler.username password = self.scheduler.password private_key = self.scheduler.private_key_path private_key_pass = self.scheduler.private_key_pass else: host = None username = None password = None private_key = None private_key_pass = None attributes = dict() attributes.update(self.attributes) attributes.pop('remote_input_files', None) job = Job(name=self.name.replace(' ', '_'), attributes=self.condorpy_template, executable=self.executable, host=host, username=username, password=password, private_key=private_key, private_key_pass=private_key_pass, remote_input_files=self.remote_input_files, working_directory=self.workspace, **attributes) job._cluster_id = self.cluster_id job._num_jobs = self.num_jobs if self.remote_id: job._remote_id = self.remote_id else: self.remote_id = job._remote_id self._condorpy_job = job return self._condorpy_job @property def statuses(self): return self.condorpy_job.statuses @property def initial_dir(self): return os.path.join(self.workspace, self.condorpy_job.initial_dir) def _update_status(self): if not self.execute_time: return 'PEN' try: condor_status = self.condorpy_job.status if condor_status == 'Various': statuses = self.condorpy_job.statuses running_statuses = statuses['Unexpanded'] + statuses[ 'Idle'] + statuses['Running'] if not running_statuses: condor_status = 'Various-Complete' except Exception, e: # raise e condor_status = 'Submission_err' self._status = self.STATUS_MAP[condor_status] self.save()
class CondorPyJob(models.Model): """ Database model for condorpy jobs """ condorpyjob_id = models.AutoField(primary_key=True) _attributes = DictionaryField(default='') _num_jobs = models.IntegerField(default=1) _remote_input_files = ListField(default='') @classmethod def get_condorpy_template(cls, template_name): template_name = template_name or 'base' template = getattr(Templates, template_name) if not template: template = Templates.base return template @property def condorpy_job(self): if not hasattr(self, '_condorpy_job'): job = Job(name=self.name.replace(' ', '_'), attributes=self.attributes, num_jobs=self.num_jobs, remote_input_files=self.remote_input_files, working_directory=self.workspace) self._condorpy_job = job return self._condorpy_job @property def attributes(self): return self._attributes # @attributes.setter # def attributes(self, attributes): # assert isinstance(attributes, dict) # self.condorpy_job._attributes = attributes # self._attributes = attributes @property def num_jobs(self): return self._num_jobs @num_jobs.setter def num_jobs(self, num_jobs): num_jobs = int(num_jobs) self.condorpy_job.num_jobs = num_jobs self._num_jobs = num_jobs @property def remote_input_files(self): return self._remote_input_files @remote_input_files.setter def remote_input_files(self, remote_input_files): self.condorpy_job.remote_input_files = remote_input_files self._remote_input_files = remote_input_files @property def initial_dir(self): return os.path.join(self.workspace, self.condorpy_job.initial_dir) def get_attribute(self, attribute): self.condorpy_job.get(attribute) def set_attribute(self, attribute, value): setattr(self.condorpy_job, attribute, value) def update_database_fields(self): self._attributes = self.condorpy_job.attributes self.num_jobs = self.condorpy_job.num_jobs self.remote_input_files = self.condorpy_job.remote_input_files
class TethysApp(models.Model, TethysBaseMixin): """ DB Model for Tethys Apps """ # The package is enforced to be unique by the file system package = models.CharField(max_length=200, unique=True, default='') # Portal admin first attributes name = models.CharField(max_length=200, default='') description = models.TextField(max_length=1000, blank=True, default='') enable_feedback = models.BooleanField(default=False) feedback_emails = ListField(default='', blank=True) tags = models.CharField(max_length=200, blank=True, default='') # Developer first attributes index = models.CharField(max_length=200, default='') icon = models.CharField(max_length=200, default='') root_url = models.CharField(max_length=200, default='') color = models.CharField(max_length=10, default='') # Portal admin only attributes enabled = models.BooleanField(default=True) show_in_apps_library = models.BooleanField(default=True) class Meta: permissions = ( ('view_app', 'Can see app in library'), ('access_app', 'Can access app'), ) verbose_name = 'Tethys App' verbose_name_plural = 'Installed Apps' def __str__(self): return self.name def add_settings(self, setting_list): """ Associate setting with app in database """ if setting_list is not None: for setting in setting_list: # Don't add the same setting twice if self.settings_set.filter(name=setting.name): return # Associate setting with this app setting.tethys_app = self setting.save() @property def settings(self): return self.settings_set.select_subclasses() @property def custom_settings(self): return self.settings_set.exclude(customsetting__isnull=True) \ .select_subclasses('customsetting') @property def dataset_service_settings(self): return self.settings_set.exclude(datasetservicesetting__isnull=True) \ .select_subclasses('datasetservicesetting') @property def spatial_dataset_service_settings(self): return self.settings_set.exclude(spatialdatasetservicesetting__isnull=True) \ .select_subclasses('spatialdatasetservicesetting') @property def wps_services_settings(self): return self.settings_set.exclude(webprocessingservicesetting__isnull=True) \ .select_subclasses('webprocessingservicesetting') @property def persistent_store_connection_settings(self): return self.settings_set.exclude(persistentstoreconnectionsetting__isnull=True) \ .select_subclasses('persistentstoreconnectionsetting') @property def persistent_store_database_settings(self): return self.settings_set.exclude(persistentstoredatabasesetting__isnull=True) \ .select_subclasses('persistentstoredatabasesetting') @property def configured(self): required_settings = [s for s in self.settings if s.required] for setting in required_settings: try: if setting.get_value() is None: return False except TethysAppSettingNotAssigned: return False return True
def test_list_field_get_prep_value_str(self): ret = ListField() self.assertEqual('foo', ret.get_prep_value(value='foo'))
class CondorPyJob(models.Model): """ Database model for condorpy jobs """ condorpyjob_id = models.AutoField(primary_key=True) _attributes = DictionaryField(default='') _num_jobs = models.IntegerField(default=1) _remote_input_files = ListField(default='') def __init__(self, *args, **kwargs): # if condorpy_template_name or attributes is passed in then get the template and add it to the _attributes attributes = kwargs.pop('attributes', dict()) _attributes = kwargs.get('_attributes', dict()) attributes.update(_attributes) condorpy_template_name = kwargs.pop('condorpy_template_name', None) if condorpy_template_name is not None: template = self.get_condorpy_template(condorpy_template_name) template.update(attributes) attributes = template kwargs['_attributes'] = attributes super(CondorPyJob, self).__init__(*args, **kwargs) @classmethod def get_condorpy_template(cls, template_name): template_name = template_name or 'base' template = getattr(Templates, template_name, None) if not template: template = Templates.base return template @property def condorpy_job(self): if not hasattr(self, '_condorpy_job'): job = Job(name=self.name.replace(' ', '_'), attributes=self.attributes, num_jobs=self.num_jobs, remote_input_files=self.remote_input_files, working_directory=self.workspace) self._condorpy_job = job return self._condorpy_job @property def attributes(self): return self._attributes @attributes.setter def attributes(self, attributes): assert isinstance(attributes, dict) self._attributes = attributes self.condorpy_job._attributes = attributes @property def num_jobs(self): return self._num_jobs @num_jobs.setter def num_jobs(self, num_jobs): num_jobs = int(num_jobs) self.condorpy_job.num_jobs = num_jobs self._num_jobs = num_jobs @property def remote_input_files(self): return self._remote_input_files @remote_input_files.setter def remote_input_files(self, remote_input_files): self.condorpy_job.remote_input_files = remote_input_files self._remote_input_files = remote_input_files @property def initial_dir(self): return os.path.join(self.workspace, self.condorpy_job.initial_dir) def get_attribute(self, attribute): return self.condorpy_job.get(attribute) def set_attribute(self, attribute, value): setattr(self.condorpy_job, attribute, value) def update_database_fields(self): self._attributes = self.condorpy_job.attributes self.num_jobs = self.condorpy_job.num_jobs self.remote_input_files = self.condorpy_job.remote_input_files