ko-felix-test/src/test/java/org/netbeans/html/ko/felix/test/KnockoutFelixAriesIT.java
author Jaroslav Tulach <jtulach@netbeans.org>
Thu, 26 Nov 2015 20:59:51 +0100
changeset 1021 c918924ad3c5
permissions -rw-r--r--
#256696: Making OSGi headers, enterprise OSGi ready
jtulach@1021
     1
/**
jtulach@1021
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jtulach@1021
     3
 *
jtulach@1021
     4
 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jtulach@1021
     5
 *
jtulach@1021
     6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
jtulach@1021
     7
 * Other names may be trademarks of their respective owners.
jtulach@1021
     8
 *
jtulach@1021
     9
 * The contents of this file are subject to the terms of either the GNU
jtulach@1021
    10
 * General Public License Version 2 only ("GPL") or the Common
jtulach@1021
    11
 * Development and Distribution License("CDDL") (collectively, the
jtulach@1021
    12
 * "License"). You may not use this file except in compliance with the
jtulach@1021
    13
 * License. You can obtain a copy of the License at
jtulach@1021
    14
 * http://www.netbeans.org/cddl-gplv2.html
jtulach@1021
    15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jtulach@1021
    16
 * specific language governing permissions and limitations under the
jtulach@1021
    17
 * License.  When distributing the software, include this License Header
jtulach@1021
    18
 * Notice in each file and include the License file at
jtulach@1021
    19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
jtulach@1021
    20
 * particular file as subject to the "Classpath" exception as provided
jtulach@1021
    21
 * by Oracle in the GPL Version 2 section of the License file that
jtulach@1021
    22
 * accompanied this code. If applicable, add the following below the
jtulach@1021
    23
 * License Header, with the fields enclosed by brackets [] replaced by
jtulach@1021
    24
 * your own identifying information:
jtulach@1021
    25
 * "Portions Copyrighted [year] [name of copyright owner]"
jtulach@1021
    26
 *
jtulach@1021
    27
 * Contributor(s):
jtulach@1021
    28
 *
jtulach@1021
    29
 * The Original Software is NetBeans. The Initial Developer of the Original
jtulach@1021
    30
 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
jtulach@1021
    31
 *
jtulach@1021
    32
 * If you wish your version of this file to be governed by only the CDDL
jtulach@1021
    33
 * or only the GPL Version 2, indicate your decision by adding
jtulach@1021
    34
 * "[Contributor] elects to include this software in this distribution
jtulach@1021
    35
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
jtulach@1021
    36
 * single choice of license, a recipient has the option to distribute
jtulach@1021
    37
 * your version of this file under either the CDDL, the GPL Version 2 or
jtulach@1021
    38
 * to extend the choice of license to its licensees as provided above.
jtulach@1021
    39
 * However, if you add GPL Version 2 code and therefore, elected the GPL
jtulach@1021
    40
 * Version 2 license, then the option applies only if the new code is
jtulach@1021
    41
 * made subject to such option by the copyright holder.
jtulach@1021
    42
 */
jtulach@1021
    43
package org.netbeans.html.ko.felix.test;
jtulach@1021
    44
jtulach@1021
    45
import java.io.Closeable;
jtulach@1021
    46
import java.io.File;
jtulach@1021
    47
import java.io.IOException;
jtulach@1021
    48
import java.lang.annotation.Annotation;
jtulach@1021
    49
import java.lang.reflect.Method;
jtulach@1021
    50
import java.net.URI;
jtulach@1021
    51
import java.util.ArrayList;
jtulach@1021
    52
import java.util.HashMap;
jtulach@1021
    53
import java.util.List;
jtulach@1021
    54
import java.util.Map;
jtulach@1021
    55
import java.util.ServiceLoader;
jtulach@1021
    56
import java.util.concurrent.Callable;
jtulach@1021
    57
import java.util.jar.JarFile;
jtulach@1021
    58
import java.util.logging.Level;
jtulach@1021
    59
import java.util.logging.Logger;
jtulach@1021
    60
import org.netbeans.html.boot.spi.Fn;
jtulach@1021
    61
import org.netbeans.html.json.tck.KOTest;
jtulach@1021
    62
