Esempio n. 1
0
 def test_cycle_simple(self):
     self.pg.update_state('A', Waiting(['B']))
     self.pg.update_state('B', Waiting(['A']))
     # NB: Order matters: the second insertion is the one tracked as a cycle.
     self.assertEquals({'B'}, set(self.pg.dependencies_of('A')))
     self.assertEquals(set(), set(self.pg.dependencies_of('B')))
     self.assertEquals(set(), set(self.pg.cyclic_dependencies_of('A')))
     self.assertEquals({'A'}, set(self.pg.cyclic_dependencies_of('B')))
Esempio n. 2
0
    def test_cycle_indirect(self):
        self.pg.update_state('A', Waiting(['B']))
        self.pg.update_state('B', Waiting(['C']))
        self.pg.update_state('C', Waiting(['A']))

        self.assertEquals({'B'}, set(self.pg.dependencies_of('A')))
        self.assertEquals({'C'}, set(self.pg.dependencies_of('B')))
        self.assertEquals(set(), set(self.pg.dependencies_of('C')))
        self.assertEquals(set(), set(self.pg.cyclic_dependencies_of('A')))
        self.assertEquals(set(), set(self.pg.cyclic_dependencies_of('B')))
        self.assertEquals({'A'}, set(self.pg.cyclic_dependencies_of('C')))
Esempio n. 3
0
    def test_cycle_long(self):
        # Creating a long chain is allowed.
        nodes = list(range(0, 100))
        self._mk_chain(self.pg, nodes, states=(Waiting, ))
        walked_nodes = [node for node, _ in self.pg.walk([nodes[0]])]
        self.assertEquals(nodes, walked_nodes)

        # Closing the chain is not.
        begin, end = nodes[0], nodes[-1]
        self.pg.update_state(end, Waiting([begin]))
        self.assertEquals(set(), set(self.pg.dependencies_of(end)))
        self.assertEquals({begin}, set(self.pg.cyclic_dependencies_of(end)))
Esempio n. 4
0
    def test_state_roundtrips(self):
        states = [
            Return('a'),
            Throw(PickleableException()),
            Waiting([TaskNode(None, None, None)]),
            Runnable(_runnable, ('an arg', )),
            Noop('nada {}', ('op', ))
        ]
        with closing(self.storage) as storage:
            for state in states:
                key = storage.put_state(state)
                actual = storage.get_state(key)

                self.assertEquals(state, actual)
                self.assertEquals(key, storage.put_state(actual))
Esempio n. 5
0
  def step(self, step_context):
    waiting_nodes = []
    # Get the binary.
    binary_state = step_context.select_for(Select(self.snapshotted_process.binary_type),
                                           subject=self.subject,
                                           variants=self.variants)
    if type(binary_state) is Throw:
      return binary_state
    elif type(binary_state) is Waiting:
      waiting_nodes.extend(binary_state.dependencies)
    elif type(binary_state) is Noop:
      return Noop("Couldn't find binary: {}".format(binary_state))
    elif type(binary_state) is not Return:
      State.raise_unrecognized(binary_state)

    # Create the request from the request callback after resolving its input clauses.
    input_values = []
    for input_selector in self.snapshotted_process.input_selectors:
      sn_state = step_context.select_for(input_selector, self.subject, self.variants)
      if type(sn_state) is Waiting:
        waiting_nodes.extend(sn_state.dependencies)
      elif type(sn_state) is Return:
        input_values.append(sn_state.value)
      elif type(sn_state) is Noop:
        if input_selector.optional:
          input_values.append(None)
        else:
          return Noop('Was missing value for (at least) input {}'.format(input_selector))
      elif type(sn_state) is Throw:
        return sn_state
      else:
        State.raise_unrecognized(sn_state)

    if waiting_nodes:
      return Waiting(waiting_nodes)

    # Now that we've returned on waiting, we can assume that relevant inputs have values.
    try:
      process_request = self.snapshotted_process.input_conversion(*input_values)
    except Exception as e:
      return Throw(e)

    # Request snapshots for the snapshot_subjects from the process request.
    snapshot_subjects_value = []
    if process_request.snapshot_subjects:
      snapshot_subjects_state = step_context.select_for(SelectDependencies(Snapshot,
                                                                           SnapshottedProcessRequest,
                                                                           'snapshot_subjects',
                                                                           field_types=(Files,)),
                                                        process_request,
                                                        self.variants)
      if type(snapshot_subjects_state) is not Return:
        return snapshot_subjects_state
      snapshot_subjects_value = snapshot_subjects_state.value

    # Ready to run.
    execution = _Process(step_context.snapshot_archive_root,
                         process_request,
                         binary_state.value,
                         snapshot_subjects_value,
                         self.snapshotted_process.output_conversion)
    return Runnable(_execute, (execution,))
Esempio n. 6
0
 def test_dependency_edges(self):
     self.pg.update_state('A', Waiting(['B', 'C']))
     self.assertEquals({'B', 'C'}, set(self.pg.dependencies_of('A')))
     self.assertEquals({'A'}, set(self.pg.dependents_of('B')))
     self.assertEquals({'A'}, set(self.pg.dependents_of('C')))
Esempio n. 7
0
 def test_disallow_completing_with_incomplete_deps(self):
     self.pg.update_state('A', Waiting(['B']))
     self.pg.update_state('B', Waiting(['C']))
     with self.assertRaises(IncompleteDependencyException):
         self.pg.update_state('A', Return('done!'))
Esempio n. 8
0
 def test_disallow_completed_state_change(self):
     self.pg.update_state('A', Return('done!'))
     with self.assertRaises(CompletedNodeException):
         self.pg.update_state('A', Waiting(['B']))