1 package org.opendaylight.controller.northbound.bundlescanner.internal;
6 import java.io.FileFilter;
7 import java.net.MalformedURLException;
8 import java.net.URISyntaxException;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.Dictionary;
13 import java.util.Enumeration;
14 import java.util.HashSet;
15 import java.util.Hashtable;
16 import java.util.List;
18 import java.util.regex.Pattern;
20 import org.junit.AfterClass;
21 import org.junit.Before;
22 import org.junit.BeforeClass;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.junit.rules.TestName;
26 import org.osgi.framework.Bundle;
27 import org.osgi.framework.BundleContext;
28 import org.osgi.framework.BundleEvent;
29 import org.osgi.framework.Constants;
30 import org.springframework.osgi.mock.MockBundle;
31 import org.springframework.osgi.mock.MockBundleContext;
33 import static junit.framework.Assert.assertNotNull;
34 import static org.junit.Assert.assertFalse;
35 import static org.junit.Assert.assertTrue;
37 public class BundleScannerTest {
39 private static BundleScanner bundleScanner;
40 private static List<Bundle> bundles;
42 public final TestName testName = new TestName();
45 public static void init() throws Exception {
46 bundles = makeMockBundles();
47 bundleScanner = new BundleScanner(bundles.toArray(new Bundle[bundles.size()]));
51 public static void destroy() throws Exception {
56 System.out.println("==== " + testName.getMethodName());
60 public void testValidateBundles() {
61 assertNotNull(bundleScanner);
62 BundleContext context = bundles.get(0).getBundleContext();
63 assertNotNull(context.getBundle());
64 assertNotNull(context.getBundles());
65 assertNotNull(context.getBundles().length >= 4);
69 public void testBundleEvents() throws Exception {
70 MockBundle newBundle = new TestMockBundle("misc", "", "bundle_misc");
71 assertTrue(bundleScanner.getAnnotatedClasses(
72 newBundle.getBundleContext(), null, null, false).size() == 0);
73 BundleEvent event = new BundleEvent(BundleEvent.RESOLVED, newBundle);
74 bundleScanner.bundleChanged(event);
75 assertTrue(bundleScanner.getAnnotatedClasses(
76 newBundle.getBundleContext(), null, null, false).size() == 1);
80 public void testAnnotatedClassesWithDependencies() throws Exception {
81 for (Bundle bundle : bundles) {
82 List<Class<?>> classes = bundleScanner.getAnnotatedClasses(
83 bundle.getBundleContext(), null, null, true);
84 String name = bundle.getSymbolicName();
85 System.out.println("name:" + name + " classes:" + classes.size());
86 if ("misc".equals(name)) {
87 assertTrue(classes.size() == 1);
88 } else if ("base".equals(name)) {
89 assertTrue(classes.size() == 5);
90 } else if ("sub1".equals(name)) {
91 assertTrue(classes.size() == 6);
92 } else if ("sub2".equals(name)) {
93 assertTrue(classes.size() == 7);
99 public void testExactFiltering() {
100 Bundle bundle = findBundle("sub1");
101 String[] annos = { "javax.xml.bind.annotation.XmlTransient" };
102 List<Class<?>> classes = bundleScanner.getAnnotatedClasses(
103 bundle.getBundleContext(), annos, null, true);
104 assertTrue(classes.size() == 1);
108 public void testNonExactFiltering() {
109 Bundle bundle = findBundle("sub1");
110 String[] annos = { "javax.xml.bind.annotation.*" };
111 List<Class<?>> classes = bundleScanner.getAnnotatedClasses(
112 bundle.getBundleContext(), annos, null, true);
113 assertTrue(classes.size() == 6);
117 public void testFilteringUnmatched() {
118 Bundle bundle = findBundle("sub1");
119 String[] annos = { "non.existent.pkg" };
120 List<Class<?>> classes = bundleScanner.getAnnotatedClasses(
121 bundle.getBundleContext(), annos, null, true);
122 assertTrue(classes.size() == 0);
126 public void testRegexMerge() {
127 Pattern pattern = BundleScanner.mergePatterns(
129 "javax.xml.bind.annotation.*",
134 assertTrue(pattern.matcher("Ljavax/xml/bind/annotation/FOO;").find());
135 assertFalse(pattern.matcher("Ljavax/servlet/FOO;").find());
139 public void testExclude() {
140 Set<String> excludes = new HashSet<String>();
141 excludes.add("bundle_base.Animal");
142 Bundle bundle = findBundle("sub1");
143 String[] annos = { "javax.xml.bind.annotation.*" };
144 List<Class<?>> classes = bundleScanner.getAnnotatedClasses(
145 bundle.getBundleContext(), annos, excludes, true);
146 assertTrue(classes.size() == 5);
149 private static Bundle findBundle(String symName) {
150 for (Bundle bundle : bundles) {
151 if (bundle.getSymbolicName().equals(symName)) return bundle;
156 private static List<Bundle> makeMockBundles() throws Exception {
157 List<Bundle> result = new ArrayList<Bundle>();
158 result.add(new MockBundle());
159 result.add(new TestMockBundle("base", "", "bundle_base"));
160 result.add(new TestMockBundle("sub1", "bundle_base", "bundle_sub1"));
161 result.add(new TestMockBundle("sub2", "bundle_base", "bundle_sub2"));
165 private static List<URL> findClasses(String pkg) throws URISyntaxException {
166 if (pkg == null) return Collections.EMPTY_LIST;
167 String npkg = pkg.replaceAll("\\.", "/");
168 URL dirUrl = BundleScannerTest.class.getClassLoader().getResource(npkg);
169 final List<URL> result = new ArrayList<URL>();
170 File dir = new File(dirUrl.toURI());
171 dir.listFiles(new FileFilter() {
174 public boolean accept(File file) {
175 if (file.isFile() && file.getName().endsWith(".class")) {
177 result.add(file.toURI().toURL());
178 } catch (MalformedURLException e) {
179 throw new IllegalStateException(e);
189 public static class TestMockBundle extends MockBundle {
191 public TestMockBundle(String name, String imports, String exports) throws Exception {
192 super(name, makeHeaders(name, imports, exports), new MockBundleContext() {
194 public Bundle[] getBundles() {
195 return bundles.toArray(new Bundle[bundles.size()]);
198 MockBundleContext ctx = (MockBundleContext) this.getBundleContext();
200 this.classes = findClasses(exports);
203 private static Dictionary<String,String> makeHeaders(
204 String name, String imports, String exports)
206 Dictionary<String,String> headers = new Hashtable<String,String>();
207 headers.put(Constants.IMPORT_PACKAGE, imports);
208 headers.put(Constants.EXPORT_PACKAGE, exports);
209 headers.put(Constants.BUNDLE_SYMBOLICNAME, name);
214 public Enumeration findEntries(String path, String filePattern, boolean recurse) {
215 return Collections.enumeration(classes);
219 public long getBundleId() {