def test_fetch_next_job(self) -> None: """Test the fetch_next_jobs method.""" exp1_id = u'1' state_name = 'Home' interaction_id = 'TextInput' exp2_id = u'2' job1_id = self._create_classifier_training_job( feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id] ['algorithm_id'], interaction_id, exp1_id, 1, datetime.datetime.utcnow(), [], state_name, feconf.TRAINING_JOB_STATUS_NEW, {}, 1) self._create_classifier_training_job( feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id] ['algorithm_id'], interaction_id, exp2_id, 1, datetime.datetime.utcnow(), [], state_name, feconf.TRAINING_JOB_STATUS_PENDING, {}, 1) # This will get the job_id of the exploration created in setup. classifier_services.fetch_next_job() next_job = classifier_services.fetch_next_job() # Ruling out the possibility of None for mypy type checking. assert next_job is not None self.assertEqual(job1_id, next_job.job_id) # This will check if 'fetch_next_job' returns None # when there are no job models to be fetched from # the job queue. next_job = classifier_services.fetch_next_job() self.assertIsNone(next_job)
def test_fetch_next_job(self): """Test the fetch_next_jobs method.""" exp1_id = u'1' state_name = 'Home' interaction_id = 'TextInput' exp2_id = u'2' job1_id = classifier_services.create_classifier_training_job( feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id] ['algorithm_id'], interaction_id, exp1_id, 1, state_name, [], feconf.TRAINING_JOB_STATUS_NEW) classifier_services.create_classifier_training_job( feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id] ['algorithm_id'], interaction_id, exp2_id, 1, state_name, [], feconf.TRAINING_JOB_STATUS_PENDING) # This will get the job_id of the exploration created in setup. classifier_services.fetch_next_job() next_job = classifier_services.fetch_next_job() self.assertEqual(job1_id, next_job.job_id)
def post(self): """Handles POST requests.""" response = {} next_job = classifier_services.fetch_next_job() if next_job is not None: classifier_services.mark_training_job_pending(next_job.job_id) response['job_id'] = next_job.job_id response['algorithm_id'] = next_job.algorithm_id response['algorithm_version'] = next_job.algorithm_version response['training_data'] = next_job.training_data return self.render_json(response)
def test_migrate_state_training_jobs(self): """Test the migrate_state_training_jobs method.""" state_name = 'Home' mock_interaction_classifier_mapping = { 'TextInput': { 'algorithm_id': 'NewTextClassifier', 'algorithm_version': 1 }, } with self.swap( feconf, 'INTERACTION_CLASSIFIER_MAPPING', mock_interaction_classifier_mapping): classifier_services.migrate_state_training_jobs( classifier_services.get_state_training_jobs_mapping( self.exp_id, 1, state_name) ) state_training_jobs_mapping = ( classifier_services.get_state_training_jobs_mapping( self.exp_id, 1, 'Home') ) self.assertIn( 'NewTextClassifier', state_training_jobs_mapping.algorithm_ids_to_job_ids) # Check migration of an existing algorithm to a newer version. mock_interaction_classifier_mapping = { 'TextInput': { 'algorithm_id': 'NewTextClassifier', 'algorithm_version': 2 }, } with self.swap( feconf, 'INTERACTION_CLASSIFIER_MAPPING', mock_interaction_classifier_mapping): classifier_services.migrate_state_training_jobs( classifier_services.get_state_training_jobs_mapping( self.exp_id, 1, state_name)) next_job = classifier_services.fetch_next_job() self.assertEqual( mock_interaction_classifier_mapping[ 'TextInput']['algorithm_version'], next_job.algorithm_version )
def test_migrate_state_training_jobs(self) -> None: """Test the migrate_state_training_jobs method.""" state_name = 'Home' mock_interaction_classifier_mapping = { 'TextInput': { 'algorithm_id': 'NewTextClassifier', 'algorithm_version': 1 }, } expected_state_training_jobs = ( classifier_services.get_state_training_jobs_mapping( self.exp_id, 1, state_name)) # Ruling out the possibility of None for mypy type checking. assert expected_state_training_jobs is not None with self.swap(feconf, 'INTERACTION_CLASSIFIER_MAPPING', mock_interaction_classifier_mapping): classifier_services.migrate_state_training_jobs( expected_state_training_jobs) state_training_jobs_mapping = ( classifier_services.get_state_training_jobs_mapping( self.exp_id, 1, 'Home')) # Ruling out the possibility of None for mypy type checking. assert state_training_jobs_mapping is not None self.assertIn('NewTextClassifier', state_training_jobs_mapping.algorithm_ids_to_job_ids) # Check migration of an existing algorithm to a newer version. mock_interaction_classifier_mapping = { 'TextInput': { 'algorithm_id': 'NewTextClassifier', 'algorithm_version': 2 }, } with self.swap(feconf, 'INTERACTION_CLASSIFIER_MAPPING', mock_interaction_classifier_mapping): classifier_services.migrate_state_training_jobs( expected_state_training_jobs) next_job = classifier_services.fetch_next_job() # Ruling out the possibility of None for mypy type checking. assert next_job is not None self.assertEqual( mock_interaction_classifier_mapping['TextInput'] ['algorithm_version'], next_job.algorithm_version)
def post(self): """Handles POST requests.""" signature = self.payload.get('signature') vm_id = self.payload.get('vm_id') message = self.payload.get('message') if vm_id == feconf.DEFAULT_VM_ID and not feconf.DEV_MODE: raise self.UnauthorizedUserException if not verify_signature(message, vm_id, signature): raise self.UnauthorizedUserException response = {} next_job = classifier_services.fetch_next_job() if next_job is not None: classifier_services.mark_training_job_pending(next_job.job_id) response['job_id'] = next_job.job_id response['algorithm_id'] = next_job.algorithm_id response['training_data'] = next_job.training_data return self.render_json(response)