Path: blob/master/test/jdk/java/util/Properties/PropertiesTest.java
41152 views
/*1* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @summary tests the load and store methods of Properties class26* @author Xueming Shen27* @bug 4094886 822420228* @modules jdk.charsets29* @key randomness30*/3132import java.io.BufferedReader;33import java.io.ByteArrayInputStream;34import java.io.ByteArrayOutputStream;35import java.io.File;36import java.io.FileInputStream;37import java.io.FileOutputStream;38import java.io.IOException;39import java.io.InputStream;40import java.io.InputStreamReader;41import java.io.OutputStream;42import java.io.OutputStreamWriter;43import java.io.Reader;44import java.io.Writer;45import java.util.Properties;46import java.util.Random;4748public class PropertiesTest {4950private static boolean failure = false;51private static int failCount = 0;5253/**54* Main to interpret arguments and run several tests.55*56*/57public static void main(String[] args) throws Exception {58BlankLines();59EscapeSpace();60LoadParsing();61SaveEncoding();62SaveLoadBasher();63SaveSeparator();64SaveClose();65SaveComments();66UnicodeEscape();6768if (failure)69throw new RuntimeException("Failure in Properties testing.");70else71System.err.println("OKAY: All tests passed.");72}7374private static void report(String testName) {75int spacesToAdd = 30 - testName.length();76StringBuffer paddedNameBuffer = new StringBuffer(testName);77for (int i=0; i<spacesToAdd; i++)78paddedNameBuffer.append(" ");79String paddedName = paddedNameBuffer.toString();80System.err.println(paddedName + ": " +81(failCount==0 ? "Passed":"Failed("+failCount+")"));82if (failCount > 0)83failure = true;84failCount = 0;85}8687private static void check(Properties prop1, Properties prop2) {88if (!prop1.equals(prop2))89failCount++;90}9192private static Reader getReader(String src, String csn)93throws Exception {94return new InputStreamReader(95new ByteArrayInputStream(src.getBytes()),96csn);97}9899private static OutputStream getFOS(String name)100throws Exception101{102return new FileOutputStream(name);103}104105private static Writer getFOSW(String name, String csn)106throws Exception107{108return new OutputStreamWriter(109new FileOutputStream(name),110csn);111}112113private static Reader getReader(byte[] src, String csn)114throws Exception {115return new InputStreamReader(new ByteArrayInputStream(src), csn);116}117118private static InputStream getInputStream(String src) {119return new ByteArrayInputStream(src.getBytes());120}121122private static InputStream getInputStream(byte[] src) {123return new ByteArrayInputStream(src);124}125126private static void BlankLines() throws Exception {127// write a single space to the output stream128ByteArrayOutputStream baos = new ByteArrayOutputStream();129baos.write(' ');130// test empty properties131Properties prop1 = new Properties();132133// now load the file we just created, into a properties object.134// the properties object should have no elements, but due to a135// bug, it has an empty key/value. key = "", value = ""136Properties prop2 = new Properties();137prop2.load(getInputStream(baos.toByteArray()));138check(prop1, prop2);139140// test reader141prop2 = new Properties();142prop2.load(getReader(baos.toByteArray(), "UTF-8"));143check(prop1, prop2);144145report("BlinkLine");146}147148private static void EscapeSpace() throws Exception {149String propsCases =150"key1=\\ \\ Value\\u4e001, has leading and trailing spaces\\ \n" +151"key2=Value\\u4e002,\\ does not have\\ leading or trailing\\ spaces\n" +152"key3=Value\\u4e003,has,no,spaces\n" +153"key4=Value\\u4e004, does not have leading spaces\\ \n" +154"key5=\\t\\ \\ Value\\u4e005, has leading tab and no trailing spaces\n" +155"key6=\\ \\ Value\\u4e006,doesnothaveembeddedspaces\\ \\ \n" +156"\\ key1\\ test\\ =key1, has leading and trailing spaces \n" +157"key2\\ test=key2, does not have leading or trailing spaces\n" +158"key3test=key3,has,no,spaces\n" +159"key4\\ test\\ =key4, does not have leading spaces \n" +160"\\t\\ key5\\ test=key5, has leading tab and no trailing spaces\n" +161"\\ \\ key6\\ \\ =\\ key6,doesnothaveembeddedspaces ";162163// Put the same properties, but without the escape char for space in164// value part.165Properties props = new Properties();166props.put("key1", " Value\u4e001, has leading and trailing spaces ");167props.put("key2", "Value\u4e002, does not have leading or trailing spaces");168props.put("key3", "Value\u4e003,has,no,spaces");169props.put("key4", "Value\u4e004, does not have leading spaces ");170props.put("key5", "\t Value\u4e005, has leading tab and no trailing spaces");171props.put("key6", " Value\u4e006,doesnothaveembeddedspaces ");172props.put(" key1 test ", "key1, has leading and trailing spaces ");173props.put("key2 test", "key2, does not have leading or trailing spaces");174props.put("key3test", "key3,has,no,spaces");175props.put("key4 test ", "key4, does not have leading spaces ");176props.put("\t key5 test", "key5, has leading tab and no trailing spaces");177props.put(" key6 ", " key6,doesnothaveembeddedspaces ");178179// Load properties with escape character '\' before space characters180Properties props1 = new Properties();181props1.load(getInputStream(propsCases));182check(props1, props);183184// Test Reader185props1 = new Properties();186props1.load(getReader(propsCases, "UTF-8"));187check(props1, props);188189// Also store the new properties to a storage190ByteArrayOutputStream baos = new ByteArrayOutputStream();191props.store(baos, "EscapeSpace Test");192193props1 = new Properties();194props1.load(getInputStream(baos.toByteArray()));195check(props1, props);196197// Reader should work as well198props1 = new Properties();199props1.load(getReader(baos.toByteArray(), "UTF-8"));200check(props1, props);201202// Try Writer203baos = new ByteArrayOutputStream();204props.store(new OutputStreamWriter(baos, "UTF-8"),205"EscapeSpace Test");206207props1 = new Properties();208props1.load(getReader(baos.toByteArray(), "UTF-8"));209check(props1, props);210211report("EscapeSpace");212}213214private static void LoadParsing() throws Exception {215File f = new File(System.getProperty("test.src", "."), "input.txt");216FileInputStream myIn = new FileInputStream(f);217Properties myProps = new Properties();218int size = 0;219try {220myProps.load(myIn);221} finally {222myIn.close();223}224225if (!myProps.getProperty("key1").equals("value1") || // comment226!myProps.getProperty("key2").equals("abc\\defg\\") || // slash227!myProps.getProperty("key3").equals("value3") || // spaces in key228!myProps.getProperty("key4").equals(":value4") || // separator229// Does not recognize comments with leading spaces230(myProps.getProperty("#") != null) ||231// Wrong number of keys in Properties232((size=myProps.size()) != 4))233failCount++;234report("LoadParsing");235}236237private static void SaveEncoding() throws Exception {238// Create a properties object to save239Properties props = new Properties();240props.put("signal", "val\u0019");241props.put("ABC 10", "value0");242props.put("\uff10test", "value\u0020");243props.put("key with spaces", "value with spaces");244props.put("key with space and Chinese_\u4e00", "valueWithChinese_\u4e00");245props.put(" special#=key ", "value3");246247// Save the properties and check output248ByteArrayOutputStream baos = new ByteArrayOutputStream();249props.store(baos,"A test");250251// Read properties file and verify \u0019252BufferedReader in = new BufferedReader(253new InputStreamReader(254new ByteArrayInputStream(255baos.toByteArray())));256String firstLine = "foo";257while (!firstLine.startsWith("signal"))258firstLine = in.readLine();259if (firstLine.length() != 16)260failCount++;261262// Load the properties set263Properties newProps = new Properties();264newProps.load(getInputStream(baos.toByteArray()));265check(newProps, props);266267// Store(Writer)/Load(Reader)268baos = new ByteArrayOutputStream();269props.store(new OutputStreamWriter(baos, "EUC_JP"), "A test");270newProps = new Properties();271newProps.load(getReader(baos.toByteArray(), "EUC_JP"));272check(newProps, props);273274report("SaveEncoding");275}276277/**278* This class tests to see if a properties object279* can successfully save and load properties280* using character encoding281*/282private static void SaveLoadBasher() throws Exception {283String keyValueSeparators = "=: \t\r\n\f#!\\";284285Properties originalProps = new Properties();286Properties loadedProps = new Properties();287288// Generate a unicode key and value289Random generator = new Random();290int achar=0;291StringBuffer aKeyBuffer = new StringBuffer(120);292StringBuffer aValueBuffer = new StringBuffer(120);293String aKey;294String aValue;295int maxKeyLen = 100;296int maxValueLen = 100;297int maxPropsNum = 300;298for (int x=0; x<maxPropsNum; x++) {299for(int y=0; y<maxKeyLen; y++) {300achar = generator.nextInt();301char test;302if(achar < 99999) {303test = (char)(achar);304}305else {306int zz = achar % 10;307test = keyValueSeparators.charAt(zz);308}309if (Character.isHighSurrogate(test)) {310aKeyBuffer.append(test);311aKeyBuffer.append('\udc00');312y++;313} else if (Character.isLowSurrogate(test)) {314aKeyBuffer.append('\ud800');315aKeyBuffer.append(test);316y++;317} else318aKeyBuffer.append(test);319}320aKey = aKeyBuffer.toString();321for(int y=0; y<maxValueLen; y++) {322achar = generator.nextInt();323char test = (char)(achar);324if (Character.isHighSurrogate(test)) {325aKeyBuffer.append(test);326aKeyBuffer.append('\udc00');327y++;328} else if (Character.isLowSurrogate(test)) {329aKeyBuffer.append('\ud800');330aKeyBuffer.append(test);331y++;332} else {333aValueBuffer.append(test);334}335}336aValue = aValueBuffer.toString();337338// Attempt to add to original339try {340originalProps.put(aKey, aValue);341}342catch (IllegalArgumentException e) {343System.err.println("disallowing...");344}345aKeyBuffer.setLength(0);346aValueBuffer.setLength(0);347}348349// Store(OutputStream)/Load(InputStream)350ByteArrayOutputStream baos = new ByteArrayOutputStream();351originalProps.store(baos, "test properties");352loadedProps.load(getInputStream(baos.toByteArray()));353check(loadedProps, originalProps);354355// Store(Writer)/Load(Reader)356baos = new ByteArrayOutputStream();357originalProps.store(new OutputStreamWriter(baos, "UTF-8"),358"test properties");359loadedProps.load(getReader(baos.toByteArray(), "UTF-8"));360check(loadedProps, originalProps);361362report("SaveLoadBasher");363}364365366/* Note: this regression test only detects incorrect line367* separator on platform running the test368*/369private static void SaveSeparator() throws Exception {370ByteArrayOutputStream baos = new ByteArrayOutputStream();371Properties props = new Properties();372props.store(baos, "A test");373374// Examine the result to verify that line.separator was used375String theSeparator = System.getProperty("line.separator");376String content = baos.toString();377if (!content.endsWith(theSeparator))378failCount++;379380// store(Writer)381baos = new ByteArrayOutputStream();382props.store(new OutputStreamWriter(baos, "UTF-8"), "A test");383content = baos.toString();384if (!content.endsWith(theSeparator))385failCount++;386387report("SaveSeparator");388}389390// Ensure that the save method doesn't close its output stream391private static void SaveClose() throws Exception {392Properties p = new Properties();393p.put("Foo", "Bar");394class MyOS extends ByteArrayOutputStream {395boolean closed = false;396public void close() throws IOException {397this.closed = true;398}399}400MyOS myos = new MyOS();401p.store(myos, "Test");402if (myos.closed)403failCount++;404405p.store(new OutputStreamWriter(myos, "UTF-8"), "Test");406if (myos.closed)407failCount++;408409report ("SaveClose");410}411412private static void UnicodeEscape() throws Exception {413checkMalformedUnicodeEscape("b=\\u012\n");414checkMalformedUnicodeEscape("b=\\u01\n");415checkMalformedUnicodeEscape("b=\\u0\n");416checkMalformedUnicodeEscape("b=\\u\n");417checkMalformedUnicodeEscape("a=\\u0123\nb=\\u012\n");418checkMalformedUnicodeEscape("a=\\u0123\nb=\\u01\n");419checkMalformedUnicodeEscape("a=\\u0123\nb=\\u0\n");420checkMalformedUnicodeEscape("a=\\u0123\nb=\\u\n");421checkMalformedUnicodeEscape("b=\\u012xyz\n");422checkMalformedUnicodeEscape("b=x\\u012yz\n");423checkMalformedUnicodeEscape("b=xyz\\u012\n");424}425426private static void checkMalformedUnicodeEscape(String propString) throws Exception {427ByteArrayOutputStream baos = new ByteArrayOutputStream();428OutputStreamWriter osw = new OutputStreamWriter(baos);429osw.write(propString);430osw.close();431Properties props = new Properties();432boolean failed = true;433try {434props.load(getInputStream(baos.toByteArray()));435} catch (IllegalArgumentException iae) {436failed = false;437}438if (failed)439failCount++;440441failed = true;442props = new Properties();443try {444props.load(getReader(baos.toByteArray(), "UTF-8"));445} catch (IllegalArgumentException iae) {446failed = false;447}448if (failed)449failCount++;450report("UnicodeEscape");451}452453private static void SaveComments() throws Exception {454String ls = System.getProperty("line.separator");455String[] input = new String[] {456"Comments with \u4e2d\u6587\u6c49\u5b57 included",457"Comments with \n Second comments line",458"Comments with \n# Second comments line",459"Comments with \n! Second comments line",460"Comments with last character is \n",461"Comments with last character is \r\n",462"Comments with last two characters are \n\n",463"Comments with last four characters are \r\n\r\n",464"Comments with \nkey4=value4",465"Comments with \n#key4=value4"};466467String[] output = new String[] {468"#Comments with \\u4E2D\\u6587\\u6C49\\u5B57 included" + ls,469"#Comments with " + ls + "# Second comments line" + ls,470"#Comments with " + ls + "# Second comments line" + ls,471"#Comments with " + ls + "! Second comments line" + ls,472"#Comments with last character is " + ls+"#"+ls,473"#Comments with last character is " + ls+"#"+ls,474"#Comments with last two characters are " + ls+"#"+ls+"#"+ls,475"#Comments with last four characters are " + ls+"#"+ls+"#"+ls};476477Properties props = new Properties();478ByteArrayOutputStream baos;479int i = 0;480for (i = 0; i < output.length; i++) {481baos = new ByteArrayOutputStream();482props.store(baos, input[i]);483String result = baos.toString("iso8859-1");484if (result.indexOf(output[i]) == -1) {485failCount++;486}487}488props.put("key1", "value1");489props.put("key2", "value2");490props.put("key3", "value3");491for (; i < input.length; i++) {492baos = new ByteArrayOutputStream();493props.store(baos, input[i]);494Properties propsNew = new Properties();495propsNew.load(getInputStream(baos.toByteArray()));496check(propsNew, props);497498baos = new ByteArrayOutputStream();499props.store(new OutputStreamWriter(baos, "UTF-8"),500input[i]);501propsNew = new Properties();502propsNew.load(getReader(baos.toByteArray(), "UTF-8"));503check(propsNew, props);504}505report("SaveComments");506}507}508509510