BUG-5280: switch transaction IDs from String to TransactionIdentifier
[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 extends AbstractTest {
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(nextTransactionId());
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(nextTransactionId());
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(nextTransactionId());
127         DataTreeSnapshot snapshot1 = readOnlyShardDataTreeTransaction.getSnapshot();
128
129         Optional<NormalizedNode<?, ?>> optional = snapshot1.readNode(CarsModel.BASE_PATH);
130
131         assertEquals(true, optional.isPresent());
132
133         return optional.get();
134     }
135
136     private static DataTreeCandidateTip addCar(ShardDataTree shardDataTree) throws ExecutionException, InterruptedException {
137         return doTransaction(shardDataTree, snapshot -> {
138                 snapshot.merge(CarsModel.BASE_PATH, CarsModel.emptyContainer());
139                 snapshot.merge(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
140                 snapshot.write(CarsModel.newCarPath("altima"), CarsModel.newCarEntry("altima", new BigInteger("100")));
141             });
142     }
143
144     private static DataTreeCandidateTip removeCar(ShardDataTree shardDataTree) throws ExecutionException, InterruptedException {
145         return doTransaction(shardDataTree, snapshot -> snapshot.delete(CarsModel.newCarPath("altima")));
146     }
147
148     @FunctionalInterface
149     private static interface DataTreeOperation {
150         void execute(DataTreeModification snapshot);
151     }
152
153     private static DataTreeCandidateTip doTransaction(ShardDataTree shardDataTree, DataTreeOperation operation)
154             throws ExecutionException, InterruptedException {
155         ReadWriteShardDataTreeTransaction transaction = shardDataTree.newReadWriteTransaction(nextTransactionId());
156         DataTreeModification snapshot = transaction.getSnapshot();
157         operation.execute(snapshot);
158         ShardDataTreeCohort cohort = shardDataTree.finishTransaction(transaction);
159
160         cohort.canCommit().get();
161         cohort.preCommit().get();
162         DataTreeCandidateTip candidate = cohort.getCandidate();
163         cohort.commit().get();
164
165         return candidate;
166     }
167
168     private static DataTreeCandidateTip applyCandidates(ShardDataTree shardDataTree, List<DataTreeCandidateTip> candidates)
169             throws ExecutionException, InterruptedException {
170         ReadWriteShardDataTreeTransaction transaction = shardDataTree.newReadWriteTransaction(nextTransactionId());
171         DataTreeModification snapshot = transaction.getSnapshot();
172         for(DataTreeCandidateTip candidateTip : candidates){
173             DataTreeCandidates.applyToModification(snapshot, candidateTip);
174         }
175         ShardDataTreeCohort cohort = shardDataTree.finishTransaction(transaction);
176
177         cohort.canCommit().get();
178         cohort.preCommit().get();
179         DataTreeCandidateTip candidate = cohort.getCandidate();
180         cohort.commit().get();
181
182         return candidate;
183     }
184
185 }