def test(self):
        # create a repo where repo 'a' is a parent of repo 'b'
        butler = dp.Butler(outputs=dp.RepositoryArgs(
            root=os.path.join(self.testDir, 'a'), mapper=MapperForTestWriting))
        del butler
        butler = dp.Butler(inputs=os.path.join(self.testDir, 'a'),
                           outputs=os.path.join(self.testDir, 'b'))
        self.assertEqual(len(butler._repos.inputs()), 1)
        self.assertEqual(butler._repos.inputs()[0].cfg.root,
                         os.path.join(self.testDir, 'a'))
        self.assertEqual(len(butler._repos.outputs()), 1)
        self.assertEqual(butler._repos.outputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))
        del butler

        # load that repo a few times, include 'a' as an input.
        for i in range(4):
            butler = dp.Butler(inputs=os.path.join(self.testDir, 'a'),
                               outputs=dp.RepositoryArgs(root=os.path.join(
                                   self.testDir, 'b'),
                                                         mode='rw'))
            self.assertEqual(len(butler._repos.inputs()), 2)
            self.assertEqual(butler._repos.inputs()[0].cfg.root,
                             os.path.join(self.testDir, 'b'))
            self.assertEqual(butler._repos.inputs()[1].cfg.root,
                             os.path.join(self.testDir, 'a'))
            self.assertEqual(len(butler._repos.outputs()), 1)
            self.assertEqual(butler._repos.outputs()[0].cfg.root,
                             os.path.join(self.testDir, 'b'))
            cfg = dp.Storage().getRepositoryCfg(os.path.join(
                self.testDir, 'b'))
            self.assertEqual(
                cfg,
                dp.RepositoryCfg(root=os.path.join(self.testDir, 'b'),
                                 mapper=MapperForTestWriting,
                                 mapperArgs=None,
                                 parents=[os.path.join(self.testDir, 'a')],
                                 policy=None))

        # load the repo a few times and don't explicitly list 'a' as an input
        for i in range(4):
            butler = dp.Butler(outputs=dp.RepositoryArgs(
                root=os.path.join(self.testDir, 'b'), mode='rw'))
            self.assertEqual(len(butler._repos.inputs()), 2)
            self.assertEqual(butler._repos.inputs()[0].cfg.root,
                             os.path.join(self.testDir, 'b'))
            self.assertEqual(butler._repos.inputs()[1].cfg.root,
                             os.path.join(self.testDir, 'a'))
            self.assertEqual(len(butler._repos.outputs()), 1)
            self.assertEqual(butler._repos.outputs()[0].cfg.root,
                             os.path.join(self.testDir, 'b'))
            cfg = dp.Storage().getRepositoryCfg(os.path.join(
                self.testDir, 'b'))
            self.assertEqual(
                cfg,
                dp.RepositoryCfg(root=os.path.join(self.testDir, 'b'),
                                 mapper=MapperForTestWriting,
                                 mapperArgs=None,
                                 parents=[os.path.join(self.testDir, 'a')],
                                 policy=None))

        # load 'b' as 'write only' and don't list 'a' as an input. This should raise, because inputs must
        # match readable outputs parents.
        with self.assertRaises(RuntimeError):
            butler = dp.Butler(outputs=os.path.join(self.testDir, 'b'))

        # load 'b' as 'write only' and explicitly list 'a' as an input.
        butler = dp.Butler(inputs=os.path.join(self.testDir, 'a'),
                           outputs=os.path.join(self.testDir, 'b'))
        self.assertEqual(len(butler._repos.inputs()), 1)
        self.assertEqual(len(butler._repos.outputs()), 1)
        self.assertEqual(butler._repos.inputs()[0].cfg.root,
                         os.path.join(self.testDir, 'a'))
        self.assertEqual(butler._repos.outputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))
        cfg = dp.Storage().getRepositoryCfg(os.path.join(self.testDir, 'b'))
    def testOneLevelInputs(self):
        """
        1. put an object with the same ID but slightly different value into 2 repositories.
        2. use those repositories as inputs to a butler, and tag them
        3. make sure that the correct object is gotten for each of
            a. one tag
            b. the other tag
            c. no tag
        4. repeat step 3 but reverse the order of input cfgs to a new butler.
        5. use the butler from step 4 and write an output. The inputs will get recorded as parents of the
           output repo.
        6. create a new butler with a new overlapping repo, and verify that objects can be gotten from the
           other's parent repos via tagging.
        """
        objA = tstObj('a')
        objB = tstObj('b')

        # put objA in repo1:
        repo1Args = dp.RepositoryArgs(mode='rw',
                                      root=os.path.join(self.testDir, 'repo1'),
                                      mapper=MapperForTestWriting)
        butler = dp.Butler(outputs=repo1Args)
        butler.put(objA, 'foo', {'bar': 1})
        del butler

        # put objB in repo2:
        repo2Args = dp.RepositoryArgs(mode='rw',
                                      root=os.path.join(self.testDir, 'repo2'),
                                      mapper=MapperForTestWriting)
        butler = dp.Butler(outputs=repo2Args)
        butler.put(objB, 'foo', {'bar': 1})
        del butler
        del repo1Args
        del repo2Args

        # make the objects inputs of repos
        # and verify the correct object can ge fetched using the tag and not using the tag

        repo1Args = dp.RepositoryArgs(root=os.path.join(self.testDir, 'repo1'),
                                      tags='one')
        repo2Args = dp.RepositoryArgs(root=os.path.join(self.testDir, 'repo2'),
                                      tags='two')

        butler = dp.Butler(inputs=(repo1Args, repo2Args))
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='one')),
                         objA)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='two')),
                         objB)
        self.assertEqual(butler.get('foo', {'bar': 1}), objA)

        butler = dp.Butler(inputs=(repo2Args, repo1Args))
        self.assertEqual(butler.get('foo', dp.DataId(bar=1, tag='one')), objA)
        self.assertEqual(butler.get('foo', dp.DataId(bar=1, tag='two')), objB)
        self.assertEqual(butler.get('foo', dp.DataId(bar=1)), objB)

        # create butler with repo1 and repo2 as parents, and an output repo3.
        repo3Args = dp.RepositoryArgs(mode='rw',
                                      root=os.path.join(self.testDir, 'repo3'),
                                      mapper=MapperForTestWriting)
        butler = dp.Butler(inputs=(repo1Args, repo2Args), outputs=repo3Args)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='one')),
                         objA)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='two')),
                         objB)
        self.assertEqual(butler.get('foo', {'bar': 1}), objA)
        # add an object to the output repo. note since the output repo mode is 'rw' that object is gettable
        # and it has first priority in search order. Other repos should be searchable by tagging.
        objC = tstObj('c')
        butler.put(objC, 'foo', {'bar': 1})
        self.assertEqual(butler.get('foo', {'bar': 1}), objC)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='one')),
                         objA)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='two')),
                         objB)
        del butler

        repo3Cfg = dp.Storage().getRepositoryCfg(
            os.path.join(self.testDir, 'repo3'))
        self.assertEqual(repo3Cfg.parents, [
            os.path.join(self.testDir, 'repo1'),
            os.path.join(self.testDir, 'repo2')
        ])

        # expand the structure to look like this:
        # ┌────────────────────────┐ ┌────────────────────────┐
        # │repo1                   │ │repo2                   │
        # │ tag:"one"              │ │ tag:"two"              │
        # │ tstObj('a')            │ │ tstObj('b')            │
        # │   at ('foo', {'bar:1'})│ │   at ('foo', {'bar:1'})│
        # └───────────┬────────────┘ └───────────┬────────────┘
        #             └─────────────┬────────────┘
        #              ┌────────────┴───────────┐ ┌────────────────────────┐
        #              │repo4                   │ │repo5                   │
        #              │ tag:"four"             │ │ tag:"five"             │
        #              │ tstObj('d')            │ │ tstObj('e')            │
        #              │   at ('foo', {'bar:2'})│ │   at ('foo', {'bar:1'})│
        #              └───────────┬────────────┘ └───────────┬────────────┘
        #                          └─────────────┬────────────┘
        #                                     ┌──┴───┐
        #                                     │butler│
        #                                     └──────┘

        repo4Args = dp.RepositoryArgs(mode='rw',
                                      root=os.path.join(self.testDir, 'repo4'),
                                      mapper=MapperForTestWriting)
        butler = dp.Butler(inputs=(os.path.join(self.testDir, 'repo1'),
                                   os.path.join(self.testDir, 'repo2')),
                           outputs=repo4Args)
        objD = tstObj('d')
        butler.put(objD, 'foo', {'bar': 2})
        del butler

        repo5Cfg = dp.RepositoryArgs(mode='rw',
                                     root=os.path.join(self.testDir, 'repo5'),
                                     mapper=MapperForTestWriting)
        butler = dp.Butler(outputs=repo5Cfg)
        objE = tstObj('e')
        butler.put(objE, 'foo', {'bar': 1})
        del butler

        repo4Args = dp.RepositoryArgs(cfgRoot=os.path.join(
            self.testDir, 'repo4'),
                                      tags='four')
        repo5Args = dp.RepositoryArgs(cfgRoot=os.path.join(
            self.testDir, 'repo5'),
                                      tags='five')
        butler = dp.Butler(inputs=(repo4Args, repo5Args))
        self.assertEqual(butler.get('foo', {'bar': 1}), objA)
        self.assertEqual(butler.get('foo', {'bar': 2}), objD)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='four')),
                         objA)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='five')),
                         objE)
        del butler

        butler = dp.Butler(inputs=(repo5Args, repo4Args))
        self.assertEqual(butler.get('foo', {'bar': 1}), objE)
        self.assertEqual(butler.get('foo', {'bar': 2}), objD)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='four')),
                         objA)
        self.assertEqual(butler.get('foo', dp.DataId({'bar': 1}, tag='five')),
                         objE)
        del butler
    def testExistingParents(self):
        # parents of inputs should be added to the inputs list
        butler = dp.Butler(
            outputs=dp.RepositoryArgs(mode='w',
                                      mapper=dpTest.EmptyTestMapper,
                                      root=os.path.join(self.testDir, 'a')))
        del butler
        butler = dp.Butler(inputs=os.path.join(self.testDir, 'a'),
                           outputs=os.path.join(self.testDir, 'b'))
        del butler
        butler = dp.Butler(inputs=os.path.join(self.testDir, 'b'))
        self.assertEqual(len(butler._repos.inputs()), 2)
        # verify serach order:
        self.assertEqual(butler._repos.inputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))
        self.assertEqual(butler._repos.inputs()[1].cfg.root,
                         os.path.join(self.testDir, 'a'))
        self.assertEqual(len(butler._repos.outputs()), 0)

        butler = dp.Butler(outputs=dp.RepositoryArgs(
            cfgRoot=os.path.join(self.testDir, 'b'), mode='rw'))
        # verify serach order:
        self.assertEqual(butler._repos.inputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))
        self.assertEqual(butler._repos.inputs()[1].cfg.root,
                         os.path.join(self.testDir, 'a'))
        self.assertEqual(len(butler._repos.outputs()), 1)
        self.assertEqual(butler._repos.outputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))

        butler = dp.Butler(inputs=os.path.join(self.testDir, 'a'),
                           outputs=dp.RepositoryArgs(cfgRoot=os.path.join(
                               self.testDir, 'b'),
                                                     mode='rw'))
        self.assertEqual(len(butler._repos.inputs()), 2)
        # verify serach order:
        self.assertEqual(butler._repos.inputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))
        self.assertEqual(butler._repos.inputs()[1].cfg.root,
                         os.path.join(self.testDir, 'a'))
        self.assertEqual(len(butler._repos.outputs()), 1)
        self.assertEqual(butler._repos.outputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))

        # parents of write-only outputs must be be listed with the inputs
        with self.assertRaises(RuntimeError):
            butler = dp.Butler(outputs=os.path.join(self.testDir, 'b'))
        butler = dp.Butler(inputs=os.path.join(self.testDir, 'a'),
                           outputs=os.path.join(self.testDir, 'b'))
        self.assertEqual(len(butler._repos.inputs()), 1)
        self.assertEqual(len(butler._repos.outputs()), 1)
        self.assertEqual(butler._repos.outputs()[0].cfg.root,
                         os.path.join(self.testDir, 'b'))

        # add a new parent to an existing output
        butler = dp.Butler(
            outputs=dp.RepositoryArgs(mode='w',
                                      mapper=dpTest.EmptyTestMapper,
                                      root=os.path.join(self.testDir, 'c')))
        butler = dp.Butler(inputs=(os.path.join(self.testDir, 'a'),
                                   os.path.join(self.testDir, 'c')),
                           outputs=os.path.join(self.testDir, 'b'))

        # should raise if the input order gets reversed:
        with self.assertRaises(RuntimeError):
            butler = dp.Butler(inputs=(os.path.join(self.testDir, 'c'),
                                       os.path.join(self.testDir, 'a')),
                               outputs=os.path.join(self.testDir, 'b'))
