BUG-1014: expose a proper ShardDataTree constructor
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / ShardDataTreeTest.java
1 /*
2  * Copyright (c) 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.controller.cluster.datastore;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import com.google.common.base.Optional;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.concurrent.ExecutionException;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.opendaylight.controller.md.cluster.datastore.model.CarsModel;
21 import org.opendaylight.controller.md.cluster.datastore.model.PeopleModel;
22 import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
23 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
27 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
28 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
29 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
30
31 public class ShardDataTreeTest {
32
33     SchemaContext fullSchema;
34
35     @Before
36     public void setUp(){
37         fullSchema = SchemaContextHelper.full();
38     }
39
40     @Test
41     public void testWrite() throws ExecutionException, InterruptedException {
42         modify(new ShardDataTree(fullSchema, TreeType.OPERATIONAL), false, true, true);
43     }
44
45     @Test
46     public void testMerge() throws ExecutionException, InterruptedException {
47         modify(new ShardDataTree(fullSchema, TreeType.OPERATIONAL), true, true, true);
48     }
49
50
51     private void modify(ShardDataTree shardDataTree, boolean merge, boolean expectedCarsPresent, boolean expectedPeoplePresent) throws ExecutionException, InterruptedException {
52
53         assertEquals(fullSchema, shardDataTree.getSchemaContext());
54
55         ReadWriteShardDataTreeTransaction transaction = shardDataTree.newReadWriteTransaction("txn-1", null);
56
57         DataTreeModification snapshot = transaction.getSnapshot();
58
59         assertNotNull(snapshot);
60
61         if(merge){
62             snapshot.merge(CarsModel.BASE_PATH, CarsModel.create());
63             snapshot.merge(PeopleModel.BASE_PATH, PeopleModel.create());
64         } else {
65             snapshot.write(CarsModel.BASE_PATH, CarsModel.create());
66             snapshot.write(PeopleModel.BASE_PATH, PeopleModel.create());
67         }
68
69         ShardDataTreeCohort cohort = shardDataTree.finishTransaction(transaction);
70
71         cohort.preCommit().get();
72         cohort.commit().get();
73
74
75         ReadOnlyShardDataTreeTransaction readOnlyShardDataTreeTransaction = shardDataTree.newReadOnlyTransaction("txn-2", null);
76
77         DataTreeSnapshot snapshot1 = readOnlyShardDataTreeTransaction.getSnapshot();
78
79         Optional<NormalizedNode<?, ?>> optional = snapshot1.readNode(CarsModel.BASE_PATH);
80
81         assertEquals(expectedCarsPresent, optional.isPresent());
82
83         Optional<NormalizedNode<?, ?>> optional1 = snapshot1.readNode(PeopleModel.BASE_PATH);
84
85         assertEquals(expectedPeoplePresent, optional1.isPresent());
86
87     }
88
89     @Test
90     public void bug4359AddRemoveCarOnce() throws ExecutionException, InterruptedException {
91         ShardDataTree shardDataTree = new ShardDataTree(fullSchema, TreeType.OPERATIONAL);
92
93         List<DataTreeCandidateTip> candidates = new ArrayList<>();
94         candidates.add(addCar(shardDataTree));
95         candidates.add(removeCar(shardDataTree));
96
97         NormalizedNode<?, ?> expected = getCars(shardDataTree);
98
99         applyCandidates(shardDataTree, candidates);
100
101         NormalizedNode<?, ?> actual = getCars(shardDataTree);
102
103         assertEquals(expected, actual);
104     }
105
106     @Test
107     public void bug4359AddRemoveCarTwice() throws ExecutionException, InterruptedException {
108         ShardDataTree shardDataTree = new ShardDataTree(fullSchema, TreeType.OPERATIONAL);
109
110         List<DataTreeCandidateTip> candidates = new ArrayList<>();
111         candidates.add(addCar(shardDataTree));
112         candidates.add(removeCar(shardDataTree));
113         candidates.add(addCar(shardDataTree));
114         candidates.add(removeCar(shardDataTree));
115
116         NormalizedNode<?, ?> expected = getCars(shardDataTree);
117
118         applyCandidates(shardDataTree, candidates);
119
120         NormalizedNode<?, ?> actual = getCars(shardDataTree);
121
122         assertEquals(expected, actual);
123     }
124
125     private static NormalizedNode<?, ?> getCars(ShardDataTree shardDataTree) {
126         ReadOnlyShardDataTreeTransaction readOnlyShardDataTreeTransaction = shardDataTree.newReadOnlyTransaction("txn-2", null);
127         DataTreeSnapshot snapshot1 = readOnlyShardDataTreeTransaction.getSnapshot();
128
129         Optional<NormalizedNode<?, ?>> optional = snapshot1.readNode(CarsModel.BASE_PATH);
130
131         assertEquals(true, optional.isPresent());
132
133         System.out.println(optional.get());
134
135         return optional.get();
136     }
137
138     private static DataTreeCandidateTip addCar(ShardDataTree shardDataTree) throws ExecutionException, InterruptedException {
139         return doTransaction(shardDataTree, new DataTreeOperation() {
140             @Override
141             public void execute(DataTreeModification snapshot) {
142                 snapshot.merge(CarsModel.BASE_PATH, CarsModel.emptyContainer());
143                 snapshot.merge(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
144                 snapshot.write(CarsModel.newCarPath("altima"), CarsModel.newCarEntry("altima", new BigInteger("100")));
145             }
146         });
147     }
148
149     private static DataTreeCandidateTip removeCar(ShardDataTree shardDataTree) throws ExecutionException, InterruptedException {
150         return doTransaction(shardDataTree, new DataTreeOperation() {
151             @Override
152             public void execute(DataTreeModification snapshot) {
153                 snapshot.delete(CarsModel.newCarPath("altima"));
154             }
155         });
156     }
157
158     private abstract static class DataTreeOperation {
159         public abstract void execute(DataTreeModification snapshot);
160     }
161
162     private static DataTreeCandidateTip doTransaction(ShardDataTree shardDataTree, DataTreeOperation operation)
163             throws ExecutionException, InterruptedException {
164         ReadWriteShardDataTreeTransaction transaction = shardDataTree.newReadWriteTransaction("txn-1", null);
165         DataTreeModification snapshot = transaction.getSnapshot();
166         operation.execute(snapshot);
167         ShardDataTreeCohort cohort = shardDataTree.finishTransaction(transaction);
168
169         cohort.canCommit().get();
170         cohort.preCommit().get();
171         DataTreeCandidateTip candidate = cohort.getCandidate();
172         cohort.commit().get();
173
174         return candidate;
175     }
176
177     private static DataTreeCandidateTip applyCandidates(ShardDataTree shardDataTree, List<DataTreeCandidateTip> candidates)
178             throws ExecutionException, InterruptedException {
179         ReadWriteShardDataTreeTransaction transaction = shardDataTree.newReadWriteTransaction("txn-1", null);
180         DataTreeModification snapshot = transaction.getSnapshot();
181         for(DataTreeCandidateTip candidateTip : candidates){
182             DataTreeCandidates.applyToModification(snapshot, candidateTip);
183         }
184         ShardDataTreeCohort cohort = shardDataTree.finishTransaction(transaction);
185
186         cohort.canCommit().get();
187         cohort.preCommit().get();
188         DataTreeCandidateTip candidate = cohort.getCandidate();
189         cohort.commit().get();
190
191         return candidate;
192     }
193
194 }