import org.netbeans.html.json.tck.KnockoutTCK;
jtulach@1021
    63
import org.osgi.framework.Bundle;
jtulach@1021
    64
import org.osgi.framework.BundleException;
jtulach@1021
    65
import org.osgi.framework.Constants;
jtulach@1021
    66
import org.osgi.framework.launch.Framework;
jtulach@1021
    67
import org.osgi.framework.launch.FrameworkFactory;
jtulach@1021
    68
import static org.testng.Assert.assertNotNull;
jtulach@1021
    69
import static org.testng.Assert.assertTrue;
jtulach@1021
    70
import static org.testng.Assert.fail;
jtulach@1021
    71
import org.testng.annotations.AfterClass;
jtulach@1021
    72
import org.testng.annotations.Factory;
jtulach@1021
    73
jtulach@1021
    74
public class KnockoutFelixAriesIT {
jtulach@1021
    75
    private static final Logger LOG = Logger.getLogger(KnockoutFelixAriesIT.class.getName());
jtulach@1021
    76
    private static Framework framework;
jtulach@1021
    77
    private static File dir;
jtulach@1021
    78
    static Framework framework() throws Exception {
jtulach@1021
    79
        if (framework != null) {
jtulach@1021
    80
            return framework;
jtulach@1021
    81
        }
jtulach@1021
    82
        for (FrameworkFactory ff : ServiceLoader.load(FrameworkFactory.class)) {
jtulach@1021
    83
            
jtulach@1021
    84
            String basedir = System.getProperty("basedir");
jtulach@1021
    85
            assertNotNull("basedir preperty provided", basedir);
jtulach@1021
    86
            File target = new File(basedir, "target");
jtulach@1021
    87
            dir = new File(target, "osgi-aries");
jtulach@1021
    88
            dir.mkdirs();
jtulach@1021
    89
            
jtulach@1021
    90
            Map<String,String> config = new HashMap<String, String>();
jtulach@1021
    91
            config.put(Constants.FRAMEWORK_STORAGE, dir.getPath());
jtulach@1021
    92
            config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "true");
jtulach@1021
    93
            config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "sun.misc,"
jtulach@1021
    94
                + "javafx.application,"
jtulach@1021
    95
                + "javafx.beans,"
jtulach@1021
    96
                + "javafx.beans.property,"
jtulach@1021
    97
                + "javafx.beans.value,"
jtulach@1021
    98
                + "javafx.collections,"
jtulach@1021
    99
                + "javafx.concurrent,"
jtulach@1021
   100
                + "javafx.event,"
jtulach@1021
   101
                + "javafx.geometry,"
jtulach@1021
   102
                + "javafx.scene,"
jtulach@1021
   103
                + "javafx.scene.control,"
jtulach@1021
   104
                + "javafx.scene.image,"
jtulach@1021
   105
                + "javafx.scene.layout,"
jtulach@1021
   106
                + "javafx.scene.text,"
jtulach@1021
   107
                + "javafx.scene.web,"
jtulach@1021
   108
                + "javafx.stage,"
jtulach@1021
   109
                + "javafx.util,"
jtulach@1021
   110
                + "netscape.javascript"
jtulach@1021
   111
            );
jtulach@1021
   112
            framework = ff.newFramework(config);
jtulach@1021
   113
            framework.init();
jtulach@1021
   114
            loadClassPathBundles(framework);
jtulach@1021
   115
            framework.start();
jtulach@1021
   116
            boolean ok = false;
jtulach@1021
   117
            for (Bundle b : framework.getBundleContext().getBundles()) {
jtulach@1021
   118
                try {
jtulach@1021
   119
                    if (!b.getSymbolicName().equals("org.apache.aries.spifly.dynamic.bundle")) {
jtulach@1021
   120
                        continue;
jtulach@1021
   121
                    }
jtulach@1021
   122
                    b.start();
jtulach@1021
   123
                    ok = true;
jtulach@1021
   124
                    LOG.log(Level.INFO, "Started {0}", b.getSymbolicName());
jtulach@1021
   125
                } catch (BundleException ex) {
jtulach@1021
   126
                    LOG.log(Level.WARNING, "Cannot start bundle " + b.getSymbolicName(), ex);
jtulach@1021
   127
                }
jtulach@1021
   128
            }
jtulach@1021
   129
            assertTrue(ok, "Aries installed");
jtulach@1021
   130
            for (Bundle b : framework.getBundleContext().getBundles()) {
jtulach@1021
   131
                try {
jtulach@1021
   132
                    if (b.getSymbolicName().contains("felix.framework")) {
jtulach@1021
   133
                        continue;
jtulach@1021
   134
                    }
jtulach@1021
   135
                    if (b.getSymbolicName().contains("glassfish.grizzly")) {
jtulach@1021
   136
                        continue;
jtulach@1021
   137
                    }
jtulach@1021
   138
                    b.start();
jtulach@1021
   139
                    LOG.log(Level.INFO, "Started {0}", b.getSymbolicName());
jtulach@1021
   140
                } catch (BundleException ex) {
jtulach@1021
   141
                    LOG.log(Level.WARNING, "Cannot start bundle " + b.getSymbolicName(), ex);
jtulach@1021
   142
                }
jtulach@1021
   143
            }
jtulach@1021
   144
            return framework;
jtulach@1021
   145
        }
