mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
08.13.2010 34ac48d938d5f3411505f7d0f883a585148ec716
sdk/tests/unit-tests-testng/src/org/opends/sdk/OpenDSTestCase.java
@@ -1,15 +1,43 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 */
package org.opends.sdk;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import java.util.IdentityHashMap;
import java.util.Set;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Set;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
/**
 * This class defines a base test case that should be subclassed by all
@@ -18,75 +46,86 @@
 * This class adds the ability to print error messages and automatically
 * have them include the class name.
 */
@Test(sequential=true)
public abstract class OpenDSTestCase
@Test(sequential = true)
public abstract class OpenDSTestCase
{
   @BeforeSuite
  public final void suppressOutput() {
    TestCaseUtils.suppressOutput();
  }
  @AfterSuite
  public final void shutdownServer() {
    TestCaseUtils.unsupressOutput();
  }
  //
  // This is all a HACK to reduce the amount of memory that's consumed.
  //
  // This could be a problem if a subclass references a @DataProvider in
  // a super-class that provides static parameters, i.e. the parameters are
  // a super-class that provides static parameters, i.e. the parameters
  // are
  // not regenerated for each invocation of the DataProvider.
  //
  /** A list of all parameters that were generated by a @DataProvider
   *  and passed to a test method of this class.  TestListener helps us
   *  keep this so that once all of the tests are finished, we can clear
   *  it out in an @AfterClass method.  We can't just clear it out right
   *  away in the TestListener because some methods share a @DataProvider.*/
  private final IdentityHashMap<Object[],Object> successfulTestParams = new IdentityHashMap<Object[],Object>();
  /**
   * A list of all parameters that were generated by a @DataProvider and
   * passed to a test method of this class. TestListener helps us keep
   * this so that once all of the tests are finished, we can clear it
   * out in an @AfterClass method. We can't just clear it out right away
   * in the TestListener because some methods share a @DataProvider.
   */
  private final IdentityHashMap<Object[], Object> successfulTestParams = new IdentityHashMap<Object[], Object>();
  /** These are test parameters from a test that has failed.  We need to
   *  keep these around because the test report expects to find them when
   *  printing out failures. */
  private final IdentityHashMap<Object[],Object> failedTestParams = new IdentityHashMap<Object[],Object>();
  /**
   * These are test parameters from a test that has failed. We need to
   * keep these around because the test report expects to find them when
   * printing out failures.
   */
  private final IdentityHashMap<Object[], Object> failedTestParams = new IdentityHashMap<Object[], Object>();
  /**
   * Adds testParams to the list of all test parameters, so it can be
   * null'ed out later if it's not part.
   */
  void addParamsFromSuccessfulTests(Object[] testParams) {
    if (testParams != null) {
  void addParamsFromSuccessfulTests(Object[] testParams)
  {
    if (testParams != null)
    {
      successfulTestParams.put(testParams, testParams);
    }
  }
  /**
   * Adds testParams to the list of all failed test parameters, so that we
   * know to NOT null it out later.
   * Adds testParams to the list of all failed test parameters, so that
   * we know to NOT null it out later.
   */
  void addParamsFromFailedTest(Object[] testParams) {
    if (testParams != null) {
  void addParamsFromFailedTest(Object[] testParams)
  {
    if (testParams != null)
    {
      failedTestParams.put(testParams, testParams);
    }
  }
  /**
   * null out all test parameters except the ones used in failed tests
   * since we might need these again.
   */
  @AfterClass(alwaysRun = true)
  public void clearSuccessfulTestParams() {
  public void clearSuccessfulTestParams()
  {
    Set<Object[]> paramsSet = successfulTestParams.keySet();
    if (paramsSet == null) {  // Can this ever happen?
    if (paramsSet == null)
    { // Can this ever happen?
      return;
    }
    for (Object[] params: paramsSet) {
      if (failedTestParams.containsKey(params)) {
    for (Object[] params : paramsSet)
    {
      if (failedTestParams.containsKey(params))
      {
        continue;
      }
      for (int i = 0; i < params.length; i++) {
      for (int i = 0; i < params.length; i++)
      {
        params[i] = null;
      }
    }
@@ -94,38 +133,47 @@
    failedTestParams.clear();
  }
  /**
   * The member variables of a test class can prevent lots of memory from being
   * reclaimed, so we use reflection to null out all of the member variables
   * after the tests have run.  Since all tests must inherit from
   * DirectoryServerTestCase, TestNG guarantees that this method runs after
   * all of the subclass methods, so this isn't too dangerous.
   * The member variables of a test class can prevent lots of memory
   * from being reclaimed, so we use reflection to null out all of the
   * member variables after the tests have run. Since all tests must
   * inherit from DirectoryServerTestCase, TestNG guarantees that this
   * method runs after all of the subclass methods, so this isn't too
   * dangerous.
   */
  @AfterClass(alwaysRun = true)
  public void nullMemberVariablesAfterTest() {
    Class cls = this.getClass();
  public void nullMemberVariablesAfterTest()
  {
    Class<?> cls = this.getClass();
    // Iterate through all of the fields in all subclasses of
    // DirectoryServerTestCase, but not DirectoryServerTestCase itself.
    while (OpenDSTestCase.class.isAssignableFrom(cls) &&
           !OpenDSTestCase.class.equals(cls))
    while (OpenDSTestCase.class.isAssignableFrom(cls)
        && !OpenDSTestCase.class.equals(cls))
    {
      Field fields[] = cls.getDeclaredFields();
      for (int i = 0; i < fields.length; i++) {
      for (int i = 0; i < fields.length; i++)
      {
        Field field = fields[i];
        int modifiers = field.getModifiers();
        Class fieldClass = field.getType();
        // If it's a non-static non-final non-primitive type, then null it out
        // so that the garbage collector can reclaim it and everything it
        Class<?> fieldClass = field.getType();
        // If it's a non-static non-final non-primitive type, then null
        // it out
        // so that the garbage collector can reclaim it and everything
        // it
        // references.
        if (!fieldClass.isPrimitive() &&
            !fieldClass.isEnum()      &&
            !Modifier.isFinal(modifiers) &&
            !Modifier.isStatic(modifiers))
        if (!fieldClass.isPrimitive() && !fieldClass.isEnum()
            && !Modifier.isFinal(modifiers)
            && !Modifier.isStatic(modifiers))
        {
          field.setAccessible(true);
          try {
          try
          {
            field.set(this, null);
          } catch (IllegalAccessException e) {
          }
          catch (IllegalAccessException e)
          {
            // We're only doing this to save memory, so it's no big deal
            // if we can't set it.
          }