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