Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: client/tests/isolate_storage_test.py

Issue 2953253003: Replace custom blob gRPC API with ByteStream (Closed)
Patch Set: Import ndb directly to test code Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/proto/isolate_bot_pb2_grpc.py ('k') | client/third_party/cachetools/README.swarming » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/tests/isolate_storage_test.py
diff --git a/client/tests/isolate_storage_test.py b/client/tests/isolate_storage_test.py
index 33ef8db3b45100a911855742ca47d4d2dfbfd18f..e26e4ff750f3fcad43a2e10906853c7fe3a97fcf 100755
--- a/client/tests/isolate_storage_test.py
+++ b/client/tests/isolate_storage_test.py
@@ -4,9 +4,11 @@
# that can be found in the LICENSE file.
import binascii
+import os
+import re
+import sys
import time
import unittest
-import sys
# Somehow this lets us find isolate_storage
import net_utils
@@ -15,8 +17,7 @@ from depot_tools import auto_stub
import isolate_storage
import test_utils
-
-class FileServiceStubMock(object):
+class ByteStreamStubMock(object):
"""Replacement for real gRPC stub
We can't mock *within* the real stub to replace individual functions, plus
@@ -28,22 +29,19 @@ class FileServiceStubMock(object):
self._push_requests = []
self._contains_requests = []
- def FetchBlobs(self, request, timeout=None):
+ def Read(self, request, timeout=None):
+ del request, timeout
raise NotImplementedError()
- def PushBlobs(self, requests):
+ def Write(self, requests, timeout=None):
+ del timeout
+ nb = 0
for r in requests:
+ nb += len(r.data)
self._push_requests.append(r.__deepcopy__())
- response = isolate_storage.isolate_bot_pb2.PushBlobsReply()
- response.status.succeeded = True
- return response
-
- def Contains(self, request, timeout=None):
- del timeout
- response = isolate_storage.isolate_bot_pb2.ContainsReply()
- self._contains_requests.append(request.__deepcopy__())
- response.status.succeeded = True
- return response
+ resp = isolate_storage.bytestream_pb2.WriteResponse()
+ resp.committed_size = nb
+ return resp
def popContainsRequests(self):
cr = self._contains_requests
@@ -55,30 +53,30 @@ class FileServiceStubMock(object):
self._push_requests = []
return pr
+def raiseError(code):
+ raise isolate_storage.grpc.RpcError(
+ 'cannot turn this into a real code yet: %s' % code)
class IsolateStorageTest(auto_stub.TestCase):
def get_server(self):
- return isolate_storage.IsolateServerGrpc('grpc-proxy.luci.com',
+ os.environ['ISOLATED_GRPC_PROXY'] = 'https://luci.com/client/bob'
+ return isolate_storage.IsolateServerGrpc('https://luci.appspot.com',
'default-gzip')
def testFetchHappySimple(self):
"""Fetch: if we get a few chunks with the right offset, everything works"""
- def FetchBlobs(self, request, timeout=None):
+ def Read(self, request, timeout=None):
del timeout
self.request = request
- response = isolate_storage.isolate_bot_pb2.FetchBlobsReply()
- response.status.succeeded = True
+ response = isolate_storage.bytestream_pb2.ReadResponse()
for i in range(0, 3):
- response.data.data = str(i)
- response.data.offset = i
+ response.data = str(i)
yield response
- self.mock(FileServiceStubMock, 'FetchBlobs', FetchBlobs)
+ self.mock(ByteStreamStubMock, 'Read', Read)
s = self.get_server()
replies = s.fetch('abc123')
response = replies.next()
- self.assertEqual(binascii.unhexlify('abc123'),
- s._stub.request.digest[0].digest)
self.assertEqual('0', response)
response = replies.next()
self.assertEqual('1', response)
@@ -87,48 +85,26 @@ class IsolateStorageTest(auto_stub.TestCase):
def testFetchHappyZeroLengthBlob(self):
"""Fetch: if we get a zero-length blob, everything works"""
- def FetchBlobs(self, request, timeout=None):
+ def Read(self, request, timeout=None):
del timeout
self.request = request
- response = isolate_storage.isolate_bot_pb2.FetchBlobsReply()
- response.status.succeeded = True
- response.data.data = ''
+ response = isolate_storage.bytestream_pb2.ReadResponse()
+ response.data = ''
yield response
- self.mock(FileServiceStubMock, 'FetchBlobs', FetchBlobs)
+ self.mock(ByteStreamStubMock, 'Read', Read)
s = self.get_server()
replies = s.fetch('abc123')
- response = replies.next()
- self.assertEqual(binascii.unhexlify('abc123'),
- s._stub.request.digest[0].digest)
- self.assertEqual(0, len(response))
-
- def testFetchThrowsOnWrongOffset(self):
- """Fetch: if we get a chunk with the wrong offset, we throw an exception"""
- def FetchBlobs(self, request, timeout=None):
- del timeout
- self.request = request
- response = isolate_storage.isolate_bot_pb2.FetchBlobsReply()
- response.status.succeeded = True
- response.data.data = str(42)
- response.data.offset = 1
- yield response
- self.mock(FileServiceStubMock, 'FetchBlobs', FetchBlobs)
-
- s = self.get_server()
- replies = s.fetch('abc123')
- with self.assertRaises(IOError):
- _response = replies.next()
+ reply = replies.next()
+ self.assertEqual(0, len(reply))
def testFetchThrowsOnFailure(self):
"""Fetch: if something goes wrong in Isolate, we throw an exception"""
- def FetchBlobs(self, request, timeout=None):
+ def Read(self, request, timeout=None):
del timeout
self.request = request
- response = isolate_storage.isolate_bot_pb2.FetchBlobsReply()
- response.status.succeeded = False
- yield response
- self.mock(FileServiceStubMock, 'FetchBlobs', FetchBlobs)
+ raiseError(isolate_storage.grpc.StatusCode.INTERNAL)
+ self.mock(ByteStreamStubMock, 'Read', Read)
s = self.get_server()
replies = s.fetch('abc123')
@@ -137,10 +113,10 @@ class IsolateStorageTest(auto_stub.TestCase):
def testFetchThrowsCorrectExceptionOnGrpcFailure(self):
"""Fetch: if something goes wrong in gRPC, we throw an IOError"""
- def FetchBlobs(_self, _request, timeout=None):
+ def Read(_self, _request, timeout=None):
del timeout
raise isolate_storage.grpc.RpcError('proxy died during initial fetch :(')
- self.mock(FileServiceStubMock, 'FetchBlobs', FetchBlobs)
+ self.mock(ByteStreamStubMock, 'Read', Read)
s = self.get_server()
replies = s.fetch('abc123')
@@ -149,19 +125,17 @@ class IsolateStorageTest(auto_stub.TestCase):
def testFetchThrowsCorrectExceptionOnStreamingGrpcFailure(self):
"""Fetch: if something goes wrong in gRPC, we throw an IOError"""
- def FetchBlobs(self, request, timeout=None):
+ def Read(self, request, timeout=None):
del timeout
self.request = request
- response = isolate_storage.isolate_bot_pb2.FetchBlobsReply()
- response.status.succeeded = True
+ response = isolate_storage.bytestream_pb2.ReadResponse()
for i in range(0, 3):
if i is 2:
raise isolate_storage.grpc.RpcError(
'proxy died during fetch stream :(')
- response.data.data = str(i)
- response.data.offset = i
+ response.data = str(i)
yield response
- self.mock(FileServiceStubMock, 'FetchBlobs', FetchBlobs)
+ self.mock(ByteStreamStubMock, 'Read', Read)
s = self.get_server()
with self.assertRaises(IOError):
@@ -175,10 +149,12 @@ class IsolateStorageTest(auto_stub.TestCase):
s.push(i, isolate_storage._IsolateServerGrpcPushState(), '1234')
requests = s._stub.popPushRequests()
self.assertEqual(1, len(requests))
- self.assertEqual(binascii.unhexlify('abc123'),
- requests[0].data.digest.digest)
- self.assertEqual(4, requests[0].data.digest.size_bytes)
- self.assertEqual('1234', requests[0].data.data)
+ m = re.search('client/bob/uploads/.*/blobs/abc123/4',
+ requests[0].resource_name)
+ self.assertTrue(m)
+ self.assertEqual('1234', requests[0].data)
+ self.assertEqual(0, requests[0].write_offset)
+ self.assertTrue(requests[0].finish_write)
def testPushHappySingleBig(self):
"""Push: send one chunk of big data by splitting it into two"""
@@ -188,12 +164,15 @@ class IsolateStorageTest(auto_stub.TestCase):
s.push(i, isolate_storage._IsolateServerGrpcPushState(), '1234')
requests = s._stub.popPushRequests()
self.assertEqual(2, len(requests))
- self.assertEqual(binascii.unhexlify('abc123'),
- requests[0].data.digest.digest)
- self.assertEqual(4, requests[0].data.digest.size_bytes)
- self.assertEqual('123', requests[0].data.data)
- self.assertFalse(requests[1].data.HasField('digest'))
- self.assertEqual('4', requests[1].data.data)
+ m = re.search('client/bob/uploads/.*/blobs/abc123/4',
+ requests[0].resource_name)
+ self.assertTrue(m)
+ self.assertEqual('123', requests[0].data)
+ self.assertEqual(0, requests[0].write_offset)
+ self.assertFalse(requests[0].finish_write)
+ self.assertEqual('4', requests[1].data)
+ self.assertEqual(3, requests[1].write_offset)
+ self.assertTrue(requests[1].finish_write)
def testPushHappyMultiSmall(self):
"""Push: sends multiple small chunks"""
@@ -202,12 +181,15 @@ class IsolateStorageTest(auto_stub.TestCase):
s.push(i, isolate_storage._IsolateServerGrpcPushState(), ['12', '34'])
requests = s._stub.popPushRequests()
self.assertEqual(2, len(requests))
- self.assertEqual(binascii.unhexlify('abc123'),
- requests[0].data.digest.digest)
- self.assertEqual(4, requests[0].data.digest.size_bytes)
- self.assertEqual('12', requests[0].data.data)
- self.assertFalse(requests[1].data.HasField('digest'))
- self.assertEqual('34', requests[1].data.data)
+ m = re.search('client/bob/uploads/.*/blobs/abc123/4',
+ requests[0].resource_name)
+ self.assertTrue(m)
+ self.assertEqual('12', requests[0].data)
+ self.assertEqual(0, requests[0].write_offset)
+ self.assertFalse(requests[0].finish_write)
+ self.assertEqual('34', requests[1].data)
+ self.assertEqual(2, requests[1].write_offset)
+ self.assertTrue(requests[1].finish_write)
def testPushHappyMultiBig(self):
"""Push: sends multiple chunks, each of which have to be split"""
@@ -217,14 +199,21 @@ class IsolateStorageTest(auto_stub.TestCase):
s.push(i, isolate_storage._IsolateServerGrpcPushState(), ['123', '456'])
requests = s._stub.popPushRequests()
self.assertEqual(4, len(requests))
- self.assertEqual(binascii.unhexlify('abc123'),
- requests[0].data.digest.digest)
- self.assertEqual(6, requests[0].data.digest.size_bytes)
- self.assertEqual('12', requests[0].data.data)
- self.assertFalse(requests[1].data.HasField('digest'))
- self.assertEqual('3', requests[1].data.data)
- self.assertEqual('45', requests[2].data.data)
- self.assertEqual('6', requests[3].data.data)
+ m = re.search('client/bob/uploads/.*/blobs/abc123/6',
+ requests[0].resource_name)
+ self.assertTrue(m)
+ self.assertEqual(0, requests[0].write_offset)
+ self.assertEqual('12', requests[0].data)
+ self.assertFalse(requests[0].finish_write)
+ self.assertEqual(2, requests[1].write_offset)
+ self.assertEqual('3', requests[1].data)
+ self.assertFalse(requests[1].finish_write)
+ self.assertEqual(3, requests[2].write_offset)
+ self.assertEqual('45', requests[2].data)
+ self.assertFalse(requests[2].finish_write)
+ self.assertEqual(5, requests[3].write_offset)
+ self.assertEqual('6', requests[3].data)
+ self.assertTrue(requests[3].finish_write)
def testPushHappyZeroLengthBlob(self):
"""Push: send a zero-length blob"""
@@ -233,19 +222,19 @@ class IsolateStorageTest(auto_stub.TestCase):
s.push(i, isolate_storage._IsolateServerGrpcPushState(), '')
requests = s._stub.popPushRequests()
self.assertEqual(1, len(requests))
- self.assertEqual(binascii.unhexlify('abc123'),
- requests[0].data.digest.digest)
- self.assertEqual(0, requests[0].data.digest.size_bytes)
- self.assertEqual('', requests[0].data.data)
+ m = re.search('client/bob/uploads/.*/blobs/abc123/0',
+ requests[0].resource_name)
+ self.assertTrue(m)
+ self.assertEqual(0, requests[0].write_offset)
+ self.assertEqual('', requests[0].data)
+ self.assertTrue(requests[0].finish_write)
def testPushThrowsOnFailure(self):
"""Push: if something goes wrong in Isolate, we throw an exception"""
- def PushBlobs(self, request, timeout=None):
+ def Write(self, request, timeout=None):
del request, timeout, self
- response = isolate_storage.isolate_bot_pb2.PushBlobsReply()
- response.status.succeeded = False
- return response
- self.mock(FileServiceStubMock, 'PushBlobs', PushBlobs)
+ raiseError(isolate_storage.grpc.StatusCode.INTERNAL_ERROR)
+ self.mock(ByteStreamStubMock, 'Write', Write)
s = self.get_server()
i = isolate_storage.Item(digest='abc123', size=0)
@@ -254,74 +243,16 @@ class IsolateStorageTest(auto_stub.TestCase):
def testPushThrowsCorrectExceptionOnGrpcFailure(self):
"""Push: if something goes wrong in Isolate, we throw an exception"""
- def PushBlobs(_self, _request, timeout=None):
+ def Write(_self, _request, timeout=None):
del timeout
raise isolate_storage.grpc.RpcError('proxy died during push :(')
- self.mock(FileServiceStubMock, 'PushBlobs', PushBlobs)
+ self.mock(ByteStreamStubMock, 'Write', Write)
s = self.get_server()
i = isolate_storage.Item(digest='abc123', size=0)
with self.assertRaises(IOError):
s.push(i, isolate_storage._IsolateServerGrpcPushState(), '1234')
- def testContainsHappySimple(self):
- """Contains: basic sanity check"""
- items = []
- for i in range(0, 3):
- digest = ''.join(['a', str(i)])
- i = isolate_storage.Item(digest=digest, size=1)
- items.append(i)
- s = self.get_server()
- response = s.contains(items)
- self.assertEqual(0, len(response))
- requests = s._stub.popContainsRequests()
- self.assertEqual(3, len(requests[0].digest))
- self.assertEqual('\xa0', requests[0].digest[0].digest)
- self.assertEqual('\xa1', requests[0].digest[1].digest)
- self.assertEqual('\xa2', requests[0].digest[2].digest)
-
- def testContainsMissingSimple(self):
- """Contains: the digests are missing"""
- def Contains(self, request, timeout=None):
- del timeout, self
- response = isolate_storage.isolate_bot_pb2.ContainsReply()
- response.status.succeeded = False
- response.status.error = (
- isolate_storage.isolate_bot_pb2.BlobStatus.MISSING_DIGEST)
- for d in request.digest:
- msg = response.status.missing_digest.add()
- msg.CopyFrom(d)
- return response
- self.mock(FileServiceStubMock, 'Contains', Contains)
-
- items = []
- for i in range(0, 3):
- digest = ''.join(['a', str(i)])
- i = isolate_storage.Item(digest=digest, size=1)
- items.append(i)
- s = self.get_server()
- response = s.contains(items)
- self.assertEqual(3, len(response))
- self.assertTrue(items[0] in response)
- self.assertTrue(items[1] in response)
- self.assertTrue(items[2] in response)
-
- def testContainsThrowsCorrectExceptionOnGrpcFailure(self):
- """Contains: the digests are missing"""
- def Contains(_self, _request, timeout=None):
- del timeout
- raise isolate_storage.grpc.RpcError('proxy died during contains :(')
- self.mock(FileServiceStubMock, 'Contains', Contains)
-
- items = []
- for i in range(0, 3):
- digest = ''.join(['a', str(i)])
- i = isolate_storage.Item(digest=digest, size=1)
- items.append(i)
- s = self.get_server()
- with self.assertRaises(IOError):
- _response = s.contains(items)
-
if __name__ == '__main__':
if not isolate_storage.grpc:
@@ -329,5 +260,5 @@ if __name__ == '__main__':
# show up as a warning and fail in presubmit.
print('gRPC could not be loaded; skipping tests')
sys.exit(0)
- isolate_storage.isolate_bot_pb2.FileServiceStub = FileServiceStubMock
+ isolate_storage.bytestream_pb2.ByteStreamStub = ByteStreamStubMock
test_utils.main()
« no previous file with comments | « client/proto/isolate_bot_pb2_grpc.py ('k') | client/third_party/cachetools/README.swarming » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698