2 * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netvirt.elan.l2gw;
10 import static org.junit.Assert.assertEquals;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.junit.After;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.mockito.Mockito;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
24 import org.opendaylight.netvirt.elan.l2gw.ha.commands.LogicalSwitchesCmd;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 public class LogicalSwitchesCmdTest extends AbstractConcurrentDataBrokerTest {
36 // Uncomment this to keep running this test indefinitely
37 // This is very useful to detect concurrency issues, respectively prove
38 // that the use of AbstractConcurrentDataBrokerTest instead of AbstractDataBrokerTest
39 // does NOT cause any concurrency issues and make this test flaky...
40 // public static @ClassRule RunUntilFailureClassRule classRepeater = new RunUntilFailureClassRule();
41 // public @Rule RunUntilFailureRule repeater = new RunUntilFailureRule(classRepeater);
43 DataBroker dataBroker;
44 ReadWriteTransaction tx;
45 LogicalSwitchesCmd cmd = new LogicalSwitchesCmd();
47 HwvtepGlobalAugmentationBuilder dstBuilder = new HwvtepGlobalAugmentationBuilder();
49 HwvtepGlobalAugmentation existingData = null;//nodata
50 HwvtepGlobalAugmentation srcData = null;
52 HwvtepGlobalAugmentation updatedData = null;
53 HwvtepGlobalAugmentation originalData = null;
55 InstanceIdentifier<Node> haNodePath = HwvtepHAUtil.convertToInstanceIdentifier("ha");
56 InstanceIdentifier<Node> d1NodePath = HwvtepHAUtil.convertToInstanceIdentifier("d1");
57 InstanceIdentifier<Node> d2NodePath = HwvtepHAUtil.convertToInstanceIdentifier("d2");
59 LogicalSwitches[] logicalSwitches = new LogicalSwitches[4];
60 InstanceIdentifier<LogicalSwitches>[] ids = new InstanceIdentifier[4];
62 String[][] data = new String[][] {
70 public void setupForHANode() {
71 dataBroker = getDataBroker();
72 tx = Mockito.spy(dataBroker.newReadWriteTransaction());
73 for (int i = 0 ; i < 4; i++) {
74 logicalSwitches[i] = buildData(data[i][0], data[i][1]);
75 ids[i] = haNodePath.augmentation(HwvtepGlobalAugmentation.class).child(LogicalSwitches.class,
76 new LogicalSwitchesKey(new HwvtepNodeName(data[i][0])));
81 public void teardown() {
86 public void testD1Connect() throws Exception {
87 srcData = getData(new LogicalSwitches[] {logicalSwitches[0], logicalSwitches[1]});
88 cmd.mergeOperationalData(dstBuilder, existingData, srcData, haNodePath);
89 assertEquals("should copy the logical switches ", 2, dstBuilder.getLogicalSwitches().size());
93 public void testD2Connect() throws Exception {
94 existingData = getData(new LogicalSwitches[] {logicalSwitches[0], logicalSwitches[1]});
95 srcData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1],
96 logicalSwitches[2], logicalSwitches[3]});
97 cmd.mergeOperationalData(dstBuilder, existingData, srcData, haNodePath);
98 assertEquals("should copy the logical switches ", 2, dstBuilder.getLogicalSwitches().size());
102 public void testOneLogicalSwitchAddedUpdate() throws Exception {
103 existingData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
104 originalData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
105 updatedData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1], logicalSwitches[2]});
106 cmd.mergeOpUpdate(existingData, updatedData, originalData, haNodePath, tx);
107 Mockito.verify(tx).put(LogicalDatastoreType.OPERATIONAL, ids[2], logicalSwitches[2],
108 WriteTransaction.CREATE_MISSING_PARENTS);
112 public void testTwoLogicalSwitchesAddedUpdate() throws Exception {
113 existingData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
114 originalData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
115 updatedData = getData(new LogicalSwitches[]{logicalSwitches[0],
116 logicalSwitches[1], logicalSwitches[2], logicalSwitches[3]});
117 cmd.mergeOpUpdate(existingData, updatedData, originalData, haNodePath, tx);
118 Mockito.verify(tx).put(LogicalDatastoreType.OPERATIONAL, ids[2], logicalSwitches[2],
119 WriteTransaction.CREATE_MISSING_PARENTS);
120 Mockito.verify(tx).put(LogicalDatastoreType.OPERATIONAL, ids[3], logicalSwitches[3],
121 WriteTransaction.CREATE_MISSING_PARENTS);
125 public void testLogicalSwitchDeletedUpdate() throws Exception {
126 existingData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1], logicalSwitches[2]});
127 originalData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1], logicalSwitches[2]});
128 updatedData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
129 cmd.mergeOpUpdate(existingData, updatedData, originalData, haNodePath, tx);
130 Mockito.verify(tx).delete(LogicalDatastoreType.OPERATIONAL, ids[2]);
135 public void testTwoLogicalSwitchesDeletedUpdate() throws Exception {
136 existingData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1],
137 logicalSwitches[2], logicalSwitches[3]});
138 originalData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1],
139 logicalSwitches[2], logicalSwitches[3]});
140 updatedData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
141 cmd.mergeOpUpdate(existingData, updatedData, originalData, haNodePath, tx);
142 Mockito.verify(tx).delete(LogicalDatastoreType.OPERATIONAL, ids[2]);
143 Mockito.verify(tx).delete(LogicalDatastoreType.OPERATIONAL, ids[3]);
147 public void testTwoAddTwoDeletedLogicalSwitchesUpdate() throws Exception {
148 existingData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
149 originalData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
150 updatedData = getData(new LogicalSwitches[]{logicalSwitches[2], logicalSwitches[3]});
151 cmd.mergeOpUpdate(existingData, updatedData, originalData, haNodePath, tx);
152 Mockito.verify(tx).put(LogicalDatastoreType.OPERATIONAL, ids[2], logicalSwitches[2],
153 WriteTransaction.CREATE_MISSING_PARENTS);
154 Mockito.verify(tx).put(LogicalDatastoreType.OPERATIONAL, ids[3], logicalSwitches[3],
155 WriteTransaction.CREATE_MISSING_PARENTS);
156 Mockito.verify(tx).delete(LogicalDatastoreType.OPERATIONAL, ids[0]);
157 Mockito.verify(tx).delete(LogicalDatastoreType.OPERATIONAL, ids[1]);
161 public void testAllDeleteUpdate() throws Exception {
162 existingData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
163 originalData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
164 updatedData = getData(new LogicalSwitches[]{});
165 cmd.mergeOpUpdate(existingData, updatedData, originalData, haNodePath, tx);
166 Mockito.verify(tx).delete(LogicalDatastoreType.OPERATIONAL, ids[0]);
167 Mockito.verify(tx).delete(LogicalDatastoreType.OPERATIONAL, ids[1]);
171 public void testNoUpdate() throws Exception {
172 existingData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
173 originalData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
174 updatedData = getData(new LogicalSwitches[]{logicalSwitches[0], logicalSwitches[1]});
175 cmd.mergeOpUpdate(existingData, updatedData, originalData, haNodePath, tx);
176 Mockito.verifyNoMoreInteractions(tx);
179 LogicalSwitches buildData(String name, String tunnelKey) {
180 LogicalSwitchesBuilder logicalSwitchesBuilder = new LogicalSwitchesBuilder();
181 logicalSwitchesBuilder.withKey(new LogicalSwitchesKey(new HwvtepNodeName(name)));
182 logicalSwitchesBuilder.setTunnelKey(tunnelKey);
183 logicalSwitchesBuilder.setHwvtepNodeName(new HwvtepNodeName(name));
184 return logicalSwitchesBuilder.build();
187 HwvtepGlobalAugmentation getData(LogicalSwitches[] elements) {
188 HwvtepGlobalAugmentationBuilder newDataBuilder = new HwvtepGlobalAugmentationBuilder();
189 List<LogicalSwitches> ls = new ArrayList<>();
190 for (LogicalSwitches ele : elements) {
193 newDataBuilder.setLogicalSwitches(ls);
194 return newDataBuilder.build();