e201890b54f7a6369b8960efa449330fbe2c749d
[hc2vpp.git] /
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.v3po.translate.impl.write.util;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.fail;
21 import static org.mockito.Mockito.doReturn;
22 import static org.mockito.Mockito.doThrow;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.never;
25 import static org.mockito.Mockito.verify;
26
27 import io.fd.honeycomb.v3po.translate.TranslationException;
28 import io.fd.honeycomb.v3po.translate.util.write.DelegatingWriterRegistry;
29 import io.fd.honeycomb.v3po.translate.write.WriteContext;
30 import io.fd.honeycomb.v3po.translate.write.Writer;
31 import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.mockito.Mockito;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
43 import org.opendaylight.yangtools.yang.binding.DataObject;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45
46 public class DelegatingWriterRegistryTest {
47
48     private final InstanceIdentifier<Vpp> vppId;
49     private final InstanceIdentifier<VppState> vppStateId;
50     private final InstanceIdentifier<Interfaces> interfaceId;
51
52     private WriteContext ctx;
53     private Writer<Vpp> writer;
54     private Writer<VppState> vppStateWriter;
55     private Writer<Interfaces> interfacesWriter;
56
57     private DelegatingWriterRegistry registry;
58
59     public DelegatingWriterRegistryTest() {
60         vppId = InstanceIdentifier.create(Vpp.class);
61         vppStateId = InstanceIdentifier.create(VppState.class);
62         interfaceId = InstanceIdentifier.create(Interfaces.class);
63     }
64
65     @SuppressWarnings("unchecked")
66     private <D extends DataObject> Writer<D> mockWriter(Class<D> clazz) {
67         final Writer<D> mock = (Writer<D>) Mockito.mock(Writer.class);
68         doReturn(InstanceIdentifier.create(clazz)).when(mock).getManagedDataObjectType();
69         return mock;
70     }
71
72     private DataObject mockDataObject(final String name, final Class<? extends DataObject> classToMock) {
73         final DataObject dataBefore = mock(classToMock, name);
74         doReturn(classToMock).when(dataBefore).getImplementedInterface();
75         return dataBefore;
76     }
77
78     @SuppressWarnings("unchecked")
79     private static Map<InstanceIdentifier<?>, DataObject> asMap(DataObject... objects) {
80         final Map<InstanceIdentifier<?>, DataObject> map = new HashMap<>();
81         for (DataObject object : objects) {
82             final Class<? extends DataObject> implementedInterface =
83                     (Class<? extends DataObject>) object.getImplementedInterface();
84             final InstanceIdentifier<?> id = InstanceIdentifier.create(implementedInterface);
85             map.put(id, object);
86         }
87         return map;
88     }
89
90     @Before
91     public void setUp() {
92         ctx = mock(WriteContext.class);
93         writer = mockWriter(Vpp.class);
94         vppStateWriter = mockWriter(VppState.class);
95         interfacesWriter = mockWriter(Interfaces.class);
96
97         final List<Writer<? extends DataObject>> writers = new ArrayList<>();
98         writers.add(writer);
99         writers.add(vppStateWriter);
100         writers.add(interfacesWriter);
101
102         registry = new DelegatingWriterRegistry(writers);
103     }
104
105     @Test(expected = UnsupportedOperationException.class)
106     public void testGetManagedDataObjectType() {
107         registry.getManagedDataObjectType();
108     }
109
110     @Test
111     public void testBulkUpdateRevert() throws Exception {
112         // Prepare data changes:
113         final DataObject dataBefore1 = mockDataObject("Vpp before", Vpp.class);
114         final DataObject dataAfter1 = mockDataObject("Vpp after", Vpp.class);
115
116         final DataObject dataBefore2 = mockDataObject("VppState before", VppState.class);
117         final DataObject dataAfter2 = mockDataObject("VppState after", VppState.class);
118
119         // Fail on update
120         Mockito.doThrow(new TranslationException("vpp failed")).when(vppStateWriter)
121                 .update(vppStateId, dataBefore2, dataAfter2, ctx);
122
123         // Run the test
124         try {
125             registry.update(asMap(dataBefore1, dataBefore2), asMap(dataAfter1, dataAfter2), ctx);
126         } catch (WriterRegistry.BulkUpdateException e) {
127             // Check second update failed
128             assertEquals(vppStateId, e.getFailedId());
129             verify(writer).update(vppId, dataBefore1, dataAfter1, ctx);
130             verify(vppStateWriter).update(vppStateId, dataBefore2, dataAfter2, ctx);
131
132             // Try to revert changes
133             e.revertChanges();
134
135             // Check revert was successful
136             verify(writer).update(vppId, dataAfter1, dataBefore1, ctx);
137             verify(vppStateWriter, never()).update(vppStateId, dataAfter2, dataBefore2, ctx);
138
139             return;
140         }
141         fail("BulkUpdateException expected");
142     }
143
144     @Test
145     public void testBulkUpdateRevertFail() throws Exception {
146         // Prepare data changes:
147         final DataObject dataBefore1 = mockDataObject("Vpp before", Vpp.class);
148         final DataObject dataAfter1 = mockDataObject("Vpp after", Vpp.class);
149
150         final DataObject dataBefore2 = mockDataObject("VppState before", VppState.class);
151         final DataObject dataAfter2 = mockDataObject("VppState after", VppState.class);
152
153         final DataObject dataBefore3 = mockDataObject("Interfaces before", Interfaces.class);
154         final DataObject dataAfter3 = mockDataObject("Interfaces after", Interfaces.class);
155
156         // Fail on the third update
157         doThrow(new TranslationException("vpp failed")).when(interfacesWriter)
158                 .update(interfaceId, dataBefore3, dataAfter3, ctx);
159
160         // Fail on the second revert
161         doThrow(new TranslationException("vpp failed again")).when(writer)
162                 .update(vppId, dataAfter1, dataBefore1, ctx);
163
164         // Run the test
165         try {
166             registry.update(asMap(dataBefore1, dataBefore2, dataBefore3), asMap(dataAfter1, dataAfter2, dataAfter3), ctx);
167         } catch (WriterRegistry.BulkUpdateException e) {
168             // Check third update failed
169             assertEquals(interfaceId, e.getFailedId());
170             verify(writer).update(vppId, dataBefore1, dataAfter1, ctx);
171             verify(vppStateWriter).update(vppStateId, dataBefore2, dataAfter2, ctx);
172             verify(interfacesWriter).update(interfaceId, dataBefore3, dataAfter3, ctx);
173
174             // Try to revert changes
175             try {
176                 e.revertChanges();
177             } catch (WriterRegistry.Reverter.RevertFailedException e2) {
178                 // Check second revert failed
179                 assertEquals(Collections.singletonList(vppId), e2.getNotRevertedChanges());
180                 verify(writer).update(vppId, dataAfter1, dataBefore1, ctx);
181                 verify(vppStateWriter).update(vppStateId, dataAfter2, dataBefore2, ctx);
182                 verify(interfacesWriter, never()).update(interfaceId, dataAfter3, dataBefore3, ctx);
183                 return;
184             }
185             fail("WriterRegistry.Revert.RevertFailedException expected");
186         }
187         fail("BulkUpdateException expected");
188     }
189 }