Exemplo n.º 4
0
    def setUp(self):
        self.testData = tempfile.mkdtemp(dir=ROOT,
                                         prefix='TestCompositeTestCase-')
        self.firstRepoPath = os.path.join(self.testData, 'repo1')
        self.objA = dpTest.TestObject("abc")
        self.objB = dpTest.TestObject("def")
        self.policy = dafPersist.Policy({
            'camera': 'lsst.afw.cameraGeom.Camera',
            'datasets': {
                'basicObject1': {
                    'python': 'lsst.daf.persistence.test.TestObject',
                    'template': 'basic/id%(id)s.pickle',
                    'storage': 'PickleStorage'
                },
                'basicObject2': {
                    'python': 'lsst.daf.persistence.test.TestObject',
                    'template': 'basic/name%(name)s.pickle',
                    'storage': 'PickleStorage'
                },
                'basicPair': {
                    'python':
                    'lsst.daf.persistence.test.TestObjectPair',
                    'composite': {
                        'a': {
                            'datasetType': 'basicObject1'
                        },
                        'b': {
                            'datasetType': 'basicObject2'
                        }
                    },
                    'assembler':
                    'lsst.daf.persistence.test.TestObjectPair.assembler',
                    'disassembler':
                    'lsst.daf.persistence.test.TestObjectPair.disassembler'
                },
                'stdTestType': {
                    'python': 'lsst.daf.persistence.test.TestObjectPair',
                    'composite': {
                        'a': {
                            'datasetType': 'basicObject1'
                        },
                        'b': {
                            'datasetType': 'basicObject2'
                        }
                    }
                },
                'bypassTestType': {
                    'python': 'lsst.daf.persistence.test.TestObjectPair',
                    'composite': {
                        'a': {
                            'datasetType': 'basicObject1'
                        },
                        'b': {
                            'datasetType': 'basicObject2'
                        }
                    }
                }
            }
        })

        repoArgs = dafPersist.RepositoryArgs(
            root=self.firstRepoPath,
            policy=self.policy,
            mapper='lsst.obs.base.test.CompositeMapper')
        butler = dafPersist.Butler(outputs=repoArgs)
        butler.put(self.objA, 'basicObject1', dataId={'id': 'foo'})
        butler.put(self.objB, 'basicObject2', dataId={'name': 'bar'})
        del butler
        del repoArgs
