Clement Escoffier | 238b8a9 | 2013-09-16 15:17:39 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one |
| 3 | * or more contributor license agreements. See the NOTICE file |
| 4 | * distributed with this work for additional information |
| 5 | * regarding copyright ownership. The ASF licenses this file |
| 6 | * to you under the Apache License, Version 2.0 (the |
| 7 | * "License"); you may not use this file except in compliance |
| 8 | * with the License. You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, |
| 13 | * software distributed under the License is distributed on an |
| 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 15 | * KIND, either express or implied. See the License for the |
| 16 | * specific language governing permissions and limitations |
| 17 | * under the License. |
| 18 | */ |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 19 | package org.apache.felix.ipojo.runtime.core; |
| 20 | |
| 21 | import aQute.lib.osgi.Constants; |
| 22 | import org.apache.commons.io.FileUtils; |
| 23 | import org.apache.commons.io.filefilter.TrueFileFilter; |
| 24 | import org.apache.felix.ipojo.ComponentInstance; |
| 25 | import org.apache.felix.ipojo.runtime.core.services.BazService; |
| 26 | import org.junit.Test; |
| 27 | import org.ops4j.pax.exam.Option; |
| 28 | import org.ops4j.pax.tinybundles.core.TinyBundle; |
| 29 | import org.ops4j.pax.tinybundles.core.TinyBundles; |
| 30 | import org.ow2.chameleon.testing.helpers.BaseTest; |
| 31 | import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy; |
| 32 | |
| 33 | import java.io.File; |
| 34 | import java.io.IOException; |
| 35 | import java.io.InputStream; |
| 36 | import java.net.MalformedURLException; |
| 37 | import java.util.ArrayList; |
| 38 | import java.util.Collection; |
| 39 | import java.util.List; |
| 40 | |
| 41 | import static junit.framework.Assert.assertEquals; |
| 42 | import static org.apache.commons.io.FileUtils.copyInputStreamToFile; |
| 43 | import static org.ops4j.pax.exam.CoreOptions.bundle; |
| 44 | |
| 45 | /** |
| 46 | * Checks that native methods can still be used in components. |
| 47 | */ |
| 48 | public class TestNativeMethod extends BaseTest { |
| 49 | |
| 50 | private static final String NATIVE_CLAUSE = "" + |
| 51 | //Mac |
| 52 | "libs/mac/libfoo.jnilib;osname=MacOSX;osname=MacOS;processor=x86;processor=x86_64;processor=PowerPC," + |
| 53 | // Linux 32 bits |
| 54 | "libs/linux64/libfoo.so;processor=x86_64;osname=Linux," + |
| 55 | // Linux 64 bits |
| 56 | "libs/linux32/libfoo.so;processor=x86;osname=Linux"; |
| 57 | |
| 58 | /** |
| 59 | * We don't deploy the test bundle, a specific one will be built. |
Clement Escoffier | d6c0690 | 2013-10-06 08:37:13 +0000 | [diff] [blame^] | 60 | * On KF we still deploy the bundle as the probe bundles needs the components and services. |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 61 | */ |
| 62 | @Override |
| 63 | public boolean deployTestBundle() { |
Clement Escoffier | d6c0690 | 2013-10-06 08:37:13 +0000 | [diff] [blame^] | 64 | return isKnopflerfish(); |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 65 | } |
| 66 | |
Clement Escoffier | 7e95146 | 2013-10-04 13:11:51 +0000 | [diff] [blame] | 67 | public boolean isKnopflerfish() { |
| 68 | if (context != null) { |
Clement Escoffier | 072f6af | 2013-10-04 15:43:34 +0000 | [diff] [blame] | 69 | return super.isKnopflerfish(); |
Clement Escoffier | 7e95146 | 2013-10-04 13:11:51 +0000 | [diff] [blame] | 70 | } else { |
| 71 | String pf = System.getProperty("pax.exam.framework"); |
| 72 | return pf != null && pf.equalsIgnoreCase("knopflerfish"); |
| 73 | } |
| 74 | } |
| 75 | |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 76 | @Override |
| 77 | protected Option[] getCustomOptions() { |
Clement Escoffier | 7e95146 | 2013-10-04 13:11:51 +0000 | [diff] [blame] | 78 | // The native bundle cannot be deployed on kf, |
| 79 | // just skip |
| 80 | if (isKnopflerfish()) { |
| 81 | return new Option[0]; |
| 82 | } |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 83 | return new Option[] { |
| 84 | buildBundleWithNativeLibraries() |
| 85 | }; |
| 86 | } |
| 87 | |
| 88 | @Test |
| 89 | public void testComponentWithNativeMethod() { |
Clement Escoffier | 8903b0a | 2013-09-22 17:55:19 +0000 | [diff] [blame] | 90 | if (isKnopflerfish()) { |
| 91 | System.out.println("Test not supported on knopflerfish"); |
| 92 | return; |
| 93 | } |
| 94 | |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 95 | ComponentInstance ci = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.components" + |
| 96 | ".nativ.NativeComponent"); |
| 97 | |
| 98 | BazService baz = osgiHelper.getServiceObject(BazService.class, "(instance.name=" + ci.getInstanceName() +")"); |
| 99 | assertEquals("foo: Test program of JNI.", baz.hello("")); |
| 100 | } |
| 101 | |
| 102 | |
| 103 | public static Option buildBundleWithNativeLibraries() { |
| 104 | File out = new File("target/tested/test-bundle-with-native.jar"); |
| 105 | if (out.exists()) { |
| 106 | try { |
| 107 | return bundle(out.toURI().toURL().toExternalForm()); |
| 108 | } catch (MalformedURLException e) { |
| 109 | // Ignore it. |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | TinyBundle tested = TinyBundles.bundle(); |
| 114 | |
| 115 | // We look inside target/classes to find the class and resources |
| 116 | File classes = new File("target/classes"); |
| 117 | Collection<File> files = FileUtils.listFilesAndDirs(classes, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); |
| 118 | List<String> exports = new ArrayList<String>(); |
| 119 | for (File file : files) { |
| 120 | if (file.isDirectory()) { |
| 121 | // By convention we export of .services and .service package |
| 122 | if (file.getAbsolutePath().contains("/services") || file.getAbsolutePath().contains("/service")) { |
| 123 | String path = file.getAbsolutePath().substring(classes.getAbsolutePath().length() +1); |
| 124 | String packageName = path.replace('/', '.'); |
| 125 | exports.add(packageName); |
| 126 | } |
| 127 | } else { |
| 128 | // We need to compute the path |
| 129 | String path = file.getAbsolutePath().substring(classes.getAbsolutePath().length() +1); |
| 130 | try { |
| 131 | tested.add(path, file.toURI().toURL()); |
| 132 | } catch (MalformedURLException e) { |
| 133 | // Ignore it. |
| 134 | } |
| 135 | System.out.println(file.getName() + " added to " + path); |
| 136 | } |
| 137 | } |
| 138 | |
Clement Escoffier | dccfdad | 2013-09-17 06:23:36 +0000 | [diff] [blame] | 139 | // Depending on the the order, the probe bundle may already have detected requirements on components. |
| 140 | String clause = "" + |
| 141 | "org.apache.felix.ipojo.runtime.core.components, " + |
| 142 | "org.apache.felix.ipojo.runtime.core.services, " + |
| 143 | "org.apache.felix.ipojo.runtime.core.services.A123"; |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 144 | for (String export : exports) { |
| 145 | if (export.length() > 0) { export += ", "; } |
| 146 | clause += export; |
| 147 | } |
| 148 | |
| 149 | System.out.println("Exported packages : " + clause); |
| 150 | |
| 151 | InputStream inputStream = tested |
Clement Escoffier | dccfdad | 2013-09-17 06:23:36 +0000 | [diff] [blame] | 152 | .set(Constants.BUNDLE_SYMBOLICNAME, BaseTest.TEST_BUNDLE_SYMBOLIC_NAME + "-with-native") |
Clement Escoffier | e4d28e8 | 2013-09-16 13:03:54 +0000 | [diff] [blame] | 153 | .set(Constants.IMPORT_PACKAGE, "*") |
| 154 | .set(Constants.EXPORT_PACKAGE, clause) |
| 155 | .set(Constants.BUNDLE_NATIVECODE, NATIVE_CLAUSE) |
| 156 | .build(IPOJOStrategy.withiPOJO(new File("src/main/resources"))); |
| 157 | |
| 158 | try { |
| 159 | copyInputStreamToFile(inputStream, out); |
| 160 | return bundle(out.toURI().toURL().toExternalForm()); |
| 161 | } catch (MalformedURLException e) { |
| 162 | throw new RuntimeException("Cannot compute the url of the manipulated bundle"); |
| 163 | } catch (IOException e) { |
| 164 | throw new RuntimeException("Cannot write of the manipulated bundle"); |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | |
| 169 | } |