Beispiel #1
0
    def test_s3_prefixes(self):
        # Requires these environment variables set
        #
        #   AWS_ACCESS_KEY_ID
        #   AWS_SECRET_ACCESS_KEY
        #   S3TS_BUCKET
        #
        # NB: **this will only work if the bucket is empty

        s3c = boto.connect_s3()
        bucket = s3c.get_bucket(os.environ['S3TS_BUCKET'])

        with EmptyS3Bucket(bucket):
            localCache = LocalFileStore(
                makeEmptyDir(os.path.join(self.workdir, 'cache')))
            treestore1 = TreeStore.create(S3FileStore(bucket,
                                                      "prefix1"), localCache,
                                          TreeStoreConfig(100, True))
            treestore2 = TreeStore.create(S3FileStore(bucket,
                                                      "prefix2"), localCache,
                                          TreeStoreConfig(100, True))

            # Confirm we can write the different values to the same path in both treestores,
            # and the different prefix keeps them separate independent
            creationTime = datetimeFromIso('2015-01-01T00:00:00.0')
            treestore1.upload('release', '', creationTime, self.srcTree,
                              CaptureUploadProgress())
            treestore2.upload('release', '', creationTime, self.srcTree2,
                              CaptureUploadProgress())
            pkg1 = treestore1.findPackage('release')
            pkg2 = treestore2.findPackage('release')
            self.assertEquals(len(pkg1.files), 3)
            self.assertEquals(len(pkg2.files), 4)
Beispiel #2
0
def createTreeStore(chunksize):
    localCacheDir = getEnv('S3TS_LOCALCACHE',
                           'the local directory used for caching')
    bucket, s3PathPrefix = connectToBucket()
    config = TreeStoreConfig(chunksize, True)
    return TreeStore.create(S3FileStore(bucket, s3PathPrefix),
                            LocalFileStore(localCacheDir), config)
Beispiel #3
0
    def test_s3_many_treestore(self):
        # Create an s3 backed treestore
        # Requires these environment variables set
        #
        #   AWS_ACCESS_KEY_ID
        #   AWS_SECRET_ACCESS_KEY
        #   S3TS_BUCKET
        #
        # NB: **this will only work if the bucket is empty

        s3c = boto.connect_s3()
        bucket = s3c.get_bucket(os.environ['S3TS_BUCKET'])

        with EmptyS3Bucket(bucket):
            fileStore = S3FileStore(bucket)
            localCache = LocalFileStore(
                makeEmptyDir(os.path.join(self.workdir, 'cache')))
            treestore = TreeStore.create(fileStore, localCache,
                                         TreeStoreConfig(100, True))

            # Upload it as a tree
            creationTime = datetimeFromIso('2015-01-01T00:00:00.0')
            treestore.uploadMany('v1.0', '', creationTime, self.srcTree,
                                 self.srcVariant, CaptureUploadProgress())
            pkg = treestore.findPackage('v1.0:kiosk-01')

            # Confirm it's in the index
            self.assertEquals(treestore.listPackages(),
                              ['v1.0:kiosk-01', 'v1.0:kiosk-02'])

            # Verify it
            treestore.verify(pkg)

            # Download it, checking we get expected progress callbacks
            cb = CaptureDownloadProgress()
            treestore.download(pkg, cb)
            self.assertEquals(sorted(cb.recorded), [29, 30, 45, 47, 100, 100])

            # Verify it locally
            treestore.verifyLocal(pkg)

            # Install it
            destTree = os.path.join(self.workdir, 'dest-1')
            treestore.install(pkg, destTree, CaptureInstallProgress())

            # Check that the installed tree is the same as the source tree
            self.assertEquals(
                subprocess.call('diff -r -x {0} {1} {2}'.format(
                    S3TS_PROPERTIES, self.srcTree + '/assets',
                    destTree + '/assets'),
                                shell=True), 0)
            self.assertEquals(
                subprocess.call('diff -r -x {0} {1} {2}'.format(
                    S3TS_PROPERTIES, self.srcTree + '/code',
                    destTree + '/code'),
                                shell=True), 0)

            self.assertEquals(
                readInstallProperties(destTree).treeName, 'v1.0:kiosk-01')