jtulach@1021
   146
        fail("No OSGi framework in the path");
jtulach@1021
   147
        return null;
jtulach@1021
   148
    }
jtulach@1021
   149
    
jtulach@1021
   150
    @AfterClass public static void cleanUp() throws Exception {
jtulach@1021
   151
        if (framework != null) framework.stop();
jtulach@1021
   152
        clearUpDir(dir);
jtulach@1021
   153
    }
jtulach@1021
   154
    private static void clearUpDir(File dir) {
jtulach@1021
   155
        if (dir.isDirectory()) {
jtulach@1021
   156
            for (File f : dir.listFiles()) {
jtulach@1021
   157
                clearUpDir(f);
jtulach@1021
   158
            }
jtulach@1021
   159
        }
jtulach@1021
   160
        dir.delete();
jtulach@1021
   161
    }
jtulach@1021
   162
    
jtulach@1021
   163
    
jtulach@1021
   164
jtulach@1021
   165
    private static void loadClassPathBundles(Framework f) throws IOException, BundleException {
jtulach@1021
   166
        for (String jar : System.getProperty("java.class.path").split(File.pathSeparator)) {
jtulach@1021
   167
            File file = new File(jar);
jtulach@1021
   168
            if (!file.isFile()) {
jtulach@1021
   169
                LOG.info("Not loading " + file);
jtulach@1021
   170
                continue;
jtulach@1021
   171
            }
jtulach@1021
   172
            JarFile jf = new JarFile(file);
jtulach@1021
   173
            final String name = jf.getManifest().getMainAttributes().getValue("Bundle-SymbolicName");
jtulach@1021
   174
            jf.close();
jtulach@1021
   175
            if (name != null) {
jtulach@1021
   176
                if (name.contains("org.eclipse.osgi")) {
jtulach@1021
   177
                    throw new IllegalStateException("Found " + name + " !");
jtulach@1021
   178
                }
jtulach@1021
   179
                if (name.contains("felix.framework")) {
jtulach@1021
   180
                    continue;
jtulach@1021
   181
                }
jtulach@1021
   182
                if (name.contains("testng")) {
jtulach@1021
   183
                    continue;
jtulach@1021
   184
                }
jtulach@1021
   185
                final String path = "reference:" + file.toURI().toString();
jtulach@1021
   186
                try {
jtulach@1021
   187
                    Bundle b = f.getBundleContext().installBundle(path);
jtulach@1021
   188
                } catch (BundleException ex) {
jtulach@1021
   189
                    LOG.log(Level.WARNING, "Cannot install " + file, ex);
jtulach@1021
   190
                }
jtulach@1021
   191
            }
jtulach@1021
   192
        }
jtulach@1021
   193
    }
jtulach@1021
   194
    
jtulach@1021
   195
    private static Class<?> loadOSGiClass(Class<?> c) throws Exception {
jtulach@1021
   196
        return KnockoutFelixTCKImpl.loadOSGiClass(c.getName(), KnockoutFelixAriesIT.framework().getBundleContext());
jtulach@1021
   197
    }
