2 * Copyright (c) 2015 Pantheon Technologies s.r.o. 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.impl.schema.tree;
10 import static junit.framework.TestCase.assertFalse;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import com.google.common.base.Optional;
14 import java.io.IOException;
15 import java.util.HashMap;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.opendaylight.yangtools.util.UnmodifiableCollection;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
25 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
32 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
33 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
34 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
35 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
36 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
39 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
40 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
41 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
42 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
43 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
44 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
46 public class Bug4454Test {
47 private static final YangStatementSourceImpl source = new YangStatementSourceImpl("/bug-4454-test.yang", false);
49 private static final QName MASTER_CONTAINER_QNAME = QName
50 .create("urn:opendaylight:params:xml:ns:yang:list-constraints-validation-test-model", "2015-02-02",
52 private static final QName MIN_MAX_LIST_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-list");
53 private static final QName MIN_MAX_LEAF_LIST_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-leaf-list");
54 private static final QName MIN_MAX_LIST_QNAME_NO_MINMAX = QName
55 .create(MASTER_CONTAINER_QNAME, "min-max-list-no-minmax");
56 private static final QName MIN_MAX_KEY_LEAF_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-key-leaf");
57 private static final QName MIN_MAX_VALUE_LEAF_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-value-leaf");
59 private static final YangInstanceIdentifier MASTER_CONTAINER_PATH = YangInstanceIdentifier
60 .of(MASTER_CONTAINER_QNAME);
61 private static final YangInstanceIdentifier MIN_MAX_LIST_PATH = YangInstanceIdentifier
62 .builder(MASTER_CONTAINER_PATH)
63 .node(MIN_MAX_LIST_QNAME).build();
64 private static final YangInstanceIdentifier MIN_MAX_LIST_NO_MINMAX_PATH = YangInstanceIdentifier
65 .builder(MASTER_CONTAINER_PATH)
66 .node(MIN_MAX_LIST_QNAME_NO_MINMAX).build();
67 private static final YangInstanceIdentifier MIN_MAX_LEAF_LIST_PATH = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
68 .node(MIN_MAX_LEAF_LIST_QNAME).build();
70 private static Map<QName,Object> fooPredicates = new HashMap<>();
72 fooPredicates.put(MIN_MAX_KEY_LEAF_QNAME,"foo");
75 private static Map<QName,Object> bazPredicates = new HashMap<>();
77 bazPredicates.put(MIN_MAX_KEY_LEAF_QNAME,"baz");
80 private final MapEntryNode fooEntryNodeWithValue = ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(new
81 NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, fooPredicates)).
82 withChild(ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "footest")).build();
83 private final MapEntryNode BazEntryNodeWithValue = ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(new
84 NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, bazPredicates)).
85 withChild(ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "baztest")).build();
86 private final MapEntryNode fooEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
88 private final MapEntryNode barEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
90 private final MapEntryNode bazEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
92 private final MapNode mapNodeBazFuzWithNodes = ImmutableNodes.mapNodeBuilder()
93 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
94 .withChild(bazEntryNode).withChild(BazEntryNodeWithValue).withChild(fooEntryNode)
96 private final MapNode mapNodeFooWithNodes = ImmutableNodes.mapNodeBuilder()
97 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
98 .withChild(fooEntryNode).withChild(fooEntryNodeWithValue).withChild(barEntryNode).withChild(bazEntryNode)
100 private final MapNode mapNodeBar = ImmutableNodes.mapNodeBuilder()
101 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
102 .withChild(barEntryNode).build();
103 private final MapNode mapNodeBaz = ImmutableNodes.mapNodeBuilder()
104 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
105 .withChild(bazEntryNode).build();
107 private InMemoryDataTree inMemoryDataTree;
110 public void prepare() throws IOException, YangSyntaxErrorException, ReactorException {
111 SchemaContext schemaContext = createTestContext();
112 assertNotNull("Schema context must not be null.", schemaContext);
113 inMemoryDataTree = (InMemoryDataTree) InMemoryDataTreeFactory.getInstance().create(TreeType.OPERATIONAL);
114 inMemoryDataTree.setSchemaContext(schemaContext);
115 final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
116 final DataTreeModification modificationTree = initialDataTreeSnapshot.newModification();
118 modificationTree.write(MASTER_CONTAINER_PATH, ImmutableNodes.containerNode(MASTER_CONTAINER_QNAME));
119 modificationTree.ready();
120 inMemoryDataTree.commit(inMemoryDataTree.prepare(modificationTree));
123 public static SchemaContext createTestContext() throws IOException, YangSyntaxErrorException, ReactorException {
124 return YangParserTestUtils.parseYangSources(source);
128 public void minMaxListDeleteWriteTest() throws DataValidationFailedException {
129 final InMemoryDataTreeModification modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
131 Map<QName, Object> key = new HashMap<>();
132 key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
134 NodeIdentifierWithPredicates mapEntryPath2 = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , key);
136 YangInstanceIdentifier MIN_MAX_LEAF_FOO = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
137 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
140 key.put(MIN_MAX_KEY_LEAF_QNAME, "NON-EXISTING-LEAF");
142 mapEntryPath2 = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, key);
144 YangInstanceIdentifier MIN_MAX_LEAF_NEL = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
145 (MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
147 final Map<QName, Object> keyTemp = new HashMap<>();
148 keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "baz");
150 NodeIdentifierWithPredicates mapEntryPathTest = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , keyTemp);
152 final YangInstanceIdentifier pathToBaz = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
153 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTest).node(MIN_MAX_VALUE_LEAF_QNAME).build();
156 keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "bar");
158 mapEntryPathTest = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , keyTemp);
160 final YangInstanceIdentifier pathToBar = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
161 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTest).node(MIN_MAX_VALUE_LEAF_QNAME).build();
164 keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
166 final NodeIdentifierWithPredicates mapEntryPathTestKey = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , keyTemp);
168 final YangInstanceIdentifier pathToKeyFoo = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
169 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTestKey).node(MIN_MAX_KEY_LEAF_QNAME).build();
171 final LeafNode<String> newNode = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test");
172 final LeafNode<String> newNode1 = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test1");
173 final LeafNode<String> newNode2 = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test2");
174 final LeafNode<String> newNodekey = ImmutableNodes.leafNode(MIN_MAX_KEY_LEAF_QNAME, "foo");
176 assertFalse(inMemoryDataTree.toString().contains("list"));
178 InMemoryDataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
179 Optional<NormalizedNode<?, ?>> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_PATH);
180 assertTrue(!minMaxListRead.isPresent());
182 modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
183 modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
184 modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
185 modificationTree1.merge(MIN_MAX_LIST_PATH, mapNodeBar);
186 modificationTree1.merge(MIN_MAX_LIST_PATH, mapNodeBaz);
187 modificationTree1.write(pathToKeyFoo, newNodekey);
188 modificationTree1.write(pathToBaz, newNode2);
189 modificationTree1.write(pathToBaz, newNode1);
190 modificationTree1.write(pathToBaz, newNode);
191 modificationTree1.delete(MIN_MAX_LEAF_FOO);
192 modificationTree1.delete(MIN_MAX_LEAF_NEL);
194 modificationTree1.ready();
195 inMemoryDataTree.validate(modificationTree1);
196 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree1);
197 inMemoryDataTree.commit(prepare);
199 InMemoryDataTreeSnapshot test = inMemoryDataTree.takeSnapshot();
200 testLoop(test, "bar", "test");
202 InMemoryDataTreeModification tempMod = test.newModification();
203 tempMod.write(pathToBaz, newNode2);
204 tempMod.write(pathToBaz, newNode1);
205 tempMod.merge(pathToBaz, newNode2);
206 tempMod.write(pathToBaz, newNode1);
209 inMemoryDataTree.validate(tempMod);
210 final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(tempMod);
211 inMemoryDataTree.commit(prepare1);
213 InMemoryDataTreeSnapshot test1 = inMemoryDataTree.takeSnapshot();
214 testLoop(test1, "bar", "test1");
216 InMemoryDataTreeModification tempMod1 = test1.newModification();
217 tempMod1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
220 inMemoryDataTree.validate(tempMod1);
221 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(tempMod1);
222 inMemoryDataTree.commit(prepare2);
224 InMemoryDataTreeSnapshot test2 = inMemoryDataTree.takeSnapshot();
225 minMaxListRead = test2.readNode(MIN_MAX_LIST_PATH);
226 assertTrue(minMaxListRead.isPresent());
227 assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 3);
229 InMemoryDataTreeModification tempMod2 = test2.newModification();
230 tempMod2.write(MIN_MAX_LIST_PATH, mapNodeBaz);
231 tempMod2.write(pathToBaz, newNode2);
234 inMemoryDataTree.validate(tempMod2);
235 final DataTreeCandidate prepare3 = inMemoryDataTree.prepare(tempMod2);
236 inMemoryDataTree.commit(prepare3);
238 InMemoryDataTreeSnapshot test3 = inMemoryDataTree.takeSnapshot();
239 minMaxListRead = test3.readNode(MIN_MAX_LIST_PATH);
240 assertTrue(minMaxListRead.isPresent());
241 assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 1);
242 assertTrue(minMaxListRead.get().getValue().toString().contains("test2"));
244 InMemoryDataTreeModification tempMod3 = test3.newModification();
245 tempMod3.merge(MIN_MAX_LIST_PATH, mapNodeBar);
246 tempMod3.merge(pathToBar, newNode1);
249 inMemoryDataTree.validate(tempMod3);
250 final DataTreeCandidate prepare4 = inMemoryDataTree.prepare(tempMod3);
251 inMemoryDataTree.commit(prepare4);
253 InMemoryDataTreeSnapshot test4 = inMemoryDataTree.takeSnapshot();
254 testLoop(test4, "test1", "test2");
258 public void minMaxLeafListPass() throws DataValidationFailedException {
259 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
261 final NodeWithValue<?> barPath = new NodeWithValue<>(MIN_MAX_LIST_QNAME, "bar");
262 final NodeWithValue<?> gooPath = new NodeWithValue<>(MIN_MAX_LIST_QNAME, "goo");
264 final LeafSetEntryNode<Object> barLeafSetEntry = ImmutableLeafSetEntryNodeBuilder.create()
265 .withNodeIdentifier(barPath)
266 .withValue("bar").build();
267 final LeafSetEntryNode<Object> gooLeafSetEntry = ImmutableLeafSetEntryNodeBuilder.create()
268 .withNodeIdentifier(gooPath)
269 .withValue("goo").build();
271 final LeafSetNode<Object> fooLeafSetNode = ImmutableLeafSetNodeBuilder.create()
272 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME))
273 .withChildValue("foo").build();
275 modificationTree.write(MIN_MAX_LEAF_LIST_PATH, fooLeafSetNode);
276 modificationTree.write(MIN_MAX_LEAF_LIST_PATH.node(barPath), barLeafSetEntry);
277 modificationTree.ready();
279 inMemoryDataTree.validate(modificationTree);
280 final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree);
281 inMemoryDataTree.commit(prepare1);
283 InMemoryDataTreeSnapshot test1 = inMemoryDataTree.takeSnapshot();
285 InMemoryDataTreeModification tempMod1 = test1.newModification();
286 tempMod1.write(MIN_MAX_LEAF_LIST_PATH.node(gooPath), gooLeafSetEntry);
287 tempMod1.write(MIN_MAX_LEAF_LIST_PATH.node(barPath), barLeafSetEntry);
290 inMemoryDataTree.validate(tempMod1);
291 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(tempMod1);
292 inMemoryDataTree.commit(prepare2);
294 final InMemoryDataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
295 final Optional<NormalizedNode<?, ?>> masterContainer = snapshotAfterCommit.readNode(MASTER_CONTAINER_PATH);
296 assertTrue(masterContainer.isPresent());
297 final Optional<NormalizedNodeContainer<?, ?, ?>> leafList = ((NormalizedNodeContainer) masterContainer.get()).getChild(
298 new NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME));
299 assertTrue(leafList.isPresent());
300 assertTrue(leafList.get().getValue().size() == 3);
304 @Test(expected = DataValidationFailedException.class)
305 public void minMaxListDeleteExceptionTest() throws DataValidationFailedException {
306 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
308 Map<QName, Object> key = new HashMap<>();
309 key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
311 NodeIdentifierWithPredicates mapEntryPath2 = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , key);
313 YangInstanceIdentifier MIN_MAX_LEAF_FOO = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
314 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
317 key.put(MIN_MAX_KEY_LEAF_QNAME, "bar");
319 mapEntryPath2 = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, key);
321 YangInstanceIdentifier MIN_MAX_LEAF_BAR = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
323 .node(mapEntryPath2).build();
326 key.put(MIN_MAX_KEY_LEAF_QNAME, "baz");
328 mapEntryPath2 = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, key);
330 YangInstanceIdentifier MIN_MAX_LEAF_BAZ = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
332 .node(mapEntryPath2).build();
334 modificationTree.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
335 modificationTree.merge(MIN_MAX_LIST_PATH, mapNodeBar);
336 modificationTree.merge(MIN_MAX_LIST_PATH, mapNodeBaz);
337 modificationTree.delete(MIN_MAX_LEAF_FOO);
338 modificationTree.delete(MIN_MAX_LEAF_BAR);
339 modificationTree.delete(MIN_MAX_LEAF_BAZ);
341 modificationTree.ready();
343 inMemoryDataTree.validate(modificationTree);
344 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
345 inMemoryDataTree.commit(prepare);
349 public void minMaxListNoMinMaxDeleteTest() throws DataValidationFailedException {
350 final MapEntryNode fooEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME_NO_MINMAX, MIN_MAX_KEY_LEAF_QNAME
352 final MapNode mapNode1 = ImmutableNodes.mapNodeBuilder()
353 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME_NO_MINMAX))
354 .withChild(fooEntryNode).build();
356 final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
358 Map<QName, Object> key = new HashMap<>();
359 key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
361 NodeIdentifierWithPredicates mapEntryPath2 = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME_NO_MINMAX , key);
363 YangInstanceIdentifier MIN_MAX_LEAF_FOO = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
364 (MIN_MAX_LIST_QNAME_NO_MINMAX).node(mapEntryPath2).build();
367 key.put(MIN_MAX_KEY_LEAF_QNAME, "non-existing-leaf");
369 mapEntryPath2 = new NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME_NO_MINMAX, key);
371 YangInstanceIdentifier MIN_MAX_LEAF_NEL = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
372 (MIN_MAX_LIST_QNAME_NO_MINMAX)
373 .node(mapEntryPath2).build();
375 modificationTree.write(MIN_MAX_LIST_NO_MINMAX_PATH, mapNode1);
376 modificationTree.delete(MIN_MAX_LEAF_FOO);
377 modificationTree.delete(MIN_MAX_LEAF_NEL);
379 modificationTree.ready();
381 inMemoryDataTree.validate(modificationTree);
382 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
383 inMemoryDataTree.commit(prepare);
385 final InMemoryDataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
386 final Optional<NormalizedNode<?, ?>> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_NO_MINMAX_PATH);
387 assertTrue(minMaxListRead.isPresent());
388 assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 0);
391 private static void testLoop(final InMemoryDataTreeSnapshot snapshot, final String first, final String second) {
392 Optional<NormalizedNode<?, ?>> minMaxListRead = snapshot.readNode(MIN_MAX_LIST_PATH);
393 assertTrue(minMaxListRead.isPresent());
394 assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 2);
395 UnmodifiableCollection<?> collectionChildren = (UnmodifiableCollection<?>) minMaxListRead.get().getValue();
397 for (Object collectionChild : collectionChildren) {
398 if (collectionChild.toString().contains(first)){
399 assertTrue(collectionChild.toString().contains(first));
401 assertTrue(collectionChild.toString().contains(second));