Home | History | Annotate | Download | only in lang
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package libcore.java.lang;
     18 
     19 import junit.framework.TestCase;
     20 
     21 import java.io.BufferedWriter;
     22 import java.io.ByteArrayOutputStream;
     23 import java.io.PrintStream;
     24 import java.io.PrintWriter;
     25 import java.io.StringWriter;
     26 import java.util.Formatter;
     27 import java.util.Properties;
     28 import java.util.concurrent.atomic.AtomicBoolean;
     29 
     30 public class SystemTest extends TestCase {
     31 
     32     public void testLineSeparator() throws Exception {
     33         try {
     34             // Before Java 7, the small number of classes that wanted the line separator would
     35             // use System.getProperty. Now they should use System.lineSeparator instead, and the
     36             // "line.separator" property has no effect after the VM has started.
     37 
     38             // Test that System.lineSeparator is not changed when the corresponding
     39             // system property is changed.
     40             assertEquals("\n", System.lineSeparator());
     41             System.setProperty("line.separator", "poop");
     42             assertEquals("\n", System.lineSeparator());
     43 
     44             // java.io.BufferedWriter --- uses System.lineSeparator on Android but not on RI.
     45             StringWriter sw = new StringWriter();
     46             BufferedWriter bw = new BufferedWriter(sw);
     47             bw.newLine();
     48             bw.flush();
     49             assertEquals(System.lineSeparator(), sw.toString());
     50 
     51             // java.io.PrintStream --- uses System.lineSeparator on Android but not on RI.
     52             ByteArrayOutputStream baos = new ByteArrayOutputStream();
     53             new PrintStream(baos).println();
     54             assertEquals(System.lineSeparator(), new String(baos.toByteArray(), "UTF-8"));
     55 
     56             // java.io.PrintWriter --- uses System.lineSeparator on Android but not on RI.
     57             sw = new StringWriter();
     58             new PrintWriter(sw).println();
     59             assertEquals(System.lineSeparator(), sw.toString());
     60 
     61             // java.util.Formatter --- uses System.lineSeparator on both.
     62             assertEquals(System.lineSeparator(), new Formatter().format("%n").toString());
     63         } finally {
     64             System.setProperty("line.separator", "\n");
     65         }
     66     }
     67 
     68     public void testArrayCopyTargetNotArray() {
     69         try {
     70             System.arraycopy(new char[5], 0, "Hello", 0, 3);
     71             fail();
     72         } catch (ArrayStoreException e) {
     73             assertEquals("destination of type java.lang.String is not an array", e.getMessage());
     74         }
     75     }
     76 
     77     public void testArrayCopySourceNotArray() {
     78         try {
     79             System.arraycopy("Hello", 0, new char[5], 0, 3);
     80             fail();
     81         } catch (ArrayStoreException e) {
     82             assertEquals("source of type java.lang.String is not an array", e.getMessage());
     83         }
     84     }
     85 
     86     public void testArrayCopyArrayTypeMismatch() {
     87         try {
     88             System.arraycopy(new char[5], 0, new Object[5], 0, 3);
     89             fail();
     90         } catch (ArrayStoreException e) {
     91             assertEquals("Incompatible types: src=char[], dst=java.lang.Object[]", e.getMessage());
     92         }
     93     }
     94 
     95     public void testArrayCopyElementTypeMismatch() {
     96         try {
     97             System.arraycopy(new Object[] { null, 5, "hello" }, 0,
     98                     new Integer[] { 1, 2, 3, null, null }, 0, 3);
     99             fail();
    100         } catch (ArrayStoreException e) {
    101             assertEquals("source[2] of type java.lang.String cannot be stored in destination array of type java.lang.Integer[]", e.getMessage());
    102         }
    103     }
    104 
    105     public void testArrayCopyNull() {
    106         try {
    107             System.arraycopy(null, 0, new char[5], 0, 3);
    108             fail();
    109         } catch (NullPointerException e) {
    110             assertEquals("src == null", e.getMessage());
    111         }
    112         try {
    113             System.arraycopy(new char[5], 0, null, 0, 3);
    114             fail();
    115         } catch (NullPointerException e) {
    116             assertEquals("dst == null", e.getMessage());
    117         }
    118     }
    119 
    120     /**
    121      * System.arraycopy() must never copy objects into arrays that can't store
    122      * them. We've had bugs where type checks and copying were done separately
    123      * and racy code could defeat the type checks. http://b/5247258
    124      */
    125     public void testArrayCopyConcurrentModification() {
    126         final AtomicBoolean done = new AtomicBoolean();
    127 
    128         final Object[] source = new Object[512 * 1024];
    129         String[] target = new String[512 * 1024];
    130 
    131         new Thread() {
    132             @Override public void run() {
    133                 // the last array element alternates between being a Thread and being null. When
    134                 // it's a Thread it isn't safe for arrayCopy; when its null it is!
    135                 while (!done.get()) {
    136                     source[source.length - 1] = this;
    137                     source[source.length - 1] = null;
    138                 }
    139             }
    140         }.start();
    141 
    142         for (int i = 0; i < 2048; i++) {
    143             try {
    144                 System.arraycopy(source, 0, target, 0, source.length);
    145                 assertNull(target[source.length - 1]); // make sure the wrong type didn't sneak in
    146             } catch (ArrayStoreException ignored) {
    147             }
    148         }
    149 
    150         done.set(true);
    151     }
    152 
    153     public void testSystemProperties_immutable() {
    154         // Android-specific: The RI does not have a concept of immutable properties.
    155 
    156         // user.dir is an immutable property
    157         String userDir = System.getProperty("user.dir");
    158         assertNotNull(userDir);
    159         System.setProperty("user.dir", "not poop");
    160         assertEquals(userDir, System.getProperty("user.dir"));
    161 
    162         System.getProperties().setProperty("user.dir", "hmmph");
    163         assertEquals(userDir, System.getProperty("user.dir"));
    164 
    165         System.getProperties().clear();
    166         assertEquals(userDir, System.getProperty("user.dir"));
    167 
    168         Properties p = new Properties();
    169         p.setProperty("user.dir", "meh");
    170         System.setProperties(p);
    171 
    172         assertEquals(userDir, System.getProperty("user.dir"));
    173     }
    174 
    175     public void testSystemProperties_mutable() {
    176         // We allow "java.io.tmpdir" and "user.home" to be changed however
    177         // we can't test for "java.io.tmpdir" consistently across test runners because
    178         // it will be immutable if set on the dalvikvm command line "-Djava.io.tmpdir="
    179         // like vogar does.
    180         String oldUserHome = System.getProperty("user.home");
    181         try {
    182             System.setProperty("user.home", "/user/home");
    183             assertEquals("/user/home", System.getProperty("user.home"));
    184         } finally {
    185             System.setProperty("user.home", oldUserHome);
    186         }
    187     }
    188 
    189     public void testSystemProperties_setProperties_null() {
    190         // user.dir is an immutable property
    191         String userDir = System.getProperty("user.dir");
    192         assertNotNull(userDir);
    193 
    194         // Add a non-standard property
    195         System.setProperty("p1", "v1");
    196 
    197         // Reset using setProperties(null)
    198         System.setProperties(null);
    199 
    200         // All the immutable properties should be reset.
    201         assertEquals(userDir, System.getProperty("user.dir"));
    202         // Non-standard properties are cleared.
    203         assertNull(System.getProperty("p1"));
    204     }
    205 
    206     public void testSystemProperties_setProperties_nonNull() {
    207         String userDir = System.getProperty("user.dir");
    208 
    209         Properties newProperties = new Properties();
    210         // Immutable property
    211         newProperties.setProperty("user.dir", "v1");
    212         // Non-standard property
    213         newProperties.setProperty("p1", "v2");
    214 
    215         System.setProperties(newProperties);
    216 
    217         // Android-specific: The RI makes the setProperties() argument the system properties object,
    218         // Android makes a new Properties object and copies the properties.
    219         assertNotSame(newProperties, System.getProperties());
    220         // Android-specific: The RI does not have a concept of immutable properties.
    221         assertEquals(userDir, System.getProperty("user.dir"));
    222 
    223         assertEquals("v2", System.getProperty("p1"));
    224     }
    225 
    226     public void testSystemProperties_getProperties_clear() {
    227         String userDir = System.getProperty("user.dir");
    228         assertNotNull(userDir);
    229         System.setProperty("p1", "v1");
    230 
    231         Properties properties = System.getProperties();
    232         assertEquals("v1", properties.getProperty("p1"));
    233 
    234         properties.clear();
    235 
    236         // Android-specific: The RI clears everything, Android resets to immutable defaults.
    237         assertEquals(userDir, System.getProperty("user.dir"));
    238         assertNull(System.getProperty("p1"));
    239     }
    240 
    241     public void testSystem_setSecurityManager_null_noException() {
    242         System.setSecurityManager(null);
    243     }
    244 
    245     public void testSystem_setSecurityManager_notNull_throwsException() {
    246         try  {
    247             System.setSecurityManager(new SecurityManager());
    248             fail("Expected " + SecurityException.class.getName());
    249         } catch (SecurityException expected) {
    250         }
    251     }
    252 }
    253