Beispiel #4
0
def openTreeStore(dryRun=False,verbose=False):
    localCacheDir = getEnv( 'S3TS_LOCALCACHE', 'the local directory used for caching'  )
    bucket,s3PathPrefix = connectToBucket()
    treeStore = TreeStore.open( S3FileStore(bucket,s3PathPrefix), LocalFileStore(localCacheDir) )
    treeStore.setDryRun(dryRun)
    if verbose:
        treeStore.setOutVerbose( outVerbose )
    return treeStore
Beispiel #5
0
def openTreeStore(dryRun=False, verbose=False):
    localCacheDir = getEnv('S3TS_LOCALCACHE',
                           'the local directory used for caching')
    bucket, s3PathPrefix = connectToBucket()
    treeStore = TreeStore.open(S3FileStore(bucket, s3PathPrefix),
                               LocalFileStore(localCacheDir))
    treeStore.setDryRun(dryRun)
    if verbose:
        treeStore.setOutVerbose(outVerbose)
    return treeStore
Beispiel #6
0
    def test_s3_merged_package(self):
        # Test the creation and subsequent installation of merged packages
        # Requires these environment variables set
        #
        #   AWS_ACCESS_KEY_ID
        #   AWS_SECRET_ACCESS_KEY
        #   S3TS_BUCKET
        #
        # NB: **this will only work if the bucket is empty

        s3c = boto.connect_s3()
        bucket = s3c.get_bucket(os.environ['S3TS_BUCKET'])

        with EmptyS3Bucket(bucket):
            localCache = LocalFileStore(
                makeEmptyDir(os.path.join(self.workdir, 'cache')))
            treestore = TreeStore.create(S3FileStore(bucket), localCache,
                                         TreeStoreConfig(100, True))
            creationTime = datetimeFromIso('2015-01-01T00:00:00.0')
            treestore.upload('src1', '', creationTime, self.srcTree,
                             CaptureUploadProgress())
            treestore.upload('src2', '', creationTime, self.srcTree2,
                             CaptureUploadProgress())
            treestore.upload('src3', '', creationTime, self.srcTree3,
                             CaptureUploadProgress())
            treestore.createMerged('merged', creationTime, {
                '.': 'src1',
                'subdir-a': 'src2',
                'subdir-b': 'src3'
            })
            pkg = treestore.findPackage('merged')
            treestore.download(pkg, CaptureDownloadProgress())
            destTree = os.path.join(self.workdir, 'merged')
            treestore.install(pkg, destTree, CaptureInstallProgress())

            def assertSameContent(path1, path2):
                with open(path1) as f1:
                    with open(path2) as f2:
                        self.assertEquals(f1.read(), f2.read())

            assertSameContent(os.path.join(destTree, "code/file1.py"),
                              os.path.join(self.srcTree, "code/file1.py"))
            assertSameContent(os.path.join(destTree, "subdir-a/code/file4.py"),
                              os.path.join(self.srcTree2, "code/file4.py"))
            assertSameContent(os.path.join(destTree, "subdir-b/text/text"),
                              os.path.join(self.srcTree3, "text/text"))
Beispiel #7
0
def runtest(testContent):
    print "----------------------------------------------------------------------"
    print "* path", testContent

    dir = tempfile.mkdtemp()
    try:
        store = LocalFileStore(os.path.join(dir, 'store'))
        cache = LocalFileStore(os.path.join(dir, 'cache'))
        config = TreeStoreConfig(1000000, True)
        ts = TreeStore.create(store, cache, config)

        creationTime = datetime.datetime.now()
        print "* Initial upload"
        stats = TransferStats()
        ts.upload( "test", "", creationTime, testContent, stats.progress)
        stats.done()
        print
        print "* Repeat upload"
        stats = TransferStats()
        ts.upload( "test", "", creationTime, testContent, stats.progress)
        stats.done()

        print
        print "* Download"
        stats = TransferStats()
        pkg = ts.find("test")
        ts.download(pkg, stats.progress)
        stats.done()

        print
        print "* Clean installation"
        installDir = os.path.join(dir,"install")
        os.makedirs(installDir)
        stats = InstallStats()
        pkg = ts.find("test")
        ts.install(pkg, installDir, stats.progress)
        stats.done()
            
    finally:
        shutil.rmtree(dir)
