2 * Copyright (c) 2016 Cisco Systems, 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.yangtools.yang.data.tree.spi;
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.hamcrest.CoreMatchers.instanceOf;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.assertThrows;
16 import static org.mockito.ArgumentMatchers.any;
17 import static org.mockito.ArgumentMatchers.isNull;
18 import static org.mockito.Mockito.doReturn;
19 import static org.mockito.Mockito.mock;
20 import static org.mockito.Mockito.times;
21 import static org.mockito.Mockito.verify;
23 import java.util.List;
24 import java.util.Optional;
25 import org.junit.Test;
26 import org.junit.runner.RunWith;
27 import org.mockito.junit.MockitoJUnitRunner;
28 import org.opendaylight.yangtools.yang.common.QName;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
32 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
33 import org.opendaylight.yangtools.yang.data.tree.api.CursorAwareDataTreeModification;
34 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
35 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
36 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
37 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModificationCursor;
38 import org.opendaylight.yangtools.yang.data.tree.api.ModificationType;
40 @RunWith(MockitoJUnitRunner.StrictStubs.class)
41 public class DataTreeCandidatesTest {
42 private static final NodeIdentifier FOO = new NodeIdentifier(QName.create("foo", "foo"));
45 public void testNewDataTreeCandidate() {
46 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
47 final DataTreeCandidate dataTreeCandidate = DataTreeCandidates.newDataTreeCandidate(
48 YangInstanceIdentifier.empty(), mockedDataTreeCandidateNode);
50 assertThat(dataTreeCandidate, instanceOf(DefaultDataTreeCandidate.class));
51 assertSame(YangInstanceIdentifier.empty(), dataTreeCandidate.getRootPath());
52 assertEquals(mockedDataTreeCandidateNode, dataTreeCandidate.getRootNode());
53 assertThat(dataTreeCandidate.toString(),
54 containsString("DefaultDataTreeCandidate{rootPath=/, rootNode=Mock for DataTreeCandidateNode, hashCode: "));
58 public void testFromNormalizedNode() {
59 final NormalizedNode mockedNormalizedNode = mock(NormalizedNode.class);
60 final DataTreeCandidate dataTreeCandidate = DataTreeCandidates.fromNormalizedNode(
61 YangInstanceIdentifier.empty(), mockedNormalizedNode);
63 assertThat(dataTreeCandidate, instanceOf(DefaultDataTreeCandidate.class));
64 assertSame(YangInstanceIdentifier.empty(), dataTreeCandidate.getRootPath());
65 assertThat(dataTreeCandidate.getRootNode(), instanceOf(NormalizedNodeDataTreeCandidateNode.class));
69 public void testApplyToCursor() {
70 final DataTreeCandidate mockedDataTreeCandidate = mock(DataTreeCandidate.class);
71 final DataTreeModificationCursor mockedCursor = mock(DataTreeModificationCursor.class);
73 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
74 doReturn(ModificationType.DELETE).when(mockedDataTreeCandidateNode).getModificationType();
75 doReturn(mockedDataTreeCandidateNode).when(mockedDataTreeCandidate).getRootNode();
76 DataTreeCandidates.applyToCursor(mockedCursor, mockedDataTreeCandidate);
77 verify(mockedCursor, times(1)).delete(isNull());
81 public void testApplyToCursorAwareModification() {
82 final DataTreeCandidate mockedDataTreeCandidate = mock(DataTreeCandidate.class);
83 final CursorAwareDataTreeModification mockedModification = mock(CursorAwareDataTreeModification.class);
85 doReturn(YangInstanceIdentifier.create(FOO)).when(mockedDataTreeCandidate).getRootPath();
87 final DataTreeModificationCursor mockedCursor = mock(DataTreeModificationCursor.class);
88 doReturn(Optional.of(mockedCursor)).when(mockedModification).openCursor(YangInstanceIdentifier.empty());
89 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
90 doReturn(mockedDataTreeCandidateNode).when(mockedDataTreeCandidate).getRootNode();
92 doReturn(ModificationType.DELETE).when(mockedDataTreeCandidateNode).getModificationType();
94 DataTreeCandidates.applyToModification(mockedModification, mockedDataTreeCandidate);
95 verify(mockedModification, times(1)).openCursor(YangInstanceIdentifier.empty());
96 verify(mockedCursor, times(1)).delete(FOO);
100 public void testApplyToCursorAwareModificationRoot() {
101 final DataTreeCandidate mockedDataTreeCandidate = mock(DataTreeCandidate.class);
102 final CursorAwareDataTreeModification mockedModification = mock(CursorAwareDataTreeModification.class);
103 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
104 doReturn(YangInstanceIdentifier.empty()).when(mockedDataTreeCandidate).getRootPath();
105 doReturn(mockedDataTreeCandidateNode).when(mockedDataTreeCandidate).getRootNode();
106 doReturn(ModificationType.DELETE).when(mockedDataTreeCandidateNode).getModificationType();
108 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
109 () -> DataTreeCandidates.applyToModification(mockedModification, mockedDataTreeCandidate));
110 assertEquals("Can not delete root.", thrown.getMessage());
114 public void testApplyToModificationWithDeleteModificationType() {
115 final DataTreeCandidate mockedDataTreeCandidate = mock(DataTreeCandidate.class);
116 final DataTreeModification mockedModification = mock(DataTreeModification.class);
118 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
119 doReturn(mockedDataTreeCandidateNode).when(mockedDataTreeCandidate).getRootNode();
120 doReturn(YangInstanceIdentifier.empty()).when(mockedDataTreeCandidate).getRootPath();
122 doReturn(ModificationType.DELETE).when(mockedDataTreeCandidateNode).getModificationType();
124 DataTreeCandidates.applyToModification(mockedModification, mockedDataTreeCandidate);
125 verify(mockedModification, times(1)).delete(YangInstanceIdentifier.empty());
129 public void testApplyToModificationWithWriteModificationType() {
130 final DataTreeCandidate mockedDataTreeCandidate = mock(DataTreeCandidate.class);
131 final DataTreeModification mockedModification = mock(DataTreeModification.class);
133 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
134 doReturn(mockedDataTreeCandidateNode).when(mockedDataTreeCandidate).getRootNode();
135 doReturn(YangInstanceIdentifier.empty()).when(mockedDataTreeCandidate).getRootPath();
136 final NormalizedNode mockedNormalizedNode = mock(NormalizedNode.class);
137 doReturn(Optional.of(mockedNormalizedNode)).when(mockedDataTreeCandidateNode).getDataAfter();
139 doReturn(ModificationType.WRITE).when(mockedDataTreeCandidateNode).getModificationType();
141 DataTreeCandidates.applyToModification(mockedModification, mockedDataTreeCandidate);
142 verify(mockedModification, times(1)).write(any(YangInstanceIdentifier.class), any(NormalizedNode.class));
146 public void testApplyToModificationWithSubtreeModifiedModificationType() {
147 final DataTreeCandidate mockedDataTreeCandidate = mock(DataTreeCandidate.class);
148 final DataTreeModification mockedModification = mock(DataTreeModification.class);
150 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
151 doReturn(mockedDataTreeCandidateNode).when(mockedDataTreeCandidate).getRootNode();
152 doReturn(YangInstanceIdentifier.empty()).when(mockedDataTreeCandidate).getRootPath();
154 doReturn(ModificationType.SUBTREE_MODIFIED).when(mockedDataTreeCandidateNode).getModificationType();
156 final DataTreeCandidateNode mockedChildNode1 = mock(DataTreeCandidateNode.class);
157 doReturn(ModificationType.DELETE).when(mockedChildNode1).getModificationType();
158 final PathArgument mockedPathArgument1 = mock(PathArgument.class);
159 doReturn(mockedPathArgument1).when(mockedChildNode1).getIdentifier();
161 final DataTreeCandidateNode mockedChildNode2 = mock(DataTreeCandidateNode.class);
162 doReturn(ModificationType.WRITE).when(mockedChildNode2).getModificationType();
163 final NormalizedNode mockedNormalizedNode = mock(NormalizedNode.class);
164 doReturn(Optional.of(mockedNormalizedNode)).when(mockedChildNode2).getDataAfter();
165 final PathArgument mockedPathArgument2 = mock(PathArgument.class);
166 doReturn(mockedPathArgument2).when(mockedChildNode2).getIdentifier();
168 final DataTreeCandidateNode mockedChildNode3 = mock(DataTreeCandidateNode.class);
169 doReturn(ModificationType.SUBTREE_MODIFIED).when(mockedChildNode3).getModificationType();
170 final DataTreeCandidateNode mockedChildNode3ChildNode = mock(DataTreeCandidateNode.class);
171 doReturn(ModificationType.DELETE).when(mockedChildNode3ChildNode).getModificationType();
172 final PathArgument mockedPathArgument31 = mock(PathArgument.class);
173 final PathArgument mockedPathArgument3 = mock(PathArgument.class);
174 doReturn(mockedPathArgument3).when(mockedChildNode3).getIdentifier();
175 doReturn(mockedPathArgument31).when(mockedChildNode3ChildNode).getIdentifier();
176 doReturn(List.of(mockedChildNode3ChildNode)).when(mockedChildNode3).getChildNodes();
178 final List<DataTreeCandidateNode> childNodes = List.of(mockedChildNode1, mockedChildNode2, mockedChildNode3);
179 doReturn(childNodes).when(mockedDataTreeCandidateNode).getChildNodes();
181 DataTreeCandidates.applyToModification(mockedModification, mockedDataTreeCandidate);
182 verify(mockedModification, times(2)).delete(any(YangInstanceIdentifier.class));
183 verify(mockedModification, times(1)).write(any(YangInstanceIdentifier.class), any(NormalizedNode.class));
187 public void testApplyToModificationWithUnsupportedModificationType() {
188 final DataTreeCandidate mockedDataTreeCandidate = mock(DataTreeCandidate.class);
189 final DataTreeModification mockedModification = mock(DataTreeModification.class);
191 final DataTreeCandidateNode mockedDataTreeCandidateNode = mock(DataTreeCandidateNode.class);
192 doReturn(mockedDataTreeCandidateNode).when(mockedDataTreeCandidate).getRootNode();
193 doReturn(YangInstanceIdentifier.empty()).when(mockedDataTreeCandidate).getRootPath();
195 doReturn(ModificationType.APPEARED).when(mockedDataTreeCandidateNode).getModificationType();
197 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
198 () -> DataTreeCandidates.applyToModification(mockedModification, mockedDataTreeCandidate));
199 assertThat(ex.getMessage(), containsString("Unsupported modification"));