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