verifyNoMoreInteractions(mockedDataTreeListener);
}
+ @Test
+ // TODO extract common logic from testSingleSubshardWrite and
+ // testSingleShardWrite tests
+ public void testSingleSubshardWrite() throws Exception {
+ final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
+ doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
+
+ InMemoryDOMDataTreeShard testShard = InMemoryDOMDataTreeShard.create(TEST_ID, executor, 1);
+ testShard.onGlobalContextUpdated(schemaContext);
+
+ final DOMDataTreeProducer regProducer = dataTreeService.createProducer(Collections.singleton(TEST_ID));
+ dataTreeService.registerDataTreeShard(TEST_ID, testShard, regProducer);
+ regProducer.close();
+
+ dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(TEST_ID),
+ true, Collections.emptyList());
+
+ final DOMDataTreeProducer producer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
+ DOMDataTreeCursorAwareTransaction tx = producer.createTransaction(false);
+ DOMDataTreeWriteCursor cursor = tx.createCursor(ROOT_ID);
+ assertNotNull(cursor);
+
+ cursor.write(TEST_ID.getRootIdentifier().getLastPathArgument(), crossShardContainer);
+
+ cursor.close();
+ tx.submit().checkedGet();
+
+ tx = producer.createTransaction(false);
+ cursor = tx.createCursor(TEST_ID);
+ assertNotNull(cursor);
+
+ cursor.delete(TestModel.INNER_CONTAINER_PATH.getLastPathArgument());
+ cursor.close();
+ tx.submit().checkedGet();
+
+ verify(mockedDataTreeListener, timeout(5000).times(3)).onDataTreeChanged(captorForChanges.capture(),
+ captorForSubtrees.capture());
+
+ final List<Collection<DataTreeCandidate>> capturedValue = captorForChanges.getAllValues();
+ final ContainerNode capturedChange =
+ (ContainerNode) capturedValue.get(1).iterator().next().getRootNode().getDataAfter().get();
+ final ContainerNode innerContainerVerify = crossShardContainer;
+ assertEquals(innerContainerVerify, capturedChange);
+ }
+
@Test
public void testMultipleWritesIntoSingleMapEntry() throws Exception {
doReturn(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).when(DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
doReturn(DOM_DATA_TREE_WRITE_CURSOR)
.when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(DOM_DATA_TREE_IDENTIFIER);
- foreignShardModificationContext.getCursor();
+ doNothing().when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).ready();
+ foreignShardModificationContext.getCursor();
+ foreignShardModificationContext.ready();
final ForeignShardThreePhaseCommitCohort foreignShardThreePhaseCommitCohort =
new ForeignShardThreePhaseCommitCohort(DOM_DATA_TREE_IDENTIFIER, foreignShardModificationContext);
private DOMDataTreeShardWriteTransaction tx;
private DOMDataTreeWriteCursor cursor;
- private volatile boolean notReady = true;
+ private volatile boolean ready = false;
public ForeignShardModificationContext(final DOMDataTreeIdentifier identifier,
final DOMDataTreeShardProducer producer) {
}
public DOMDataTreeWriteCursor getCursor() {
- Preconditions.checkState(notReady, "Context %s has been readied", this);
+ Preconditions.checkState(!ready, "Context %s has been readied", this);
if (cursor == null) {
if (tx == null) {
}
public void ready() {
- if (!notReady) {
+ if (ready) {
// Idempotent, but emit a debug
LOG.debug("Duplicate ready() of context {}", this);
return;
}
- notReady = false;
+ ready = true;
if (cursor != null) {
cursor.close();
cursor = null;
}
public ListenableFuture<Void> submit() {
+ Preconditions.checkState(ready, "Modification context %s has to be ready before submit", this);
final ListenableFuture<Void> commit = tx.commit();
+ ready = false;
tx = null;
return commit;
}