def test_init_with_identical_jobs(self): A = make_job("A") second_A = make_job("A") third_A = make_job("A") session = SessionState([A, second_A, third_A]) # But we don't really store both, just the first one self.assertEqual(session.job_list, [A])
def test_get_vote(self): """ verify how CompositeQualifier.get_vote() behaves in various situations """ # Default is IGNORE self.assertEqual( CompositeQualifier([]).get_vote(make_job("foo")), IJobQualifier.VOTE_IGNORE) # Any match is INCLUDE self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo"), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_INCLUDE) # Any negative match is EXCLUDE self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo", inclusive=False), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_EXCLUDE) # Negative matches take precedence over positive matches self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo"), RegExpJobQualifier("foo", inclusive=False), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_EXCLUDE) # Unrelated patterns are not affecting the result self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo"), RegExpJobQualifier("bar"), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_INCLUDE)
def setUp(self): self.A = make_job('a', name='A') self.B = make_job('b', name='B', plugin='local', description='foo') self.C = make_job('c', name='C') self.D = self.B.create_child_job_from_record( RFC822Record(data={ 'id': 'd', 'name': 'D', 'plugin': 'shell' }, origin=Origin(source=JobOutputTextSource(self.B), line_start=1, line_end=1))) self.E = self.B.create_child_job_from_record( RFC822Record(data={ 'id': 'e', 'name': 'E', 'plugin': 'shell' }, origin=Origin(source=JobOutputTextSource(self.B), line_start=1, line_end=1))) self.F = make_job('f', name='F', plugin='resource', description='baz') self.tree = SelectableJobTreeNode.create_tree( [self.A, self.B, self.C, self.D, self.E, self.F], legacy_mode=True)
def test_get_job_map_find_duplicates(self): A = make_job('A') another_A = make_job('A') with self.assertRaises(DependencyDuplicateError) as call: DependencySolver._get_job_map([A, another_A]) self.assertIs(call.exception.job, A) self.assertIs(call.exception.duplicate_job, another_A)
def setUp(self): self.A = make_job('a', name='A') self.B = make_job('b', name='B', plugin='local', description='foo') self.C = make_job('c', name='C') self.D = self.B.create_child_job_from_record( RFC822Record( data={'id': 'd', 'name': 'D', 'plugin': 'shell'}, origin=Origin(source=JobOutputTextSource(self.B), line_start=1, line_end=1))) self.E = self.B.create_child_job_from_record( RFC822Record( data={'id': 'e', 'name': 'E', 'plugin': 'shell'}, origin=Origin(source=JobOutputTextSource(self.B), line_start=1, line_end=1))) self.F = make_job('f', name='F', plugin='resource', description='baz') self.tree = SelectableJobTreeNode.create_tree([ self.A, self.B, self.C, self.D, self.E, self.F ], legacy_mode=True)
def test_get_job_map_find_duplicates(self): A = make_job('A') another_A = make_job('A') with self.assertRaises(DependencyDuplicateError) as call: DependencySolver._get_job_map([A, another_A]) self.assertIs(call.exception.job, A) self.assertIs(call.exception.duplicate_job, another_A)
def setUp(self): self.job_list = [make_job('foo'), make_job('bar')] self.whitelist_list = [ WhiteList([], name='ihv-foo'), WhiteList([], name='other')] self.real_provider = DummyProvider1( job_list=self.job_list, whitelist_list=self.whitelist_list) self.ihv_provider = IHVProvider(self.real_provider)
def test_1388055(self): """ https://bugs.launchpad.net/plainbox/+bug/1388055 """ # This bug is about being able to resume a session despite job database # modification. Let's assume the following session first: # - desired job list: [a] # - run list [a_dep, a] (computed) # - job_repr: {a_dep: checksum} job_a = make_job(id='a', depends='a_dep') job_a_dep = make_job(id='a_dep') state = SessionState([job_a, job_a_dep]) state.update_desired_job_list([job_a]) self.assertEqual(state.run_list, [job_a_dep, job_a]) self.assertEqual(state.desired_job_list, [job_a]) helper = SessionSuspendHelper4() session_dir = None # Mock away the meta-data as we're not testing that with mock.patch.object(helper, '_repr_SessionMetaData') as m: m.return_value = 'mocked' actual = helper._repr_SessionState(state, session_dir) expected = { 'jobs': { job_a_dep.id: job_a_dep.checksum, job_a.id: job_a.checksum, }, 'desired_job_list': [job_a.id], 'mandatory_job_list': [], 'results': {}, 'metadata': 'mocked' } self.assertEqual(expected, actual)
def test_get_vote(self): """ verify how CompositeQualifier.get_vote() behaves in various situations """ # Default is IGNORE self.assertEqual( CompositeQualifier([]).get_vote(make_job("foo")), IJobQualifier.VOTE_IGNORE) # Any match is INCLUDE self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo", self.origin), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_INCLUDE) # Any negative match is EXCLUDE self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo", self.origin, inclusive=False), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_EXCLUDE) # Negative matches take precedence over positive matches self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo", self.origin), RegExpJobQualifier("foo", self.origin, inclusive=False), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_EXCLUDE) # Unrelated patterns are not affecting the result self.assertEqual( CompositeQualifier([ RegExpJobQualifier("foo", self.origin), RegExpJobQualifier("bar", self.origin), ]).get_vote(make_job("foo")), IJobQualifier.VOTE_INCLUDE)
def test_mandatory_jobs_are_first_in_run_list(self): A = make_job('A') B = make_job('B') session = SessionState([A, B]) session.update_mandatory_job_list([B]) session.update_desired_job_list([A]) self.assertEqual(session.run_list, [B, A])
def test_duplicate_error(self): A = make_job('A') another_A = make_job('A') job_list = [A, another_A] with self.assertRaises(DependencyDuplicateError) as call: DependencySolver.resolve_dependencies(job_list) self.assertIs(call.exception.job, A) self.assertIs(call.exception.duplicate_job, another_A)
def test_duplicate_error(self): A = make_job('A') another_A = make_job('A') job_list = [A, another_A] with self.assertRaises(DependencyDuplicateError) as call: DependencySolver.resolve_dependencies(job_list) self.assertIs(call.exception.job, A) self.assertIs(call.exception.duplicate_job, another_A)
def test_smoke(self): """ various smoke tests that check if JobIdQualifier.designates() works """ self.assertTrue(JobIdQualifier('name').designates(make_job('name'))) self.assertFalse(JobIdQualifier('nam').designates(make_job('name'))) self.assertFalse(JobIdQualifier('.*').designates(make_job('name'))) self.assertFalse(JobIdQualifier('*').designates(make_job('name')))
def test_smoke(self): """ various smoke tests that check if JobIdQualifier.designates() works """ self.assertTrue(JobIdQualifier('name').designates(make_job('name'))) self.assertFalse(JobIdQualifier('nam').designates(make_job('name'))) self.assertFalse(JobIdQualifier('.*').designates(make_job('name'))) self.assertFalse(JobIdQualifier('*').designates(make_job('name')))
def test_init_with_identical_jobs(self): A = make_job("A") second_A = make_job("A") third_A = make_job("A") # Identical jobs are folded for backwards compatibility with some local # jobs that re-added existing jobs session = SessionState([A, second_A, third_A]) # But we don't really store both, just the first one self.assertEqual(session.job_list, [A])
def test_resource_deps(self): # This tests resource deps # A ~> R A = make_job(id='A', requires='R.foo == "bar"') R = make_job(id='R', plugin='resource') job_list = [A, R] expected = [R, A] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_init_with_identical_jobs(self): A = make_job("A") second_A = make_job("A") third_A = make_job("A") # Identical jobs are folded for backwards compatibility with some local # jobs that re-added existing jobs session = SessionState([A, second_A, third_A]) # But we don't really store both, just the first one self.assertEqual(session.job_list, [A])
def test_dependency_cycle_simple(self): # This tests dependency loops # A -> B -> A A = make_job(name='A', depends='B') B = make_job(name='B', depends='A') job_list = [A, B] with self.assertRaises(DependencyCycleError) as call: DependencySolver.resolve_dependencies(job_list) self.assertEqual(call.exception.job_list, [A, B, A])
def test_dependency_cycle_via_resource(self): # This tests dependency loops # A -> R -> A A = make_job(id='A', requires='R.key == "value"') R = make_job(id='R', depends='A', plugin="resource") job_list = [A, R] with self.assertRaises(DependencyCycleError) as call: DependencySolver.resolve_dependencies(job_list) self.assertEqual(call.exception.job_list, [A, R, A])
def test_dependency_cycle_via_resource(self): # This tests dependency loops # A -> R -> A A = make_job(name='A', requires='R.key == "value"') R = make_job(name='R', depends='A', plugin="resource") job_list = [A, R] with self.assertRaises(DependencyCycleError) as call: DependencySolver.resolve_dependencies(job_list) self.assertEqual(call.exception.job_list, [A, R, A])
def test_resource_deps(self): # This tests resource deps # A ~> R A = make_job(name='A', requires='R.foo == "bar"') R = make_job(name='R', plugin='resource') job_list = [A, R] expected = [R, A] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_dependency_cycle_simple(self): # This tests dependency loops # A -> B -> A A = make_job(id='A', depends='B') B = make_job(id='B', depends='A') job_list = [A, B] with self.assertRaises(DependencyCycleError) as call: DependencySolver.resolve_dependencies(job_list) self.assertEqual(call.exception.job_list, [A, B, A])
def test_get_estimated_duration_manual_unknown(self): four_seconds = make_job("four_seconds", plugin="shell", command="fibble", estimated_duration=4.0) no_estimated_duration = make_job("no_estimated_duration", plugin="user-verify", command="bibble") session = SessionState([four_seconds, no_estimated_duration]) session.update_desired_job_list([four_seconds, no_estimated_duration]) self.assertEqual(session.get_estimated_duration(), (4.0, None))
def test_get_estimated_duration_automated_unknown(self): three_seconds = make_job("three_seconds", plugin="shell", command="frob", estimated_duration=3.0) no_estimated_duration = make_job("no_estimated_duration", plugin="shell", command="borf") session = SessionState([three_seconds, no_estimated_duration]) session.update_desired_job_list([three_seconds, no_estimated_duration]) self.assertEqual(session.get_estimated_duration(), (None, 0.0))
def test_get_estimated_duration_manual(self): two_seconds = make_job("two_seconds", plugin="manual", command="farboo", estimated_duration=2.0) shell_job = make_job("shell_job", plugin="shell", command="boofar", estimated_duration=0.6) session = SessionState([two_seconds, shell_job]) session.update_desired_job_list([two_seconds, shell_job]) self.assertEqual(session.get_estimated_duration(), (0.6, 32.0))
def test_direct_deps(self): # This tests the following simple job chain # A -> B -> C A = make_job(name='A', depends='B') B = make_job(name='B', depends='C') C = make_job(name='C') job_list = [A, B, C] expected = [C, B, A] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_direct_deps(self): # This tests the following simple job chain # A -> B -> C A = make_job(id='A', depends='B') B = make_job(id='B', depends='C') C = make_job(id='C') job_list = [A, B, C] expected = [C, B, A] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_visiting_blackend_node(self): # This tests a visit to already visited job # A # B -> A # A will be visited twice A = make_job(id='A') B = make_job(id='B', depends='A') job_list = [A, B] expected = [A, B] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_dependency_cycle_longer(self): # This tests dependency loops # A -> B -> C -> D -> B A = make_job(name='A', depends='B') B = make_job(name='B', depends='C') C = make_job(name='C', depends='D') D = make_job(name='D', depends='B') job_list = [A, B, C, D] with self.assertRaises(DependencyCycleError) as call: DependencySolver.resolve_dependencies(job_list) self.assertEqual(call.exception.job_list, [B, C, D, B])
def test_visiting_blackend_node(self): # This tests a visit to already visited job # A # B -> A # A will be visited twice A = make_job(name='A') B = make_job(name='B', depends='A') job_list = [A, B] expected = [A, B] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_dependency_cycle_longer(self): # This tests dependency loops # A -> B -> C -> D -> B A = make_job(id='A', depends='B') B = make_job(id='B', depends='C') C = make_job(id='C', depends='D') D = make_job(id='D', depends='B') job_list = [A, B, C, D] with self.assertRaises(DependencyCycleError) as call: DependencySolver.resolve_dependencies(job_list) self.assertEqual(call.exception.job_list, [B, C, D, B])
def setUp(self): # All of the tests need a SessionState object and some jobs to work # with. Actual values don't matter much. self.job_a = make_job(name='a') self.job_b = make_job(name='b') self.session = SessionState([self.job_a, self.job_b]) self.good_repr = { "desired_job_list": ['a', 'b'] } self.resume_fn = \ SessionResumeHelper._restore_SessionState_desired_job_list
def test_init_with_colliding_jobs(self): # This is similar to the test above but the jobs actually differ In # this case the _second_ job is rejected but it really signifies a # deeper problem that should only occur during development of jobs A = make_job("A") different_A = make_job("A", plugin="resource") with self.assertRaises(DependencyDuplicateError) as call: SessionState([A, different_A]) self.assertIs(call.exception.job, A) self.assertIs(call.exception.duplicate_job, different_A) self.assertIs(call.exception.affected_job, different_A)
def make_test_session(self): # Create a small session with two jobs and two results job_a = make_job('job_a') job_b = make_job('job_b') session = SessionState([job_a, job_b]) session.update_desired_job_list([job_a, job_b]) result_a = make_job_result(outcome=IJobResult.OUTCOME_PASS) result_b = make_job_result(outcome=IJobResult.OUTCOME_FAIL) session.update_job_result(job_a, result_a) session.update_job_result(job_b, result_b) return session
def test_get_estimated_duration_automated_unknown(self): three_seconds = make_job("three_seconds", plugin="shell", command="frob", estimated_duration=3.0) no_estimated_duration = make_job("no_estimated_duration", plugin="shell", command="borf") session = SessionState([three_seconds, no_estimated_duration]) session.update_desired_job_list([three_seconds, no_estimated_duration]) self.assertEqual(session.get_estimated_duration(), (None, 0.0))
def make_test_session(self): # Create a small session with two jobs and two results job_a = make_job('job_a') job_b = make_job('job_b') session = SessionState([job_a, job_b]) session.update_desired_job_list([job_a, job_b]) result_a = make_job_result(job_a, 'pass') result_b = make_job_result(job_b, 'fail') session.update_job_result(job_a, result_a) session.update_job_result(job_b, result_b) return session
def test_init_with_colliding_jobs(self): # This is similar to the test above but the jobs actually differ In # this case the _second_ job is rejected but it really signifies a # deeper problem that should only occur during development of jobs A = make_job("A") different_A = make_job("A", plugin="resource") with self.assertRaises(DependencyDuplicateError) as call: SessionState([A, different_A]) self.assertIs(call.exception.job, A) self.assertIs(call.exception.duplicate_job, different_A) self.assertIs(call.exception.affected_job, different_A)
def test_inclusive(self): self.assertTrue( CompositeQualifier( inclusive_qualifier_list=[RegExpJobQualifier('foo')], exclusive_qualifier_list=[] ).designates(make_job("foo"))) self.assertFalse( CompositeQualifier( inclusive_qualifier_list=[RegExpJobQualifier('foo')], exclusive_qualifier_list=[] ).designates(make_job("bar")))
def make_test_session(self): # Create a small session with two jobs and two results job_a = make_job('job_a') job_b = make_job('job_b') session = SessionState([job_a, job_b]) session.update_desired_job_list([job_a, job_b]) result_a = make_job_result(outcome=IJobResult.OUTCOME_PASS) result_b = make_job_result(outcome=IJobResult.OUTCOME_FAIL) session.update_job_result(job_a, result_a) session.update_job_result(job_b, result_b) return session
def test_get_estimated_duration_auto(self): # Define jobs with an estimated duration one_second = make_job("one_second", plugin="shell", command="foobar", estimated_duration=1.0) half_second = make_job("half_second", plugin="shell", command="barfoo", estimated_duration=0.5) session = SessionState([one_second, half_second]) session.update_desired_job_list([one_second, half_second]) self.assertEqual(session.get_estimated_duration(), (1.5, 0.0))
def test_get_estimated_duration_manual_unknown(self): four_seconds = make_job("four_seconds", plugin="shell", command="fibble", estimated_duration=4.0) no_estimated_duration = make_job("no_estimated_duration", plugin="user-verify", command="bibble") session = SessionState([four_seconds, no_estimated_duration]) session.update_desired_job_list([four_seconds, no_estimated_duration]) self.assertEqual(session.get_estimated_duration(), (4.0, None))
def test_inclusive(self): """ verify that inclusive selection works """ self.assertTrue( CompositeQualifier([ RegExpJobQualifier('foo'), ]).designates(make_job("foo"))) self.assertFalse( CompositeQualifier([ RegExpJobQualifier('foo'), ]).designates(make_job("bar")))
def test_crash_in_update_desired_job_list(self): # This checks if a DependencyError can cause crash # update_desired_job_list() with a ValueError, in certain conditions. A = make_job('A', depends='X') L = make_job('L', plugin='local') session = SessionState([A, L]) problems = session.update_desired_job_list([A, L]) # We should get exactly one DependencyMissingError related to job A and # the undefined job X (that is presumably defined by the local job L) self.assertEqual(len(problems), 1) self.assertIsInstance(problems[0], DependencyMissingError) self.assertIs(problems[0].affected_job, A)
def test_independent_groups_deps(self): # This tests two independent job chains # A1 -> B1 # A2 -> B2 A1 = make_job(id='A1', depends='B1') B1 = make_job(id='B1',) A2 = make_job(id='A2', depends='B2') B2 = make_job(id='B2') job_list = [A1, B1, A2, B2] expected = [B1, A1, B2, A2] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_crash_in_update_desired_job_list(self): # This checks if a DependencyError can cause crash # update_desired_job_list() with a ValueError, in certain conditions. A = make_job('A', depends='X') L = make_job('L', plugin='local') session = SessionState([A, L]) problems = session.update_desired_job_list([A, L]) # We should get exactly one DependencyMissingError related to job A and # the undefined job X (that is presumably defined by the local job L) self.assertEqual(len(problems), 1) self.assertIsInstance(problems[0], DependencyMissingError) self.assertIs(problems[0].affected_job, A)
def test_get_estimated_duration_manual(self): two_seconds = make_job("two_seconds", plugin="manual", command="farboo", estimated_duration=2.0) shell_job = make_job("shell_job", plugin="shell", command="boofar", estimated_duration=0.6) session = SessionState([two_seconds, shell_job]) session.update_desired_job_list([two_seconds, shell_job]) self.assertEqual(session.get_estimated_duration(), (0.6, 32.0))
def test_independent_groups_deps(self): # This tests two independent job chains # A1 -> B1 # A2 -> B2 A1 = make_job(name='A1', depends='B1') B1 = make_job(name='B1',) A2 = make_job(name='A2', depends='B2') B2 = make_job(name='B2') job_list = [A1, B1, A2, B2] expected = [B1, A1, B2, A2] observed = DependencySolver.resolve_dependencies(job_list) self.assertEqual(expected, observed)
def test_inclusive(self): """ verify that inclusive selection works """ self.assertTrue( CompositeQualifier([ RegExpJobQualifier('foo', self.origin), ]).designates(make_job("foo"))) self.assertFalse( CompositeQualifier([ RegExpJobQualifier('foo', self.origin), ]).designates(make_job("bar")))
def test_dont_remove_missing_jobs(self): """ http://pad.lv/1444126 """ A = make_job("A", depends="B") B = make_job("B", depends="C") state = SessionState([A, B]) problems = state.update_desired_job_list([A, B]) self.assertEqual(problems, [ DependencyMissingError(B, 'C', 'direct'), DependencyMissingError(A, 'B', 'direct'), ]) self.assertEqual(state.desired_job_list, []) self.assertEqual(state.run_list, [])
def test_get_estimated_duration_auto(self): # Define jobs with an estimated duration one_second = make_job("one_second", plugin="shell", command="foobar", estimated_duration=1.0) half_second = make_job("half_second", plugin="shell", command="barfoo", estimated_duration=0.5) session = SessionState([one_second, half_second]) session.update_desired_job_list([one_second, half_second]) self.assertEqual(session.get_estimated_duration(), (1.5, 0.0))
def test_resume_session(self): # All of the tests below are using one session. The session has four # jobs, Job A depends on a resource provided by job R which has no # dependencies at all. Both Job X and Y depend on job A. # # A -(resource dependency)-> R # # X -(direct dependency) -> A # # Y -(direct dependency) -> A self.job_A = make_job("A", requires="R.attr == 'value'") self.job_A_expr = self.job_A.get_resource_program().expression_list[0] self.job_R = make_job("R", plugin="resource") self.job_X = make_job("X", depends='A') self.job_Y = make_job("Y", depends='A') self.job_list = [self.job_A, self.job_R, self.job_X, self.job_Y] # Create a new session (session_dir is empty) self.session = SessionState(self.job_list) result_R = JobResult({ 'job': self.job_R, 'io_log': make_io_log(((0, 'stdout', b"attr: value\n"), ), self._sandbox) }) result_A = JobResult({ 'job': self.job_A, 'outcome': JobResult.OUTCOME_PASS }) result_X = JobResult({ 'job': self.job_X, 'outcome': JobResult.OUTCOME_PASS }) # Job Y can't start as it requires job A self.assertFalse(self.job_state('Y').can_start()) self.session.update_desired_job_list([self.job_X, self.job_Y]) self.session.open() self.session.update_job_result(self.job_R, result_R) self.session.update_job_result(self.job_A, result_A) self.session.update_job_result(self.job_X, result_X) self.session.persistent_save() self.session.close() # Create a new session (session_dir should contain session data) self.session = SessionState(self.job_list) self.session.open() # Resume the previous session self.session.resume() # This time job Y can start self.assertTrue(self.job_state('Y').can_start()) self.session.close()
def test_designates(self): """ verify that WhiteList.designates() works """ self.assertTrue( WhiteList.from_string("foo").designates(make_job('foo'))) self.assertTrue( WhiteList.from_string("foo\nbar\n").designates(make_job('foo'))) self.assertTrue( WhiteList.from_string("foo\nbar\n").designates(make_job('bar'))) # Note, it's not matching either! self.assertFalse( WhiteList.from_string("foo").designates(make_job('foobar'))) self.assertFalse( WhiteList.from_string("bar").designates(make_job('foobar')))
def test_designates(self): """ verify that WhiteList.designates() works """ self.assertTrue( WhiteList.from_string("foo").designates(make_job('foo'))) self.assertTrue( WhiteList.from_string("foo\nbar\n").designates(make_job('foo'))) self.assertTrue( WhiteList.from_string("foo\nbar\n").designates(make_job('bar'))) # Note, it's not matching either! self.assertFalse( WhiteList.from_string("foo").designates(make_job('foobar'))) self.assertFalse( WhiteList.from_string("bar").designates(make_job('foobar')))
def test_resume_session(self): # All of the tests below are using one session. The session has four # jobs, Job A depends on a resource provided by job R which has no # dependencies at all. Both Job X and Y depend on job A. # # A -(resource dependency)-> R # # X -(direct dependency) -> A # # Y -(direct dependency) -> A self.job_A = make_job("A", requires="R.attr == 'value'") self.job_A_expr = self.job_A.get_resource_program().expression_list[0] self.job_R = make_job("R", plugin="resource") self.job_X = make_job("X", depends='A') self.job_Y = make_job("Y", depends='A') self.job_list = [self.job_A, self.job_R, self.job_X, self.job_Y] # Create a new session (session_dir is empty) self.session = SessionState(self.job_list) result_R = JobResult({ 'job': self.job_R, 'io_log': make_io_log(((0, 'stdout', b"attr: value\n"),), self._sandbox) }) result_A = JobResult({ 'job': self.job_A, 'outcome': JobResult.OUTCOME_PASS }) result_X = JobResult({ 'job': self.job_X, 'outcome': JobResult.OUTCOME_PASS }) # Job Y can't start as it requires job A self.assertFalse(self.job_state('Y').can_start()) self.session.update_desired_job_list([self.job_X, self.job_Y]) self.session.open() self.session.update_job_result(self.job_R, result_R) self.session.update_job_result(self.job_A, result_A) self.session.update_job_result(self.job_X, result_X) self.session.persistent_save() self.session.close() # Create a new session (session_dir should contain session data) self.session = SessionState(self.job_list) self.session.open() # Resume the previous session self.session.resume() # This time job Y can start self.assertTrue(self.job_state('Y').can_start()) self.session.close()
def setUp(self): # All of the tests below are using one session. The session has four # jobs, clustered into two independent groups. Job A depends on a # resource provided by job R which has no dependencies at all. Job X # depends on job Y which in turn has no dependencies at all. # # A -(resource dependency)-> R # # X -(direct dependency) -> Y self.job_A = make_job("A", requires="R.attr == 'value'") self.job_A_expr = self.job_A.get_resource_program().expression_list[0] self.job_R = make_job("R", plugin="resource") self.job_X = make_job("X", depends='Y') self.job_Y = make_job("Y") self.job_list = [self.job_A, self.job_R, self.job_X, self.job_Y] self.session = SessionState(self.job_list)
def test_simple_session(self): """ verify that _restore_SessionState_jobs_and_results() works when faced with a representation of a simple session (no generated jobs or anything "exotic"). """ job = make_job(name='job') session_repr = { 'jobs': { job.name: job.get_checksum(), }, 'results': { job.name: [{ 'outcome': 'pass', 'comments': None, 'execution_duration': None, 'return_code': None, 'io_log': [], }] } } helper = SessionResumeHelper([job]) session = SessionState([job]) helper._restore_SessionState_jobs_and_results(session, session_repr) # Session still has one job in it self.assertEqual(session.job_list, [job]) # Resources don't have anything (no resource jobs) self.assertEqual(session.resource_map, {}) # The result was restored correctly. This is just a smoke test # as specific tests for restoring results are written elsewhere self.assertEqual( session.job_state_map[job.name].result.outcome, 'pass')
def test_smoke(self): with self.mocked_file(self._name, self._content): whitelist = WhiteList.from_file(self._name) self.assertEqual( repr(whitelist.inclusive_qualifier_list[0]), "<RegExpJobQualifier pattern:'^foo$'>") self.assertTrue(whitelist.designates(make_job('foo')))