Merge "Fixed incorrect test location."
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / 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.yangtools.yang.parser.util;
9
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.hamcrest.core.AnyOf.anyOf;
12 import static org.hamcrest.core.IsEqual.equalTo;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertThat;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
17
18 import com.google.common.collect.Sets;
19
20 import java.text.DateFormat;
21 import java.text.SimpleDateFormat;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Map.Entry;
29 import java.util.Set;
30
31 import org.hamcrest.Matcher;
32 import org.junit.Test;
33 import org.opendaylight.yangtools.yang.model.api.Module;
34 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
35 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
36 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort.ModuleNodeImpl;
37 import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Edge;
38
39 public class ModuleDependencySortTest {
40     private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
41     private final ModuleBuilder a = mockModuleBuilder("a", null);
42     private final ModuleBuilder b = mockModuleBuilder("b", null);
43     private final ModuleBuilder c = mockModuleBuilder("c", null);
44     private final ModuleBuilder d = mockModuleBuilder("d", null);
45
46     @Test
47     public void testValid() throws Exception {
48
49         mockDependency(a, b);
50         mockDependency(b, c);
51         mockDependency(b, d);
52
53         ModuleBuilder[] builders = new ModuleBuilder[] { d, b, c, a };
54
55         List<ModuleBuilder> l = ModuleDependencySort.sort(builders);
56
57         assertDependencyGraph(ModuleDependencySort.createModuleGraph(ModuleOrModuleBuilder.fromAll(
58                 Collections.<Module>emptySet(), Arrays.asList(builders))));
59
60         Matcher<String> cOrD = anyOf(equalTo(c.getName()), equalTo(d.getName()));
61
62         assertThat(l.get(0).getName(), cOrD);
63         assertThat(l.get(1).getName(), cOrD);
64         assertEquals(b.getName(), l.get(2).getName());
65         assertEquals(a.getName(), l.get(3).getName());
66     }
67
68     @Test
69     public void testValidModule() throws Exception {
70
71         Date rev = new Date();
72         Module a = mockModule("a", rev);
73         Module b = mockModule("b", rev);
74         Module c = mockModule("c", rev);
75
76         mockDependency(a, b);
77         mockDependency(b, c);
78         mockDependency(a, c);
79
80         Module[] builders = new Module[] { a, b, c };
81
82         List<Module> l = ModuleDependencySort.sort(builders);
83
84         assertEquals(c.getName(), l.get(0).getName());
85         assertEquals(b.getName(), l.get(1).getName());
86         assertEquals(a.getName(), l.get(2).getName());
87     }
88
89     @Test(expected = YangValidationException.class)
90     public void testModuleTwice() throws Exception {
91         ModuleBuilder a2 = mockModuleBuilder("a", null);
92
93         ModuleBuilder[] builders = new ModuleBuilder[] { a, a2 };
94         try {
95             ModuleDependencySort.sort(builders);
96         } catch (YangValidationException e) {
97             assertThat(e.getMessage(), containsString("Module:a with revision:default declared twice"));
98             throw e;
99         }
100     }
101
102     @Test(expected = YangValidationException.class)
103     public void testImportNotExistingModule() throws Exception {
104         mockDependency(a, b);
105
106         ModuleBuilder[] builders = new ModuleBuilder[] { a };
107         try {
108             ModuleDependencySort.sort(builders);
109         } catch (YangValidationException e) {
110             assertThat(e.getMessage(), 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
125     public void testModuleTwiceWithDifferentRevs() throws Exception {
126         ModuleBuilder a2 = mockModuleBuilder("a", new Date());
127
128         ModuleBuilder[] builders = new ModuleBuilder[] { a, a2 };
129         ModuleDependencySort.sort(builders);
130     }
131
132     @Test(expected = YangValidationException.class)
133     public void testModuleTwice2() throws Exception {
134         Date rev = new Date();
135         ModuleBuilder a2 = mockModuleBuilder("a", rev);
136         ModuleBuilder a3 = mockModuleBuilder("a", rev);
137
138         ModuleBuilder[] builders = new ModuleBuilder[] { a, a2, a3 };
139         try {
140             ModuleDependencySort.sort(builders);
141         } catch (YangValidationException e) {
142             assertThat(e.getMessage(), containsString("Module:a with revision:" + SIMPLE_DATE_FORMAT.format(rev)
143                     + " declared twice"));
144             throw e;
145         }
146     }
147
148     private void assertDependencyGraph(final Map<String, Map<Date, ModuleNodeImpl>> moduleGraph) {
149         for (Entry<String, Map<Date, ModuleNodeImpl>> node : moduleGraph.entrySet()) {
150             String name = node.getKey();
151
152             // Expects only one module revision
153
154             Set<Edge> inEdges = node.getValue().values().iterator().next().getInEdges();
155             Set<Edge> outEdges = node.getValue().values().iterator().next().getOutEdges();
156
157             if (name.equals("a")) {
158                 assertEdgeCount(inEdges, 0, outEdges, 1);
159             } else if (name.equals("b")) {
160                 assertEdgeCount(inEdges, 1, outEdges, 2);
161             } else {
162                 assertEdgeCount(inEdges, 1, outEdges, 0);
163             }
164         }
165     }
166
167     private void assertEdgeCount(final Set<Edge> inEdges, final int i, final Set<Edge> outEdges, final int j) {
168         assertEquals(i, inEdges.size());
169         assertEquals(j, outEdges.size());
170     }
171
172     private void mockDependency(final ModuleBuilder a, final ModuleBuilder b) {
173         ModuleImport imprt = mock(ModuleImport.class);
174         doReturn(b.getName()).when(imprt).getModuleName();
175         doReturn(b.getName()).when(imprt).getPrefix();
176         doReturn(b.getRevision()).when(imprt).getRevision();
177         a.getImports().put(b.getName(), imprt);
178     }
179
180     private void mockDependency(final Module a, final Module b) {
181         ModuleImport imprt = mock(ModuleImport.class);
182         doReturn(b.getName()).when(imprt).getModuleName();
183         doReturn(b.getRevision()).when(imprt).getRevision();
184         a.getImports().add(imprt);
185     }
186
187     private ModuleBuilder mockModuleBuilder(final String name, final Date rev) {
188         ModuleBuilder a = mock(ModuleBuilder.class);
189         doReturn(name).when(a).getName();
190         Map<String, ModuleImport> map = new HashMap<>();
191         doReturn(map).when(a).getImports();
192         if (rev != null) {
193             doReturn(rev).when(a).getRevision();
194         }
195         return a;
196     }
197
198     private Module mockModule(final String name, final Date rev) {
199         Module a = mock(Module.class);
200         doReturn(name).when(a).getName();
201         Set<ModuleImport> set = Sets.newHashSet();
202         doReturn(set).when(a).getImports();
203         if (rev != null) {
204             doReturn(rev).when(a).getRevision();
205         }
206         return a;
207     }
208 }