Beispiel #8
0
    def test_metapackages(self):
        # Create a file system backed treestore
        fileStore = LocalFileStore(
            makeEmptyDir(os.path.join(self.workdir, 'fs')))
        localCache = LocalFileStore(
            makeEmptyDir(os.path.join(self.workdir, 'cache')))
        treestore = TreeStore.create(fileStore, localCache,
                                     TreeStoreConfig(10, True))

        creationTime = datetimeFromIso('2015-01-01T00:00:00.0')
        treestore.upload('v1.0', '', creationTime, self.srcTree,
                         CaptureUploadProgress())
        treestore.upload('v1.3', '', creationTime, self.srcTree3,
                         CaptureUploadProgress())
        treestore.upload('v1.4', '', creationTime, self.srcTree4,
                         CaptureUploadProgress())

        meta1 = MetaPackage(name='meta1',
                            description='',
                            creationTime=creationTime,
                            components=[
                                SubPackage('dir-1', 'v1.0'),
                                SubPackage('dir-2', 'v1.3'),
                            ])

        meta1.verify(treestore, {})
        treestore.uploadMetaPackage(meta1)
        meta1p = treestore.find('meta1', {})
        treestore.download(meta1p, CaptureDownloadProgress())

        # Install it
        destTree = os.path.join(self.workdir, 'dest-1')
        treestore.install(meta1p, destTree, CaptureInstallProgress())

        def assertContains(path, text):
            self.assertEquals(open(os.path.join(destTree, path)).read(), text)

        assertContains("dir-1/code/file1.py", self.FILE1)
        assertContains("dir-2/text/text", self.FILE5)
Beispiel #9
0
def createTreeStore(chunksize):
    localCacheDir = getEnv( 'S3TS_LOCALCACHE', 'the local directory used for caching'  )
    bucket,s3PathPrefix = connectToBucket()
    config = TreeStoreConfig( chunksize, True )
    return TreeStore.create( S3FileStore(bucket,s3PathPrefix), LocalFileStore(localCacheDir), config )