jtulach@1021
   198
    
jtulach@1021
   199
    private static Class<?> browserClass;
jtulach@1021
   200
    private static Object browserContext;
jtulach@1021
   201
jtulach@1021
   202
    @Factory public static Object[] compatibilityTests() throws Exception {
jtulach@1021
   203
        Class<?> tck = loadOSGiClass(KnockoutTCK.class);
jtulach@1021
   204
        Class<?> peer = loadOSGiClass(KnockoutFelixTCKImpl.class);
jtulach@1021
   205
        // initialize the TCK
jtulach@1021
   206
        Callable<Class[]> inst = (Callable<Class[]>) peer.newInstance();
jtulach@1021
   207
        
jtulach@1021
   208
        Class[] arr = inst.call();
jtulach@1021
   209
        for (int i = 0; i < arr.length; i++) {
jtulach@1021
   210
            if (arr[i].getClassLoader() == ClassLoader.getSystemClassLoader()) {
jtulach@1021
   211
                fail("Should be an OSGi class: " + arr[i]);
jtulach@1021
   212
            }
jtulach@1021
   213
        }
jtulach@1021
   214
        
jtulach@1021
   215
        URI uri = DynamicHTTP.initServer();
jtulach@1021
   216
jtulach@1021
   217
        Method start = peer.getMethod("start", String.class, URI.class, boolean.class);
jtulach@1021
   218
        start.invoke(null, KnockoutFelixAriesIT.class.getName(), uri, false);
jtulach@1021
   219
        
jtulach@1021
   220
        ClassLoader l = getClassLoader();
jtulach@1021
   221
        List<Object> res = new ArrayList<Object>();
jtulach@1021
   222
        for (int i = 0; i < arr.length; i++) {
jtulach@1021
   223
            seekKOTests(arr[i], res);
jtulach@1021
   224
        }
jtulach@1021
   225
        return res.toArray();
jtulach@1021
   226
    }
jtulach@1021
   227
jtulach@1021
   228
    private static void seekKOTests(Class<?> c, List<Object> res) throws SecurityException, ClassNotFoundException {
jtulach@1021
   229
        Class<? extends Annotation> koTest =
jtulach@1021
   230
            c.getClassLoader().loadClass(KOTest.class.getName()).
jtulach@1021
   231
            asSubclass(Annotation.class);
jtulach@1021
   232
        for (Method m : c.getMethods()) {
jtulach@1021
   233
            if (m.getAnnotation(koTest) != null) {
jtulach@1021
   234
                res.add(new KOFx(KnockoutFelixAriesIT.class, browserContext, m));
jtulach@1021
   235
            }
jtulach@1021
   236
        }
jtulach@1021
   237
    }
jtulach@1021
   238
jtulach@1021
   239
    static synchronized ClassLoader getClassLoader() throws InterruptedException {
jtulach@1021
   240
        while (browserClass == null) {
jtulach@1021
   241
            KnockoutFelixAriesIT.class.wait();
jtulach@1021
   242
        }
jtulach@1021
   243
        return browserClass.getClassLoader();
jtulach@1021
   244
    }
jtulach@1021
   245
jtulach@1021
   246
    public static synchronized void initialized(Class<?> browserCls, Object presenter) throws Exception {
jtulach@1021
   247
        browserClass = browserCls;
jtulach@1021
   248
        browserContext = presenter;
jtulach@1021
   249
        KnockoutFelixAriesIT.class.notifyAll();
jtulach@1021
   250
    }
jtulach@1021
   251
jtulach@1021
   252
    public static Closeable activateInOSGi(Object presenter) throws Exception {
jtulach@1021
   253
        Class<?> presenterClass = loadOSGiClass(Fn.Presenter.class);
jtulach@1021
   254
        Class<?> fnClass = loadOSGiClass(Fn.class);
jtulach@1021
   255
        Method m = fnClass.getMethod("activate", presenterClass);
jtulach@1021
   256
        return (Closeable) m.invoke(null, presenter);
jtulach@1021
   257
    }
jtulach@1021
   258
}