ea7f50cd7afd01369c6c7fa2be0cebf80783ea2d
[vtn.git] /
1 /*
2  * Copyright (c) 2015 NEC Corporation.  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.vtn.manager.internal.util.flow.cond;
10
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16
17 import org.junit.Test;
18
19 import org.mockito.Mockito;
20
21 import org.opendaylight.vtn.manager.internal.util.inventory.SalPort;
22 import org.opendaylight.vtn.manager.internal.util.rpc.RpcErrorTag;
23 import org.opendaylight.vtn.manager.internal.util.rpc.RpcException;
24
25 import org.opendaylight.vtn.manager.internal.TestBase;
26
27 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.VtnFlowConditions;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.VtnFlowConditionsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.cond.config.VtnFlowMatch;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.cond.config.VtnFlowMatchKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.conditions.VtnFlowCondition;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.conditions.VtnFlowConditionBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.conditions.VtnFlowConditionKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnErrorTag;
41
42 /**
43  * JUnit test for {@link FlowCondUtils}.
44  */
45 public class FlowCondUtilsTest extends TestBase {
46     /**
47      * Test case for the following methods.
48      *
49      * <ul>
50      *   <li>{@link FlowCondUtils#getNotFoundException(String)}</li>
51      *   <li>{@link FlowCondUtils#getNotFoundException(String, Throwable)}</li>
52      *   <li>{@link FlowCondUtils#getMatchIndexMissingException()}</li>
53      * </ul>
54      */
55     @Test
56     public void testException() {
57         String[] names = {
58             "flow_cond",
59             "fcond",
60             "fc",
61         };
62
63         Throwable cause = new IllegalStateException();
64         for (String name: names) {
65             String msg = name + ": Flow condition does not exist.";
66             RpcException e = FlowCondUtils.getNotFoundException(name);
67             assertEquals(null, e.getCause());
68             assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
69             assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
70             assertEquals(msg, e.getMessage());
71
72             e = FlowCondUtils.getNotFoundException(name, cause);
73             assertSame(cause, e.getCause());
74             assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
75             assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
76             assertEquals(msg, e.getMessage());
77         }
78
79         String msg = "Match index cannot be null";
80         RpcException e = FlowCondUtils.getMatchIndexMissingException();
81         assertEquals(RpcErrorTag.MISSING_ELEMENT, e.getErrorTag());
82         assertEquals(VtnErrorTag.BADREQUEST, e.getVtnErrorTag());
83         assertEquals(msg, e.getMessage());
84         assertEquals(null, e.getCause());
85     }
86
87     /**
88      * Test case for the following methods.
89      *
90      * <ul>
91      *   <li>{@link FlowCondUtils#checkName(String)}</li>
92      *   <li>{@link FlowCondUtils#checkName(VnodeName)}</li>
93      *   <li>{@link FlowCondUtils#getVnodeName(String)}</li>
94      *   <li>{@link FlowCondUtils#getIdentifier(String)}</li>
95      *   <li>{@link FlowCondUtils#getIdentifier(VnodeName)}</li>
96      *   <li>{@link FlowCondUtils#getIdentifier(String, Integer)}</li>
97      *   <li>{@link FlowCondUtils#getIdentifier(VnodeName, Integer)}</li>
98      *   <li>{@link FlowCondUtils#getName(InstanceIdentifier)}</li>
99      * </ul>
100      *
101      * @throws Exception  An error occurred.
102      */
103     @Test
104     public void testName() throws Exception {
105         // Valid name.
106         String[] names = {
107             "0",
108             "01",
109             "012",
110             "0123",
111             "012345678901234567890123456789",
112             "0123456789012345678901234567890",
113             "a",
114             "ab",
115             "abc",
116             "abcABC",
117             "abcABC_",
118             "abcABC_0123",
119             "abcABC_0123_XXXXXXXXXXXXXXXXXXX",
120         };
121         Integer[] indices = {
122             1, 2, 3, 444, 1000, 2000, 3333, 44444, 55555, 65534, 65535,
123         };
124
125         for (String name: names) {
126             VnodeName vname = new VnodeName(name);
127             assertEquals(vname, FlowCondUtils.checkName(name));
128             assertEquals(name, FlowCondUtils.checkName(vname));
129             assertEquals(vname, FlowCondUtils.getVnodeName(name));
130
131             VtnFlowConditionKey key = new VtnFlowConditionKey(vname);
132             InstanceIdentifier<VtnFlowCondition> expected = InstanceIdentifier.
133                 builder(VtnFlowConditions.class).
134                 child(VtnFlowCondition.class, key).build();
135             assertEquals(expected, FlowCondUtils.getIdentifier(name));
136             assertEquals(expected, FlowCondUtils.getIdentifier(vname));
137             assertEquals(name, FlowCondUtils.getName(expected));
138
139             for (Integer idx: indices) {
140                 VtnFlowMatchKey mkey = new VtnFlowMatchKey(idx);
141                 InstanceIdentifier<VtnFlowMatch> ex = InstanceIdentifier.
142                     builder(VtnFlowConditions.class).
143                     child(VtnFlowCondition.class, key).
144                     child(VtnFlowMatch.class, mkey).build();
145                 assertEquals(ex, FlowCondUtils.getIdentifier(name, idx));
146                 assertEquals(ex, FlowCondUtils.getIdentifier(vname, idx));
147                 assertEquals(name, FlowCondUtils.getName(ex));
148             }
149
150             String msg = "Match index cannot be null";
151             try {
152                 FlowCondUtils.getIdentifier(name, null);
153                 unexpected();
154             } catch (RpcException e) {
155                 assertEquals(RpcErrorTag.MISSING_ELEMENT, e.getErrorTag());
156                 assertEquals(VtnErrorTag.BADREQUEST, e.getVtnErrorTag());
157                 assertEquals(msg, e.getMessage());
158                 assertEquals(null, e.getCause());
159             }
160
161             try {
162                 FlowCondUtils.getIdentifier(vname, null);
163                 unexpected();
164             } catch (RpcException e) {
165                 assertEquals(RpcErrorTag.MISSING_ELEMENT, e.getErrorTag());
166                 assertEquals(VtnErrorTag.BADREQUEST, e.getVtnErrorTag());
167                 assertEquals(msg, e.getMessage());
168                 assertEquals(null, e.getCause());
169             }
170         }
171
172         // Null name.
173         String msg = "Flow condition name cannot be null";
174         RpcErrorTag etag = RpcErrorTag.MISSING_ELEMENT;
175         VtnErrorTag vtag = VtnErrorTag.BADREQUEST;
176         try {
177             FlowCondUtils.checkName((String)null);
178             unexpected();
179         } catch (RpcException e) {
180             assertEquals(etag, e.getErrorTag());
181             assertEquals(vtag, e.getVtnErrorTag());
182             assertEquals(msg, e.getMessage());
183             assertEquals(null, e.getCause());
184         }
185
186         try {
187             FlowCondUtils.checkName((VnodeName)null);
188             unexpected();
189         } catch (RpcException e) {
190             assertEquals(etag, e.getErrorTag());
191             assertEquals(vtag, e.getVtnErrorTag());
192             assertEquals(msg, e.getMessage());
193             assertEquals(null, e.getCause());
194         }
195
196         try {
197             FlowCondUtils.getVnodeName(null);
198             unexpected();
199         } catch (RpcException e) {
200             assertEquals(etag, e.getErrorTag());
201             assertEquals(vtag, e.getVtnErrorTag());
202             assertEquals(msg, e.getMessage());
203             assertEquals(null, e.getCause());
204         }
205
206         try {
207             FlowCondUtils.getIdentifier((String)null);
208             unexpected();
209         } catch (RpcException e) {
210             assertEquals(etag, e.getErrorTag());
211             assertEquals(vtag, e.getVtnErrorTag());
212             assertEquals(msg, e.getMessage());
213             assertEquals(null, e.getCause());
214         }
215
216         try {
217             FlowCondUtils.getIdentifier((String)null, Integer.valueOf(1));
218             unexpected();
219         } catch (RpcException e) {
220             assertEquals(etag, e.getErrorTag());
221             assertEquals(vtag, e.getVtnErrorTag());
222             assertEquals(msg, e.getMessage());
223             assertEquals(null, e.getCause());
224         }
225
226         // Empty name.
227         msg = "Flow condition name cannot be empty";
228         etag = RpcErrorTag.BAD_ELEMENT;
229         try {
230             FlowCondUtils.checkName("");
231             unexpected();
232         } catch (RpcException e) {
233             assertEquals(etag, e.getErrorTag());
234             assertEquals(vtag, e.getVtnErrorTag());
235             assertEquals(msg, e.getMessage());
236             assertEquals(null, e.getCause());
237         }
238
239         try {
240             FlowCondUtils.getVnodeName("");
241             unexpected();
242         } catch (RpcException e) {
243             assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
244             assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
245             assertEquals(": Flow condition does not exist.", e.getMessage());
246
247             Throwable cause = e.getCause();
248             assertTrue(cause instanceof RpcException);
249             RpcException re = (RpcException)cause;
250             assertEquals(etag, re.getErrorTag());
251             assertEquals(vtag, re.getVtnErrorTag());
252             assertEquals(msg, re.getMessage());
253             assertEquals(null, re.getCause());
254         }
255
256         try {
257             FlowCondUtils.getIdentifier("");
258             unexpected();
259         } catch (RpcException e) {
260             assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
261             assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
262             assertEquals(": Flow condition does not exist.", e.getMessage());
263
264             Throwable cause = e.getCause();
265             assertTrue(cause instanceof RpcException);
266             RpcException re = (RpcException)cause;
267             assertEquals(etag, re.getErrorTag());
268             assertEquals(vtag, re.getVtnErrorTag());
269             assertEquals(msg, re.getMessage());
270             assertEquals(null, re.getCause());
271         }
272
273         try {
274             FlowCondUtils.getIdentifier("", Integer.valueOf(1));
275             unexpected();
276         } catch (RpcException e) {
277             assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
278             assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
279             assertEquals(": Flow condition does not exist.", e.getMessage());
280
281             Throwable cause = e.getCause();
282             assertTrue(cause instanceof RpcException);
283             RpcException re = (RpcException)cause;
284             assertEquals(etag, re.getErrorTag());
285             assertEquals(vtag, re.getVtnErrorTag());
286             assertEquals(msg, re.getMessage());
287             assertEquals(null, re.getCause());
288         }
289
290         // Invalid name.
291         msg = "Flow condition name is invalid";
292         String[] invalidNames = {
293             "01234567890123456789012345678901",
294             "abcABC_0123_XXXXXXXXXXXXXXXXXXXX",
295             "_flow_cond",
296             "flow-cond",
297             "flow%cond",
298             "_",
299             " ",
300             "\u3042",
301         };
302         for (String name: invalidNames) {
303             try {
304                 FlowCondUtils.checkName(name);
305                 unexpected();
306             } catch (RpcException e) {
307                 assertEquals(etag, e.getErrorTag());
308                 assertEquals(vtag, e.getVtnErrorTag());
309                 assertEquals(msg, e.getMessage());
310                 Throwable cause = e.getCause();
311                 assertTrue(cause instanceof IllegalArgumentException);
312             }
313
314             try {
315                 FlowCondUtils.getVnodeName(name);
316                 unexpected();
317             } catch (RpcException e) {
318                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
319                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
320                 assertEquals(name + ": Flow condition does not exist.",
321                              e.getMessage());
322
323                 Throwable cause = e.getCause();
324                 assertTrue(cause instanceof RpcException);
325                 RpcException re = (RpcException)cause;
326                 assertEquals(etag, re.getErrorTag());
327                 assertEquals(vtag, re.getVtnErrorTag());
328                 assertEquals(msg, re.getMessage());
329                 cause = re.getCause();
330                 assertTrue(cause instanceof IllegalArgumentException);
331             }
332
333             try {
334                 FlowCondUtils.getIdentifier(name);
335                 unexpected();
336             } catch (RpcException e) {
337                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
338                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
339                 assertEquals(name + ": Flow condition does not exist.",
340                              e.getMessage());
341
342                 Throwable cause = e.getCause();
343                 assertTrue(cause instanceof RpcException);
344                 RpcException re = (RpcException)cause;
345                 assertEquals(etag, re.getErrorTag());
346                 assertEquals(vtag, re.getVtnErrorTag());
347                 assertEquals(msg, re.getMessage());
348                 cause = re.getCause();
349                 assertTrue(cause instanceof IllegalArgumentException);
350             }
351
352             try {
353                 FlowCondUtils.getIdentifier(name, Integer.valueOf(1));
354                 unexpected();
355             } catch (RpcException e) {
356                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
357                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
358                 assertEquals(name + ": Flow condition does not exist.",
359                              e.getMessage());
360
361                 Throwable cause = e.getCause();
362                 assertTrue(cause instanceof RpcException);
363                 RpcException re = (RpcException)cause;
364                 assertEquals(etag, re.getErrorTag());
365                 assertEquals(vtag, re.getVtnErrorTag());
366                 assertEquals(msg, re.getMessage());
367                 cause = re.getCause();
368                 assertTrue(cause instanceof IllegalArgumentException);
369             }
370         }
371
372         // getName() should return null if the given path does not contain a
373         // flow condition key.
374         SalPort sport = new SalPort(1L, 2L);
375         List<InstanceIdentifier<?>> list = new ArrayList<>();
376         list.add(sport.getNodeIdentifier());
377         list.add(sport.getNodeConnectorIdentifier());
378         list.add(sport.getVtnNodeIdentifier());
379         list.add(sport.getVtnPortIdentifier());
380         for (InstanceIdentifier<?> path: list) {
381             assertEquals(null, FlowCondUtils.getName(path));
382         }
383
384         VtnFlowConditionKey nullKey = new VtnFlowConditionKey((VnodeName)null);
385         InstanceIdentifier<VtnFlowCondition> path = InstanceIdentifier.
386             builder(VtnFlowConditions.class).
387             child(VtnFlowCondition.class, nullKey).build();
388         assertEquals(null, FlowCondUtils.getName(path));
389
390         InstanceIdentifier<VtnFlowMatch> mpath = InstanceIdentifier.
391             builder(VtnFlowConditions.class).
392             child(VtnFlowCondition.class, nullKey).
393             child(VtnFlowMatch.class, new VtnFlowMatchKey(1)).build();
394         assertEquals(null, FlowCondUtils.getName(mpath));
395     }
396
397     /**
398      * Test case for the following methods.
399      *
400      * <ul>
401      *   <li>{@link FlowCondUtils#verifyMatchIndex(Set, Integer)}</li>
402      *   <li>{@link FlowCondUtils#verifyMatchIndex(Integer)}</li>
403      * </ul>
404      *
405      * @throws Exception  An error occurred.
406      */
407     @Test
408     public void testMatchIndex() throws Exception {
409         Integer[] indices = {
410             1, 2, 3, 444, 1000, 2000, 3333, 44444, 55555, 65534, 65535,
411         };
412
413         Set<Integer> idxSet = new HashSet<>();
414         for (Integer index: indices) {
415             FlowCondUtils.verifyMatchIndex(index);
416             FlowCondUtils.verifyMatchIndex(idxSet, index);
417         }
418
419         // Index is null.
420         String msg = "Match index cannot be null";
421         RpcErrorTag etag = RpcErrorTag.MISSING_ELEMENT;
422         VtnErrorTag vtag = VtnErrorTag.BADREQUEST;
423         try {
424             FlowCondUtils.verifyMatchIndex(null);
425             unexpected();
426         } catch (RpcException e) {
427             assertEquals(etag, e.getErrorTag());
428             assertEquals(vtag, e.getVtnErrorTag());
429             assertEquals(msg, e.getMessage());
430             assertEquals(null, e.getCause());
431         }
432
433         // Invalid index.
434         Integer[] badIndices = {
435             Integer.MIN_VALUE, -10000000, -3000, -200, -3, -2, -1, 0,
436             65536, 65537, 70000, 1000000, Integer.MAX_VALUE,
437         };
438         etag = RpcErrorTag.BAD_ELEMENT;
439         for (Integer index: badIndices) {
440             msg = "Invalid match index: " + index;
441             try {
442                 FlowCondUtils.verifyMatchIndex(index);
443                 unexpected();
444             } catch (RpcException e) {
445                 assertEquals(etag, e.getErrorTag());
446                 assertEquals(vtag, e.getVtnErrorTag());
447                 assertEquals(msg, e.getMessage());
448
449                 Throwable cause = e.getCause();
450                 assertTrue(cause instanceof IllegalArgumentException);
451             }
452         }
453
454         // Duplicate index.
455         for (Integer index: indices) {
456             msg = "Duplicate match index: " + index;
457             try {
458                 FlowCondUtils.verifyMatchIndex(idxSet, index);
459                 unexpected();
460             } catch (RpcException e) {
461                 assertEquals(etag, e.getErrorTag());
462                 assertEquals(vtag, e.getVtnErrorTag());
463                 assertEquals(msg, e.getMessage());
464                 assertEquals(null, e.getCause());
465             }
466         }
467     }
468
469     /**
470      * Test case for {@link FlowCondUtils#isEmpty(VtnFlowConditions)}.
471      */
472     @Test
473     public void testIsEmpty() {
474         VtnFlowConditions root = null;
475         assertEquals(true, FlowCondUtils.isEmpty(root));
476
477         root = new VtnFlowConditionsBuilder().build();
478         assertEquals(true, FlowCondUtils.isEmpty(root));
479
480         List<VtnFlowCondition> vlist = new ArrayList<>();
481         root = new VtnFlowConditionsBuilder().
482             setVtnFlowCondition(vlist).build();
483         assertEquals(true, FlowCondUtils.isEmpty(root));
484
485         vlist.add(new VtnFlowConditionBuilder().build());
486         assertEquals(false, FlowCondUtils.isEmpty(root));
487     }
488
489     /**
490      * Test case for
491      * {@link FlowCondUtils#checkPresent(ReadTransaction, VnodeName)}.
492      *
493      * @throws Exception  An error occurred.
494      */
495     @Test
496     public void testCheckPresent() throws Exception {
497         // Set up mock-up of MD-SAL read transaction.
498         ReadTransaction rtx = Mockito.mock(ReadTransaction.class);
499         LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
500         List<VnodeName> names = new ArrayList<>();
501         List<InstanceIdentifier<VtnFlowCondition>> paths = new ArrayList<>();
502         Set<VnodeName> present = new HashSet<>();
503
504         for (int i = 0; i < 10; i++) {
505             String name = "present" + i;
506             VnodeName vname = new VnodeName(name);
507             names.add(vname);
508             assertEquals(true, present.add(vname));
509             VtnFlowCondition vfc = new VtnFlowConditionBuilder().
510                 setName(vname).build();
511             InstanceIdentifier<VtnFlowCondition> path =
512                 FlowCondUtils.getIdentifier(vname);
513             paths.add(path);
514             Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(vfc));
515         }
516
517         VtnFlowCondition vfcNull = null;
518         for (int i = 0; i < 10; i++) {
519             String name = "notfound" + i;
520             VnodeName vname = new VnodeName(name);
521             names.add(vname);
522             assertEquals(false, present.contains(vname));
523             InstanceIdentifier<VtnFlowCondition> path =
524                 FlowCondUtils.getIdentifier(vname);
525             paths.add(path);
526             Mockito.when(rtx.read(oper, path)).
527                 thenReturn(getReadResult(vfcNull));
528         }
529
530         for (VnodeName vname: names) {
531             try {
532                 FlowCondUtils.checkPresent(rtx, vname);
533                 assertEquals(true, present.contains(vname));
534             } catch (RpcException e) {
535                 assertEquals(false, present.contains(vname));
536                 assertEquals(null, e.getCause());
537                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
538                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
539                 String msg = vname.getValue() +
540                     ": Flow condition does not exist.";
541                 assertEquals(msg, e.getMessage());
542             }
543         }
544
545         for (InstanceIdentifier<VtnFlowCondition> path: paths) {
546             Mockito.verify(rtx).read(oper, path);
547         }
548     }
549
550     /**
551      * Test case for {@link FlowCondUtils#readFlowConditions(ReadTransaction)}.
552      *
553      * @throws Exception  An error occurred.
554      */
555     @Test
556     public void testReadConditions() throws Exception {
557         // Set up mock-up of MD-SAL read transaction.
558         ReadTransaction rtx = Mockito.mock(ReadTransaction.class);
559         LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
560         InstanceIdentifier<VtnFlowConditions> path =
561             InstanceIdentifier.create(VtnFlowConditions.class);
562
563         // Root container is not present.
564         VtnFlowConditions root = null;
565         List<VTNFlowCondition> expected = new ArrayList<>();
566         Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(root));
567         assertEquals(expected, FlowCondUtils.readFlowConditions(rtx));
568         Mockito.verify(rtx).read(oper, path);
569         Mockito.reset(rtx);
570
571         // Flow condition list is null.
572         root = new VtnFlowConditionsBuilder().build();
573         Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(root));
574         assertEquals(expected, FlowCondUtils.readFlowConditions(rtx));
575         Mockito.verify(rtx).read(oper, path);
576         Mockito.reset(rtx);
577
578         // Flow condition list is empty.
579         List<VtnFlowCondition> vlist = new ArrayList<>();
580         root = new VtnFlowConditionsBuilder().
581             setVtnFlowCondition(vlist).build();
582         Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(root));
583         assertEquals(expected, FlowCondUtils.readFlowConditions(rtx));
584         Mockito.verify(rtx).read(oper, path);
585         Mockito.reset(rtx);
586
587         // Flow conditions are present.
588         Map<FlowCondParams, FlowCondParams> cases =
589             FlowCondParams.createFlowConditions();
590         for (FlowCondParams params: cases.values()) {
591             vlist.add(params.toVtnFlowConditionBuilder().build());
592             expected.add(params.toVTNFlowCondition());
593         }
594         root = new VtnFlowConditionsBuilder().
595             setVtnFlowCondition(vlist).build();
596         Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(root));
597         assertEquals(expected, FlowCondUtils.readFlowConditions(rtx));
598         Mockito.verify(rtx).read(oper, path);
599         Mockito.reset(rtx);
600     }
601
602     /**
603      * Test case for
604      * {@link FlowCondUtils#readFlowCondition(ReadTransaction, String)}.
605      *
606      * @throws Exception  An error occurred.
607      */
608     @Test
609     public void testReadCondition() throws Exception {
610         // Set up mock-up of MD-SAL read transaction.
611         ReadTransaction rtx = Mockito.mock(ReadTransaction.class);
612         LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
613
614         // Null name.
615         try {
616             FlowCondUtils.readFlowCondition(rtx, (String)null);
617             unexpected();
618         } catch (RpcException e) {
619             assertEquals(RpcErrorTag.MISSING_ELEMENT, e.getErrorTag());
620             assertEquals(VtnErrorTag.BADREQUEST, e.getVtnErrorTag());
621             assertEquals("Flow condition name cannot be null", e.getMessage());
622         }
623
624         // Invalid name should be treated as if the specified flow condition
625         // is not present.
626         String[] invalidNames = {
627             "",
628             "01234567890123456789012345678901",
629             "abcABC_0123_XXXXXXXXXXXXXXXXXXXX",
630             "_flow_cond",
631             "flow-cond",
632             "flow%cond",
633             "_",
634             " ",
635             "\u3042",
636         };
637         for (String name: invalidNames) {
638             try {
639                 FlowCondUtils.readFlowCondition(rtx, name);
640                 unexpected();
641             } catch (RpcException e) {
642                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
643                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
644                 String msg = name + ": Flow condition does not exist.";
645                 assertEquals(msg, e.getMessage());
646             }
647         }
648         Mockito.verify(rtx, Mockito.never()).
649             read(Mockito.any(LogicalDatastoreType.class),
650                  (InstanceIdentifier<?>)Mockito.any(InstanceIdentifier.class));
651
652         // Flow condition is not present.
653         VtnFlowCondition vfc = null;
654         Map<FlowCondParams, FlowCondParams> cases =
655             FlowCondParams.createFlowConditions();
656         for (FlowCondParams params: cases.values()) {
657             String name = params.getName();
658             InstanceIdentifier<VtnFlowCondition> path =
659                 FlowCondUtils.getIdentifier(name);
660             Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(vfc));
661             try {
662                 FlowCondUtils.readFlowCondition(rtx, name);
663                 unexpected();
664             } catch (RpcException e) {
665                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
666                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
667                 String msg = name + ": Flow condition does not exist.";
668                 assertEquals(msg, e.getMessage());
669             }
670             Mockito.verify(rtx).read(oper, path);
671         }
672
673         // Flow condition is present.
674         for (FlowCondParams params: cases.values()) {
675             String name = params.getName();
676             InstanceIdentifier<VtnFlowCondition> path =
677                 FlowCondUtils.getIdentifier(name);
678             vfc = params.toVtnFlowConditionBuilder().build();
679             Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(vfc));
680             assertEquals(params.toVTNFlowCondition(),
681                          FlowCondUtils.readFlowCondition(rtx, name));
682             Mockito.verify(rtx, Mockito.times(2)).read(oper, path);
683         }
684     }
685
686     /**
687      * Test case for
688      * {@link FlowCondUtils#readFlowMatch(ReadTransaction, String, int)}.
689      *
690      * @throws Exception  An error occurred.
691      */
692     @Test
693     public void testReadMatch() throws Exception {
694         // Set up mock-up of MD-SAL read transaction.
695         ReadTransaction rtx = Mockito.mock(ReadTransaction.class);
696         LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
697
698         // Null name.
699         try {
700             FlowCondUtils.readFlowMatch(rtx, (String)null, 1);
701             unexpected();
702         } catch (RpcException e) {
703             assertEquals(RpcErrorTag.MISSING_ELEMENT, e.getErrorTag());
704             assertEquals(VtnErrorTag.BADREQUEST, e.getVtnErrorTag());
705             assertEquals("Flow condition name cannot be null", e.getMessage());
706         }
707
708         // Invalid name should be treated as if the specified flow condition
709         // is not present.
710         String[] invalidNames = {
711             "",
712             "01234567890123456789012345678901",
713             "abcABC_0123_XXXXXXXXXXXXXXXXXXXX",
714             "_flow_cond",
715             "flow-cond",
716             "flow%cond",
717             "_",
718             " ",
719             "\u3042",
720         };
721         for (String name: invalidNames) {
722             try {
723                 FlowCondUtils.readFlowMatch(rtx, name, 1);
724                 unexpected();
725             } catch (RpcException e) {
726                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
727                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
728                 String msg = name + ": Flow condition does not exist.";
729                 assertEquals(msg, e.getMessage());
730             }
731         }
732         Mockito.verify(rtx, Mockito.never()).
733             read(Mockito.any(LogicalDatastoreType.class),
734                  (InstanceIdentifier<?>)Mockito.any(InstanceIdentifier.class));
735
736         VtnFlowCondition vfc = new VtnFlowConditionBuilder().build();
737         VtnFlowCondition vfcNull = null;
738         VtnFlowMatch vfm = null;
739         Map<FlowMatchParams, FlowMatchParams> cases =
740             FlowMatchParams.createFlowMatches();
741         String name = "fcond";
742         InstanceIdentifier<VtnFlowCondition> fcPath =
743             FlowCondUtils.getIdentifier(name);
744         String msg = name + ": Flow condition does not exist.";
745         int fcCount = 0;
746         for (FlowMatchParams params: cases.values()) {
747             // Flow match is not present.
748             Integer index = params.getIndex();
749             InstanceIdentifier<VtnFlowMatch> path =
750                 FlowCondUtils.getIdentifier(name, index);
751             Mockito.when(rtx.read(oper, fcPath)).thenReturn(getReadResult(vfc));
752             Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(vfm));
753             assertEquals(null, FlowCondUtils.readFlowMatch(rtx, name, index));
754             fcCount++;
755             Mockito.verify(rtx, Mockito.times(fcCount)).read(oper, fcPath);
756             Mockito.verify(rtx).read(oper, path);
757
758             // Flow condition is not present.
759             Mockito.when(rtx.read(oper, fcPath)).
760                 thenReturn(getReadResult(vfcNull));
761             try {
762                 FlowCondUtils.readFlowMatch(rtx, name, index);
763                 unexpected();
764             } catch (RpcException e) {
765                 assertEquals(RpcErrorTag.DATA_MISSING, e.getErrorTag());
766                 assertEquals(VtnErrorTag.NOTFOUND, e.getVtnErrorTag());
767                 assertEquals(msg, e.getMessage());
768             }
769
770             fcCount++;
771             Mockito.verify(rtx, Mockito.times(fcCount)).read(oper, fcPath);
772             Mockito.verify(rtx, Mockito.times(2)).read(oper, path);
773         }
774
775         // Flow match is present.
776         for (FlowMatchParams params: cases.values()) {
777             Integer index = params.getIndex();
778             InstanceIdentifier<VtnFlowMatch> path =
779                 FlowCondUtils.getIdentifier(name, index);
780             vfm = params.toVtnFlowMatchBuilder().build();
781             Mockito.when(rtx.read(oper, path)).thenReturn(getReadResult(vfm));
782             assertEquals(params.toVTNFlowMatch(),
783                          FlowCondUtils.readFlowMatch(rtx, name, index));
784             Mockito.verify(rtx, Mockito.times(fcCount)).read(oper, fcPath);
785             Mockito.verify(rtx, Mockito.times(3)).read(oper, path);
786         }
787     }
788 }