c38771d939360e994035436c4ac103218c3f0018
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / test / java / org / opendaylight / controller / yang / model / parser / util / ModuleDependencySortTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  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 package org.opendaylight.controller.yang.model.parser.util;
9
10 import static org.hamcrest.core.AnyOf.anyOf;
11 import static org.hamcrest.core.Is.is;
12 import static org.junit.Assert.assertThat;
13 import static org.junit.matchers.JUnitMatchers.containsString;
14 import static org.mockito.Mockito.*;
15
16 import java.util.Date;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Map.Entry;
20 import java.util.Set;
21
22 import org.hamcrest.Matcher;
23 import org.junit.Test;
24 import org.opendaylight.controller.yang.model.api.ModuleImport;
25 import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
26 import org.opendaylight.controller.yang.model.parser.impl.YangParserListenerImpl;
27 import org.opendaylight.controller.yang.model.parser.util.ModuleDependencySort.ModuleNodeImpl;
28 import org.opendaylight.controller.yang.model.parser.util.ModuleDependencySort.ModuleSimple;
29 import org.opendaylight.controller.yang.model.parser.util.TopologicalSort.Edge;
30
31 import com.google.common.collect.Sets;
32
33 public class ModuleDependencySortTest {
34
35     private ModuleBuilder a = mockModule("a", null);
36     private ModuleBuilder b = mockModule("b", null);
37     private ModuleBuilder c = mockModule("c", null);
38     private ModuleBuilder d = mockModule("d", null);
39
40     @Test
41     public void testValid() throws Exception {
42
43         mockDependency(a, b);
44         mockDependency(b, c);
45         mockDependency(b, d);
46
47         ModuleBuilder[] builders = new ModuleBuilder[] { d, b, c, a };
48         ModuleDependencySort sort = new ModuleDependencySort(builders);
49
50         assertDependencyGraph(sort.getModuleGraph());
51
52         List<ModuleSimple> l = sort.sort();
53
54         @SuppressWarnings("unchecked")
55         Matcher<String> cOrD = anyOf(is(c.getName()), is(d.getName()));
56
57         assertThat(l.get(0).getName(), cOrD);
58         assertThat(l.get(1).getName(), cOrD);
59         assertThat(l.get(2).getName(), is(b.getName()));
60         assertThat(l.get(3).getName(), is(a.getName()));
61     }
62
63     @Test(expected = YangValidationException.class)
64     public void testModuleTwice() throws Exception {
65         ModuleBuilder a2 = mockModule("a", null);
66
67         ModuleBuilder[] builders = new ModuleBuilder[] { a, a2 };
68         try {
69             new ModuleDependencySort(builders);
70         } catch (YangValidationException e) {
71             assertThat(e.getMessage(),
72                     containsString("Module:a with revision:default declared twice"));
73             throw e;
74         }
75     }
76
77     @Test(expected = YangValidationException.class)
78     public void testImportNotExistingModule() throws Exception {
79         mockDependency(a, b);
80
81         ModuleBuilder[] builders = new ModuleBuilder[] { a };
82         try {
83             new ModuleDependencySort(builders);
84         } catch (YangValidationException e) {
85             assertThat(e.getMessage(),
86                     containsString("Not existing module imported:b:default by:a:default"));
87             throw e;
88         }
89     }
90
91     @Test
92     public void testImportTwice() throws Exception {
93         mockDependency(a, b);
94         mockDependency(c, b);
95
96         ModuleBuilder[] builders = new ModuleBuilder[] { a, b, c };
97         new ModuleDependencySort(builders);
98     }
99
100     @Test(expected = YangValidationException.class)
101     public void testImportTwiceDifferentRevision() throws Exception {
102         Date date = new Date();
103         ModuleBuilder b2 = mockModule("b", date);
104
105         mockDependency(a, b);
106         mockDependency(c, b2);
107
108         ModuleBuilder[] builders = new ModuleBuilder[] { a, c, b, b2 };
109         try {
110             ModuleDependencySort aaa = new ModuleDependencySort(builders);
111             System.out.println(aaa.getModuleGraph());
112         } catch (YangValidationException e) {
113             assertThat(e.getMessage(),
114                     containsString("Module:b imported twice with different revisions:default, "
115                             + YangParserListenerImpl.simpleDateFormat
116                                     .format(date)));
117             throw e;
118         }
119     }
120
121     @Test
122     public void testModuleTwiceWithDifferentRevs() throws Exception {
123         ModuleBuilder a2 = mockModule("a", new Date());
124
125         ModuleBuilder[] builders = new ModuleBuilder[] { a, a2 };
126         new ModuleDependencySort(builders);
127     }
128
129     @Test(expected = YangValidationException.class)
130     public void testModuleTwice2() throws Exception {
131         Date rev = new Date();
132         ModuleBuilder a2 = mockModule("a", rev);
133         ModuleBuilder a3 = mockModule("a", rev);
134
135         ModuleBuilder[] builders = new ModuleBuilder[] { a, a2, a3 };
136         try {
137             new ModuleDependencySort(builders);
138         } catch (YangValidationException e) {
139             assertThat(e.getMessage(), containsString("Module:a with revision:"
140                     + YangParserListenerImpl.simpleDateFormat.format(rev)
141                     + " declared twice"));
142             throw e;
143         }
144     }
145
146     private void assertDependencyGraph(
147             Map<String, Map<Date, ModuleNodeImpl>> moduleGraph) {
148         for (Entry<String, Map<Date, ModuleNodeImpl>> node : moduleGraph
149                 .entrySet()) {
150             String name = node.getKey();
151
152             // Expects only one module revision
153
154             Set<Edge> inEdges = node.getValue().values().iterator().next()
155                     .getInEdges();
156             Set<Edge> outEdges = node.getValue().values().iterator().next()
157                     .getOutEdges();
158
159             if (name.equals("a")) {
160                 assertEdgeCount(inEdges, 0, outEdges, 1);
161             } else if (name.equals("b")) {
162                 assertEdgeCount(inEdges, 1, outEdges, 2);
163             } else {
164                 assertEdgeCount(inEdges, 1, outEdges, 0);
165             }
166         }
167     }
168
169     private void assertEdgeCount(Set<Edge> inEdges, int i, Set<Edge> outEdges,
170             int j) {
171         assertThat(inEdges.size(), is(i));
172         assertThat(outEdges.size(), is(j));
173     }
174
175     private void mockDependency(ModuleBuilder a, ModuleBuilder b) {
176         ModuleImport imprt = mock(ModuleImport.class);
177         doReturn(b.getName()).when(imprt).getModuleName();
178         doReturn(b.getRevision()).when(imprt).getRevision();
179         a.getModuleImports().add(imprt);
180     }
181
182     private ModuleBuilder mockModule(String name, Date rev) {
183         ModuleBuilder a = mock(ModuleBuilder.class);
184         doReturn(name).when(a).getName();
185         Set<ModuleImport> set = Sets.newHashSet();
186         doReturn(set).when(a).getModuleImports();
187         if (rev != null) {
188             doReturn(rev).when(a).getRevision();
189         }
190         return a;
191     }
192 }