Exemplo n.º 5
0
    def setUp(self):
        self.testData = tempfile.mkdtemp(dir=ROOT,
                                         prefix='TestGenericAssembler-')
        self.firstRepoPath = os.path.join(self.testData, 'repo1')
        self.secondRepoPath = os.path.join(self.testData, 'repo2')
        self.objA = dpTest.TestObject("abc")
        self.objB = dpTest.TestObject("def")
        self.policy = dafPersist.Policy({
            'camera': 'lsst.afw.cameraGeom.Camera',
            'datasets': {
                'basicObject1': {
                    'python': 'lsst.daf.persistence.test.TestObject',
                    'template': 'basic/id%(id)s.pickle',
                    'storage': 'PickleStorage'
                },
                'basicObject2': {
                    'python': 'lsst.daf.persistence.test.TestObject',
                    'template': 'basic/name%(name)s.pickle',
                    'storage': 'PickleStorage'
                },
                'basicPair': {
                    'python': 'lsst.daf.persistence.test.TestObjectPair',
                    'composite': {
                        'a': {
                            'datasetType': 'basicObject1'
                        },
                        'b': {
                            'datasetType': 'basicObject2'
                        }
                    },
                    # note, no assembler or disassembler specified here, will use
                    # setter names inferred by component name.
                },
                # "generic assembler default constructor pair"
                'gaDefCtorPair':
                {  # dataset defition that uses the default ctor
                    'python': 'lsst.daf.persistence.test.TestObjectPair',
                    'composite': {
                        # note that the component names are the same as the argument
                        # names in the TestObjectPair.__init__ func.
                        'objA': {
                            'datasetType': 'basicObject1',
                            'getter': 'get_a'
                        },
                        'objB': {
                            'datasetType': 'basicObject2',
                            'getter': 'get_b'
                        }
                    },
                    # note, no assembler or disassembler specified here.
                },
                # "generic assembler default "
                'gaPairWithSetter': {
                    'python': 'lsst.daf.persistence.test.TestObjectPair',
                    'composite': {
                        # note that the component names do not match argument names
                        # in the TestObjectPair.__init__ func or the set functions
                        # in the python object.
                        'z': {
                            'datasetType': 'basicObject1',
                            'setter': 'set_a',
                            'getter': 'get_a'
                        },
                        'x': {
                            'datasetType': 'basicObject2',
                            'setter': 'set_b',
                            'getter': 'get_b'
                        }
                    }
                },
                # simple object where setter and getter is named with underscore
                # separator
                'underscoreSetter': {
                    'python':
                    'lsst.daf.persistence.test.TestObjectUnderscoreSetter',
                    'composite': {
                        'foo': {
                            'datasetType': 'basicObject1'
                        }
                    }
                },
                # simple object where setter and getter is named with camelcase
                'camelCaseSetter': {
                    'python':
                    'lsst.daf.persistence.test.TestObjectCamelCaseSetter',
                    'composite': {
                        'foo': {
                            'datasetType': 'basicObject1'
                        }
                    }
                }
            }
        })

        repoArgs = dafPersist.RepositoryArgs(
            root=self.firstRepoPath,
            policy=self.policy,
            mapper='lsst.obs.base.test.CompositeMapper')
        butler = dafPersist.Butler(outputs=repoArgs)
        butler.put(self.objA, 'basicObject1', dataId={'id': 'foo'})
        butler.put(self.objB, 'basicObject2', dataId={'name': 'bar'})
        del butler
        del repoArgs
