LSSTApplications  20.0.0
LSSTDataManagementBasePackage
Functions
lsst.pipe.base.testUtils Namespace Reference

Functions

def makeQuantum (task, butler, dataId, ioDataIds)
 
def runTestQuantum (task, butler, quantum, mockRun=True)
 
def assertValidOutput (task, result)
 

Function Documentation

◆ assertValidOutput()

def lsst.pipe.base.testUtils.assertValidOutput (   task,
  result 
)
Test that the output of a call to ``run`` conforms to its own connections.

Parameters
----------
task : `lsst.pipe.base.PipelineTask`
    The task whose connections need validation. This is a fully-configured
    task object to support features such as optional outputs.
result : `lsst.pipe.base.Struct`
    A result object produced by calling ``task.run``.

Raises
-------
AssertionError:
    Raised if ``result`` does not match what's expected from ``task's``
    connections.

Definition at line 201 of file testUtils.py.

201 def assertValidOutput(task, result):
202  """Test that the output of a call to ``run`` conforms to its own connections.
203 
204  Parameters
205  ----------
206  task : `lsst.pipe.base.PipelineTask`
207  The task whose connections need validation. This is a fully-configured
208  task object to support features such as optional outputs.
209  result : `lsst.pipe.base.Struct`
210  A result object produced by calling ``task.run``.
211 
212  Raises
213  -------
214  AssertionError:
215  Raised if ``result`` does not match what's expected from ``task's``
216  connections.
217  """
218  connections = task.config.ConnectionsClass(config=task.config)
219  recoveredOutputs = result.getDict()
220 
221  for name in connections.outputs:
222  connection = connections.__getattribute__(name)
223  # name
224  try:
225  output = recoveredOutputs[name]
226  except KeyError:
227  raise AssertionError(f"No such output: {name}")
228  # multiple
229  if connection.multiple:
230  if not isinstance(output, collections.abc.Sequence):
231  raise AssertionError(f"Expected {name} to be a sequence, got {output} instead.")
232  else:
233  # use lazy evaluation to not use StorageClassFactory unless necessary
234  if isinstance(output, collections.abc.Sequence) \
235  and not issubclass(
236  StorageClassFactory().getStorageClass(connection.storageClass).pytype,
237  collections.abc.Sequence):
238  raise AssertionError(f"Expected {name} to be a single value, got {output} instead.")
239  # no test for storageClass, as I'm not sure how much persistence depends on duck-typing

◆ makeQuantum()

def lsst.pipe.base.testUtils.makeQuantum (   task,
  butler,
  dataId,
  ioDataIds 
)
Create a Quantum for a particular data ID(s).

Parameters
----------
task : `lsst.pipe.base.PipelineTask`
    The task whose processing the quantum represents.
butler : `lsst.daf.butler.Butler`
    The collection the quantum refers to.
dataId: any data ID type
    The data ID of the quantum. Must have the same dimensions as
    ``task``'s connections class.
ioDataIds : `collections.abc.Mapping` [`str`]
    A mapping keyed by input/output names. Values must be data IDs for
    single connections and sequences of data IDs for multiple connections.

Returns
-------
quantum : `lsst.daf.butler.Quantum`
    A quantum for ``task``, when called with ``dataIds``.

Definition at line 34 of file testUtils.py.

