Skip to content

Commit

Permalink
only require instrument class name
Browse files Browse the repository at this point in the history
Class instance and instrument name can all be obtained from the
class name.

Use abstract property to ensure that the class name is provided.
  • Loading branch information
n8pease committed May 15, 2020
1 parent fe5e17c commit 7a5c68c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 28 deletions.
27 changes: 16 additions & 11 deletions python/lsst/obs/base/cli/butler_cmd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,41 @@
import click.testing

from lsst.daf.butler.cli import butler
from lsst.utils import doImport


class ButlerCmdTestBase(metaclass=abc.ABCMeta):
"""Base class for tests of butler command line interface subcommands.
Subclass from this, then `unittest.TestCase` to get a working test suite.
"""

@staticmethod
@property
@abc.abstractmethod
def instrumentClass():
"""Get the fully qualified instrument class.
def instrumentClassName(self):
"""The fully qualified instrument class name.
Returns
-------
`str`
The fully qualified instrument class.
The fully qualified instrument class name.
"""
pass

@staticmethod
@abc.abstractmethod
def instrumentName():
"""Get the instrument name.
@property
def instrument(self):
"""The instrument class."""
return doImport(self.instrumentClassName)

@property
def instrumentName(self):
"""The name of the instrument.
Returns
-------
`str`
The name of the instrument.
"""
pass
return self.instrument.getName()

def test_cli(self):
runner = click.testing.CliRunner()
Expand All @@ -67,10 +72,10 @@ def test_cli(self):
self.assertEqual(result.exit_code, 0, f"output: {result.output} exception: {result.exception}")
result = runner.invoke(butler.cli, ["register-instrument",
"here",
"-i", self.instrumentClass()])
"-i", self.instrumentClassName])
self.assertEqual(result.exit_code, 0, f"output: {result.output} exception: {result.exception}")
result = runner.invoke(butler.cli, ["write-curated-calibrations",
"here",
"-i", self.instrumentName(),
"-i", self.instrumentName,
"--output-run", "output_run"])
self.assertEqual(result.exit_code, 0, f"output: {result.output} exception: {result.exception}")
50 changes: 33 additions & 17 deletions python/lsst/obs/base/ingest_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from lsst.daf.butler import Butler
from lsst.daf.butler.script import createRepo
import lsst.obs.base
from lsst.utils import doImport
from .utils import getInstrument
from .script import ingestRaws, registerInstrument, writeCuratedCalibrations

Expand All @@ -47,9 +48,6 @@ class IngestTestBase(metaclass=abc.ABCMeta):
actual directory will be a tempdir under this one.
"""

instrument = None
"""The instrument to be registered and tested."""

dataIds = []
"""list of butler data IDs of files that should have been ingested."""

Expand All @@ -66,38 +64,56 @@ class IngestTestBase(metaclass=abc.ABCMeta):

defineVisitsTask = lsst.obs.base.DefineVisitsTask
"""The task to use to define visits from groups of exposures.
This is ignored if ``visits`` is `None`.
"""

visits = {}
"""A dictionary mapping visit data IDs the lists of exposure data IDs that
are associated with them.
If this is empty (but not `None`), visit definition will be run but no
visits will be expected (e.g. because no exposures are on-sky
observations).
"""

instrument = ""
"""The fully qualified name of the instrument.
"""

instrumentName = ""
"""The name of the instrument.
"""

outputRun = "raw"
"""The name of the output run to use in tests.
"""

@property
@abc.abstractmethod
def instrumentClassName(self):
"""The fully qualified instrument class name.
Returns
-------
`str`
The fully qualified instrument class name.
"""
pass

@property
def instrument(self):
"""The instrument class."""
return doImport(self.instrumentClassName)

@property
def instrumentName(self):
"""The name of the instrument.
Returns
-------
`str`
The name of the instrument.
"""
return self.instrument.getName()

def setUp(self):
# Use a temporary working directory
self.root = tempfile.mkdtemp(dir=self.ingestDir)
createRepo(self.root)

# Register the instrument and its static metadata
registerInstrument(self.root, self.instrument)
registerInstrument(self.root, self.instrumentClassName)

def tearDown(self):
if os.path.exists(self.root):
Expand Down Expand Up @@ -211,15 +227,15 @@ def testDefineVisits(self):

config = self.defineVisitsTask.ConfigClass()
butler = Butler(self.root, run=self.outputRun)
instrument = getInstrument(self.instrumentName, butler.registry)
instrument.applyConfigOverrides(self.defineVisitsTask._DefaultName, config)
instr = getInstrument(self.instrumentName, butler.registry)
instr.applyConfigOverrides(self.defineVisitsTask._DefaultName, config)
task = self.defineVisitsTask(config=config, butler=butler)
task.run(self.dataIds)

# Test that we got the visits we expected.
visits = set(butler.registry.queryDimensions(["visit"], expand=True))
self.assertCountEqual(visits, self.visits.keys())
camera = instrument.getCamera()
camera = instr.getCamera()
for foundVisit, (expectedVisit, expectedExposures) in zip(visits, self.visits.items()):
# Test that this visit is associated with the expected exposures.
foundExposures = set(butler.registry.queryDimensions(["exposure"], dataId=expectedVisit,
Expand Down

0 comments on commit 7a5c68c

Please sign in to comment.