Exemplo n.º 6
0
    def testSwiftStorage(self):
        """Verify that SwiftStorage implements all the StorageInterface
        functions."""
        storage = SwiftStorage(uri=self.uri, create=True)
        self.assertEqual(storage._containerName, self.container1Name)
        self.assertTrue(storage.containerExists())
        # Test containerExists by changing the container name so that it will
        # return false, and then put the name back.
        containerName = storage._containerName
        storage._containerName = "foo"
        self.assertFalse(storage.containerExists())
        storage._containerName = containerName

        testObject = dpTest.TestObject("abc")
        butlerLocation = dp.ButlerLocation(
            pythonType='lsst.daf.persistence.test.TestObject',
            cppType=None,
            storageName='PickleStorage',
            locationList='firstTestObject',
            dataId={},
            mapper=None,
            storage=storage)

        # Test writing an object to storage
        storage.write(butlerLocation, testObject)
        # Test getting a local copy of the file in storage.
        localFile = storage.getLocalFile('firstTestObject')
        # Test reading the file in a new object using the localFile's name, as
        # well as using the localFile handle directly.
        for f in (open(localFile.name, 'r'), localFile):
            if sys.version_info.major >= 3:
                obj = pickle.load(f, encoding="latin1")
            else:
                obj = pickle.load(f)
            self.assertEqual(testObject, obj)
        # Test reading the butlerLocation, should return the object instance.
        reloadedObject = storage.read(butlerLocation)
        self.assertEqual(testObject, reloadedObject[0])
        # Test the 'exists' function with a string
        self.assertTrue(storage.exists('firstTestObject'))
        self.assertFalse(storage.exists('secondTestObject'))
        # Test the 'exists' function with a ButlerLocation. (note that most of
        # the butler location fields are unused in exists and so are set to
        # None here.)
        location = dp.ButlerLocation(pythonType=None,
                                     cppType=None,
                                     storageName=None,
                                     locationList=['firstTestObject'],
                                     dataId={},
                                     mapper=None,
                                     storage=None)
        self.assertTrue(storage.exists(location))
        location = dp.ButlerLocation(pythonType=None,
                                     cppType=None,
                                     storageName=None,
                                     locationList=['secondTestObject'],
                                     dataId={},
                                     mapper=None,
                                     storage=None)
        self.assertFalse(storage.exists(location))
        # Test the 'instanceSearch' function, with and without the fits header
        # extension
        self.assertEqual(storage.instanceSearch('firstTestObject'),
                         ['firstTestObject'])
        self.assertEqual(storage.instanceSearch('firstTestObject[1]'),
                         ['firstTestObject[1]'])
        self.assertEqual(storage.instanceSearch('first*Object'),
                         ['firstTestObject'])
        self.assertEqual(storage.instanceSearch('*TestObject[1]'),
                         ['firstTestObject[1]'])
        self.assertIsNone(storage.instanceSearch('secondTestObject'))
        self.assertIsNone(storage.instanceSearch('secondTestObject[1]'))
        # Test the 'search' function
        self.assertEqual(storage.search(self.uri, 'firstTestObject'),
                         ['firstTestObject'])
        # Test the copy function
        storage.copyFile('firstTestObject', 'secondTestObject')
        with self.assertRaises(RuntimeError):
            storage.copyFile('thirdTestObject', 'fourthTestObject')
        # Test locationWithRoot
        self.assertEqual(storage.locationWithRoot('firstTestObject'),
                         self.uri + '/' + 'firstTestObject')
        # Test getRepositoryCfg and putRepositoryCfg
        repositoryCfg = dp.RepositoryCfg.makeFromArgs(dp.RepositoryArgs(
            root=self.uri, mapper=TestMapper),
                                                      parents=None)
        storage.putRepositoryCfg(repositoryCfg)
        reloadedRepoCfg = storage.getRepositoryCfg(self.uri)
        self.assertEqual(repositoryCfg, reloadedRepoCfg)
        # Test getting a non-existant RepositoryCfg
        self.assertIsNone(storage.getRepositoryCfg(self.uri2))
        # Test getting the mapper class from the repoCfg in the repo.
        mapper = SwiftStorage.getMapperClass(self.uri)
        self.assertEqual(mapper, TestMapper)
        # Test for a repoCfg that resides outside its repository; it has a
        # root that is not the same as its location.
        repositoryCfg = dp.RepositoryCfg.makeFromArgs(dp.RepositoryArgs(
            root='foo/bar/baz', mapper='lsst.obs.base.CameraMapper'),
                                                      parents=None)
        storage.putRepositoryCfg(repositoryCfg, loc=self.uri)
        reloadedRepoCfg = storage.getRepositoryCfg(self.uri)
        self.assertEqual(repositoryCfg, reloadedRepoCfg)

        storage.deleteContainer()
        self.assertFalse(storage.containerExists())