Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 52177 invoked from network); 8 Jun 2007 16:36:35 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 8 Jun 2007 16:36:35 -0000 Received: (qmail 77637 invoked by uid 500); 8 Jun 2007 16:36:37 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 77601 invoked by uid 500); 8 Jun 2007 16:36:36 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 77529 invoked by uid 99); 8 Jun 2007 16:36:36 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Jun 2007 09:36:36 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Jun 2007 09:36:24 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 8B70E1A9866; Fri, 8 Jun 2007 09:35:38 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r545554 [12/13] - in /harmony/enhanced/buildtest/branches/2.0/tests/reliability: ./ run/ src/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/harmony/ src/java/org/apache/harmony/test/ src/java/org/apache/harmony/test/relia... Date: Fri, 08 Jun 2007 16:35:10 -0000 To: commits@harmony.apache.org From: smishura@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070608163539.8B70E1A9866@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,142 @@ +/* + * Copyright 2007 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Aleksey Ignatenko + * @version $Revision: 1.0 $ + */ + +/** + * GOAL: the test checks that for each loaded class (from "java.home") invocation of java.lang.Class methods + * in multiple threads running in parallel does not cause unexpected errors (crashes, hangs, exceptions). + * + * NOTE: see additional description in ClassMultiBase class. + * + * The test does: + * 1. Reads parameter, which is: + * param[0] - number of threads to launch for parallel classes processing + * + * 2. Overrides method testContent(Class) in which almost all methods of java.lang.Class are invoked. + * Finally, newInstance() is invoked only for "java." classes. + * + * 3. The test fails if crash or hang or unexpected runtime exception occurred while invocations of + * java.lang.Class methods in testContent(Class). + * + */ + +package org.apache.harmony.test.reliability.vm.classloading; + +import java.lang.reflect.GenericSignatureFormatError; +import java.lang.reflect.MalformedParameterizedTypeException; + +public class ClassAttributesTest extends ClassMultiTestBase{ + + public static void main(String[] args){ + System.exit(new ClassAttributesTest().test(args)); + } + + void testContent(Class cls) { + cls.getName(); + cls.getAnnotations(); + try{ + cls.getClassLoader(); + } catch (SecurityException e){ + // Expected + } + cls.getComponentType(); + cls.getDeclaredAnnotations(); + cls.getDeclaringClass(); + cls.getEnclosingConstructor(); + cls.getEnumConstants(); + cls.getGenericInterfaces(); + cls.getModifiers(); + + // check package info + Package pk = cls.getPackage(); + pk.getName(); + pk.getImplementationTitle(); + pk.getImplementationVendor(); + pk.getImplementationVersion(); + pk.getSpecificationTitle(); + pk.getSpecificationVendor(); + pk.getSpecificationVersion(); + pk.isSealed(); + + try{ + cls.getProtectionDomain(); + } catch (SecurityException e){ + // Expected + } + + try{ + cls.getGenericSuperclass(); + } catch(GenericSignatureFormatError e){ + // Expected + } catch (TypeNotPresentException e){ + // Expected + } catch (MalformedParameterizedTypeException e){ + // Expected + } + + try{ + cls.getProtectionDomain(); + } catch (SecurityException e){ + // Expected + } + + cls.getSigners(); + cls.isAnonymousClass(); + cls.getCanonicalName(); + cls.getSimpleName(); + + cls.getSuperclass(); + + try{ + cls.getTypeParameters(); + } catch(GenericSignatureFormatError e){ + // Expected + } + cls.hashCode(); + cls.isAnnotation(); + cls.isArray(); + cls.isEnum(); + cls.isInterface(); + cls.isLocalClass(); + cls.isPrimitive(); + cls.isSynthetic(); + cls.toString(); + + // make newInstance only for "java." classes to avoid hangs, avoid "awt" and "swing" to avoid XServer up requirement + if (cls.getName().startsWith("java.") && !cls.getName().contains("awt") && !cls.getName().contains("swing")){ + try { + cls.newInstance(); + } catch(IllegalAccessException e){ + // Expected + } catch (InstantiationException e){ + // Expected + } catch (ExceptionInInitializerError e){ + // Expected + } catch (SecurityException e){ + // Expected + }catch (Exception e){ + // Expected - propogated exception from class default constructor + } + } + + } + +} \ No newline at end of file Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,131 @@ +/* + * Copyright 2007 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Aleksey Ignatenko + * @version $Revision: 1.0 $ + */ + +/** + * NOTE: this class is not a test for running, it is a base class for other tests which + * process classes from "java.home"'s jar files. + * + * The class does: + * 1. Reads parameter, which is: + * param[0] - number of threads to launch for parallel classes processing + * param[1] - flag indicates what OS is used, true == linux, it is required not to initialize loaded classes as it requires + * XServer to be up. + * + * 2. Gets names of all classes from all jar files found in "java.home" and its subdirectories. + * + * 2. Starts param[0] threads. + * Each thread: + * For each class name: + * - tries to load the class by Class.forName() (classes are not initialized on linux because it requires XServer to be up) + * - if class could not be loaded for any reason, it is ignored, otherwise, + * - testContent() method which must be overridden in real tests is invoked. + * + * 3. If there are no unexpected exceptions, PASS status is returned, otherwise, FAIL + */ + +package org.apache.harmony.test.reliability.vm.classloading; + +import java.util.ArrayList; +import java.lang.reflect.*; +import java.lang.annotation.*; + +import org.apache.harmony.test.reliability.share.Test; +import org.apache.harmony.test.reliability.share.JarFilesScanner; + + +public class ClassMultiTestBase extends Test implements Runnable{ + volatile boolean failed = false; + final static String classFilesExt = ".class"; + final static char slashCharDelimiter1 = '/'; + final static char slashCharDelimiter2 = '\\'; + final static char dotCharDelimiter = '.'; + final static int NUMBER_OF_THREADS = 3; + int numberOfThreads = NUMBER_OF_THREADS; + int classCounter = 0; + ArrayList jarFiles; + + void testContent(Class cls) { + fail("The " + this.getClass().getName() + " class is for infra purposes only! - NOT TEST!"); + } + + public int test(String []args){ + parseParams(args); + jarFiles = new JarFilesScanner().getClassFilesInJRE(); + + + Thread[] thrds = new Thread[numberOfThreads]; + for (int i = 0; i< thrds.length; i++){ + thrds[i] = new Thread(this); + thrds[i].start(); + } + + for (int i = 0; i< thrds.length; i++){ + try { + thrds[i].join(); + } catch (InterruptedException e) { + failed = true; + log.add("Failed to join thread " + e); + } + } + + if (failed){ + return fail("FAILED"); + } + //System.out.println("Number of classes tested "+ classCounter); + return pass("OK"); + } + + + public void run(){ + for (int i=0; i= 1) { + numberOfThreads = Integer.parseInt(params[0]); + } + } + +} + Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java ------------------------------------------------------------------------------ svn:eol-style = native Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,203 @@ +/* + * Copyright 2007 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Aleksey Ignatenko + * @version $Revision: 1.0 $ + */ + +/** + * GOAL: the test checks that for each loaded class (from "java.home") invocation of java.lang.reflect methods + * in multiple threads running in parallel does not cause unexpected errors (crashes, hangs, exceptions). + * + * NOTE: see additional description in ClassMultiBase class. + * + * The test does: + * 1. Reads parameter, which is: + * param[0] - number of threads to launch for parallel classes processing + * + * 2. Overrides method testContent(Class) in which functionality of java.lang.reflect package is used. + * + * 3. The test fails if crash or hang or unexpected runtime exception occurred while processing + * in testContent(Class). + * + */ + +package org.apache.harmony.test.reliability.vm.classloading; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.GenericSignatureFormatError; +import java.lang.reflect.MalformedParameterizedTypeException; +import java.lang.reflect.Method; + +public class ClassReflectionTest extends ClassMultiTestBase{ + + public static void main(String[] args){ + System.exit(new ClassReflectionTest().test(args)); + } + + void testContent(Class cls) { + Constructor[] ctrs = null; + try{ + ctrs = cls.getConstructors(); + } catch (SecurityException e){ + // Expected + } + if (ctrs != null){ + for (int i=0; i= 1) { + CLASS_DIR = params[0]; + } + if (params.length >= 2) { + NUMBER_OF_CLASSES_TO_LOAD = Integer.parseInt(params[1]); + } + if (params.length >= 3) { + NUMBER_OF_THREADS_TO_START = Integer.parseInt(params[2]); + } + } + + String getTestedClassURI() { + String s = pckgName + "." + testedClassName; + return (s.replace('.', '/') + ".class"); + } + +} + + +class LoadingThread extends Thread { + + ClassUnloadingTest base; + + LoadingThread (ClassUnloadingTest base) { + this.base = base; + } + + public void run() { + + for (int i = 0; i < base.NUMBER_OF_CLASSES_TO_LOAD; i++) { + CustomLoader cl = new CustomLoader(base); + try { + String className = base.pckgName + "." + base.testedClassName; + String classFileName = base.testedClassName + ".class"; + Class cls = cl.loadClass(className, classFileName); + + if (cls == null){ + base.failed = true; + continue; + } + if (cls.getClassLoader() != cl) { + base.log.add("getClassLoader() returned not the custom classloader"); + base.failed = true; + continue; + } + + Object obj = cls.newInstance(); + Method meth = cls.getMethod("test", new Class[0]); + meth.invoke(obj, new Object[0]); + + // Force unloading + meth = null; + obj = null; + cls = null; + cl = null; + } catch (Throwable t) { + base.log.add("Thread " + this.getId() + ": unexpected exception was thrown: " + t.getMessage()); + base.failed = true; + } + } + } +} + +class CustomLoader extends ClassLoader { + + ClassUnloadingTest base; + + CustomLoader(ClassUnloadingTest base) { + this.base = base; + } + + protected URL findResource(String name){ + URL ret = null; + try { + File workDir = new File(base.CLASS_DIR); + ret = new URL(workDir.toURI().toString() + "/" + base.getTestedClassURI()); + } catch (MalformedURLException e) { + throw new Error(e); + } + return ret; + } + + public Class loadClass(String cname, String fname) { + + InputStream is = getResourceAsStream(fname); + + if (is == null) { + throw new RuntimeException("Couldn't find resource: " + fname); + } + + byte[] data = new byte[0]; + byte[] piece = new byte[512]; + int len; + try { + while ((len = is.read(piece)) != -1) { + byte[] tmp = data; + data = new byte[tmp.length + len]; + System.arraycopy(tmp, 0, data, 0, tmp.length); + System.arraycopy(piece, 0, data, tmp.length, len); + tmp = null; + } + } catch (IOException ex) { + throw new Error(ex); + } + + try { + is.close(); + } catch (IOException ex) { + throw new Error(ex); + } + return defineClass(cname, data, 0, data.length); + } +} + + Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassUnloadingTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,200 @@ +/* + * Copyright 2007 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Aleksey Ignatenko + * @version $Revision: 1.0 $ + */ + +package org.apache.harmony.test.reliability.vm.classloading; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.apache.harmony.test.reliability.share.Test; + +/* + * Goal: Test class loading delegation model + * The main idea is to make chain of User Defined classloaders where + * every part of chain could load only definite classes + * Therefore, covering all classes with appropriate classloaders we + * can garantee that loading class we'll not meet ClassNotFoundException + * + * passed parameters: + * parameter[0] - number of threads to start + * parameter[1] - folder where to scan class files + * + * The test Thread does the following: + * * scans class.path for class folders with class files + * * for every folder found UserDefined classloader is created which can find classes + * only in this folder, every previous classloader is parent for a next one + * * in the cycle start loading of found classes with child classloader + * * No ClassNotFoundException is to be raised! + * */ + +public class DelegationModelTest extends Test{ + static volatile boolean failed = false; + static final int NUMBER_OF_THREADS = 10; + static int numberOfThreads = NUMBER_OF_THREADS; + public static String classFolder = System.getProperty("java.class.path");; + + public static void main(String[] params){ + System.exit(new DelegationModelTest().test(params)); + } + + public int test(String[] params){ + parseParams(params); + + Thread[] thrds = new Thread[numberOfThreads]; + for (int i=0; i< numberOfThreads; i++){ + thrds[i] = new Delegation(); + thrds[i].start(); + } + + for (int i=0; i< numberOfThreads; i++){ + try { + thrds[i].join(); + } catch (InterruptedException e) { + failed = true; + } + } + + if (failed == true){ + return fail("FAILED"); + } + return pass("OK"); + } + + public void parseParams(String[] params) { + + if (params.length >= 1) { + numberOfThreads = Integer.parseInt(params[0]); + } + if (params.length >= 2) { + classFolder = params[1]; + } + } +} + +class Delegation extends Thread{ + public void run (){ + ClassLoader cCl = null; + HashMap > classFilesFolders = new HashMap >(); + String cp = DelegationModelTest.classFolder; + + scanClassFilesFolders(cp, classFilesFolders); + if (classFilesFolders.size() == 0){ + DelegationModelTest.failed = true; + } + + // create classloaders, each previous is parent for next one + Iterator it = classFilesFolders.entrySet().iterator(); + if (it.hasNext()){ + Map.Entry> entry = (Map.Entry)it.next(); + String key = (String)entry.getKey(); + cCl = new CustomELoader(key, ClassLoader.getSystemClassLoader()); + } + while (it.hasNext()){ + Map.Entry> entry = (Map.Entry)it.next(); + String key = (String)entry.getKey(); + cCl = new CustomELoader(key, cCl); + } + + // trying to load something + Iterator itr = classFilesFolders.entrySet().iterator(); + while (itr.hasNext()){ + Map.Entry> entry = (Map.Entry)itr.next(); + String key = (String)entry.getKey(); + ArrayList val = (ArrayList)entry.getValue(); + for (int i = 0; i < val.size(); i++){ + String nm = val.get(i); + nm = nm.replace(".class", ""); + try{ + // try to load class with the top classloader in hierarchy + Class c = cCl.loadClass(nm); + } + catch (ClassNotFoundException e){ + // garanteed to find class because all folders are covered with classloaders + DelegationModelTest.failed = true; + } + // Expected: linkage and other errors + catch (Exception e){ + + }catch (Error e){ + + } + } + + } + } + + // scan class files in test folder + void scanClassFilesFolders(String dir, HashMap > classFoldersFiles){ + File root = new File(dir); + File[] files = root.listFiles(); + if (files.length > 0){ + ArrayList filesInFolder = new ArrayList(); + classFoldersFiles.put(dir, filesInFolder); + for (int i=0; i< files.length; i++){ + String name = files[i].getName(); + if (name.endsWith(".class") && !name.contains("$")){ + filesInFolder.add(name); + } + if (files[i].isDirectory()){ + scanClassFilesFolders(files[i].getAbsolutePath(), classFoldersFiles); + } + } + } + files = null; + root = null; + } + +} + +class CustomELoader extends ClassLoader { + File resourceFolder = null; + CustomELoader(String folder, ClassLoader parent){ + super(parent); + resourceFolder = new File(folder); + } + + private byte[] loadBinary(String className){ + String fullPath = resourceFolder.getAbsolutePath() + "/" + className + ".class"; + byte[] b = null; + try { + FileInputStream fis = new FileInputStream(fullPath); + b = new byte[fis.available()]; + fis.read(b); + fis.close(); + } catch (Exception e) { + return null; + } + + return b; + } + + protected Class findClass(String name) throws ClassNotFoundException { + byte[] b = loadBinary(name); + if (b == null){ + throw new ClassNotFoundException(); + } + return defineClass(b, 0, b.length); + } +} Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,257 @@ +/* + * Copyright 2007 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Aleksey Ignatenko + * @version $Revision: 1.0 $ + */ + +package org.apache.harmony.test.reliability.vm.classloading; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; +import org.apache.harmony.test.reliability.share.Test; + +/* + * Goal: Test class loading in MT environment + * The main idea is to test loading of the same class in many threads + * All synchronizations are to be done on classloader level in VM + * The main members of the test are: initiating, defining classloaders, + * delegation model + * + * passed parameters: + * parameter[0] - number of threads to start + * + * The test Thread does the following: + * * scans class.path for class folders with class files + * * for every folder found 10 UserDefined classloaders are created which can find classes + * only in this folder + * * start threads which load the same class with classloaders chosen by Random (but related to the folder where class is located) + * * Check that classes loaded w different classloaders are different types! + * */ + +public class MultiThreadedLoading extends Test{ + static volatile boolean failed = false; + static final int NUMBER_OF_THREADS = 30; + static int numberOfThreads = NUMBER_OF_THREADS; + static final int NUMBER_OF_CLASSLOADERS = 10; + static volatile Entry sharedEntry = null; + static ArrayList reportedClasses = new ArrayList(); + public static String classFolder = System.getProperty("java.class.path"); + + static void reportClass(Class c){ + synchronized(reportedClasses){ + reportedClasses.add(c); + } + } + + public static void main(String[] params){ + System.exit(new MultiThreadedLoading().test(params)); + } + + public int test(String[] params){ + parseParams(params); + + ClassLoader[] cCl = null; + String cp = classFolder; + + HashMap > classFilesFolders = new HashMap >(); + scanClassFilesFolders(cp, classFilesFolders); + if (classFilesFolders.size() == 0){ + log.add("Did not found any golden file!"); + return fail("FAILED"); + } + + // create classloaders, each previous is parent for next one + ArrayList classFilesLoaders = new ArrayList(); + Iterator it = classFilesFolders.entrySet().iterator(); + while (it.hasNext()){ + Map.Entry> entry = (Map.Entry)it.next(); + + // create classloaders - number is randomized, not more than 10 + String key = (String)entry.getKey(); + cCl = new ClassLoader[NUMBER_OF_CLASSLOADERS]; + for (int i=0; i< cCl.length; i++){ + cCl[i] = new MultiClassloader(key); + } + + // create relations between class and classloader + + ArrayList classFiles = (ArrayList)entry.getValue(); + for (int i=0; i < classFiles.size(); i++){ + classFilesLoaders.add(new Entry(classFiles.get(i), cCl)); + } + } + + if (classFilesLoaders.size() == 0){ + log.add("Unknown error happent!"); + return fail("FAILED"); + } + + for (int j = 0; j < classFilesLoaders.size(); j++){ + // choose entry to process + reportedClasses.clear(); + sharedEntry = classFilesLoaders.get(j); + + // start processing + Thread[] thrds = new Thread[numberOfThreads]; + for (int i=0; i hs = new HashSet(); + if (reportedClasses.size() > 0){ + for (int i=1; i= 1) { + numberOfThreads = Integer.parseInt(params[0]); + } + if (params.length >= 2) { + classFolder = params[1]; + } + } + + // scan class files in test folder + void scanClassFilesFolders(String dir, HashMap > classFoldersFiles){ + File root = new File(dir); + File[] files = root.listFiles(); + if (files.length > 0){ + ArrayList filesInFolder = new ArrayList(); + classFoldersFiles.put(dir, filesInFolder); + for (int i=0; i< files.length; i++){ + String name = files[i].getName(); + if (name.endsWith(".class") && !name.contains("$")){ + filesInFolder.add(name.replace(".class", "")); + } + if (files[i].isDirectory()){ + scanClassFilesFolders(files[i].getAbsolutePath(), classFoldersFiles); + } + } + } + files = null; + root = null; + } + +} + +class ThreadLoader extends Thread{ + public void run (){ + Random rm = new Random(); + String className = MultiThreadedLoading.sharedEntry.className; + int len = MultiThreadedLoading.sharedEntry.cls.length; + int ind = rm.nextInt(len); + ClassLoader cl = MultiThreadedLoading.sharedEntry.cls[ind]; + + Class c = null; + try{ + c = cl.loadClass(className); + MultiThreadedLoading.reportClass(c); + }catch (LinkageError e){ + // Expected + }catch(ClassNotFoundException e){ + // Expected + }catch (Throwable t){ + // Expected something else + } + } +} + +class MultiClassloader extends ClassLoader { + String classFileFolder = null; + + MultiClassloader(String fileFolderPath){ + classFileFolder = fileFolderPath; + } + + private byte[] loadBinary(String className){ + byte[] b = null; + try { + String classFileFullPath = classFileFolder + "/" + className + ".class"; + FileInputStream fis = new FileInputStream(classFileFullPath); + b = new byte[fis.available()]; + fis.read(b); + fis.close(); + } catch (Exception e) { + return null; + } + + return b; + } + + protected Class findClass(String name) throws ClassNotFoundException { + byte[] b = loadBinary(name); + if (b == null){ + throw new ClassNotFoundException(); + } + return defineClass(b, 0, b.length); + } +} + +class Entry{ + Entry(String nm, ClassLoader[] c_l){ + className = nm; + cls = c_l; + } + public String className; + public ClassLoader cls[]; +} \ No newline at end of file Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java ------------------------------------------------------------------------------ svn:eol-style = native Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,48 @@ +/* + * Copyright 2007 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Aleksey Ignatenko + * @version $Revision: 1.0 $ + */ + +/** + * The class is loaded by User Defined Classloader + * test function emulates some work +**/ + +package org.apache.harmony.test.reliability.vm.classloading; + +import java.math.BigInteger; +import java.util.Random; + +public class TestUnloadingClass { + public void test(){ + res = sum(v1,v2); + } + int v1 = 5,v2 = 7; + int res; + int sum(int p1, int p2) { + Random rm = new Random(); + int res = 0; + for (int i = 0; i < 10; i++ ){ + BigInteger bi = new BigInteger(10, rm); + res = p1+p2 + bi.intValue(); + } + return res; + } +} Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java ------------------------------------------------------------------------------ svn:eol-style = native Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,492 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.test.reliability.vm.exceptions; + +import org.apache.harmony.test.reliability.share.Test; +import org.apache.harmony.test.reliability.share.Result; +import java.util.Random; +import java.util.Hashtable; + +/** + * Two scenarios are executed: + * + * 1. There are 5 methods which can call each other recursively + * up to specified depth. Each method calls randomly selected method + * and then throws a particular exception which is caught within + * this method. When recursion depth reaches the specified value, + * the method doesn't call more methods and only throws and catches + * + * 2. There are 8 methods which reproduce 8 situations of try-catch-finally + * block execution described in JLS14.20.2. The runner method consequently + * calls each of these methods and checks that there are no exceptions + * raised when there shouldn't be any exceptions, and there are expected + * exceptions raised when they should be raised according to specification. + * + * Parameters: number of threads, the length of handler's chain (recursion depth) + */ + +public class ExceptionsTest extends Test implements Runnable { + + private static final Random rnd = new Random(); + + private static int invCount; + private static int numThreads; + private int result = Result.PASS; + + public static void main(String[] args) { + System.exit(new ExceptionsTest().test(args)); + } + + public int test(String[] args) { + if(args.length != 2) { + log.add("2 parameters expected: number of threads and chain length"); + return error("ERROR"); + } + invCount = Integer.parseInt(args[1]); + numThreads = Integer.parseInt(args[0]); + Thread[] th = new Thread[numThreads]; + + for (int i = 0; i < th.length; i++) { + th[i] = new Thread(new ExceptionsTest()); + th[i].start(); + } + for (int i = 0; i < th.length; i++) { + try { + th[i].join(); + } catch (InterruptedException e) { + } + } + if (result == Result.PASS) { + return pass("PASSED"); + } + return result; + } + + public void run() { + int res; + res = new Scenario1().run(); + if (res != Result.PASS) { + result = res; + return; + } + res = new Scenario3().run(); + if (res != Result.PASS) { + result = res; + } + } + + + private static class Scenario1 { + private int count = 0; + public int run() { + int next = rnd.nextInt(5); + int res = Result.FAIL; + switch (next) { + case 0: + res = methNPE(); + break; + case 1: + res = methAE(); + break; + case 2: + res = methAIOOBE(); + break; + case 3: + res = methULE(); + break; + case 4: + res = methUserException(); + break; + } + return res; + } + private int methNPE() { + int next = -1; + try { + count++; + if (count == invCount) { + return Result.PASS; + } + next = rnd.nextInt(5); + int res = Result.FAIL; + switch (next) { + case 0: + res = methNPE(); + break; + case 1: + res = methAE(); + break; + case 2: + res = methAIOOBE(); + break; + case 3: + res = methULE(); + break; + case 4: + res = methUserException(); + break; + } + if (res != Result.PASS) { + log.add("in methNPE(): invocation of " + next + " resulted \"FAILED\""); + return res; + } + + // Cause a NPE + new Hashtable().get(new Object()).toString(); + } catch (NullPointerException e) { + return Result.PASS; + } catch (Throwable t) { + log.add("in methNPE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName()); + return Result.FAIL; + } + log.add("in methNPE(): NPE wasn't thrown"); + return Result.FAIL; + } + private int methAE() { + int next = -1; + try { + count++; + if (count == invCount) { + return Result.PASS; + } + next = rnd.nextInt(5); + int res = Result.FAIL; + switch (next) { + case 0: + res = methNPE(); + break; + case 1: + res = methAE(); + break; + case 2: + res = methAIOOBE(); + break; + case 3: + res = methULE(); + break; + case 4: + res = methUserException(); + break; + } + if (res != Result.PASS) { + log.add("in methAE(): invocation of " + next + " resulted \"FAILED\""); + return res; + } + + // Cause an AE + int i = count / (count / (2 * invCount)); + } catch (ArithmeticException e) { + return Result.PASS; + } catch (Throwable t) { + log.add("in methAE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName()); + return Result.FAIL; + } + log.add("in methAE: AE wasn't thrown"); + return Result.FAIL; + } + private int methAIOOBE() { + int next = -1; + try { + count++; + if (count == invCount) { + return Result.PASS; + } + next = rnd.nextInt(5); + int res = Result.FAIL; + switch (next) { + case 0: + res = methNPE(); + break; + case 1: + res = methAE(); + break; + case 2: + res = methAIOOBE(); + break; + case 3: + res = methULE(); + break; + case 4: + res = methUserException(); + break; + } + if (res != Result.PASS) { + log.add("in methAIOOBE(): invocation of " + next + " resulted \"FAILED\""); + return res; + } + + // Cause an AIOOBE + int[] arr = new int[count]; + int a = arr[invCount]; + } catch (ArrayIndexOutOfBoundsException e) { + return Result.PASS; + } catch (Throwable t) { + log.add("in methAIOOBE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName()); + return Result.FAIL; + } + log.add("in methAIOOBE: AIOOBE wasn't thrown"); + return Result.FAIL; + } + private int methULE() { + int next = -1; + try { + count++; + if (count == invCount) { + return Result.PASS; + } + next = rnd.nextInt(5); + int res = Result.FAIL; + switch (next) { + case 0: + res = methNPE(); + break; + case 1: + res = methAE(); + break; + case 2: + res = methAIOOBE(); + break; + case 3: + res = methULE(); + break; + case 4: + res = methUserException(); + break; + } + if (res != Result.PASS) { + log.add("in methULE(): invocation of " + next + " resulted \"FAILED\""); + return res; + } + + // Cause an ULE + nativeMethod(); + } catch (UnsatisfiedLinkError e) { + return Result.PASS; + } catch (Throwable t) { + log.add("in methULE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName()); + return Result.FAIL; + } + log.add("in methULE: ULE wasn't thrown"); + return Result.FAIL; + } + private int methUserException() { + int next = -1; + class UserException extends Exception { + public UserException() { + super("User exception"); + } + } + try { + count++; + if (count == invCount) { + return Result.PASS; + } + next = rnd.nextInt(5); + int res = Result.FAIL; + switch (next) { + case 0: + res = methNPE(); + break; + case 1: + res = methAE(); + break; + case 2: + res = methAIOOBE(); + break; + case 3: + res = methULE(); + break; + case 4: + res = methUserException(); + break; + } + if (res != Result.PASS) { + log.add("in methUserException(): invocation of " + next + " resulted \"FAILED\""); + return res; + } + + // Cause a UserException + throw new UserException(); + } catch (UserException e) { + return Result.PASS; + } catch (Throwable t) { + log.add("in methUserException(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName()); + return Result.FAIL; + } + } + } + + private static class Scenario3 { + int res = Result.FAIL; + public int run() { + res = doTry11(); + if (res != Result.PASS) { + log.add("doTry11() failed"); + return res; + } + + try { + doTry12(); + log.add("Expected exception was not thrown in doTry12()"); + return Result.FAIL; + } catch (NullPointerException e) { + } catch (Throwable t) { + log.add("Unexpected exception thrown in doTry12()"); + return Result.FAIL; + } + + res = doTry2111(); + if (res != Result.PASS) { + log.add("doTry2111() failed"); + return res; + } + + try { + doTry2112(); + } catch (NullPointerException e) { + } catch (Throwable t) { + log.add("Unexpected exception thrown in doTry2112()"); + return Result.FAIL; + } + + try { + doTry2121(); + } catch (NullPointerException e) { + } catch (Throwable t) { + log.add("Unexpected exception thrown in doTry2121()"); + return Result.FAIL; + } + + try { + doTry2122(); + } catch (NullPointerException e) { + } catch (Throwable t) { + log.add("Unexpected exception thrown in doTry2122()"); + return Result.FAIL; + } + + try { + doTry221(); + } catch (NullPointerException e) { + } catch (Throwable t) { + log.add("Unexpected exception thrown in doTry221()"); + return Result.FAIL; + } + + try { + doTry222(); + } catch (NullPointerException e) { + } catch (Throwable t) { + log.add("Unexpected exception thrown in doTry222()"); + return Result.FAIL; + } + return Result.PASS; + } + + private int doTry11() { + try { + } catch (Throwable t) { + log.add("Unexpected exception caught in doTry11()"); + return Result.FAIL; + } finally { + } + return Result.PASS; + } + private void doTry12() throws MyException { + try { + } catch (Throwable t) { + log.add("Unexpected exception caught in doTry12()"); + throw new MyException("Unexpected exception caught"); + } finally { + new Hashtable().get(new Object()).toString(); + } + } + private int doTry2111() { + try { + throw new MyException("MyException thrown"); + } catch (MyException e) { + } catch (Throwable t) { + log.add("Unexpected exception caught in doTry2111()"); + return Result.FAIL; + } finally { + } + return Result.PASS; + } + private void doTry2112() throws MyException { + try { + throw new MyException("MyException thrown"); + } catch (MyException e) { + } catch (Throwable t) { + log.add("Unexpected exception caught in doTry2112()"); + throw new MyException("Unexpected exception caught"); + } finally { + new Hashtable().get(new Object()).toString(); + } + } + private void doTry2121() throws MyException { + try { + throw new MyException("MyException thrown"); + } catch (MyException e) { + new Hashtable().get(new Object()).toString(); + } catch (Throwable t) { + log.add("Unexpected exception caught in doTry2121()"); + throw new MyException("Unexpected exception caught"); + } finally { + } + } + private void doTry2122() throws MyException { + try { + throw new MyException("MyException thrown"); + } catch (MyException e) { + throw new MyException("MyException caught"); + } catch (Throwable t) { + log.add("Unexpected exception caught in doTry2122()"); + throw new MyException("Unexpected exception caught"); + } finally { + new Hashtable().get(new Object()).toString(); + } + } + private void doTry221() throws MyException { + try { + new Hashtable().get(new Object()).toString(); + } catch (ClassCircularityError e) { + log.add("Unexpected exception caught in doTry221()"); + throw new MyException("Unexpected OOME caught"); + } finally { + } + } + private void doTry222() throws MyException { + try { + throw new MyException("MyException thrown"); + } catch (NullPointerException e) { + log.add("Unexpected exception caught in doTry222()"); + throw new MyException("Unexpected NPE caught"); + } finally { + new Hashtable().get(new Object()).toString(); + } + } + } + + private static native void nativeMethod(); + + private static class MyException extends Exception { + public MyException(String msg) { + super(msg); + } + } +} Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java?view=auto&rev=545554 ============================================================================== --- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java (added) +++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java Fri Jun 8 09:34:52 2007 @@ -0,0 +1,523 @@ +/* + * Copyright 2006 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Tatyana V. Doubtsova + * @version $Revision: 1.1 $ + */ + +package org.apache.harmony.test.reliability.vm.finalization; + +import org.apache.harmony.test.reliability.share.Test; +import java.util.Random; + +/* + * Goal: check that no memory leaks occur and finalization works with objects of various types + * created and then lost for GC-ing being elemnents of static or instance arrays. + * + * The test does: + * + * 1. For each of the types: Object, Thread, Classloader + * + * a. Initializes instance and static arrays of the given type. + * + * b. For each of mode: synchronized array, synchronized array's element + * + * * Runs N_OF_THREADS Threads. Each Thread randomly chooses range of array indexes + * to substitute objects and substitutes the objects (the elements of the array), + * either locking the whole array or just element being substituted. + * + * * Runs Runtime.runFinalization() and System.gc(). + * + * * The test is not to crash, hang or throw OOME + */ + +public class ArrayElemFinalizationTest extends Test { + + // These are tested object arrays holders: + + static Object[] static_object_array = null; + Object[] instance_object_array = null; + + static Object[] static_thread_array = null; + Object[] instance_thread_array = null; + + static Object[] static_classloader_array = null; + Object[] instance_classloader_array = null; + + + static final int ARRAY_SIZE = 1000; + + static final int BYTE_ARRAY_SIZE = 1000; + + static final int N_OF_THREADS = 100; + + static final int SYNCED_OBJECT = 1; + static final int SYNCED_ARRAY = 2; + + + public static void main(String[] args) { + System.exit(new ArrayElemFinalizationTest().test(args)); + } + + + public int test(String[] params) { + + boolean passed = true; + boolean status = false; + Object[][] arr; + + parseParams(params); + + //------------------ CASE 1: + + // Initialize 2 arrays (static anf instance) of Object objects: + + arr = initializeObjectArrays(); + + // Run threads which lock Objects of arrays, substitute objects + + status = (new TestObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_OBJECT); + passed &= status; + + //log.add("Finalization of Objects in array, Objects are synchronized. Passed? " + status); + + //------------------ CASE 2: + + // Run threads which lock arrays of Objects, substitute objects + + status = (new TestObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_ARRAY); + passed &= status; + + //log.add("Finalization of Objects, array is synchronized. Passed? " + status); + + + //------------------ CASE 3: + + // Initialize 2 arrays (static anf instance) of Thread objects: + + arr = initializeThreadArrays(); + + // Run threads which lock Thread objects of arrays, substitute threads in array + + status = (new TestThreadObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_OBJECT); + passed &= status; + + //log.add("Finalization of Thread objects in array, Thread objects are synchronized. Passed? " + status); + + + //------------------ CASE 4: + + // Run threads which lock arrays of Threads, substitute Thread objects + + status = (new TestThreadObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_ARRAY); + passed &= status; + + //log.add("Finalization of Thread objects, array is synchronized. Passed? " + status); + + + //------------------ CASE 5: + + // Initialize 2 arrays (static anf instance) of Classloader objects: + + arr = initializeClArrays(); + + // Run threads which lock Classloader objects of arrays, substitute classloaders in array + + status = (new TestClassLoaderObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_OBJECT); + passed &= status; + + //log.add("Finalization of classloader objects in array, classloader objects are synchronized. Passed? " + status); + + + //------------------ CASE 6: + + // Run threads which lock arrays of Classloaders objects, substitute Classloader objects + + status = (new TestClassLoaderObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_ARRAY); + passed &= status; + + //log.add("Finalization of Classloader objects, array is synchronized. Passed? " + status); + + if (!passed) { + return fail("Failed"); + } + + return pass("OK"); + } + + + Object[][] initializeObjectArrays() { + + // The method initializes instance and static arrays of Objects + + static_object_array = new Object[ARRAY_SIZE]; + instance_object_array = new Object[ARRAY_SIZE]; + + Object[][] arr = new Object[2][]; + + arr[0] = static_object_array; + arr[1] = instance_object_array; + + for (int i = 0; i < arr.length; ++i) { + for (int j = 0; j < arr[i].length; ++j) { + arr[i][j] = new FinalizableObject(); // simple Object + } + } + + return arr; + } + + Object[][] initializeThreadArrays() { + + // The method initializes instance and static arrays of Thread objects + + static_thread_array = new Object[ARRAY_SIZE]; + instance_thread_array = new Object[ARRAY_SIZE]; + + Object[][] arr = new Object[2][]; + + arr[0] = static_thread_array; + arr[1] = instance_thread_array; + + for (int i = 0; i < arr.length; ++i) { + for (int j = 0; j < arr[i].length; ++j) { + arr[i][j] = new FinalizableThreadObject(); // Thread object + } + } + return arr; + } + + + Object[][] initializeClArrays() { + + // The method initializes instance and static arrays of Classloader objects + + static_classloader_array = new Object[ARRAY_SIZE]; + instance_classloader_array = new Object[ARRAY_SIZE]; + + Object[][] arr = new Object[2][]; + + arr[0] = static_classloader_array; + arr[1] = instance_classloader_array; + + for (int i = 0; i < arr.length; ++i) { + for (int j = 0; j < arr[i].length; ++j) { + arr[i][j] = new FinalizableClassloaderObject(); // Classloader object + } + } + return arr; + } + + + public void parseParams(String[] params) { + + } + +} + + +class TestObjectFinalization { + + // This is the base class for the other 2 classes (which work with + // arrays of Thread and Classloader objects). + + ArrayElemFinalizationTest base; + + public TestObjectFinalization(ArrayElemFinalizationTest base){ + + // Why we need the base? - just to use "log" to print output to. + + this.base = base; + } + + boolean finalizeObjectsInArray(Object[][] arr, int type) { + + // The method just creates N_OF_THREADS Threads each substituting + // objects in the "arr" arrays. arr[0] is instance array, arr[1] is + // static array. + + Thread[] t = new Thread[ArrayElemFinalizationTest.N_OF_THREADS]; + + for (int j = 0; j < arr.length; ++j) { + + for (int i = 0; i < t.length ; ++i) { + t[i] = createThread(arr[j], type); + t[i].start(); + } + + for (int i = 0; i < t.length ; ++i) { + try { + t[i].join(); + } catch (InterruptedException ie) { + ArrayElemFinalizationTest.log.add("Thread " + t[i] + " was interrupted."); + return false; + } + } + + Runtime.getRuntime().runFinalization(); + System.gc(); + } + + return true; + } + + + Thread createThread(Object[] arr, int type) { + + // The method is overriden in 2 subclasses which use own Threads + // for substitution objects in arrays. + + return new TSubstSyncedObectInArray(arr, type); + } + + long get_num_of_created_objects() { + return FinalizableObject.num_of_created_objects; + } + + long get_num_of_finalized_objects() { + return FinalizableObject.num_of_finalized_objects; + } + + void null_num_of_finalized_objects() { + FinalizableObject.num_of_finalized_objects = 0; + } + + void null_num_of_created_objects() { + FinalizableObject.num_of_created_objects = 0; + } +} + + +class TestThreadObjectFinalization extends TestObjectFinalization { + + public TestThreadObjectFinalization(ArrayElemFinalizationTest base){ + super(base); + } + + Thread createThread(Object[] arr, int type) { + return new TSubstSyncedThrObectInArray(arr, type); + } + + long get_num_of_created_objects() { + return FinalizableThreadObject.num_of_created_objects; + } + + long get_num_of_finalized_objects() { + return FinalizableThreadObject.num_of_finalized_objects; + } + + void null_num_of_finalized_objects() { + FinalizableThreadObject.num_of_finalized_objects = 0; + } + + void null_num_of_created_objects() { + FinalizableThreadObject.num_of_created_objects = 0; + } +} + + +class TestClassLoaderObjectFinalization extends TestObjectFinalization { + + public TestClassLoaderObjectFinalization(ArrayElemFinalizationTest base){ + super(base); + } + + Thread createThread(Object[] arr, int type) { + return new TSubstSyncedClObectInArray(arr, type); + } + + long get_num_of_created_objects() { + return FinalizableClassloaderObject.num_of_created_objects; + } + + long get_num_of_finalized_objects() { + return FinalizableClassloaderObject.num_of_finalized_objects; + } + + void null_num_of_finalized_objects() { + FinalizableClassloaderObject.num_of_finalized_objects = 0; + } + + void null_num_of_created_objects() { + FinalizableClassloaderObject.num_of_created_objects = 0; + } +} + + +class TSubstSyncedObectInArray extends Thread { + + static Random r = new Random(10); + int type = ArrayElemFinalizationTest.SYNCED_OBJECT; + + Object[] obj_array; + + static final int SLEEP_TIMEOUT = 20; + + public TSubstSyncedObectInArray(Object[] obj_array, int type) { + this.obj_array = obj_array; + this.type = type; + } + + public void run() { + + // When thread starts it sleeps for some arbitrary time: + + try { + Thread.sleep(r.nextInt(SLEEP_TIMEOUT)); + } catch (InterruptedException ie){ + } + + // Then, we select index from which substitute objects in array + // and index up to which substitute objects: + + int i = r.nextInt(obj_array.length); + int j = r.nextInt(obj_array.length); + + int from = i < j ? i : j; + int to = i >= j ? i : j; + + // Finally, substitute objects either locking the whole array or locking + // just beings substituted object. + + if (type == ArrayElemFinalizationTest.SYNCED_OBJECT) { + + for (int x = from; x < to; ++x) { + synchronized(obj_array[x]){ + obj_array[x] = createObject(); + } + } + + } else if (type == ArrayElemFinalizationTest.SYNCED_ARRAY) { + + synchronized(obj_array){ + for (int x = from; x < to; ++x) { + obj_array[x] = createObject(); + } + } + } + + // System.out.println(" " + from + ", " + to); + } + + + Object createObject() { + return new FinalizableObject(); + } +} + + +class TSubstSyncedThrObectInArray extends TSubstSyncedObectInArray { + + public TSubstSyncedThrObectInArray(Object[] obj_array, int type) { + super(obj_array, type); + } + + Object createObject() { + return new FinalizableThreadObject(); + } + +} + + +class TSubstSyncedClObectInArray extends TSubstSyncedObectInArray { + + public TSubstSyncedClObectInArray(Object[] obj_array, int type) { + super(obj_array, type); + } + + Object createObject() { + return new FinalizableClassloaderObject(); + } + +} + + +class FinalizableObject { + + volatile public static long num_of_created_objects = 0; + + volatile public static long num_of_finalized_objects = 0; + + byte[] b; + + public FinalizableObject() { + num_of_created_objects++; + b = new byte[ArrayElemFinalizationTest.BYTE_ARRAY_SIZE]; + } + + protected void finalize() { + synchronized(this) { // just in case + num_of_finalized_objects++; + } + } + +} + + +class FinalizableThreadObject extends Thread { + + volatile public static long num_of_created_objects = 0; + + volatile public static long num_of_finalized_objects = 0; + + byte[] b; + + public FinalizableThreadObject() { + num_of_created_objects++; + b = new byte[ArrayElemFinalizationTest.BYTE_ARRAY_SIZE]; + } + + protected void finalize() { + synchronized(this) { // just in case + num_of_finalized_objects++; + } + } + + public void run() { + } + +} + + +class FinalizableClassloaderObject extends ClassLoader { + + volatile public static long num_of_created_objects = 0; + + volatile public static long num_of_finalized_objects = 0; + + byte[] b; + + public FinalizableClassloaderObject() { + num_of_created_objects++; + b = new byte[ArrayElemFinalizationTest.BYTE_ARRAY_SIZE]; + } + + protected void finalize() { + synchronized(this) { // just in case + num_of_finalized_objects++; + } + } + + +} + + + + + + Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java ------------------------------------------------------------------------------ svn:eol-style = native