/* * Copyright (c) 2014, 2019, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FilePermission; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Properties; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.LoggingPermission;
/** * @test * @bug 8059767 * @summary tests that FileHandler can accept a long limit. * @modules java.logging/java.util.logging:open * @run main/othervm FileHandlerLongLimit UNSECURE * @run main/othervm -Djava.security.manager=allow FileHandlerLongLimit SECURE * @author danielfuchs * @key randomness
*/ publicclass FileHandlerLongLimit {
/** * We will test handling of limit and overflow of MeteredStream.written in * two configurations. * UNSECURE: No security manager. * SECURE: With the security manager present - and the required * permissions granted.
*/ publicstaticenum TestCase {
UNSECURE, SECURE; publicvoid run(Properties propertyFile) throws Exception {
System.out.println("Running test case: " + name());
Configure.setUp(this, propertyFile);
test(this.name() + " " + propertyFile.getProperty("test.name"), propertyFile, Long.parseLong(propertyFile.getProperty(FileHandler.class.getName()+".limit")));
}
}
privatestaticfinal String PREFIX = "FileHandler-" + UUID.randomUUID() + ".log"; privatestaticfinal String userDir = System.getProperty("user.dir", "."); privatestaticfinalboolean userDirWritable = Files.isWritable(Paths.get(userDir)); privatestaticfinal Field limitField; privatestaticfinal Field meterField; privatestaticfinal Field writtenField; privatestaticfinal Field outField;
publicstatic FileHandler testFileHandlerLimit(FileHandlerSupplier supplier, long limit) throws Exception {
Configure.doPrivileged(() -> { try {
Files.deleteIfExists(Paths.get(PREFIX));
} catch (IOException x) { thrownew RuntimeException(x);
}
}); final FileHandler fh = supplier.test(); try { // verify we have the expected limit
assertEquals(limit, getLimit(fh), "limit");
// get the metered output stream
OutputStream metered = getMeteredOutput(fh);
// we don't want to actually write to the file, so let's // redirect the metered to our own TestOutputStream.
setTestOutputStream(metered);
// check that fh.meter.written is 0
assertEquals(0, getWritten(metered), "written");
// now we're going to publish a series of log records // we're using the same log record over and over to make // sure we get the same amount of bytes.
String msg = "this is at least 10 chars long";
LogRecord record = new LogRecord(Level.SEVERE, msg);
fh.publish(record);
fh.flush(); long w = getWritten(metered); long offset = getWritten(metered);
System.out.println("first offset is: " + offset);
fh.publish(record);
fh.flush();
offset = getWritten(metered) - w;
w = getWritten(metered);
System.out.println("second offset is: " + offset);
fh.publish(record);
fh.flush();
offset = getWritten(metered) - w;
w = getWritten(metered);
System.out.println("third offset is: " + offset);
// Now set fh.meter.written to something close to the limit, // so that we can trigger log file rotation.
assertEquals(limit-2*offset+10, setWritten(metered, limit-2*offset+10), "written");
w = getWritten(metered);
// publish one more log record. we should still be just beneath // the limit
fh.publish(record);
fh.flush();
assertEquals(w+offset, getWritten(metered), "written");
// check that fh still has the same MeteredStream - indicating // that the file hasn't rotated. if (getMeteredOutput(fh) != metered) { thrownew RuntimeException("Log should not have rotated");
}
// Now publish two log record. The spec is a bit vague about when // exactly the log will be rotated - it could happen just after // writing the first log record or just before writing the next // one. We publich two - so we're sure that the log must have // rotated.
fh.publish(record);
fh.flush();
fh.publish(record);
fh.flush();
// Check that fh.meter is a different instance of MeteredStream. if (getMeteredOutput(fh) == metered) { thrownew RuntimeException("Log should have rotated");
} // success! return fh;
} catch (Error | Exception x) { // if we get an exception we need to close fh. // if we don't get an exception, fh will be closed by the caller. // (and that's why we dont use try-with-resources/finally here). try { fh.close(); } catch(Throwable t) {t.printStackTrace();} throw x;
}
}
if (userDirWritable || expectedException != null) { // These calls will create files in user.dir. // The file name contain a random UUID (PREFIX) which identifies them // and allow us to remove them cleanly at the end (see finally block // in main()).
checkException(expectedException, () -> new FileHandler());
checkException(expectedException, () -> { final FileHandler fh = new FileHandler();
assertEquals(limit, getLimit(fh), "limit"); return fh;
});
checkException(expectedException, () -> testFileHandlerLimit(
() -> new FileHandler(),
limit));
checkException(expectedException, () -> testFileHandlerLimit(
() -> new FileHandler(PREFIX, Long.MAX_VALUE, 1, true), Long.MAX_VALUE));
}
}
staticfinalclass PermissionsBuilder { final Permissions perms; public PermissionsBuilder() { this(new Permissions());
} public PermissionsBuilder(Permissions perms) { this.perms = perms;
} public PermissionsBuilder add(Permission p) {
perms.add(p); returnthis;
} public PermissionsBuilder addAll(PermissionCollection col) { if (col != null) { for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
perms.add(e.nextElement());
}
} returnthis;
} public Permissions toPermissions() { final PermissionsBuilder builder = new PermissionsBuilder();
builder.addAll(perms); return builder.perms;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.