[ARVADOS] updated: 23a940aaf47411cd07615b3301d24d3868a11bce
git at public.curoverse.com
git at public.curoverse.com
Wed Apr 15 16:51:11 EDT 2015
Summary of changes:
sdk/python/arvados/arvfile.py | 21 +++++---
sdk/python/arvados/collection.py | 75 ++++++++++++++-------------
sdk/python/tests/test_arvfile.py | 8 +--
services/fuse/arvados_fuse/__init__.py | 13 +++--
services/fuse/arvados_fuse/fusedir.py | 94 ++++++++++++++++++++++++----------
services/fuse/arvados_fuse/fusefile.py | 5 ++
services/fuse/tests/test_mount.py | 67 +++++++++++++++++++++++-
7 files changed, 207 insertions(+), 76 deletions(-)
via 23a940aaf47411cd07615b3301d24d3868a11bce (commit)
via f91b1eaef727a11769edb8d02410b43386652b0d (commit)
from 499d871d59a5c05cf1034580e7c10ba37cefef4a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 23a940aaf47411cd07615b3301d24d3868a11bce
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date: Wed Apr 15 16:51:07 2015 -0400
3198: Can modify file, collection objects, changes are reflected in FUSE.
diff --git a/sdk/python/arvados/arvfile.py b/sdk/python/arvados/arvfile.py
index 53653c0..13bb507 100644
--- a/sdk/python/arvados/arvfile.py
+++ b/sdk/python/arvados/arvfile.py
@@ -9,6 +9,7 @@ import Queue
import copy
import errno
import re
+import logging
from .errors import KeepWriteError, AssertionError
from .keep import KeepLocator
@@ -18,6 +19,8 @@ from .retry import retry_method
MOD = "mod"
+_logger = logging.getLogger('arvados.arvfile')
+
def split(path):
"""split(path) -> streamname, filename
diff --git a/services/fuse/arvados_fuse/__init__.py b/services/fuse/arvados_fuse/__init__.py
index 58fc571..b376d64 100644
--- a/services/fuse/arvados_fuse/__init__.py
+++ b/services/fuse/arvados_fuse/__init__.py
@@ -23,11 +23,15 @@ import itertools
import ciso8601
import collections
-from fusedir import sanitize_filename, Directory, CollectionDirectory, MagicDirectory, TagsDirectory, ProjectDirectory, SharedDirectory
+from fusedir import sanitize_filename, Directory, CollectionDirectory, MagicDirectory, TagsDirectory, ProjectDirectory, SharedDirectory, CollectionDirectoryBase
from fusefile import StringFile, FuseArvadosFile
_logger = logging.getLogger('arvados.arvados_fuse')
+# log_handler = logging.StreamHandler()
+# llogger = logging.getLogger('llfuse')
+# llogger.addHandler(log_handler)
+# llogger.setLevel(logging.DEBUG)
class FileHandle(object):
"""Connects a numeric file handle to a File object that has
@@ -198,10 +202,13 @@ class Operations(llfuse.Operations):
entry.st_mode = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
if isinstance(e, Directory):
entry.st_mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH | stat.S_IFDIR
- elif isinstance(e, FuseArvadosFile):
- entry.st_mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH | stat.S_IFREG
else:
entry.st_mode |= stat.S_IFREG
+ if isinstance(e, FuseArvadosFile):
+ entry.st_mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
+
+ if e.writable():
+ entry.st_mode |= stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH
entry.st_nlink = 1
entry.st_uid = self.uid
diff --git a/services/fuse/arvados_fuse/fusedir.py b/services/fuse/arvados_fuse/fusedir.py
index c1cfaa4..53f53c7 100644
--- a/services/fuse/arvados_fuse/fusedir.py
+++ b/services/fuse/arvados_fuse/fusedir.py
@@ -164,37 +164,72 @@ class Directory(FreshBase):
def mtime(self):
return self._mtime
+ def writable(self):
+ return False
+
+
+class CollectionDirectoryBase(Directory):
+ def __init__(self, parent_inode, inodes, collection):
+ super(CollectionDirectoryBase, self).__init__(parent_inode, inodes)
+ self.collection = collection
-class CollectionDirectory(Directory):
+ def new_entry(self, name, item, mtime):
+ name = sanitize_filename(name)
+ if isinstance(item, arvados.collection.RichCollectionBase):
+ self._entries[name] = self.inodes.add_entry(CollectionDirectoryBase(self.inode, self.inodes, item))
+ self._entries[name].populate(mtime)
+ else:
+ self._entries[name] = self.inodes.add_entry(FuseArvadosFile(self.inode, item, mtime))
+
+ def on_event(self, event, collection, name, item):
+ _logger.warn("Got event! %s %s %s %s", event, collection, name, item)
+ if collection == self.collection:
+ with llfuse.lock:
+ if event == arvados.collection.ADD:
+ self.new_entry(name, item, self.mtime())
+ elif event == arvados.collection.DEL:
+ ent = self._entries[name]
+ llfuse.invalidate_entry(self.inode, name)
+ self.inodes.del_entry(ent)
+ elif event == arvados.collection.MOD:
+ ent = self._entries[name]
+ llfuse.invalidate_entry(self.inode, name)
+ llfuse.invalidate_inode(ent.inode)
+
+ def populate(self, mtime):
+ self._mtime = mtime
+ self.collection.subscribe(self.on_event)
+ for entry, item in self.collection.items():
+ self.new_entry(entry, item, self.mtime())
+
+ def writable(self):
+ return self.collection.writable()
+
+
+class CollectionDirectory(CollectionDirectoryBase):
"""Represents the root of a directory tree holding a collection."""
- def __init__(self, parent_inode, inodes, api, num_retries, collection):
- super(CollectionDirectory, self).__init__(parent_inode, inodes)
+ def __init__(self, parent_inode, inodes, api, num_retries, collection_record=None, explicit_collection=None):
+ super(CollectionDirectory, self).__init__(parent_inode, inodes, None)
self.api = api
self.num_retries = num_retries
self.collection_object_file = None
self.collection_object = None
- if isinstance(collection, dict):
- self.collection_locator = collection['uuid']
- self._mtime = convertTime(collection.get('modified_at'))
+ if isinstance(collection_record, dict):
+ self.collection_locator = collection_record['uuid']
+ self._mtime = convertTime(collection_record.get('modified_at'))
else:
- self.collection_locator = collection
+ self.collection_locator = collection_record
self._mtime = 0
self._manifest_size = 0
+ if self.collection_locator:
+ self._writable = (uuid_pattern.match(self.collection_locator) is not None)
def same(self, i):
return i['uuid'] == self.collection_locator or i['portable_data_hash'] == self.collection_locator
- @staticmethod
- def populate(inodes, cwd, collection, mtime):
- for entry, item in collection.items():
- entry = sanitize_filename(entry)
- if isinstance(item, arvados.collection.RichCollectionBase):
- cwd._entries[entry] = inodes.add_entry(Directory(cwd.inode, inodes))
- cwd._mtime = mtime
- CollectionDirectory.populate(inodes, cwd._entries[entry], item, mtime)
- else:
- cwd._entries[entry] = inodes.add_entry(FuseArvadosFile(cwd.inode, item, mtime))
+ def writable(self):
+ return self.collection.writable() if self.collection else self._writable
# Used by arv-web.py to switch the contents of the CollectionDirectory
def change_collection(self, new_locator):
@@ -208,16 +243,19 @@ class CollectionDirectory(Directory):
self.update()
def new_collection(self, new_collection_object, coll_reader):
- self.clear(force=True)
+ if self.inode:
+ self.clear(force=True)
self.collection_object = new_collection_object
- self._mtime = convertTime(self.collection_object.get('modified_at'))
+ if self.collection_object:
+ self._mtime = convertTime(self.collection_object.get('modified_at'))
- if self.collection_object_file is not None:
- self.collection_object_file.update(self.collection_object)
+ if self.collection_object_file is not None:
+ self.collection_object_file.update(self.collection_object)
- CollectionDirectory.populate(self.inodes, self, coll_reader, self.mtime())
+ self.collection = coll_reader
+ self.populate(self.mtime())
def update(self):
try:
@@ -229,9 +267,14 @@ class CollectionDirectory(Directory):
return True
with llfuse.lock_released:
- coll_reader = arvados.CollectionReader(
- self.collection_locator, self.api, self.api.keep,
- num_retries=self.num_retries)
+ if uuid_pattern.match(self.collection_locator):
+ coll_reader = arvados.collection.Collection(
+ self.collection_locator, self.api, self.api.keep,
+ num_retries=self.num_retries)
+ else:
+ coll_reader = arvados.collection.CollectionReader(
+ self.collection_locator, self.api, self.api.keep,
+ num_retries=self.num_retries)
new_collection_object = coll_reader.api_response() or {}
# If the Collection only exists in Keep, there will be no API
# response. Fill in the fields we need.
@@ -241,7 +284,6 @@ class CollectionDirectory(Directory):
new_collection_object["portable_data_hash"] = new_collection_object["uuid"]
if 'manifest_text' not in new_collection_object:
new_collection_object['manifest_text'] = coll_reader.manifest_text()
- coll_reader.normalize()
# end with llfuse.lock_released, re-acquire lock
if self.collection_object is None or self.collection_object["portable_data_hash"] != new_collection_object["portable_data_hash"]:
diff --git a/services/fuse/arvados_fuse/fusefile.py b/services/fuse/arvados_fuse/fusefile.py
index 9af341f..fcb7711 100644
--- a/services/fuse/arvados_fuse/fusefile.py
+++ b/services/fuse/arvados_fuse/fusefile.py
@@ -27,6 +27,8 @@ class File(FreshBase):
def clear(self, force=False):
return True
+ def writable(self):
+ return False
class FuseArvadosFile(File):
"""Wraps a ArvadosFile."""
@@ -44,6 +46,9 @@ class FuseArvadosFile(File):
def stale(self):
return False
+ def writable(self):
+ return self.arvfile.writable()
+
class StringFile(File):
"""Wrap a simple string as a file"""
diff --git a/services/fuse/tests/test_mount.py b/services/fuse/tests/test_mount.py
index ecc0888..9a0674b 100644
--- a/services/fuse/tests/test_mount.py
+++ b/services/fuse/tests/test_mount.py
@@ -12,6 +12,7 @@ import tempfile
import threading
import time
import unittest
+import logging
import run_test_server
@@ -32,6 +33,7 @@ class MountTestBase(unittest.TestCase):
threading.Thread(None, llfuse.main).start()
# wait until the driver is finished initializing
operations.initlock.wait()
+ return operations.inodes[llfuse.ROOT_INODE]
def tearDown(self):
# llfuse.close is buggy, so use fusermount instead.
@@ -98,7 +100,7 @@ class FuseMountTest(MountTestBase):
self.api.collections().create(body={"manifest_text":cw.manifest_text()}).execute()
def runTest(self):
- self.make_mount(fuse.CollectionDirectory, collection=self.testcollection)
+ self.make_mount(fuse.CollectionDirectory, collection_record=self.testcollection)
self.assertDirContents(None, ['thing1.txt', 'thing2.txt',
'edgecases', 'dir1', 'dir2'])
@@ -311,6 +313,69 @@ class FuseHomeTest(MountTestBase):
d3 = os.listdir(os.path.join(self.mounttmp, 'Unrestricted public data', 'GNU General Public License, version 3'))
self.assertEqual(["GNU_General_Public_License,_version_3.pdf"], d3)
+class FuseUpdateFileTest(MountTestBase):
+ def runTest(self):
+ collection = arvados.collection.Collection(api_client=self.api)
+ with collection.open("file1.txt", "w") as f:
+ f.write("blub")
+
+ m = self.make_mount(fuse.CollectionDirectory)
+ with llfuse.lock:
+ m.new_collection(None, collection)
+
+ d1 = os.listdir(self.mounttmp)
+ self.assertEqual(["file1.txt"], d1)
+ with open(os.path.join(self.mounttmp, "file1.txt")) as f:
+ self.assertEqual("blub", f.read())
+
+ with collection.open("file1.txt", "w") as f:
+ f.write("plnp")
+
+ d1 = os.listdir(self.mounttmp)
+ self.assertEqual(["file1.txt"], d1)
+ with open(os.path.join(self.mounttmp, "file1.txt")) as f:
+ self.assertEqual("plnp", f.read())
+
+class FuseAddFileToCollectionTest(MountTestBase):
+ def runTest(self):
+ collection = arvados.collection.Collection(api_client=self.api)
+ with collection.open("file1.txt", "w") as f:
+ f.write("blub")
+
+ m = self.make_mount(fuse.CollectionDirectory)
+ with llfuse.lock:
+ m.new_collection(None, collection)
+
+ d1 = os.listdir(self.mounttmp)
+ self.assertEqual(["file1.txt"], d1)
+
+ with collection.open("file2.txt", "w") as f:
+ f.write("plnp")
+
+ d1 = os.listdir(self.mounttmp)
+ self.assertEqual(["file1.txt", "file2.txt"], sorted(d1))
+
+class FuseRemoveFileFromCollectionTest(MountTestBase):
+ def runTest(self):
+ collection = arvados.collection.Collection(api_client=self.api)
+ with collection.open("file1.txt", "w") as f:
+ f.write("blub")
+
+ with collection.open("file2.txt", "w") as f:
+ f.write("plnp")
+
+ m = self.make_mount(fuse.CollectionDirectory)
+ with llfuse.lock:
+ m.new_collection(None, collection)
+
+ d1 = os.listdir(self.mounttmp)
+ self.assertEqual(["file1.txt", "file2.txt"], sorted(d1))
+
+ collection.remove("file2.txt")
+
+ d1 = os.listdir(self.mounttmp)
+ self.assertEqual(["file1.txt"], d1)
+
class FuseUnitTest(unittest.TestCase):
def test_sanitize_filename(self):
commit f91b1eaef727a11769edb8d02410b43386652b0d
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date: Wed Apr 15 15:39:00 2015 -0400
3198: Store filename/directory name in ArvadosFile/Subcollection object.
Simplify callbacks to support a single callback, and allow callback on
Subcollection. Notify MOD event on file flush.
diff --git a/sdk/python/arvados/arvfile.py b/sdk/python/arvados/arvfile.py
index ce342b5..53653c0 100644
--- a/sdk/python/arvados/arvfile.py
+++ b/sdk/python/arvados/arvfile.py
@@ -16,6 +16,8 @@ from ._normalize_stream import normalize_stream
from ._ranges import locators_and_ranges, replace_range, Range
from .retry import retry_method
+MOD = "mod"
+
def split(path):
"""split(path) -> streamname, filename
@@ -588,7 +590,7 @@ class ArvadosFile(object):
"""
- def __init__(self, parent, stream=[], segments=[]):
+ def __init__(self, parent, name, stream=[], segments=[]):
"""
ArvadosFile constructor.
@@ -605,6 +607,7 @@ class ArvadosFile(object):
for s in segments:
self._add_segment(stream, s.locator, s.range_size)
self._current_bblock = None
+ self.name = name
def writable(self):
return self.parent.writable()
@@ -614,9 +617,9 @@ class ArvadosFile(object):
return copy.copy(self._segments)
@synchronized
- def clone(self, new_parent):
+ def clone(self, new_parent, new_name):
"""Make a copy of this file."""
- cp = ArvadosFile(new_parent)
+ cp = ArvadosFile(new_parent, new_name)
cp.replace_contents(self)
return cp
@@ -799,6 +802,7 @@ class ArvadosFile(object):
if self._current_bblock:
self._repack_writes()
self.parent._my_block_manager().commit_bufferblock(self._current_bblock)
+ self.parent.notify(MOD, self.parent, self.name, (self, self))
@must_be_writable
@synchronized
@@ -853,8 +857,8 @@ class ArvadosFileReader(ArvadosFileReaderBase):
"""
- def __init__(self, arvadosfile, name, mode="r", num_retries=None):
- super(ArvadosFileReader, self).__init__(name, mode, num_retries=num_retries)
+ def __init__(self, arvadosfile, mode="r", num_retries=None):
+ super(ArvadosFileReader, self).__init__(arvadosfile.name, mode, num_retries=num_retries)
self.arvadosfile = arvadosfile
def size(self):
@@ -889,8 +893,8 @@ class ArvadosFileWriter(ArvadosFileReader):
"""
- def __init__(self, arvadosfile, name, mode, num_retries=None):
- super(ArvadosFileWriter, self).__init__(arvadosfile, name, mode, num_retries=num_retries)
+ def __init__(self, arvadosfile, mode, num_retries=None):
+ super(ArvadosFileWriter, self).__init__(arvadosfile, mode, num_retries=num_retries)
@_FileLikeObjectBase._before_close
@retry_method
diff --git a/sdk/python/arvados/collection.py b/sdk/python/arvados/collection.py
index f03deed..8091e8b 100644
--- a/sdk/python/arvados/collection.py
+++ b/sdk/python/arvados/collection.py
@@ -488,6 +488,7 @@ class RichCollectionBase(CollectionBase):
def __init__(self, parent=None):
self.parent = parent
self._modified = True
+ self._callback = None
self._items = {}
def _my_api(self):
@@ -537,9 +538,9 @@ class RichCollectionBase(CollectionBase):
if item is None:
# create new file
if create_type == COLLECTION:
- item = Subcollection(self)
+ item = Subcollection(self, pathcomponents[0])
else:
- item = ArvadosFile(self)
+ item = ArvadosFile(self, pathcomponents[0])
self._items[pathcomponents[0]] = item
self._modified = True
self.notify(ADD, self, pathcomponents[0], item)
@@ -547,7 +548,7 @@ class RichCollectionBase(CollectionBase):
else:
if item is None:
# create new collection
- item = Subcollection(self)
+ item = Subcollection(self, pathcomponents[0])
self._items[pathcomponents[0]] = item
self._modified = True
self.notify(ADD, self, pathcomponents[0], item)
@@ -633,9 +634,9 @@ class RichCollectionBase(CollectionBase):
name = os.path.basename(path)
if mode == "r":
- return ArvadosFileReader(arvfile, name, mode, num_retries=self.num_retries)
+ return ArvadosFileReader(arvfile, mode, num_retries=self.num_retries)
else:
- return ArvadosFileWriter(arvfile, name, mode, num_retries=self.num_retries)
+ return ArvadosFileWriter(arvfile, mode, num_retries=self.num_retries)
@synchronized
def modified(self):
@@ -733,7 +734,7 @@ class RichCollectionBase(CollectionBase):
def _clonefrom(self, source):
for k,v in source.items():
- self._items[k] = v.clone(self)
+ self._items[k] = v.clone(self, k)
def clone(self):
raise NotImplementedError()
@@ -763,7 +764,7 @@ class RichCollectionBase(CollectionBase):
modified_from = self[target_name]
# Actually make the copy.
- dup = source_obj.clone(self)
+ dup = source_obj.clone(self, target_name)
self._items[target_name] = dup
self._modified = True
@@ -881,15 +882,15 @@ class RichCollectionBase(CollectionBase):
holding_collection = Collection(api_client=self._my_api(), keep_client=self._my_keep())
for k in self:
if k not in end_collection:
- changes.append((DEL, os.path.join(prefix, k), self[k].clone(holding_collection)))
+ changes.append((DEL, os.path.join(prefix, k), self[k].clone(holding_collection, "")))
for k in end_collection:
if k in self:
if isinstance(end_collection[k], Subcollection) and isinstance(self[k], Subcollection):
changes.extend(self[k].diff(end_collection[k], os.path.join(prefix, k), holding_collection))
elif end_collection[k] != self[k]:
- changes.append((MOD, os.path.join(prefix, k), self[k].clone(holding_collection), end_collection[k].clone(holding_collection)))
+ changes.append((MOD, os.path.join(prefix, k), self[k].clone(holding_collection, ""), end_collection[k].clone(holding_collection, "")))
else:
- changes.append((ADD, os.path.join(prefix, k), end_collection[k].clone(holding_collection)))
+ changes.append((ADD, os.path.join(prefix, k), end_collection[k].clone(holding_collection, "")))
return changes
@must_be_writable
@@ -945,6 +946,24 @@ class RichCollectionBase(CollectionBase):
return hashlib.md5(stripped).hexdigest() + '+' + str(len(stripped))
@synchronized
+ def subscribe(self, callback):
+ if self._callback is None:
+ self._callback = callback
+ else:
+ raise errors.ArgumentError("A callback is already set on this collection.")
+
+ @synchronized
+ def unsubscribe(self):
+ if self._callback is not None:
+ self._callback = None
+
+ @synchronized
+ def notify(self, event, collection, name, item):
+ if self._callback:
+ self._callback(event, collection, name, item)
+ self.root_collection().notify(event, collection, name, item)
+
+ @synchronized
def __eq__(self, other):
if other is self:
return True
@@ -1046,7 +1065,6 @@ class Collection(RichCollectionBase):
self._api_response = None
self.lock = threading.RLock()
- self.callbacks = []
self.events = None
if manifest_locator_or_text:
@@ -1200,7 +1218,7 @@ class Collection(RichCollectionBase):
return self._manifest_locator
@synchronized
- def clone(self, new_parent=None, readonly=False, new_config=None):
+ def clone(self, new_parent=None, new_name=None, readonly=False, new_config=None):
if new_config is None:
new_config = self._config
if readonly:
@@ -1334,19 +1352,6 @@ class Collection(RichCollectionBase):
self.set_unmodified()
@synchronized
- def subscribe(self, callback):
- self.callbacks.append(callback)
-
- @synchronized
- def unsubscribe(self, callback):
- self.callbacks.remove(callback)
-
- @synchronized
- def notify(self, event, collection, name, item):
- for c in self.callbacks:
- c(event, collection, name, item)
-
- @synchronized
def _import_manifest(self, manifest_text):
"""Import a manifest into a `Collection`.
@@ -1408,6 +1413,11 @@ class Collection(RichCollectionBase):
self.set_unmodified()
+ @synchronized
+ def notify(self, event, collection, name, item):
+ if self._callback:
+ self._callback(event, collection, name, item)
+
class Subcollection(RichCollectionBase):
"""This is a subdirectory within a collection that doesn't have its own API
@@ -1417,10 +1427,11 @@ class Subcollection(RichCollectionBase):
"""
- def __init__(self, parent):
+ def __init__(self, parent, name):
super(Subcollection, self).__init__(parent)
self.lock = self.root_collection().lock
self._manifest_text = None
+ self.name = name
def root_collection(self):
return self.parent.root_collection()
@@ -1437,18 +1448,12 @@ class Subcollection(RichCollectionBase):
def _my_block_manager(self):
return self.root_collection()._my_block_manager()
- def notify(self, event, collection, name, item):
- return self.root_collection().notify(event, collection, name, item)
-
def stream_name(self):
- for k, v in self.parent.items():
- if v is self:
- return os.path.join(self.parent.stream_name(), k)
- return '.'
+ return os.path.join(self.parent.stream_name(), self.name)
@synchronized
- def clone(self, new_parent):
- c = Subcollection(new_parent)
+ def clone(self, new_parent, new_name):
+ c = Subcollection(new_parent, new_name)
c._clonefrom(self)
return c
diff --git a/sdk/python/tests/test_arvfile.py b/sdk/python/tests/test_arvfile.py
index 825465c..92c778e 100644
--- a/sdk/python/tests/test_arvfile.py
+++ b/sdk/python/tests/test_arvfile.py
@@ -415,8 +415,8 @@ class ArvadosFileReaderTestCase(StreamFileReaderTestCase):
blocks[loc] = d
stream.append(Range(loc, n, len(d)))
n += len(d)
- af = ArvadosFile(ArvadosFileReaderTestCase.MockParent(blocks, nocache), stream=stream, segments=[Range(1, 0, 3), Range(6, 3, 3), Range(11, 6, 3)])
- return ArvadosFileReader(af, "count.txt")
+ af = ArvadosFile(ArvadosFileReaderTestCase.MockParent(blocks, nocache), "count.txt", stream=stream, segments=[Range(1, 0, 3), Range(6, 3, 3), Range(11, 6, 3)])
+ return ArvadosFileReader(af)
def test_read_returns_first_block(self):
# read() calls will be aligned on block boundaries - see #3663.
@@ -483,10 +483,10 @@ class ArvadosFileReadTestCase(unittest.TestCase, StreamRetryTestMixin):
blockmanager = arvados.arvfile._BlockManager(self.keep_client())
blockmanager.prefetch_enabled = False
col = Collection(keep_client=self.keep_client(), block_manager=blockmanager)
- af = ArvadosFile(col,
+ af = ArvadosFile(col, "test",
stream=stream,
segments=segments)
- return ArvadosFileReader(af, "test", **kwargs)
+ return ArvadosFileReader(af, **kwargs)
def read_for_test(self, reader, byte_count, **kwargs):
return reader.read(byte_count, **kwargs)
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list