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