Beispiel #10
0
    def test_s3_treestore(self):
        # Create an s3 backed treestore
        # Requires these environment variables set
        #
        #   AWS_ACCESS_KEY_ID
        #   AWS_SECRET_ACCESS_KEY
        #   S3TS_BUCKET
        #
        # NB: **this will only work if the bucket is empty

        s3c = boto.connect_s3()
        bucket = s3c.get_bucket(os.environ['S3TS_BUCKET'])

        with EmptyS3Bucket(bucket):
            fileStore = S3FileStore(bucket)
            localCache = LocalFileStore(
                makeEmptyDir(os.path.join(self.workdir, 'cache')))
            treestore = TreeStore.create(fileStore, localCache,
                                         TreeStoreConfig(100, True))

            # Upload it as a tree
            creationTime = datetimeFromIso('2015-01-01T00:00:00.0')
            treestore.upload('v1.0', '', creationTime, self.srcTree,
                             CaptureUploadProgress())
            pkg = treestore.findPackage('v1.0')

            # Confirm it's in the index
            self.assertEquals(treestore.listPackages(), ['v1.0'])

            # Verify it
            treestore.verify(pkg)

            # Download it, checking we get expected progress callbacks
            cb = CaptureDownloadProgress()
            treestore.download(pkg, cb)
            self.assertEquals(sorted(cb.recorded), [30, 45, 47, 100, 100])

            # Verify it locally
            treestore.verifyLocal(pkg)

            # Install it
            destTree = os.path.join(self.workdir, 'dest-1')
            treestore.install(pkg, destTree, CaptureInstallProgress())

            # Check that the installed tree is the same as the source tree
            self.assertEquals(
                subprocess.call('diff -r -x {0} {1} {2}'.format(
                    S3TS_PROPERTIES, self.srcTree, destTree),
                                shell=True), 0)
            self.assertEquals(readInstallProperties(destTree).treeName, 'v1.0')

            # Use the compareInstall function to confirm the installed package is ok, and
            # then check that modifying the files show up in the comparison
            result = treestore.compareInstall(pkg, destTree)
            self.assertEquals(len(result.missing), 0)
            self.assertEquals(len(result.extra), 0)
            self.assertEquals(len(result.diffs), 0)

            with open(os.path.join(destTree, "code/file1.py"), "w") as f:
                f.write("x")
            with open(os.path.join(destTree, "code/file3.py"), "w") as f:
                f.write("y")
            os.unlink(os.path.join(destTree, 'assets/car-01.db'))

            result = treestore.compareInstall(pkg, destTree)
            self.assertEquals(result.missing, set(['assets/car-01.db']))
            self.assertEquals(result.extra, set(['code/file3.py']))
            self.assertEquals(result.diffs, set(['code/file1.py']))

            # Reinstall to fix directory content
            shutil.rmtree(destTree)
            treestore.install(pkg, destTree, CaptureInstallProgress())
            result = treestore.compareInstall(pkg, destTree)
            self.assertEquals(len(result.missing), 0)
            self.assertEquals(len(result.extra), 0)
            self.assertEquals(len(result.diffs), 0)

            # Now create a pre-signed version of the package
            pkg = treestore.findPackage('v1.0')
            treestore.addUrls(pkg, 3600)
            self.assertEquals(len(result.missing), 0)
            self.assertEquals(len(result.extra), 0)
            self.assertEquals(len(result.diffs), 0)

            # And download it directly via http. Create a new local cache
            # to ensure that we actually redownload each chunk
            localCache = LocalFileStore(
                makeEmptyDir(os.path.join(self.workdir, 'cache')))
            treestore2 = TreeStore.forHttpOnly(localCache)
            cb = CaptureDownloadProgress()
            treestore2.downloadHttp(pkg, cb)
            self.assertEquals(sorted(cb.recorded), [30, 45, 47, 100, 100])

            # Install it
            destTree2 = os.path.join(self.workdir, 'dest-2')
            treestore2.install(pkg, destTree2, CaptureInstallProgress())

            # Check that the new installed tree is the same as the source tree
            self.assertEquals(
                subprocess.call('diff -r -x {0} {1} {2}'.format(
                    S3TS_PROPERTIES, self.srcTree, destTree2),
                                shell=True), 0)

            # Rename the tree, and check that installing that is the same
            treestore.rename('v1.0', 'v1.0x')
            pkg = treestore.findPackage('v1.0x')
            treestore.download(pkg, CaptureDownloadProgress())
            destTree = os.path.join(self.workdir, 'dest-3')
            treestore.install(pkg, destTree, CaptureInstallProgress())
            self.assertEquals(
                subprocess.call('diff -r -x {0} {1} {2}'.format(
                    S3TS_PROPERTIES, self.srcTree, destTree),
                                shell=True), 0)

            # Remove the tree
            treestore.remove('v1.0x')
