2 * Copyright (c) 2013 Cisco Systems, Inc. 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.parser.util;
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;
18 import com.google.common.collect.Sets;
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;
28 import java.util.Map.Entry;
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;
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);
47 public void testValid() throws Exception {
53 ModuleBuilder[] builders = new ModuleBuilder[] { d, b, c, a };
55 List<ModuleBuilder> l = ModuleDependencySort.sort(builders);
57 assertDependencyGraph(ModuleDependencySort.createModuleGraph(ModuleOrModuleBuilder.fromAll(
58 Collections.<Module>emptySet(), Arrays.asList(builders))));
60 Matcher<String> cOrD = anyOf(equalTo(c.getName()), equalTo(d.getName()));
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());
69 public void testValidModule() throws Exception {
71 Date rev = new Date();
72 Module a = mockModule("a", rev);
73 Module b = mockModule("b", rev);
74 Module c = mockModule("c", rev);
80 Module[] builders = new Module[] { a, b, c };
82 List<Module> l = ModuleDependencySort.sort(builders);
84 assertEquals(c.getName(), l.get(0).getName());
85 assertEquals(b.getName(), l.get(1).getName());
86 assertEquals(a.getName(), l.get(2).getName());
89 @Test(expected = YangValidationException.class)
90 public void testModuleTwice() throws Exception {
91 ModuleBuilder a2 = mockModuleBuilder("a", null);
93 ModuleBuilder[] builders = new ModuleBuilder[] { a, a2 };
95 ModuleDependencySort.sort(builders);
96 } catch (YangValidationException e) {
97 assertThat(e.getMessage(), containsString("Module:a with revision:default declared twice"));
102 @Test(expected = YangValidationException.class)
103 public void testImportNotExistingModule() throws Exception {
104 mockDependency(a, b);
106 ModuleBuilder[] builders = new ModuleBuilder[] { a };
108 ModuleDependencySort.sort(builders);
109 } catch (YangValidationException e) {
110 assertThat(e.getMessage(), containsString("Not existing module imported:b:default by:a:default"));
116 public void testImportTwice() throws Exception {
117 mockDependency(a, b);
118 mockDependency(c, b);
120 ModuleBuilder[] builders = new ModuleBuilder[] { a, b, c };
121 ModuleDependencySort.sort(builders);
125 public void testModuleTwiceWithDifferentRevs() throws Exception {
126 ModuleBuilder a2 = mockModuleBuilder("a", new Date());
128 ModuleBuilder[] builders = new ModuleBuilder[] { a, a2 };
129 ModuleDependencySort.sort(builders);
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);
138 ModuleBuilder[] builders = new ModuleBuilder[] { a, a2, a3 };
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"));
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();
152 // Expects only one module revision
154 Set<Edge> inEdges = node.getValue().values().iterator().next().getInEdges();
155 Set<Edge> outEdges = node.getValue().values().iterator().next().getOutEdges();
157 if (name.equals("a")) {
158 assertEdgeCount(inEdges, 0, outEdges, 1);
159 } else if (name.equals("b")) {
160 assertEdgeCount(inEdges, 1, outEdges, 2);
162 assertEdgeCount(inEdges, 1, outEdges, 0);
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());
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);
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);
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();
193 doReturn(rev).when(a).getRevision();
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();
204 doReturn(rev).when(a).getRevision();