eb70b7ec61861d46d732f037495e1d9267abb853
[mdsal.git] / dom / mdsal-dom-broker / src / test / java / org / opendaylight / mdsal / dom / broker / test / DOMBrokerTest.java
1 /*
2  * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.mdsal.dom.broker.test;
10
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
15 import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
16
17 import org.opendaylight.mdsal.dom.broker.test.util.TestModel;
18
19 import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
20 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
21
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.mdsal.common.api.TransactionCommitDeadlockException;
24 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
25 import org.opendaylight.mdsal.dom.broker.AbstractDOMDataBroker;
26 import org.opendaylight.mdsal.dom.broker.SerializedDOMDataBroker;
27 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
28 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
29 import com.google.common.base.Optional;
30 import com.google.common.collect.ImmutableMap;
31 import com.google.common.util.concurrent.ForwardingExecutorService;
32 import com.google.common.util.concurrent.ListenableFuture;
33 import com.google.common.util.concurrent.ListeningExecutorService;
34 import com.google.common.util.concurrent.MoreExecutors;
35 import java.util.Collections;
36 import java.util.concurrent.ExecutionException;
37 import java.util.concurrent.ExecutorService;
38 import java.util.concurrent.Executors;
39 import java.util.concurrent.RejectedExecutionException;
40 import java.util.concurrent.TimeUnit;
41 import java.util.concurrent.atomic.AtomicReference;
42 import org.junit.After;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.mockito.Mockito;
46 import org.opendaylight.yangtools.util.concurrent.DeadlockDetectingListeningExecutorService;
47 import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
48 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
49 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
50 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
51
52 public class DOMBrokerTest {
53
54     private SchemaContext schemaContext;
55     private AbstractDOMDataBroker domBroker;
56     private ListeningExecutorService executor;
57     private ExecutorService futureExecutor;
58     private CommitExecutorService commitExecutor;
59
60     @Before
61     public void setupStore() {
62
63         InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("OPER",
64                 MoreExecutors.newDirectExecutorService());
65         InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("CFG",
66                 MoreExecutors.newDirectExecutorService());
67         schemaContext = TestModel.createTestContext();
68
69         operStore.onGlobalContextUpdated(schemaContext);
70         configStore.onGlobalContextUpdated(schemaContext);
71
72         ImmutableMap<LogicalDatastoreType, DOMStore> stores = ImmutableMap.<LogicalDatastoreType, DOMStore> builder() //
73                 .put(CONFIGURATION, configStore) //
74                 .put(OPERATIONAL, operStore) //
75                 .build();
76
77         commitExecutor = new CommitExecutorService(Executors.newSingleThreadExecutor());
78         futureExecutor = SpecialExecutors.newBlockingBoundedCachedThreadPool(1, 5, "FCB");
79         executor = new DeadlockDetectingListeningExecutorService(commitExecutor,
80                 TransactionCommitDeadlockException.DEADLOCK_EXCEPTION_SUPPLIER, futureExecutor);
81         domBroker = new SerializedDOMDataBroker(stores, executor);
82     }
83
84     @After
85     public void tearDown() {
86         if( executor != null ) {
87             executor.shutdownNow();
88         }
89
90         if(futureExecutor != null) {
91             futureExecutor.shutdownNow();
92         }
93     }
94
95     @Test(timeout=10000)
96     public void testTransactionIsolation() throws InterruptedException, ExecutionException {
97
98         assertNotNull(domBroker);
99
100         DOMDataTreeReadTransaction readTx = domBroker.newReadOnlyTransaction();
101         assertNotNull(readTx);
102
103         DOMDataTreeWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
104         assertNotNull(writeTx);
105         /**
106          *
107          * Writes /test in writeTx
108          *
109          */
110         writeTx.put(OPERATIONAL, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
111
112
113         /**
114          *
115          * Reads /test from readTx Read should return Absent.
116          *
117          */
118         ListenableFuture<Optional<NormalizedNode<?, ?>>> readTxContainer = readTx
119                 .read(OPERATIONAL, TestModel.TEST_PATH);
120         assertFalse(readTxContainer.get().isPresent());
121     }
122
123     @Test(timeout=10000)
124     public void testTransactionCommit() throws InterruptedException, ExecutionException {
125
126         DOMDataTreeWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
127         assertNotNull(writeTx);
128         /**
129          *
130          * Writes /test in writeTx
131          *
132          */
133         writeTx.put(OPERATIONAL, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
134
135         writeTx.submit().get();
136
137         Optional<NormalizedNode<?, ?>> afterCommitRead = domBroker.newReadOnlyTransaction()
138                 .read(OPERATIONAL, TestModel.TEST_PATH).get();
139         assertTrue(afterCommitRead.isPresent());
140     }
141
142     @Test(expected=TransactionCommitFailedException.class)
143     public void testRejectedCommit() throws Exception {
144
145         commitExecutor.delegate = Mockito.mock( ExecutorService.class );
146         Mockito.doThrow( new RejectedExecutionException( "mock" ) )
147             .when( commitExecutor.delegate ).execute( Mockito.any( Runnable.class ) );
148         Mockito.doNothing().when( commitExecutor.delegate ).shutdown();
149         Mockito.doReturn( Collections.emptyList() ).when( commitExecutor.delegate ).shutdownNow();
150         Mockito.doReturn( "" ).when( commitExecutor.delegate ).toString();
151         Mockito.doReturn( true ).when( commitExecutor.delegate )
152             .awaitTermination( Mockito.anyLong(), Mockito.any( TimeUnit.class ) );
153
154         DOMDataTreeWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
155         writeTx.put( OPERATIONAL, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME) );
156
157         writeTx.submit().checkedGet( 5, TimeUnit.SECONDS );
158     }
159
160     AtomicReference<Throwable> submitTxAsync( final DOMDataTreeWriteTransaction writeTx ) {
161         final AtomicReference<Throwable> caughtEx = new AtomicReference<>();
162         new Thread() {
163             @Override
164             public void run() {
165
166                 try {
167                     writeTx.submit();
168                 } catch( Throwable e ) {
169                     caughtEx.set( e );
170                 }
171             }
172
173         }.start();
174
175         return caughtEx;
176     }
177
178     static class CommitExecutorService extends ForwardingExecutorService {
179
180         ExecutorService delegate;
181
182         public CommitExecutorService( final ExecutorService delegate ) {
183             this.delegate = delegate;
184         }
185
186         @Override
187         protected ExecutorService delegate() {
188             return delegate;
189         }
190     }
191 }