Beispiel #11
0
    def test_sync(self):
        # Create a file system backed treestore
        fileStore = LocalFileStore(
            makeEmptyDir(os.path.join(self.workdir, 'fs')))
        localCache = LocalFileStore(
            makeEmptyDir(os.path.join(self.workdir, 'cache')))
        treestore = TreeStore.create(fileStore, localCache,
                                     TreeStoreConfig(10, True))

        creationTime = datetimeFromIso('2015-01-01T00:00:00.0')
        treestore.upload('v1.0', '', creationTime, self.srcTree,
                         CaptureUploadProgress())
        treestore.upload('v1.3', '', creationTime, self.srcTree3,
                         CaptureUploadProgress())
        treestore.upload('v1.4', '', creationTime, self.srcTree4,
                         CaptureUploadProgress())

        testdir = makeEmptyDir(os.path.join(self.workdir, 'test'))

        def assertExists(path):
            self.assertTrue(os.path.exists(os.path.join(testdir, path)))

        def assertContains(path, text):
            self.assertEquals(open(os.path.join(testdir, path)).read(), text)

        def assertDoesntExist(path):
            self.assertFalse(os.path.exists(os.path.join(testdir, path)))

        def assertInstalled(pkg, testdir):
            result = treestore.compareInstall(pkg, testdir)
            self.assertEquals(result.missing, set())
            self.assertEquals(result.extra, set())
            self.assertEquals(result.diffs, set())

        # sync a package to an empty directory
        pkg = treestore.findPackage('v1.0')
        treestore.download(pkg, CaptureDownloadProgress())
        treestore.sync(pkg, testdir, CaptureInstallProgress())
        assertContains("code/file1.py", self.FILE1)
        assertContains("code/file2.py", self.FILE2)
        assertContains("assets/car-01.db", self.CAR01)
        assertExists(S3TS_PACKAGEFILE)
        assertInstalled(pkg, testdir)

        # Re-sync the same package
        pkg = treestore.findPackage('v1.0')
        treestore.download(pkg, CaptureDownloadProgress())
        treestore.sync(pkg, testdir, CaptureInstallProgress())
        assertContains("code/file1.py", self.FILE1)
        assertContains("code/file2.py", self.FILE2)
        assertContains("assets/car-01.db", self.CAR01)
        assertExists(S3TS_PACKAGEFILE)
        assertInstalled(pkg, testdir)

        # Sync to a different package
        pkg = treestore.findPackage('v1.3')
        treestore.download(pkg, CaptureDownloadProgress())
        treestore.sync(pkg, testdir, CaptureInstallProgress())
        assertContains("code/file1.py", self.FILE1)
        assertContains("code/file2.py", self.FILE2_A)
        assertDoesntExist("assets/car-01.db")
        assertContains("code/file4.py", self.FILE4)
        assertContains("text/text", self.FILE5)
        assertExists(S3TS_PACKAGEFILE)
        assertInstalled(pkg, testdir)

        # Sync back to the first package
        pkg = treestore.findPackage('v1.0')
        treestore.download(pkg, CaptureDownloadProgress())
        treestore.sync(pkg, testdir, CaptureInstallProgress())
        assertContains("code/file1.py", self.FILE1)
        assertContains("code/file2.py", self.FILE2)
        assertContains("assets/car-01.db", self.CAR01)
        assertDoesntExist("code/file4.py")
        assertExists(S3TS_PACKAGEFILE)
        assertInstalled(pkg, testdir)

        # Remove the package file, and sync the second package again
        os.unlink(os.path.join(testdir, S3TS_PACKAGEFILE))
        pkg = treestore.findPackage('v1.3')
        treestore.download(pkg, CaptureDownloadProgress())
        treestore.sync(pkg, testdir, CaptureInstallProgress())
        assertContains("code/file1.py", self.FILE1)
        assertContains("code/file2.py", self.FILE2_A)
        assertDoesntExist("assets/car-01.db")
        assertContains("code/file4.py", self.FILE4)
        assertExists(S3TS_PACKAGEFILE)
        assertInstalled(pkg, testdir)

        # Add an extra file not in the package, and ensure
        # that syncing deletes it
        with open(os.path.join(testdir, "debug.log"), 'w') as f:
            f.write("something")
        pkg = treestore.findPackage('v1.3')
        treestore.sync(pkg, testdir, CaptureInstallProgress())
        assertInstalled(pkg, testdir)

        # Sync to test replacing a directory with a file
        pkg = treestore.findPackage('v1.4')
        treestore.download(pkg, CaptureDownloadProgress())
        treestore.sync(pkg, testdir, CaptureInstallProgress())
        assertContains("text", self.FILE5)
        assertInstalled(pkg, testdir)
