blob: 3e62fa93f496a3cc00a7d84e95e0a1693460faaa [file] [log] [blame]
/*
* Copyright (c) 2018, 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.
*/
/*
* @test
* @summary tests the load and store methods of Properties class
* @author Xueming Shen
* @bug 4094886
* @modules jdk.charsets
* @key randomness
*/
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;
import java.util.Random;
public class PropertiesTest {
private static boolean failure = false;
private static int failCount = 0;
/**
* Main to interpret arguments and run several tests.
*
*/
public static void main(String[] args) throws Exception {
BlankLines();
EscapeSpace();
LoadParsing();
SaveEncoding();
SaveLoadBasher();
SaveSeparator();
SaveClose();
SaveComments();
UnicodeEscape();
if (failure)
throw new RuntimeException("Failure in Properties testing.");
else
System.err.println("OKAY: All tests passed.");
}
private static void report(String testName) {
int spacesToAdd = 30 - testName.length();
StringBuffer paddedNameBuffer = new StringBuffer(testName);
for (int i=0; i<spacesToAdd; i++)
paddedNameBuffer.append(" ");
String paddedName = paddedNameBuffer.toString();
System.err.println(paddedName + ": " +
(failCount==0 ? "Passed":"Failed("+failCount+")"));
if (failCount > 0)
failure = true;
failCount = 0;
}
private static void check(Properties prop1, Properties prop2) {
if (!prop1.equals(prop2))
failCount++;
}
private static Reader getReader(String src, String csn)
throws Exception {
return new InputStreamReader(
new ByteArrayInputStream(src.getBytes()),
csn);
}
private static OutputStream getFOS(String name)
throws Exception
{
return new FileOutputStream(name);
}
private static Writer getFOSW(String name, String csn)
throws Exception
{
return new OutputStreamWriter(
new FileOutputStream(name),
csn);
}
private static Reader getReader(byte[] src, String csn)
throws Exception {
return new InputStreamReader(new ByteArrayInputStream(src), csn);
}
private static InputStream getInputStream(String src) {
return new ByteArrayInputStream(src.getBytes());
}
private static InputStream getInputStream(byte[] src) {
return new ByteArrayInputStream(src);
}
private static void BlankLines() throws Exception {
// write a single space to the output stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(' ');
// test empty properties
Properties prop1 = new Properties();
// now load the file we just created, into a properties object.
// the properties object should have no elements, but due to a
// bug, it has an empty key/value. key = "", value = ""
Properties prop2 = new Properties();
prop2.load(getInputStream(baos.toByteArray()));
check(prop1, prop2);
// test reader
prop2 = new Properties();
prop2.load(getReader(baos.toByteArray(), "UTF-8"));
check(prop1, prop2);
report("BlinkLine");
}
private static void EscapeSpace() throws Exception {
String propsCases =
"key1=\\ \\ Value\\u4e001, has leading and trailing spaces\\ \n" +
"key2=Value\\u4e002,\\ does not have\\ leading or trailing\\ spaces\n" +
"key3=Value\\u4e003,has,no,spaces\n" +
"key4=Value\\u4e004, does not have leading spaces\\ \n" +
"key5=\\t\\ \\ Value\\u4e005, has leading tab and no trailing spaces\n" +
"key6=\\ \\ Value\\u4e006,doesnothaveembeddedspaces\\ \\ \n" +
"\\ key1\\ test\\ =key1, has leading and trailing spaces \n" +
"key2\\ test=key2, does not have leading or trailing spaces\n" +
"key3test=key3,has,no,spaces\n" +
"key4\\ test\\ =key4, does not have leading spaces \n" +
"\\t\\ key5\\ test=key5, has leading tab and no trailing spaces\n" +
"\\ \\ key6\\ \\ =\\ key6,doesnothaveembeddedspaces ";
// Put the same properties, but without the escape char for space in
// value part.
Properties props = new Properties();
props.put("key1", " Value\u4e001, has leading and trailing spaces ");
props.put("key2", "Value\u4e002, does not have leading or trailing spaces");
props.put("key3", "Value\u4e003,has,no,spaces");
props.put("key4", "Value\u4e004, does not have leading spaces ");
props.put("key5", "\t Value\u4e005, has leading tab and no trailing spaces");
props.put("key6", " Value\u4e006,doesnothaveembeddedspaces ");
props.put(" key1 test ", "key1, has leading and trailing spaces ");
props.put("key2 test", "key2, does not have leading or trailing spaces");
props.put("key3test", "key3,has,no,spaces");
props.put("key4 test ", "key4, does not have leading spaces ");
props.put("\t key5 test", "key5, has leading tab and no trailing spaces");
props.put(" key6 ", " key6,doesnothaveembeddedspaces ");
// Load properties with escape character '\' before space characters
Properties props1 = new Properties();
props1.load(getInputStream(propsCases));
check(props1, props);
// Test Reader
props1 = new Properties();
props1.load(getReader(propsCases, "UTF-8"));
check(props1, props);
// Also store the new properties to a storage
ByteArrayOutputStream baos = new ByteArrayOutputStream();
props.store(baos, "EscapeSpace Test");
props1 = new Properties();
props1.load(getInputStream(baos.toByteArray()));
check(props1, props);
// Reader should work as well
props1 = new Properties();
props1.load(getReader(baos.toByteArray(), "UTF-8"));
check(props1, props);
// Try Writer
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "UTF-8"),
"EscapeSpace Test");
props1 = new Properties();
props1.load(getReader(baos.toByteArray(), "UTF-8"));
check(props1, props);
report("EscapeSpace");
}
private static void LoadParsing() throws Exception {
File f = new File(System.getProperty("test.src", "."), "input.txt");
FileInputStream myIn = new FileInputStream(f);
Properties myProps = new Properties();
int size = 0;
try {
myProps.load(myIn);
} finally {
myIn.close();
}
if (!myProps.getProperty("key1").equals("value1") || // comment
!myProps.getProperty("key2").equals("abc\\defg\\") || // slash
!myProps.getProperty("key3").equals("value3") || // spaces in key
!myProps.getProperty("key4").equals(":value4") || // separator
// Does not recognize comments with leading spaces
(myProps.getProperty("#") != null) ||
// Wrong number of keys in Properties
((size=myProps.size()) != 4))
failCount++;
report("LoadParsing");
}
private static void SaveEncoding() throws Exception {
// Create a properties object to save
Properties props = new Properties();
props.put("signal", "val\u0019");
props.put("ABC 10", "value0");
props.put("\uff10test", "value\u0020");
props.put("key with spaces", "value with spaces");
props.put("key with space and Chinese_\u4e00", "valueWithChinese_\u4e00");
props.put(" special#=key ", "value3");
// Save the properties and check output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
props.store(baos,"A test");
// Read properties file and verify \u0019
BufferedReader in = new BufferedReader(
new InputStreamReader(
new ByteArrayInputStream(
baos.toByteArray())));
String firstLine = "foo";
while (!firstLine.startsWith("signal"))
firstLine = in.readLine();
if (firstLine.length() != 16)
failCount++;
// Load the properties set
Properties newProps = new Properties();
newProps.load(getInputStream(baos.toByteArray()));
check(newProps, props);
// Store(Writer)/Load(Reader)
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "EUC_JP"), "A test");
newProps = new Properties();
newProps.load(getReader(baos.toByteArray(), "EUC_JP"));
check(newProps, props);
report("SaveEncoding");
}
/**
* This class tests to see if a properties object
* can successfully save and load properties
* using character encoding
*/
private static void SaveLoadBasher() throws Exception {
String keyValueSeparators = "=: \t\r\n\f#!\\";
Properties originalProps = new Properties();
Properties loadedProps = new Properties();
// Generate a unicode key and value
Random generator = new Random();
int achar=0;
StringBuffer aKeyBuffer = new StringBuffer(120);
StringBuffer aValueBuffer = new StringBuffer(120);
String aKey;
String aValue;
int maxKeyLen = 100;
int maxValueLen = 100;
int maxPropsNum = 300;
for (int x=0; x<maxPropsNum; x++) {
for(int y=0; y<maxKeyLen; y++) {
achar = generator.nextInt();
char test;
if(achar < 99999) {
test = (char)(achar);
}
else {
int zz = achar % 10;
test = keyValueSeparators.charAt(zz);
}
if (Character.isHighSurrogate(test)) {
aKeyBuffer.append(test);
aKeyBuffer.append('\udc00');
y++;
} else if (Character.isLowSurrogate(test)) {
aKeyBuffer.append('\ud800');
aKeyBuffer.append(test);
y++;
} else
aKeyBuffer.append(test);
}
aKey = aKeyBuffer.toString();
for(int y=0; y<maxValueLen; y++) {
achar = generator.nextInt();
char test = (char)(achar);
if (Character.isHighSurrogate(test)) {
aKeyBuffer.append(test);
aKeyBuffer.append('\udc00');
y++;
} else if (Character.isLowSurrogate(test)) {
aKeyBuffer.append('\ud800');
aKeyBuffer.append(test);
y++;
} else {
aValueBuffer.append(test);
}
}
aValue = aValueBuffer.toString();
// Attempt to add to original
try {
originalProps.put(aKey, aValue);
}
catch (IllegalArgumentException e) {
System.err.println("disallowing...");
}
aKeyBuffer.setLength(0);
aValueBuffer.setLength(0);
}
// Store(OutputStream)/Load(InputStream)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
originalProps.store(baos, "test properties");
loadedProps.load(getInputStream(baos.toByteArray()));
check(loadedProps, originalProps);
// Store(Writer)/Load(Reader)
baos = new ByteArrayOutputStream();
originalProps.store(new OutputStreamWriter(baos, "UTF-8"),
"test properties");
loadedProps.load(getReader(baos.toByteArray(), "UTF-8"));
check(loadedProps, originalProps);
report("SaveLoadBasher");
}
/* Note: this regression test only detects incorrect line
* separator on platform running the test
*/
private static void SaveSeparator() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Properties props = new Properties();
props.store(baos, "A test");
// Examine the result to verify that line.separator was used
String theSeparator = System.getProperty("line.separator");
String content = baos.toString();
if (!content.endsWith(theSeparator))
failCount++;
// store(Writer)
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "UTF-8"), "A test");
content = baos.toString();
if (!content.endsWith(theSeparator))
failCount++;
report("SaveSeparator");
}
// Ensure that the save method doesn't close its output stream
private static void SaveClose() throws Exception {
Properties p = new Properties();
p.put("Foo", "Bar");
class MyOS extends ByteArrayOutputStream {
boolean closed = false;
public void close() throws IOException {
this.closed = true;
}
}
MyOS myos = new MyOS();
p.store(myos, "Test");
if (myos.closed)
failCount++;
p.store(new OutputStreamWriter(myos, "UTF-8"), "Test");
if (myos.closed)
failCount++;
report ("SaveClose");
}
private static void UnicodeEscape() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(baos);
osw.write("a=b\nb=\\u0\n");
osw.close();
Properties props = new Properties();
boolean failed = true;
try {
props.load(getInputStream(baos.toByteArray()));
} catch (IllegalArgumentException iae) {
failed = false;
}
if (failed)
failCount++;
failed = true;
props = new Properties();
try {
props.load(getReader(baos.toByteArray(), "UTF-8"));
} catch (IllegalArgumentException iae) {
failed = false;
}
if (failed)
failCount++;
report("UnicodeEscape");
}
private static void SaveComments() throws Exception {
String ls = System.getProperty("line.separator");
String[] input = new String[] {
"Comments with \u4e2d\u6587\u6c49\u5b57 included",
"Comments with \n Second comments line",
"Comments with \n# Second comments line",
"Comments with \n! Second comments line",
"Comments with last character is \n",
"Comments with last character is \r\n",
"Comments with last two characters are \n\n",
"Comments with last four characters are \r\n\r\n",
"Comments with \nkey4=value4",
"Comments with \n#key4=value4"};
String[] output = new String[] {
"#Comments with \\u4E2D\\u6587\\u6C49\\u5B57 included" + ls,
"#Comments with " + ls + "# Second comments line" + ls,
"#Comments with " + ls + "# Second comments line" + ls,
"#Comments with " + ls + "! Second comments line" + ls,
"#Comments with last character is " + ls+"#"+ls,
"#Comments with last character is " + ls+"#"+ls,
"#Comments with last two characters are " + ls+"#"+ls+"#"+ls,
"#Comments with last four characters are " + ls+"#"+ls+"#"+ls};
Properties props = new Properties();
ByteArrayOutputStream baos;
int i = 0;
for (i = 0; i < output.length; i++) {
baos = new ByteArrayOutputStream();
props.store(baos, input[i]);
String result = baos.toString("iso8859-1");
if (result.indexOf(output[i]) == -1) {
failCount++;
}
}
props.put("key1", "value1");
props.put("key2", "value2");
props.put("key3", "value3");
for (; i < input.length; i++) {
baos = new ByteArrayOutputStream();
props.store(baos, input[i]);
Properties propsNew = new Properties();
propsNew.load(getInputStream(baos.toByteArray()));
check(propsNew, props);
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "UTF-8"),
input[i]);
propsNew = new Properties();
propsNew.load(getReader(baos.toByteArray(), "UTF-8"));
check(propsNew, props);
}
report("SaveComments");
}
}