34 def makeQuantum(task, butler, dataId, ioDataIds):
35  """Create a Quantum for a particular data ID(s).
36 
37  Parameters
38  ----------
39  task : `lsst.pipe.base.PipelineTask`
40  The task whose processing the quantum represents.
41  butler : `lsst.daf.butler.Butler`
42  The collection the quantum refers to.
43  dataId: any data ID type
44  The data ID of the quantum. Must have the same dimensions as
45  ``task``'s connections class.
46  ioDataIds : `collections.abc.Mapping` [`str`]
47  A mapping keyed by input/output names. Values must be data IDs for
48  single connections and sequences of data IDs for multiple connections.
49 
50  Returns
51  -------
52  quantum : `lsst.daf.butler.Quantum`
53  A quantum for ``task``, when called with ``dataIds``.
54  """
55  quantum = Quantum(taskClass=type(task), dataId=dataId)
56  connections = task.config.ConnectionsClass(config=task.config)
57 
58  try:
59  for name in itertools.chain(connections.inputs, connections.prerequisiteInputs):
60  connection = connections.__getattribute__(name)
61  _checkDataIdMultiplicity(name, ioDataIds[name], connection.multiple)
62  ids = _normalizeDataIds(ioDataIds[name])
63  for id in ids:
64  quantum.addPredictedInput(_refFromConnection(butler, connection, id))
65  for name in connections.outputs:
66  connection = connections.__getattribute__(name)
67  _checkDataIdMultiplicity(name, ioDataIds[name], connection.multiple)
68  ids = _normalizeDataIds(ioDataIds[name])
69  for id in ids:
70  quantum.addOutput(_refFromConnection(butler, connection, id))
71  return quantum
72  except KeyError as e:
73  raise ValueError("Mismatch in input data.") from e
74 
75 

◆ runTestQuantum()

def lsst.pipe.base.testUtils.runTestQuantum (   task,
  butler,
  quantum,
  mockRun = True 
)
Run a PipelineTask on a Quantum.

Parameters
----------
task : `lsst.pipe.base.PipelineTask`
    The task to run on the quantum.
butler : `lsst.daf.butler.Butler`
    The collection to run on.
quantum : `lsst.daf.butler.Quantum`
    The quantum to run.
mockRun : `bool`
    Whether or not to replace ``task``'s ``run`` method. The default of
    `True` is recommended unless ``run`` needs to do real work (e.g.,
    because the test needs real output datasets).

Returns
-------
run : `unittest.mock.Mock` or `None`
    If ``mockRun`` is set, the mock that replaced ``run``. This object can
    be queried for the arguments ``runQuantum`` passed to ``run``.

Definition at line 166 of file testUtils.py.

166 def runTestQuantum(task, butler, quantum, mockRun=True):
167  """Run a PipelineTask on a Quantum.
168 
169  Parameters
170  ----------
171  task : `lsst.pipe.base.PipelineTask`
172  The task to run on the quantum.
173  butler : `lsst.daf.butler.Butler`
174  The collection to run on.
175  quantum : `lsst.daf.butler.Quantum`
176  The quantum to run.
177  mockRun : `bool`
178  Whether or not to replace ``task``'s ``run`` method. The default of
179  `True` is recommended unless ``run`` needs to do real work (e.g.,
180  because the test needs real output datasets).
181 
182  Returns
183  -------
184  run : `unittest.mock.Mock` or `None`
185  If ``mockRun`` is set, the mock that replaced ``run``. This object can
186  be queried for the arguments ``runQuantum`` passed to ``run``.
187  """
188  butlerQc = ButlerQuantumContext(butler, quantum)
189  connections = task.config.ConnectionsClass(config=task.config)
190  inputRefs, outputRefs = connections.buildDatasetRefs(quantum)
191  if mockRun:
192  with unittest.mock.patch.object(task, "run") as mock, \
193  unittest.mock.patch("lsst.pipe.base.ButlerQuantumContext.put"):
194  task.runQuantum(butlerQc, inputRefs, outputRefs)
195  return mock
196  else:
197  task.runQuantum(butlerQc, inputRefs, outputRefs)
198  return None
199 
200 
lsst.pipe.base.testUtils.makeQuantum
def makeQuantum(task, butler, dataId, ioDataIds)
Definition: testUtils.py:34
lsst.pipe.base.testUtils.runTestQuantum
def runTestQuantum(task, butler, quantum, mockRun=True)
Definition: testUtils.py:166
type
table::Key< int > type
Definition: Detector.cc:163
lsst.pipe.base.testUtils.assertValidOutput
def assertValidOutput(task, result)
Definition: testUtils.py:201