view j2se/test/java/util/concurrent/Executors/PrivilegedCallables.java @ 3:64ed597c0ad3 trunk

[svn] Load openjdk/jdk7/b15 into jdk/trunk.
author xiomara
date Thu, 05 Jul 2007 23:47:33 +0000
parents
children 37f131a4a8e7
line wrap: on
line source

/*
 * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test 1.2 07/06/22
 * @bug 6552961 6558429
 * @summary Test privilegedCallable, privilegedCallableUsingCurrentClassLoader
 * @run main/othervm PrivilegedCallables
 * @author Martin Buchholz
 */

import java.util.concurrent.*;
import java.util.*;
import java.security.*;
import static java.util.concurrent.Executors.*;

public class PrivilegedCallables {
    Callable<Integer> real;

    final Callable<Integer> realCaller = new Callable<Integer>() {
	public Integer call() throws Exception {
	    return real.call(); }};

    final Random rnd = new Random();

    @SuppressWarnings("serial") Throwable[] throwables = {
	new Exception() {},
	new RuntimeException() {},
	new Error() {}
    };
    Throwable randomThrowable() {
	return throwables[rnd.nextInt(throwables.length)];
    }

    //----------------------------------------------------------------
    // A Policy class designed to make permissions fiddling very easy.
    //----------------------------------------------------------------
    static class Policy extends java.security.Policy {
	private Permissions perms;

	public void setPermissions(Permission...permissions) {
	    perms = new Permissions();
	    for (Permission permission : permissions)
		perms.add(permission);
	}

	public Policy() { setPermissions(/* Nothing */); }

	public PermissionCollection getPermissions(CodeSource cs) {
	    return perms;
	}

	public PermissionCollection getPermissions(ProtectionDomain pd) {
	    return perms;
	}

	public boolean implies(ProtectionDomain pd, Permission p) {
	    return perms.implies(p);
	}

	public void refresh() {}
    }

    void test(String[] args) {
	testPrivileged();
	
	final Policy policy = new Policy();
	Policy.setPolicy(policy);
	policy.setPermissions(new RuntimePermission("getClassLoader"),
			      new RuntimePermission("setContextClassLoader"),
			      new RuntimePermission("stopThread"));
	System.setSecurityManager(new SecurityManager());

	testPrivileged();

	policy.setPermissions(/* Nothing */);

	THROWS(AccessControlException.class,
	       new F() {void f(){ privilegedCallableUsingCurrentClassLoader(realCaller); }},
	       new F() {void f(){ privilegedThreadFactory(); }});

	policy.setPermissions(new RuntimePermission("setSecurityManager"));
	System.setSecurityManager(null);
    }

    void testPrivileged() {
	try { test(privilegedCallable(realCaller)); }
	catch (Throwable t) { unexpected(t); }

	try { test(privilegedCallableUsingCurrentClassLoader(realCaller)); }
	catch (Throwable t) { unexpected(t); }

	try { privilegedThreadFactory(); }
	catch (Throwable t) { unexpected(t); }
    }

    void test(final Callable<Integer> c) throws Throwable {
	for (int i = 0; i < 20; i++)
	    if (rnd.nextBoolean()) {
		final Throwable t = randomThrowable();
		real = new Callable<Integer>() {
		    @SuppressWarnings("deprecation")
		    public Integer call() throws Exception {
			Thread.currentThread().stop(t);
			return null; }};
		try {
		    c.call();
		    fail("Expected exception not thrown");
		} catch (Throwable tt) { check(t == tt); }
	    } else {
		final int n = rnd.nextInt();
		real = new Callable<Integer>() {
		    public Integer call() { return n; }};
		equal(c.call(), n);
	    }
    }

    //--------------------- Infrastructure ---------------------------
    volatile int passed = 0, failed = 0;
    void pass() {passed++;}
    void fail() {failed++; Thread.dumpStack();}
    void fail(String msg) {System.err.println(msg); fail();}
    void unexpected(Throwable t) {failed++; t.printStackTrace();}
    void check(boolean cond) {if (cond) pass(); else fail();}
    void equal(Object x, Object y) {
	if (x == null ? y == null : x.equals(y)) pass();
	else fail(x + " not equal to " + y);}
    public static void main(String[] args) throws Throwable {
	new PrivilegedCallables().instanceMain(args);}
    void instanceMain(String[] args) throws Throwable {
	try {test(args);} catch (Throwable t) {unexpected(t);}
	System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
	if (failed > 0) throw new AssertionError("Some tests failed");}
    abstract class F {abstract void f() throws Throwable;}
    void THROWS(Class<? extends Throwable> k, F... fs) {
	for (F f : fs)
	    try {f.f(); fail("Expected " + k.getName() + " not thrown");}
	    catch (Throwable t) {
		if (k.isAssignableFrom(t.getClass())) pass();
		else unexpected(t);}}
}