package org.example.tests.osgi; import static org.example.tests.utils.Utils.copyToTempFile; import static org.example.tests.utils.Utils.createTempDir; import static org.example.tests.utils.Utils.deleteWithException; import static org.example.tests.utils.Utils.readStream; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import java.io.File; import java.io.StringWriter; import java.util.Collections; import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.example.tests.utils.WibbleAnalyzer; import org.mockito.ArgumentCaptor; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.service.indexer.Capability; import org.osgi.service.indexer.Requirement; import org.osgi.service.indexer.Resource; import org.osgi.service.indexer.ResourceAnalyzer; import org.osgi.service.indexer.ResourceIndexer; import org.osgi.service.log.LogService; import junit.framework.TestCase; public class TestOSGiServices extends TestCase { private final BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); private File tempDir; @Override protected void setUp() throws Exception { tempDir = createTempDir(); } @Override protected void tearDown() throws Exception { deleteWithException(tempDir); } public void testBasicServiceInvocation() throws Exception { ServiceReference<ResourceIndexer> ref = context.getServiceReference(ResourceIndexer.class); ResourceIndexer indexer = context.getService(ref); StringWriter writer = new StringWriter(); Map<String,String> config = new HashMap<String,String>(); config.put(ResourceIndexer.ROOT_URL, tempDir.getAbsoluteFile().toURI().toString()); indexer.indexFragment(Collections.singleton(copyToTempFile(tempDir, "testdata/01-bsn+version.jar")), writer, config); assertEquals(readStream(TestOSGiServices.class.getResourceAsStream("/testdata/fragment-basic.txt")), writer.toString().trim()); context.ungetService(ref); } // Test whiteboard registration of Resource Analyzers. public void testWhiteboardAnalyzer() throws Exception { ServiceRegistration<ResourceAnalyzer> reg = context.registerService(ResourceAnalyzer.class, new WibbleAnalyzer(), null); ServiceReference<ResourceIndexer> ref = context.getServiceReference(ResourceIndexer.class); ResourceIndexer indexer = context.getService(ref); StringWriter writer = new StringWriter(); Map<String,String> config = new HashMap<String,String>(); config.put(ResourceIndexer.ROOT_URL, tempDir.getAbsoluteFile().toURI().toString()); indexer.indexFragment(Collections.singleton(copyToTempFile(tempDir, "testdata/01-bsn+version.jar")), writer, config); assertEquals(readStream(TestOSGiServices.class.getResourceAsStream("/testdata/fragment-wibble.txt")), writer.toString().trim()); context.ungetService(ref); reg.unregister(); } // Test whiteboard registration of Resource Analyzers, with resource filter // property. public void testWhiteboardAnalyzerWithFilter() throws Exception { Dictionary<String,Object> analyzerProps = new Hashtable<String,Object>(); analyzerProps.put(ResourceAnalyzer.FILTER, "(location=*sion.jar)"); ServiceRegistration<ResourceAnalyzer> reg = context.registerService(ResourceAnalyzer.class, new WibbleAnalyzer(), analyzerProps); ServiceReference<ResourceIndexer> ref = context.getServiceReference(ResourceIndexer.class); ResourceIndexer indexer = context.getService(ref); StringWriter writer = new StringWriter(); Set<File> files = new LinkedHashSet<File>(); files.add(copyToTempFile(tempDir, "testdata/01-bsn+version.jar")); files.add(copyToTempFile(tempDir, "testdata/02-localization.jar")); Map<String,String> config = new HashMap<String,String>(); config.put(ResourceIndexer.ROOT_URL, tempDir.getAbsoluteFile().toURI().toString()); indexer.indexFragment(files, writer, config); assertEquals(readStream(TestOSGiServices.class.getResourceAsStream("/testdata/fragment-wibble-filtered.txt")), writer.toString().trim()); context.ungetService(ref); reg.unregister(); } // Test that exceptions thrown by analyzers are forwarded to the OSGi Log // Service public void testLogNotification() throws Exception { // Register mock LogService, to receive notifications LogService mockLog = mock(LogService.class); ServiceRegistration<LogService> mockLogReg = context.registerService(LogService.class, mockLog, null); // Register a broken analyzer that throws exceptions ResourceAnalyzer brokenAnalyzer = new ResourceAnalyzer() { public void analyzeResource(Resource resource, List<Capability> capabilities, List<Requirement> requirements) throws Exception { throw new Exception("Bang!"); } }; ServiceRegistration<ResourceAnalyzer> mockAnalyzerReg = context.registerService(ResourceAnalyzer.class, brokenAnalyzer, null); // Call the indexer ServiceReference<ResourceIndexer> ref = context.getServiceReference(ResourceIndexer.class); ResourceIndexer indexer = context.getService(ref); StringWriter writer = new StringWriter(); Set<File> files = Collections.singleton(copyToTempFile(tempDir, "testdata/01-bsn+version.jar")); Map<String,String> config = new HashMap<String,String>(); config.put(ResourceIndexer.ROOT_URL, tempDir.getAbsoluteFile().toURI().toString()); indexer.indexFragment(files, writer, config); // Verify log output ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class); verify(mockLog).log(any(ServiceReference.class), eq(LogService.LOG_ERROR), anyString(), exceptionCaptor.capture()); assertEquals("Bang!", exceptionCaptor.getValue().getMessage()); mockAnalyzerReg.unregister(); mockLogReg.unregister(); } }