1 /**
2  * Copyright (C) 2009 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.googlecode.guice;
18 
19 
20 import aQute.bnd.main.bnd;
21 
22 import com.googlecode.guice.bundle.OSGiTestActivator;
23 
24 import junit.framework.TestCase;
25 
26 import org.osgi.framework.BundleContext;
27 import org.osgi.framework.launch.Framework;
28 import org.osgi.framework.launch.FrameworkFactory;
29 
30 import java.io.BufferedOutputStream;
31 import java.io.File;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
34 import java.io.OutputStream;
35 import java.util.Iterator;
36 import java.util.Properties;
37 
38 import javax.imageio.spi.ServiceRegistry;
39 
40 /**
41  * Run various tests inside one or more OSGi containers.
42  *
43  * @author mcculls@gmail.com (Stuart McCulloch)
44  */
45 public class OSGiContainerTest
46     extends TestCase {
47 
48   // build properties passed from Ant
49   static final String VERSION = System.getProperty("version", "snapshot");
50   static final String BUILD_DIR = System.getProperty("build.dir", "build");
51 
52   static final String BUILD_DIST_DIR = BUILD_DIR + "/dist";
53   static final String BUILD_TEST_DIR = BUILD_DIR + "/test";
54 
55   static final String GUICE_JAR = BUILD_DIST_DIR + "/guice-" + VERSION + ".jar";
56 
57 /*if[AOP]*/
58   static final String AOPALLIANCE_JAR = System.getProperty("aopalliance.jar", "lib/aopalliance.jar");
59 /*end[AOP]*/
60   static final String JAVAX_INJECT_JAR = System.getProperty("javax.inject.jar", "lib/javax.inject.jar");
61   static final String GUAVA_JAR = System.getProperty("guava.jar", "lib/guava-16.0.1.jar");
62 
63   // dynamically build test bundles
setUp()64   @Override protected void setUp()
65       throws Exception {
66 
67     // verify properties
68     assertTrue(failMsg(), new File(BUILD_DIR).isDirectory());
69     assertTrue(failMsg(), new File(GUICE_JAR).isFile());
70 
71 /*if[AOP]*/
72     assertTrue(failMsg(), new File(AOPALLIANCE_JAR).isFile());
73 /*end[AOP]*/
74     assertTrue(failMsg(), new File(JAVAX_INJECT_JAR).isFile());
75     assertTrue(failMsg(), new File(GUAVA_JAR).isFile());
76 
77     Properties instructions = new Properties();
78 
79 /*if[AOP]*/
80     // aopalliance is an API bundle --> export the full API
81     instructions.setProperty("Export-Package", "org.aopalliance.*");
82     buildBundle("aopalliance", instructions, AOPALLIANCE_JAR);
83     instructions.clear();
84 /*end[AOP]*/
85 
86     // javax.inject is an API bundle --> export the full API
87     instructions.setProperty("Export-Package", "javax.inject.*");
88     buildBundle("javax.inject", instructions, JAVAX_INJECT_JAR);
89     instructions.clear();
90 
91     // early versions of guava did not ship with OSGi metadata
92     instructions.setProperty("Export-Package", "com.google.common.*");
93     instructions.setProperty("Import-Package", "*;resolution:=optional");
94     buildBundle("guava", instructions, GUAVA_JAR);
95     instructions.clear();
96 
97     // strict imports to make sure test bundle only has access to these packages
98     instructions.setProperty("Import-Package", "org.osgi.framework,"
99 /*if[AOP]*/
100         + "org.aopalliance.intercept,"
101 /*end[AOP]*/
102         + "com.google.inject(|.binder|.matcher|.name)");
103 
104     // test bundle should only contain the local test classes, nothing else
105     instructions.setProperty("Bundle-Activator", OSGiTestActivator.class.getName());
106     instructions.setProperty("Private-Package", OSGiTestActivator.class.getPackage().getName());
107     buildBundle("osgitests", instructions, BUILD_TEST_DIR);
108     instructions.clear();
109   }
110 
111   // build an OSGi bundle at runtime
buildBundle(String name, Properties instructions, String classpath)112   private static void buildBundle(String name, Properties instructions, String classpath)
113       throws IOException {
114 
115     // write BND instructions to temporary test directory
116     String bndFileName = BUILD_TEST_DIR + '/' + name + ".bnd";
117     OutputStream os = new BufferedOutputStream(new FileOutputStream(bndFileName));
118     instructions.store(os, "BND instructions");
119     os.close();
120 
121     // assemble bundle, use -failok switch to avoid early exit
122     bnd.main(new String[]{"-failok", "build", "-classpath", classpath, bndFileName});
123   }
124 
failMsg()125   private String failMsg() {
126     return "This test may fail if it is not run from ant, or if it is not run after ant has "
127          + "compiled & built jars. This is because the test is validating that the Guice jar "
128          + "is properly setup to load in an OSGi container";
129   }
130 
131   //This test may fail if it is not run from ant, or if it is not run after ant has
132   //compiled & built jars. This is because the test is validating that the Guice jar
133   //is properly setup to load in an OSGi container
testGuiceWorksInOSGiContainer()134   public void testGuiceWorksInOSGiContainer()
135       throws Throwable {
136 
137     // ask framework to clear cache on startup
138     Properties properties = new Properties();
139     properties.setProperty("org.osgi.framework.storage", BUILD_TEST_DIR + "/bundle.cache");
140     properties.setProperty("org.osgi.framework.storage.clean", "onFirstInit");
141 
142     // test each available OSGi framework in turn
143     Iterator<FrameworkFactory> f = ServiceRegistry.lookupProviders(FrameworkFactory.class);
144     while (f.hasNext()) {
145       Framework framework = f.next().newFramework(properties);
146 
147       framework.start();
148       BundleContext systemContext = framework.getBundleContext();
149 
150       // load all the necessary bundles and start the OSGi test bundle
151 /*if[AOP]*/
152       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/aopalliance.jar");
153 /*end[AOP]*/
154       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/javax.inject.jar");
155       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/guava.jar");
156       systemContext.installBundle("reference:file:" + GUICE_JAR);
157       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/osgitests.jar").start();
158 
159       framework.stop();
160     }
161   }
162 }
163