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.controller.config.yangjmxgenerator.plugin;
10 import static org.hamcrest.CoreMatchers.equalTo;
11 import static org.hamcrest.CoreMatchers.is;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.assertThat;
16 import static org.junit.Assert.assertTrue;
17 import static org.junit.Assert.fail;
18 import static org.junit.matchers.JUnitMatchers.containsString;
19 import static org.mockito.Matchers.any;
20 import static org.mockito.Mockito.doNothing;
21 import static org.mockito.Mockito.doReturn;
22 import static org.mockito.Mockito.mock;
25 import java.io.IOException;
26 import java.nio.charset.Charset;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.List;
36 import javax.xml.parsers.DocumentBuilder;
37 import javax.xml.parsers.DocumentBuilderFactory;
39 import org.apache.commons.io.FileUtils;
40 import org.apache.maven.plugin.logging.Log;
41 import org.apache.maven.project.MavenProject;
42 import org.eclipse.jdt.core.JavaCore;
43 import org.eclipse.jdt.core.compiler.IProblem;
44 import org.eclipse.jdt.core.dom.AST;
45 import org.eclipse.jdt.core.dom.ASTParser;
46 import org.eclipse.jdt.core.dom.ASTVisitor;
47 import org.eclipse.jdt.core.dom.CompilationUnit;
48 import org.eclipse.jdt.core.dom.FieldDeclaration;
49 import org.eclipse.jdt.core.dom.MethodDeclaration;
50 import org.eclipse.jdt.core.dom.NormalAnnotation;
51 import org.eclipse.jdt.core.dom.PackageDeclaration;
52 import org.eclipse.jdt.core.dom.TypeDeclaration;
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.opendaylight.controller.config.api.annotations.Description;
56 import org.opendaylight.controller.config.api.annotations.RequireInterface;
57 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
58 import org.opendaylight.controller.config.spi.Module;
59 import org.opendaylight.controller.config.spi.ModuleFactory;
60 import org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants;
61 import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslatorTest;
62 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntryTest;
63 import org.xml.sax.ErrorHandler;
64 import org.xml.sax.InputSource;
65 import org.xml.sax.SAXException;
66 import org.xml.sax.SAXParseException;
68 import com.google.common.base.Predicate;
69 import com.google.common.collect.Collections2;
70 import com.google.common.collect.Maps;
71 import com.google.common.collect.Sets;
72 import com.google.common.io.Files;
74 public class JMXGeneratorTest extends AbstractGeneratorTest {
76 JMXGenerator jmxGenerator;
78 protected final HashMap<String, String> map = Maps.newHashMap();
79 protected File outputBaseDir;
80 File generatedResourcesDir;
82 private static final List<String> expectedModuleFileNames = ServiceInterfaceEntryTest
83 .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, " +
84 "AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, " +
85 "AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, " +
86 "AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, " +
87 "AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, " +
88 "AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, " +
89 "AsyncEventBusRuntimeRegistrator.java, DynamicThreadPoolModule.java, " +
90 "DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, " +
91 "DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, " +
92 "DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, " +
93 "EventBusModuleMXBean.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, " +
94 "InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, " +
95 "NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, Peer.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
97 private static final List<String> expectedBGPNames = ServiceInterfaceEntryTest
98 .toFileNames("[AbstractBgpListenerImplModule.java, " + "AbstractBgpListenerImplModuleFactory.java, " +
99 "BgpListenerImplModule.java, " + "BgpListenerImplModuleFactory.java, " +
100 "BgpListenerImplModuleMXBean.java, Peers.java]");
102 private static final List<String> expectedNetconfNames = ServiceInterfaceEntryTest
103 .toFileNames("[AbstractNetconfTestImplModule.java, " + "AbstractNetconfTestImplModuleFactory.java, " +
104 "AbstractTestImplModule.java, " + "AbstractTestImplModuleFactory.java, " +
105 "AutoCloseableServiceInterface.java, " + "ComplexDtoBInner.java, ComplexList.java, Deep.java, " +
106 "DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, DtoC.java," + "NetconfTestImplModule.java, NetconfTestImplModuleFactory.java," + "NetconfTestImplModuleMXBean.java, Peer.java, SimpleList.java, TestImplModule.java, " + "TestImplModuleFactory.java," + " TestImplModuleMXBean.java" + "]");
107 private static final List<String> expectedTestFiles = ServiceInterfaceEntryTest
108 .toFileNames("[AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, " +
109 "AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, " +
110 "AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, " +
111 "AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, DtoA.java, " +
112 "DtoA.java, NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, " +
113 "NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, " +
114 "NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, " +
115 "NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, " +
116 "NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java]");
117 private static final List<String> expectedAllFileNames = ServiceInterfaceEntryTest
118 .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, " +
119 "AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, " +
120 "AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, " +
121 "AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, " +
122 "AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, " +
123 "AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, " +
124 "AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, " +
125 "AbstractNetconfTestImplModule.java, AbstractNetconfTestImplModuleFactory.java, " +
126 "AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, " +
127 "AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, " +
128 "AbstractTestImplModule.java, AbstractTestImplModuleFactory.java, AsyncEventBusModule.java, " +
129 "AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, " +
130 "AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, " +
131 "AsyncEventBusRuntimeRegistrator.java, AutoCloseableServiceInterface.java, " +
132 "BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java," +
133 " BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, " +
134 "BgpListenerImplRuntimeRegistrator.java, ComplexDtoBInner.java, ComplexList.java, Deep.java, " +
135 "DtoA.java, DtoA.java, DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, " +
136 "DtoC.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, " +
137 "DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, " +
138 "DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, " +
139 "EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, " +
140 "EventBusServiceInterface.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, " +
141 "InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, " +
142 "NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, " +
143 "NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, " +
144 "NetconfTestFileImplModule.java, NetconfTestFileImplModuleFactory.java, " +
145 "NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, " +
146 "NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, " +
147 "NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, " +
148 "NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, " +
149 "NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, NetconfTestImplModule.java, NetconfTestImplModuleFactory.java, NetconfTestImplModuleMXBean.java, NetconfTestImplRuntimeMXBean.java, NetconfTestImplRuntimeRegistration.java, NetconfTestImplRuntimeRegistrator.java, Peer.java, Peer.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java, ScheduledThreadPoolServiceInterface.java, SimpleList.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java, TestImplModule.java, TestImplModuleFactory.java, TestImplModuleMXBean.java, TestImplRuntimeMXBean.java, TestImplRuntimeRegistration.java, TestImplRuntimeRegistrator.java, ThreadFactoryServiceInterface.java, ThreadPoolServiceInterface.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]");
150 private static final List<String> expectedGenerateMBEsListNames = ServiceInterfaceEntryTest
151 .toFileNames("[AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java]");
154 public void setUp() {
155 map.put(JMXGenerator.NAMESPACE_TO_PACKAGE_PREFIX + "1",
156 ConfigConstants.CONFIG_NAMESPACE
157 + JMXGenerator.NAMESPACE_TO_PACKAGE_DIVIDER
158 + PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX);
159 map.put(JMXGenerator.MODULE_FACTORY_FILE_BOOLEAN, "false");
160 jmxGenerator = new JMXGenerator(new FreeMarkerCodeWriterImpl());
161 jmxGenerator.setAdditionalConfig(map);
162 File targetDir = new File(generatorOutputPath, "target");
163 generatedResourcesDir = new File(targetDir, "generated-resources");
164 jmxGenerator.setResourceBaseDir(generatedResourcesDir);
165 Log mockedLog = mock(Log.class);
166 doReturn(false).when(mockedLog).isDebugEnabled();
167 doNothing().when(mockedLog).debug(any(CharSequence.class));
168 doNothing().when(mockedLog).info(any(CharSequence.class));
169 doNothing().when(mockedLog).error(any(CharSequence.class),
170 any(Throwable.class));
171 jmxGenerator.setLog(mockedLog);
172 MavenProject project = mock(MavenProject.class);
173 doReturn(generatorOutputPath).when(project).getBasedir();
174 jmxGenerator.setMavenProject(project);
175 outputBaseDir = JMXGenerator.concatFolders(targetDir,
176 "generated-sources", "config");
180 public void generateSIsMBsTest() {
181 Collection<File> files = jmxGenerator.generateSources(context,
182 outputBaseDir, context.getModules());
183 List<String> expectedFileNames = new ArrayList<>();
185 .addAll(ServiceInterfaceEntryTest.expectedSIEFileNames);
186 expectedFileNames.addAll(expectedModuleFileNames);
188 expectedFileNames.addAll(expectedBGPNames);
189 expectedFileNames.addAll(expectedNetconfNames);
190 expectedFileNames.addAll(expectedTestFiles);
191 Collections.sort(expectedFileNames);
192 // TODO: separate expectedAllFileNames into expectedBGPNames,
193 // expectedNetconfNames
194 assertEquals(expectedAllFileNames, toFileNames(files));
196 verifyModuleFactoryFile(false);
199 private void verifyModuleFactoryFile(boolean shouldBePresent) {
200 File factoryFile = new File(generatedResourcesDir, "META-INF"
201 + File.separator + "services" + File.separator
202 + ModuleFactory.class.getName());
203 if (!shouldBePresent)
204 assertFalse("Factory file should not be generated",
205 factoryFile.exists());
207 assertTrue("Factory file should be generated", factoryFile.exists());
210 public static List<String> toFileNames(Collection<File> files) {
211 List<String> result = new ArrayList<>();
212 for (File f : files) {
213 result.add(f.getName());
215 Collections.sort(result);
220 public void generateSIEsTest() throws IOException {
221 Collection<File> files = jmxGenerator.generateSources(context,
222 outputBaseDir, Sets.newHashSet(threadsModule));
223 assertEquals(ServiceInterfaceEntryTest.expectedSIEFileNames,
226 Map<String, ASTVisitor> verifiers = Maps.newHashMap();
228 for (File file : files) {
229 verifiers.put(file.getName(), new SieASTVisitor());
232 processGeneratedCode(files, verifiers);
234 for (File file : files) {
235 String fileName = file.getName();
236 SieASTVisitor verifier = (SieASTVisitor) verifiers.get(fileName);
238 assertEquals(fileName.substring(0, fileName.length() - 5),
242 containsString("org.opendaylight.controller.config.api.annotations.AbstractServiceInterface"));
243 assertEquals(PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
244 + ".threads", verifier.packageName);
245 assertNotNull(verifier.javadoc);
247 if ("ThreadPoolServiceInterface.java".equals(fileName)) {
248 assertContains(verifier.descriptionAnotValue,
249 "A simple pool of threads able to execute work.");
250 assertContains(verifier.sieAnnotValue, "threadpool");
251 assertContains(verifier.sieAnnotOsgiRegistrationType,
252 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
253 + ".threadpool.ThreadPool.class");
254 } else if ("ScheduledThreadPoolServiceInterface.java"
256 assertContains(verifier.extnds,
257 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
258 + ".threads.ThreadPoolServiceInterface");
260 verifier.descriptionAnotValue,
261 "An extension of the simple pool of threads able to schedule work to be executed at some point in time.");
262 assertContains(verifier.sieAnnotValue, "scheduled-threadpool");
263 assertContains(verifier.sieAnnotOsgiRegistrationType,
264 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
265 + ".threadpool.ScheduledThreadPool.class");
266 } else if ("EventBusServiceInterface.java".equals(fileName)) {
268 verifier.descriptionAnotValue,
269 "Service representing an event bus. The service acts as message router between event producers and event consumers");
270 assertContains(verifier.sieAnnotValue, "eventbus");
271 assertContains(verifier.sieAnnotOsgiRegistrationType,
272 "com.google.common.eventbus.EventBus.class");
273 } else if ("ThreadFactoryServiceInterface.java".equals(fileName)) {
275 verifier.descriptionAnotValue,
276 "Service representing a ThreadFactory instance. It is directly useful in Java world, where various library pieces need to create threads and you may want to inject a customized thread implementation.");
277 assertContains(verifier.sieAnnotValue, "threadfactory");
278 assertContains(verifier.sieAnnotOsgiRegistrationType,
279 "java.util.concurrent.ThreadFactory.class");
281 } else if ("ScheduledExecutorServiceServiceInterface.java"
283 assertContains(verifier.sieAnnotOsgiRegistrationType,
284 "java.util.concurrent.ScheduledExecutorService.class");
286 fail("Unknown generated sie " + fileName);
292 public void generateMBEsListTest() throws Exception {
293 // default value for module factory file is true
294 map.put(JMXGenerator.MODULE_FACTORY_FILE_BOOLEAN, "randomValue");
295 jmxGenerator.setAdditionalConfig(map);
297 Collection<File> files = jmxGenerator.generateSources(context,
298 outputBaseDir, Sets.newHashSet(bgpListenerJavaModule));
300 assertEquals(expectedGenerateMBEsListNames, toFileNames(files));
304 public void generateMBEsTest() throws Exception {
305 // default value for module factory file is true
306 map.put(JMXGenerator.MODULE_FACTORY_FILE_BOOLEAN, "randomValue");
307 jmxGenerator.setAdditionalConfig(map);
309 Collection<File> files = jmxGenerator.generateSources(context,
310 outputBaseDir, Sets.newHashSet(threadsJavaModule));
312 assertEquals(expectedModuleFileNames, toFileNames(files));
314 Map<String, ASTVisitor> verifiers = Maps.newHashMap();
316 Collection<File> xmlFiles = Collections2.filter(files,
317 new Predicate<File>() {
320 public boolean apply(File input) {
321 return input.getName().endsWith("xml");
325 Collection<File> javaFiles = Collections2.filter(files,
326 new Predicate<File>() {
329 public boolean apply(File input) {
330 return input.getName().endsWith("java");
334 MbeASTVisitor abstractDynamicThreadPoolModuleVisitor = null;
335 MbeASTVisitor asyncEventBusModuleMXBeanVisitor = null;
336 MbeASTVisitor abstractNamingThreadFactoryModuleFactoryVisitor = null;
337 MbeASTVisitor asyncEventBusModuleVisitor = null;
338 MbeASTVisitor eventBusModuleFactoryVisitor = null;
340 for (File file : javaFiles) {
341 String name = file.getName();
342 MbeASTVisitor visitor = new MbeASTVisitor();
343 verifiers.put(name, visitor);
344 if (name.equals("AbstractDynamicThreadPoolModule.java"))
345 abstractDynamicThreadPoolModuleVisitor = visitor;
346 if (name.equals("AsyncEventBusModuleMXBean.java"))
347 asyncEventBusModuleMXBeanVisitor = visitor;
348 if (name.equals("AbstractNamingThreadFactoryModuleFactory.java"))
349 abstractNamingThreadFactoryModuleFactoryVisitor = visitor;
350 if (name.equals("AsyncEventBusModule.java"))
351 asyncEventBusModuleVisitor = visitor;
352 if (name.equals("EventBusModuleFactory.java"))
353 eventBusModuleFactoryVisitor = visitor;
356 processGeneratedCode(javaFiles, verifiers);
358 assertAbstractDynamicThreadPoolModule(abstractDynamicThreadPoolModuleVisitor);
359 assertAsyncEventBusModuleMXBean(asyncEventBusModuleMXBeanVisitor);
360 assertAbstractNamingThreadFactoryModuleFactory(abstractNamingThreadFactoryModuleFactoryVisitor);
361 assertAsyncEventBusModule(asyncEventBusModuleVisitor);
362 assertEventBusModuleFactory(eventBusModuleFactoryVisitor);
364 verifyXmlFiles(xmlFiles);
365 // verify ModuleFactory file
366 File moduleFactoryFile = JMXGenerator.concatFolders(
367 generatedResourcesDir, "META-INF", "services",
368 ModuleFactory.class.getName());
369 assertThat(moduleFactoryFile.exists(), is(true));
370 Set<String> lines = Sets.newHashSet(FileUtils
371 .readLines(moduleFactoryFile));
372 Set<String> expectedLines = Sets.newHashSet(//
373 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
374 + ".threads.java.EventBusModuleFactory",//
375 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
376 + ".threads.java.AsyncEventBusModuleFactory", //
377 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
378 + ".threads.java.DynamicThreadPoolModuleFactory",//
379 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
380 + ".threads.java.NamingThreadFactoryModuleFactory");
381 assertThat(lines, equalTo(expectedLines));
385 private void verifyXmlFiles(Collection<File> xmlFiles) throws Exception {
386 ErrorHandler errorHandler = new ErrorHandler() {
389 public void warning(SAXParseException exception)
390 throws SAXException {
391 fail("Generated blueprint xml is not well formed "
392 + exception.getMessage());
396 public void fatalError(SAXParseException exception)
397 throws SAXException {
398 fail("Generated blueprint xml is not well formed "
399 + exception.getMessage());
403 public void error(SAXParseException exception) throws SAXException {
404 fail("Generated blueprint xml is not well formed "
405 + exception.getMessage());
409 for (File file : xmlFiles) {
410 DocumentBuilderFactory factory = DocumentBuilderFactory
412 factory.setValidating(false);
413 factory.setNamespaceAware(true);
415 DocumentBuilder builder = factory.newDocumentBuilder();
417 builder.setErrorHandler(errorHandler);
418 builder.parse(new InputSource(file.getPath()));
423 private void assertEventBusModuleFactory(MbeASTVisitor visitor) {
424 assertEquals(PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
425 + ".threads.java", visitor.packageName);
426 assertEquals("EventBusModuleFactory", visitor.type);
427 assertContains(visitor.extnds,
428 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
429 + ".threads.java.AbstractEventBusModuleFactory");
431 assertEquals(0, visitor.fieldDeclarations.size());
433 assertEquals("Incorrenct number of generated methods", 0,
434 visitor.methods.size());
435 assertEquals("Incorrenct number of generated constructors", 0,
436 visitor.constructors.size());
437 assertEquals("Incorrenct number of generated method descriptions", 0,
438 visitor.methodDescriptions.size());
439 assertEquals("Incorrenct number of generated method javadoc", 0,
440 visitor.methodJavadoc.size());
443 private void assertAsyncEventBusModule(MbeASTVisitor visitor) {
444 assertEquals(PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
445 + ".threads.java", visitor.packageName);
446 assertEquals("AsyncEventBusModule", visitor.type);
447 assertContains(visitor.extnds,
448 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
449 + ".threads.java.AbstractAsyncEventBusModule");
451 assertEquals(0, visitor.fieldDeclarations.size());
453 assertEquals("Incorrenct number of generated methods", 2,
454 visitor.methods.size());
455 assertEquals("Incorrenct number of generated constructors", 2,
456 visitor.constructors.size());
457 assertEquals("Incorrenct number of generated method descriptions", 0,
458 visitor.methodDescriptions.size());
459 assertEquals("Incorrenct number of generated method javadoc", 0,
460 visitor.methodJavadoc.size());
463 private void assertAbstractNamingThreadFactoryModuleFactory(
464 MbeASTVisitor visitor) {
465 assertEquals(PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
466 + ".threads.java", visitor.packageName);
467 assertEquals("AbstractNamingThreadFactoryModuleFactory", visitor.type);
468 assertContains(visitor.implmts,
469 "org.opendaylight.controller.config.spi.ModuleFactory");
470 Set<String> fieldDeclarations = visitor.fieldDeclarations;
471 assertDeclaredField(fieldDeclarations,
472 "public static final java.lang.String NAME=\"threadfactory-naming\"");
475 "private static final java.util.Set<Class<? extends org.opendaylight.controller.config.api.annotations.AbstractServiceInterface>> serviceIfcs=new java.util.HashSet<Class<? extends org.opendaylight.controller.config.api.annotations.AbstractServiceInterface>>()");
477 assertEquals(2, fieldDeclarations.size());
479 assertEquals("Incorrenct number of generated methods", 5,
480 visitor.methods.size());
481 assertEquals("Incorrenct number of generated method descriptions", 0,
482 visitor.methodDescriptions.size());
483 assertEquals("Incorrenct number of generated method javadoc", 0,
484 visitor.methodJavadoc.size());
488 private void assertAsyncEventBusModuleMXBean(MbeASTVisitor visitor) {
489 assertEquals(PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
490 + ".threads.java", visitor.packageName);
491 assertEquals("AsyncEventBusModuleMXBean", visitor.type);
493 assertEquals("Incorrenct number of generated methods", 2,
494 visitor.methods.size());
497 private void assertAbstractDynamicThreadPoolModule(MbeASTVisitor visitor) {
498 assertEquals(PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
499 + ".threads.java", visitor.packageName);
500 assertNotNull(visitor.javadoc);
501 assertContains(visitor.descriptionAnotValue,
502 "threadpool-dynamic description");
503 assertEquals("AbstractDynamicThreadPoolModule", visitor.type);
504 assertContains(visitor.implmts,
505 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
506 + ".threads.java.DynamicThreadPoolModuleMXBean",
507 Module.class.getCanonicalName(),
508 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
509 + ".threads.ScheduledThreadPoolServiceInterface",
510 PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
511 + ".threads.ThreadPoolServiceInterface");
512 assertEquals(2, visitor.constructors.size());
513 Set<String> fieldDeclarations = visitor.fieldDeclarations;
514 assertDeclaredField(fieldDeclarations,
515 "private java.lang.Long maximumSize");
516 assertDeclaredField(fieldDeclarations,
517 "private javax.management.ObjectName threadfactory");
518 assertDeclaredField(fieldDeclarations,
519 "private java.util.concurrent.ThreadFactory threadfactoryDependency");
520 assertDeclaredField(fieldDeclarations,
521 "private java.lang.Long keepAlive=10");
522 assertDeclaredField(fieldDeclarations,
523 "private java.lang.Long coreSize");
524 assertDeclaredField(fieldDeclarations, "private byte[] binary");
525 assertEquals(22, fieldDeclarations.size());
527 assertEquals(1, visitor.requireIfc.size());
528 String reqIfc = visitor.requireIfc.get("setThreadfactory");
529 assertNotNull("Missing generated setter for threadfactory", reqIfc);
530 assertContains(reqIfc, PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX
531 + ".threads.ThreadFactoryServiceInterface");
533 assertEquals("Incorrenct number of generated methods", 24,
534 visitor.methods.size());
535 assertEquals("Incorrenct number of generated method descriptions", 3,
536 visitor.methodDescriptions.size());
537 assertEquals("Incorrenct number of generated method javadoc", 3,
538 visitor.methodJavadoc.size());
539 assertNotNull("Missing javadoc for setMaximumSize method",
540 visitor.methodJavadoc.get("setMaximumSize"));
543 private void assertDeclaredField(Set<String> fieldDeclarations,
544 String declaration) {
545 assertTrue("Missing field " + declaration + ", got: "
547 fieldDeclarations.contains(declaration + ";\n"));
550 private static class SieASTVisitor extends ASTVisitor {
551 protected String packageName, descriptionAnotValue, sieAnnotValue,
552 sieAnnotOsgiRegistrationType, type, extnds, javadoc;
553 protected Map<String, String> methodDescriptions = Maps.newHashMap();
556 public boolean visit(PackageDeclaration node) {
557 packageName = node.getName().toString();
558 return super.visit(node);
562 public boolean visit(NormalAnnotation node) {
563 if (node.getTypeName().toString()
564 .equals(Description.class.getCanonicalName())) {
565 if (node.getParent() instanceof TypeDeclaration) {
566 descriptionAnotValue = node.values().get(0).toString();
567 } else if (node.getParent() instanceof MethodDeclaration) {
568 String descr = node.values().get(0).toString();
569 methodDescriptions.put(((MethodDeclaration) node
570 .getParent()).getName().toString(), descr);
575 .equals(ServiceInterfaceAnnotation.class.getCanonicalName())) {
576 String text1 = node.values().get(0).toString();
577 String text2 = node.values().get(1).toString();
578 if (text1.contains("value")) {
579 sieAnnotValue = text1;
580 sieAnnotOsgiRegistrationType = text2;
582 sieAnnotValue = text2;
583 sieAnnotOsgiRegistrationType = text1;
586 return super.visit(node);
590 public boolean visit(TypeDeclaration node) {
591 javadoc = node.getJavadoc() == null ? null : node.getJavadoc()
593 type = node.getName().toString();
594 List<?> superIfcs = node.superInterfaceTypes();
595 extnds = superIfcs != null && !superIfcs.isEmpty() ? superIfcs
597 return super.visit(node);
601 private static class MbeASTVisitor extends SieASTVisitor {
602 private String implmts;
603 private final Set<String> fieldDeclarations = Sets.newHashSet();
604 private final Set<String> constructors = Sets.newHashSet();
605 private final Map<String, String> methods = Maps.newHashMap();
606 private final Map<String, String> requireIfc = Maps.newHashMap();
607 private final Map<String, String> methodJavadoc = Maps.newHashMap();
610 public boolean visit(NormalAnnotation node) {
611 boolean result = super.visit(node);
612 if (node.getTypeName().toString()
613 .equals(RequireInterface.class.getCanonicalName())
614 && node.getParent() instanceof MethodDeclaration) {
615 // remember only top level description annotation
616 String reqVal = node.values().get(0).toString();
617 requireIfc.put(((MethodDeclaration) node.getParent()).getName()
618 .toString(), reqVal);
624 public boolean visit(FieldDeclaration node) {
625 fieldDeclarations.add(node.toString());
626 return super.visit(node);
630 public boolean visit(MethodDeclaration node) {
631 if (node.isConstructor())
632 constructors.add(node.toString());
634 String methodName = node.getName().toString();
635 if (node.getJavadoc() != null)
636 methodJavadoc.put(methodName, node.getJavadoc().toString());
637 methods.put(methodName, node.toString());
639 return super.visit(node);
643 public boolean visit(TypeDeclaration node) {
644 boolean visit = super.visit(node);
645 List<?> superIfcs = node.superInterfaceTypes();
646 implmts = superIfcs != null && !superIfcs.isEmpty() ? superIfcs
648 extnds = node.getSuperclassType() == null ? null : node
649 .getSuperclassType().toString();
655 private void assertContains(String source, String... contained) {
656 for (String string : contained) {
657 assertThat(source, containsString(string));
661 private void processGeneratedCode(Collection<File> files,
662 Map<String, ASTVisitor> verifiers) throws IOException {
663 ASTParser parser = ASTParser.newParser(AST.JLS3);
664 Map<?, ?> options = JavaCore.getOptions();
665 JavaCore.setComplianceOptions(JavaCore.VERSION_1_7, options);
666 parser.setCompilerOptions(options);
668 parser.setKind(ASTParser.K_COMPILATION_UNIT);
670 for (File file : files) {
671 char[] source = readFileAsChars(file);
672 parser.setSource(source);
673 parser.setResolveBindings(true);
675 CompilationUnit cu = (CompilationUnit) parser.createAST(null);
676 // Check for compilation problems in generated file
677 for (IProblem c : cu.getProblems()) {
678 // 1610613332 = Syntax error, annotations are only available if
679 // source level is 5.0
680 if (c.getID() == 1610613332)
682 // 1610613332 = Syntax error, parameterized types are only
683 // available if source level is 5.0
684 if (c.getID() == 1610613329)
686 fail("Error in generated source code " + file + ":"
687 + c.getSourceLineNumber() + " " + c.toString());
690 ASTVisitor visitor = verifiers.get(file.getName());
692 fail("Unknown generated file " + file.getName());
698 public static char[] readFileAsChars(File file) throws IOException {
699 List<String> readLines = Files
700 .readLines(file, Charset.forName("utf-8"));
701 char[] retVal = new char[0];
702 for (String string : readLines) {
703 char[] line = string.toCharArray();
704 int beforeLength = retVal.length;
705 retVal = Arrays.copyOf(retVal, retVal.length + line.length + 1);
706 System.arraycopy(line, 0, retVal, beforeLength, line.length);
707 retVal[retVal.length - 1] = '\n';