use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class StreamTransactionMetadataTasksTest method txnCreationTest.
@Test(timeout = 10000)
public void txnCreationTest() {
// Create mock writer objects.
EventStreamWriterMock<CommitEvent> commitWriter = new EventStreamWriterMock<>();
EventStreamWriterMock<AbortEvent> abortWriter = new EventStreamWriterMock<>();
StreamMetadataStore streamStoreMock = spy(StreamStoreFactory.createZKStore(zkClient, executor));
// Create transaction tasks.
txnTasks = new StreamTransactionMetadataTasks(streamStoreMock, SegmentHelperMock.getSegmentHelperMock(), executor, "host", new GrpcAuthHelper(this.authEnabled, "secret", 600));
txnTasks.initializeStreamWriters(commitWriter, abortWriter);
final ScalingPolicy policy1 = ScalingPolicy.fixed(2);
final StreamConfiguration configuration1 = StreamConfiguration.builder().scalingPolicy(policy1).build();
// Create stream and scope
streamStoreMock.createScope(SCOPE, null, executor).join();
streamStoreMock.createStream(SCOPE, STREAM, configuration1, System.currentTimeMillis(), null, executor).join();
streamStoreMock.setState(SCOPE, STREAM, State.ACTIVE, null, executor).join();
// mock streamMetadataStore.generateTxnId should throw excecption first time.
// Note: it should be retried.
// now the id should have been generated
doAnswer(new Answer<CompletableFuture<UUID>>() {
AtomicInteger count = new AtomicInteger(0);
@Override
public CompletableFuture<UUID> answer(InvocationOnMock invocation) throws Throwable {
// first time throw exception.
if (count.getAndIncrement() == 0) {
return Futures.failedFuture(StoreException.create(StoreException.Type.WRITE_CONFLICT, "write conflict on counter update"));
}
// subsequent times call origin method
@SuppressWarnings("unchecked") CompletableFuture<UUID> future = (CompletableFuture<UUID>) invocation.callRealMethod();
return future;
}
}).when(streamStoreMock).generateTransactionId(eq(SCOPE), eq(STREAM), any(), any());
doAnswer(new Answer<CompletableFuture<VersionedTransactionData>>() {
AtomicInteger count = new AtomicInteger(0);
@Override
public CompletableFuture<VersionedTransactionData> answer(InvocationOnMock invocation) throws Throwable {
// first time throw exception.
if (count.getAndIncrement() == 0) {
return Futures.failedFuture(StoreException.create(StoreException.Type.DATA_NOT_FOUND, "Epoch not found"));
}
// subsequent times call origin method
@SuppressWarnings("unchecked") CompletableFuture<VersionedTransactionData> future = (CompletableFuture<VersionedTransactionData>) invocation.callRealMethod();
return future;
}
}).when(streamStoreMock).createTransaction(any(), any(), any(), anyLong(), anyLong(), any(), any());
Pair<VersionedTransactionData, List<StreamSegmentRecord>> txn = txnTasks.createTxn(SCOPE, STREAM, 10000L, 0L, 1024 * 1024L).join();
// verify that generate transaction id is called 3 times
verify(streamStoreMock, times(3)).generateTransactionId(any(), any(), any(), any());
// verify that create transaction is called 2 times
verify(streamStoreMock, times(2)).createTransaction(any(), any(), any(), anyLong(), anyLong(), any(), any());
// verify that the txn id that is generated is of type ""
UUID txnId = txn.getKey().getId();
assertEquals(0, (int) (txnId.getMostSignificantBits() >> 32));
assertEquals(2, txnId.getLeastSignificantBits());
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class TimeoutServiceTest method testPingSuccess.
@Test(timeout = 10000)
public void testPingSuccess() throws InterruptedException {
UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join();
VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 10 * LEASE, null, executor).join();
timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE, txData.getMaxExecutionExpiryTime());
Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (0.75 * LEASE), TimeUnit.MILLISECONDS);
Assert.assertNull(result);
TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.OPEN, status);
PingTxnStatus pingStatus = timeoutService.pingTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE);
Assert.assertEquals(PingTxnStatus.Status.OK, pingStatus.getStatus());
result = timeoutService.getTaskCompletionQueue().poll((long) (0.5 * LEASE), TimeUnit.MILLISECONDS);
Assert.assertNull(result);
status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.OPEN, status);
result = timeoutService.getTaskCompletionQueue().poll((long) (0.8 * LEASE), TimeUnit.MILLISECONDS);
Assert.assertNotNull(result);
status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.ABORTING, status);
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class TimeoutServiceTest method testPingFailureMaxExecutionTimeExceeded.
@Test(timeout = 10000)
public void testPingFailureMaxExecutionTimeExceeded() throws InterruptedException {
UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join();
VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 2 * LEASE, null, executor).join();
timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE, txData.getMaxExecutionExpiryTime());
TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.OPEN, status);
// 3 * LEASE > 2 * LEASE
PingTxnStatus pingStatus = timeoutService.pingTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), 3 * LEASE);
Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus());
status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.OPEN, status);
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class TimeoutServiceTest method testTimeout.
@Test(timeout = 10000)
public void testTimeout() throws InterruptedException {
UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join();
VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 10 * LEASE, null, executor).join();
long begin = System.currentTimeMillis();
timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE, txData.getMaxExecutionExpiryTime());
Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (1.3 * LEASE), TimeUnit.MILLISECONDS);
long end = System.currentTimeMillis();
Assert.assertNotNull(result);
log.info("Delay until timeout = " + (end - begin));
Assert.assertTrue((end - begin) >= LEASE);
TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join();
Assert.assertEquals(TxnStatus.ABORTING, status);
}
use of io.pravega.controller.store.stream.VersionedTransactionData in project pravega by pravega.
the class TimeoutServiceTest method testPingOwnershipTransfer.
@Test(timeout = 30000)
public void testPingOwnershipTransfer() throws Exception {
StreamMetadataStore streamStore2 = getStore();
HostControllerStore hostStore = HostStoreFactory.createInMemoryStore(HostMonitorConfigImpl.dummyConfig());
BucketStore bucketStore = StreamStoreFactory.createInMemoryBucketStore();
TaskMetadataStore taskMetadataStore = TaskStoreFactory.createStore(PRAVEGA_ZK_CURATOR_RESOURCE.storeClient, executor);
SegmentHelper helperMock = SegmentHelperMock.getSegmentHelperMock();
@Cleanup StreamMetadataTasks streamMetadataTasks2 = new StreamMetadataTasks(streamStore2, bucketStore, taskMetadataStore, helperMock, executor, "2", GrpcAuthHelper.getDisabledAuthHelper());
@Cleanup StreamTransactionMetadataTasks streamTransactionMetadataTasks2 = new StreamTransactionMetadataTasks(streamStore2, helperMock, executor, "2", TimeoutServiceConfig.defaultConfig(), new LinkedBlockingQueue<>(5), GrpcAuthHelper.getDisabledAuthHelper());
streamTransactionMetadataTasks2.initializeStreamWriters(new EventStreamWriterMock<>(), new EventStreamWriterMock<>());
// Create TimeoutService
TimerWheelTimeoutService timeoutService2 = (TimerWheelTimeoutService) streamTransactionMetadataTasks2.getTimeoutService();
ControllerService controllerService2 = new ControllerService(kvtStore, kvtMetadataTasks, streamStore2, bucketStore, streamMetadataTasks2, streamTransactionMetadataTasks2, helperMock, executor, null, requestTracker);
UUID txnId = controllerService.createTransaction(SCOPE, STREAM, LEASE, 9L).thenApply(x -> x.getKey()).join();
VersionedTransactionData txnData = streamStore.getTransactionData(SCOPE, STREAM, txnId, null, executor).join();
Assert.assertEquals(txnData.getVersion(), getVersion(0));
Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (0.75 * LEASE), TimeUnit.MILLISECONDS);
Assert.assertNull(result);
TxnState txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId, 9L).join();
Assert.assertEquals(TxnState.State.OPEN, txnState.getState());
// increasing lease -> total effective lease = 3 * LEASE
PingTxnStatus pingStatus = controllerService2.pingTransaction(SCOPE, STREAM, txnId, 2 * LEASE, 9L).join();
Assert.assertEquals(PingTxnStatus.Status.OK, pingStatus.getStatus());
txnData = streamStore.getTransactionData(SCOPE, STREAM, txnId, null, executor).join();
Assert.assertEquals(txnData.getVersion(), getVersion(1));
// timeoutService1 should believe that LEASE has expired and should get non empty completion tasks
result = timeoutService.getTaskCompletionQueue().poll((long) (1.3 * LEASE + RETRY_DELAY), TimeUnit.MILLISECONDS);
Assert.assertNotNull(result);
// the txn may have been attempted to be aborted by timeoutService1 but would have failed. So txn to remain open
txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId, 9L).join();
Assert.assertEquals(TxnState.State.OPEN, txnState.getState());
// timeoutService2 should continue to wait on lease expiry and should get empty completion tasks
result = timeoutService2.getTaskCompletionQueue().poll(0L, TimeUnit.MILLISECONDS);
Assert.assertNull(result);
result = timeoutService2.getTaskCompletionQueue().poll(2 * LEASE + RETRY_DELAY, TimeUnit.MILLISECONDS);
Assert.assertNotNull(result);
// now txn should have moved to aborting because timeoutservice2 has initiated abort
txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId, 9L).join();
Assert.assertEquals(TxnState.State.ABORTING, txnState.getState());
}
Aggregations