use of build.buildfarm.common.Write in project bazel-buildfarm by bazelbuild.
the class MemoryWriteOutputStreamTest method asyncWriteCompletionIsComplete.
@Test
public void asyncWriteCompletionIsComplete() throws IOException {
ContentAddressableStorage cas = mock(ContentAddressableStorage.class);
ByteString content = ByteString.copyFromUtf8("Hello, World!");
Digest digest = DIGEST_UTIL.compute(content);
SettableFuture<ByteString> writtenFuture = SettableFuture.create();
Write write = new MemoryWriteOutputStream(cas, digest, writtenFuture);
content.substring(0, 6).writeTo(write.getOutput(1, TimeUnit.SECONDS, () -> {
}));
writtenFuture.set(content);
assertThat(write.isComplete()).isTrue();
assertThat(write.getCommittedSize()).isEqualTo(digest.getSizeBytes());
verifyZeroInteractions(cas);
}
use of build.buildfarm.common.Write in project bazel-buildfarm by bazelbuild.
the class StubInstanceTest method completedWriteBeforeCloseThrowsOnNextInteraction.
@Test
public void completedWriteBeforeCloseThrowsOnNextInteraction() throws IOException, InterruptedException {
String resourceName = "early-completed-output-stream-test";
serviceRegistry.addService(new ByteStreamImplBase() {
boolean completed = false;
int writtenBytes = 0;
@Override
public StreamObserver<WriteRequest> write(StreamObserver<WriteResponse> responseObserver) {
return new StreamObserver<WriteRequest>() {
@Override
public void onNext(WriteRequest request) {
if (!completed) {
writtenBytes = request.getData().size();
responseObserver.onNext(WriteResponse.newBuilder().setCommittedSize(writtenBytes).build());
responseObserver.onCompleted();
completed = true;
}
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onCompleted() {
}
};
}
@Override
public void queryWriteStatus(QueryWriteStatusRequest request, StreamObserver<QueryWriteStatusResponse> responseObserver) {
if (request.getResourceName().equals(resourceName)) {
responseObserver.onNext(QueryWriteStatusResponse.newBuilder().setCommittedSize(writtenBytes).setComplete(completed).build());
responseObserver.onCompleted();
} else {
responseObserver.onError(Status.NOT_FOUND.asException());
}
}
});
Instance instance = newStubInstance("early-completed-outputStream-test");
ByteString content = ByteString.copyFromUtf8("test-content");
boolean writeThrewException = false;
Write operationStreamWrite = instance.getOperationStreamWrite(resourceName);
try (OutputStream out = operationStreamWrite.getOutput(1, SECONDS, () -> {
})) {
content.writeTo(out);
try {
content.writeTo(out);
} catch (Exception e) {
writeThrewException = true;
}
}
assertThat(writeThrewException).isTrue();
instance.stop();
}
use of build.buildfarm.common.Write in project bazel-buildfarm by bazelbuild.
the class ByteStreamServiceTest method uploadsCanProgressAfterCancellation.
@Test
public void uploadsCanProgressAfterCancellation() throws Exception {
ByteString content = ByteString.copyFromUtf8("Hello, World!");
Digest digest = DIGEST_UTIL.compute(content);
UUID uuid = UUID.randomUUID();
SettableFuture<Long> writtenFuture = SettableFuture.create();
ByteString.Output output = ByteString.newOutput((int) digest.getSizeBytes());
FeedbackOutputStream out = new FeedbackOutputStream() {
@Override
public void close() {
if (output.size() == digest.getSizeBytes()) {
writtenFuture.set(digest.getSizeBytes());
}
}
@Override
public void write(byte[] b, int off, int len) {
output.write(b, off, len);
}
@Override
public void write(int b) {
output.write(b);
}
@Override
public boolean isReady() {
return true;
}
};
Write write = mock(Write.class);
when(write.getOutput(any(Long.class), any(TimeUnit.class), any(Runnable.class))).thenReturn(out);
doAnswer(invocation -> (long) output.size()).when(write).getCommittedSize();
when(write.getFuture()).thenReturn(writtenFuture);
when(instance.getBlobWrite(digest, uuid, RequestMetadata.getDefaultInstance())).thenReturn(write);
HashCode hash = HashCode.fromString(digest.getHash());
String resourceName = ByteStreamUploader.uploadResourceName(/* instanceName=*/
null, uuid, hash, digest.getSizeBytes());
Channel channel = InProcessChannelBuilder.forName(fakeServerName).directExecutor().build();
ByteStreamStub service = ByteStreamGrpc.newStub(channel);
FutureWriteResponseObserver futureResponder = new FutureWriteResponseObserver();
StreamObserver<WriteRequest> requestObserver = service.write(futureResponder);
ByteString shortContent = content.substring(0, 6);
requestObserver.onNext(WriteRequest.newBuilder().setWriteOffset(0).setResourceName(resourceName).setData(shortContent).build());
requestObserver.onError(Status.CANCELLED.asException());
// should be done
assertThat(futureResponder.isDone()).isTrue();
futureResponder = new FutureWriteResponseObserver();
requestObserver = service.write(futureResponder);
requestObserver.onNext(WriteRequest.newBuilder().setWriteOffset(6).setResourceName(resourceName).setData(content.substring(6)).setFinishWrite(true).build());
assertThat(futureResponder.get()).isEqualTo(WriteResponse.newBuilder().setCommittedSize(content.size()).build());
requestObserver.onCompleted();
verify(write, atLeastOnce()).getCommittedSize();
verify(write, atLeastOnce()).getOutput(any(Long.class), any(TimeUnit.class), any(Runnable.class));
verify(write, times(2)).getFuture();
}
use of build.buildfarm.common.Write in project bazel-buildfarm by bazelbuild.
the class ByteStreamService method queryWriteStatus.
@Override
public void queryWriteStatus(QueryWriteStatusRequest request, StreamObserver<QueryWriteStatusResponse> responseObserver) {
String resourceName = request.getResourceName();
try {
logger.log(Level.FINE, format("queryWriteStatus(%s)", resourceName));
Write write = getWrite(resourceName);
responseObserver.onNext(QueryWriteStatusResponse.newBuilder().setCommittedSize(write.getCommittedSize()).setComplete(write.isComplete()).build());
responseObserver.onCompleted();
logger.log(Level.FINE, format("queryWriteStatus(%s) => committed_size = %d, complete = %s", resourceName, write.getCommittedSize(), write.isComplete()));
} catch (IllegalArgumentException | InvalidResourceNameException e) {
logger.log(Level.SEVERE, format("queryWriteStatus(%s)", resourceName), e);
responseObserver.onError(INVALID_ARGUMENT.withDescription(e.getMessage()).asException());
} catch (EntryLimitException e) {
logger.log(Level.WARNING, format("queryWriteStatus(%s): %s", resourceName, e.getMessage()));
responseObserver.onNext(QueryWriteStatusResponse.getDefaultInstance());
responseObserver.onCompleted();
} catch (RuntimeException e) {
logger.log(Level.SEVERE, format("queryWriteStatus(%s)", resourceName), e);
responseObserver.onError(Status.fromThrowable(e).asException());
}
}
use of build.buildfarm.common.Write in project bazel-buildfarm by bazelbuild.
the class Utils method putBlobFuture.
// TODO make this *actually* async with onReady for FeedbackOutputStream
public static ListenableFuture<Digest> putBlobFuture(Instance instance, Digest digest, ByteString data, long writeDeadlineAfter, TimeUnit writeDeadlineAfterUnits, RequestMetadata requestMetadata) {
if (digest.getSizeBytes() != data.size()) {
return immediateFailedFuture(invalidDigestSize(digest.getSizeBytes(), data.size()).asRuntimeException());
}
SettableFuture<Digest> future = SettableFuture.create();
try {
Write write = instance.getBlobWrite(digest, UUID.randomUUID(), requestMetadata);
// indicate that we know this write is novel
write.reset();
Futures.addCallback(write.getFuture(), new FutureCallback<Long>() {
@Override
public void onSuccess(Long committedSize) {
future.set(digest);
}
@SuppressWarnings("NullableProblems")
@Override
public void onFailure(Throwable t) {
future.setException(t);
}
}, directExecutor());
try (OutputStream out = write.getOutput(writeDeadlineAfter, writeDeadlineAfterUnits, () -> {
})) {
data.writeTo(out);
}
} catch (Exception e) {
future.setException(e);
}
return future;
}
Aggregations