Beispiel #12
0
    def test_fs_treestore(self):
        # Create a file system backed treestore
        fileStore = LocalFileStore(
            makeEmptyDir(os.path.join(self.workdir, 'fs')))
        localCache = LocalFileStore(
            makeEmptyDir(os.path.join(self.workdir, 'cache')))
        treestore = TreeStore.create(fileStore, localCache,
                                     TreeStoreConfig(100, True))

        # Upload 2 trees
        creationTime = datetimeFromIso('2015-01-01T00:00:00.0')
        treestore.upload('v1.0', '', creationTime, self.srcTree,
                         CaptureUploadProgress())
        pkg = treestore.findPackage('v1.0')

        # Confirm it's in the index
        self.assertEquals(treestore.listPackages(), ['v1.0'])

        # Verify it
        treestore.verify(pkg)

        # Test the cache priming function
        treestore.prime(self.srcTree2, CaptureUploadProgress())

        # Test whether the verifyCache works
        corruptedFiles = treestore.validateLocalCache()
        self.assertEquals(len(corruptedFiles), 0)

        # Download it, checking we get expected progress callbacks
        # The order of the callbacks will depend on the order of the
        # chunks in the package definition, which will depend on the
        # iteration order of the file system when the package was created.
        # So check independently of ordering.
        cb = CaptureDownloadProgress()
        treestore.download(pkg, cb)
        self.assertEquals(sorted(cb.recorded), [30, 45, 47, 100, 100])

        # Verify it locally
        treestore.verifyLocal(pkg)

        # Install it
        destTree = os.path.join(self.workdir, 'dest-1')
        treestore.install(pkg, destTree, CaptureInstallProgress())

        # Check that the installed tree is the same as the source tree
        self.assertEquals(
            subprocess.call('diff -r -x {0} {1} {2}'.format(
                S3TS_PROPERTIES, self.srcTree, destTree),
                            shell=True), 0)

        # Rename the tree, and check that installing that is the same
        treestore.rename('v1.0', 'v1.0x')
        pkg = treestore.findPackage('v1.0x')
        treestore.download(pkg, CaptureDownloadProgress())
        destTree = os.path.join(self.workdir, 'dest-2')
        treestore.install(pkg, destTree, CaptureInstallProgress())
        self.assertEquals(
            subprocess.call('diff -r -x {0} {1} {2}'.format(
                S3TS_PROPERTIES, self.srcTree, destTree),
                            shell=True), 0)

        # Test the flushStore function has nothing to remove)
        treestore.upload('extra', '', creationTime, self.srcTree2,
                         CaptureUploadProgress())
        removed = treestore.flushStore()
        self.assertEquals(len(removed), 0)

        # Remove a tree
        treestore.remove('v1.0x')

        # Test the store now has dangling chunks when can be removed
        removed = treestore.flushStore()
        self.assertTrue(len(removed) > 0)

        treestore.upload('v1.0', '', creationTime, self.srcTree,
                         CaptureUploadProgress())

        # Initially the local cache should contain chunks for v1.0 and extra. Empty
        # the local cache by successive flush operations
        removed = treestore.flushLocalCache(['extra'])
        self.assertTrue(len(removed) > 0)
        removed = treestore.flushLocalCache(['v1.0'])
        self.assertTrue(len(removed) > 0)

        # Confirm that removing everything from the local cache is refused
        with self.assertRaises(RuntimeError):
            treestore.flushLocalCache([])
Beispiel #13
0
def nonS3TreeStore():
    # Don't use or require S3 - some operations won't be available
    localCacheDir = getEnv('S3TS_LOCALCACHE',
                           'the local directory used for caching')
    return TreeStore(FileStore(), LocalFileStore(localCacheDir), None)