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

neil_a_wilson
12.37.2006 9326a9d154902c9a798bd52937f6d83422cb4e8e
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/asn1/TestASN1Set.java
@@ -26,237 +26,505 @@
 */
package org.opends.server.protocols.asn1;
import static org.opends.server.util.StaticUtils.listsAreEqual;
import static org.testng.AssertJUnit.assertTrue;
import java.util.ArrayList;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
 * This class defines a set of tests for the
 * org.opends.server.protocols.asn1.ASN1Set class.
 */
public class TestASN1Set extends ASN1TestCase {
  // The sets of pre-encoded ASN.1 elements that will be included in the
  // test
  // case.
  private ArrayList<ArrayList<ASN1Element>> testElementSets;
public class TestASN1Set
       extends ASN1TestCase
{
  // The array of element arrays to use for the testing.  Each element is a
  // single-element array containing a byte[] with the encoded elements.
  private Object[][] elementArrays;
  // The set of pre-encoded element sets that will be used in the test
  // cases.
  private ArrayList<byte[]> testEncodedElementSets;
  // The array of elements to use for the testing.  Each element is a
  // single-element array containing an ArrayList<ASN1Element>.
  private Object[][] elementLists;
  /**
   * Performs any necessary initialization for this test case.
   * Constructs the element lists that will be used to perform the testing.
   */
  @BeforeClass
  public void setUp() {
    // Initialize the sets of ASN.1 elements that will be used in
    // testing the
    // group encode/decode operations.
    testElementSets = new ArrayList<ArrayList<ASN1Element>>();
    testEncodedElementSets = new ArrayList<byte[]>();
  @BeforeClass()
  public void populateElementLists()
  {
    ArrayList<ArrayList<ASN1Element>> lists =
         new ArrayList<ArrayList<ASN1Element>>();
    testElementSets.add(null); // The null set.
    testEncodedElementSets.add(new byte[0]);
    // Add a null element.
    lists.add(null);
    testElementSets.add(new ArrayList<ASN1Element>(0)); // The empty
    // set.
    testEncodedElementSets.add(new byte[0]);
    // Add an empty list.
    lists.add(new ArrayList<ASN1Element>());
    // Sets containing from 1 to 10 zero-length elements.
    for (int i = 1; i <= 10; i++) {
      ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(i);
    // Create an array of single elements, and add each of them in their own
    // lists.
    ASN1Element[] elementArray =
    {
      new ASN1OctetString(),
      new ASN1OctetString((byte) 0x50),
      new ASN1OctetString(new byte[50]),
      new ASN1OctetString("Hello"),
      new ASN1Element((byte) 0x50),
      new ASN1Element((byte) 0x50, new byte[50]),
      new ASN1Boolean(false),
      new ASN1Boolean(true),
      new ASN1Enumerated(0),
      new ASN1Enumerated(1),
      new ASN1Enumerated(127),
      new ASN1Enumerated(128),
      new ASN1Enumerated(255),
      new ASN1Enumerated(256),
      new ASN1Integer(0),
      new ASN1Integer(1),
      new ASN1Integer(127),
      new ASN1Integer(128),
      new ASN1Integer(255),
      new ASN1Integer(256),
      new ASN1Long(0),
      new ASN1Long(1),
      new ASN1Long(127),
      new ASN1Long(128),
      new ASN1Long(255),
      new ASN1Long(256),
      new ASN1Null(),
      new ASN1Sequence(),
      new ASN1Set()
    };
      for (int j = 0; j < i; j++) {
        elements.add(new ASN1Element((byte) 0x00));
      }
      testElementSets.add(elements);
      testEncodedElementSets.add(new byte[i * 2]);
    // Add lists of single elements.
    for (ASN1Element e : elementArray)
    {
      ArrayList<ASN1Element> list = new ArrayList<ASN1Element>(1);
      list.add(e);
      lists.add(list);
    }
    // Sets containing from 1 to 10 1-byte-length elements.
    for (int i = 1; i <= 10; i++) {
      ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(i);
      byte[] encodedElements = new byte[i * 3];
      for (int j = 0; j < i; j++) {
        elements.add(new ASN1Element((byte) 0x00, new byte[1]));
        encodedElements[(j * 3) + 1] = (byte) 0x01;
    // Create multi-element lists based on the single-element lists.
    for (int i=0; i < elementArray.length; i++)
    {
      ArrayList<ASN1Element> list = new ArrayList<ASN1Element>(i+1);
      for (int j=0; j <=i; j++)
      {
        list.add(elementArray[j]);
      }
      testElementSets.add(elements);
      testEncodedElementSets.add(encodedElements);
      lists.add(list);
    }
    // Sets containing from 1 to 10 127-byte-length elements.
    for (int i = 1; i <= 10; i++) {
      ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(i);
      byte[] encodedElements = new byte[i * 129];
      for (int j = 0; j < i; j++) {
        elements.add(new ASN1Element((byte) 0x00, new byte[127]));
        encodedElements[(j * 129) + 1] = (byte) 0x7F;
      }
      testElementSets.add(elements);
      testEncodedElementSets.add(encodedElements);
    // Convert the lists into object arrays.
    elementLists = new Object[lists.size()][1];
    for (int i=0; i < elementLists.length; i++)
    {
      elementLists[i] = new Object[] { lists.get(i) };
    }
    // Sets containing from 1 to 10 128-byte-length elements.
    for (int i = 1; i <= 10; i++) {
      ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(i);
      byte[] encodedElements = new byte[i * 131];
      for (int j = 0; j < i; j++) {
        elements.add(new ASN1Element((byte) 0x00, new byte[128]));
        encodedElements[(j * 131) + 1] = (byte) 0x81;
        encodedElements[(j * 131) + 2] = (byte) 0x80;
      }
      testElementSets.add(elements);
      testEncodedElementSets.add(encodedElements);
    lists.remove(null);
    elementArrays = new Object[lists.size()][1];
    for (int i=0; i < elementArrays.length; i++)
    {
      elementArrays[i] = new Object[] { ASN1Element.encodeValue(lists.get(i)) };
    }
  }
  /**
   * Retrieves lists of byte arrays that can be used to construct sets.
   *
   * @return  Lists of byte arrays that can be used to construct sets.
   */
  @DataProvider(name = "elementArrays")
  public Object[][] getElementArrays()
  {
    return elementArrays;
  }
  /**
   * Retrieves lists of ASN.1 elements that can be used to construct sets.
   *
   * @return  Lists of ASN.1 elements that can be used to construct sets.
   */
  @DataProvider(name = "elementLists")
  public Object[][] getElementLists()
  {
    return elementLists;
  }
  /**
   * Tests the first constructor, which doesn't take any arguments.
   */
  @Test()
  public void testConstructor1()
  {
    new ASN1Set();
  }
  /**
   * Create the values that can be used for testing BER types.
   *
   * @return  The values that can be used for testing BER types.
   */
  @DataProvider(name = "types")
  public Object[][] getTypes()
  {
    // Create an array with all of the valid single-byte types.  We don't
    // support multi-byte types, so this should be a comprehensive data set.
    Object[][] testTypes = new Object[0xFF][1];
    for (int i=0x00; i < 0xFF; i++)
    {
      testTypes[i] = new Object[] { (byte) (i & 0xFF) };
    }
    return testTypes;
  }
  /**
   * Tests the second constructor, which takes a byte argument.
   *
   * @param  b  The BER type to use for the set.
   */
  @Test(dataProvider = "types")
  public void testConstructor2(byte b)
  {
    new ASN1Set(b);
  }
  /**
   * Tests the third constructor, which takes a list of elements.
   *
   * @param  elements  The list of elements to use to create the set.
   */
  @Test(dataProvider = "elementLists")
  public void testConstructor3(ArrayList<ASN1Element> elements)
  {
    new ASN1Set(elements);
  }
  /**
   * Tests the third constructor, which takes a byte and a list of elements.
   *
   * @param  elements  The list of elements to use to create the set.
   */
  @Test(dataProvider = "elementLists")
  public void testConstructor4(ArrayList<ASN1Element> elements)
  {
    for (int i=0; i < 255; i++)
    {
      new ASN1Set((byte) (i & 0xFF), elements);
    }
  }
  /**
   * Tests the <CODE>elements</CODE> method.
   *
   * @param  elements  The list of elements to use to create the set.
   */
  @Test()
  public void testElements() {
    int numElementSets = testElementSets.size();
    for (int i = 0; i < numElementSets; i++) {
      ArrayList<ASN1Element> elementSet = testElementSets.get(i);
      ArrayList<ASN1Element> compareList;
      if (elementSet == null) {
        compareList = new ArrayList<ASN1Element>(0);
      } else {
        compareList = elementSet;
      }
      ASN1Set element = new ASN1Set(elementSet);
      assertTrue(listsAreEqual(compareList, element.elements()));
  @Test(dataProvider = "elementLists")
  public void testGetElements(ArrayList<ASN1Element> elements)
  {
    ASN1Set s = new ASN1Set(elements);
    if (elements == null)
    {
      assertEquals(new ArrayList<ASN1Element>(), s.elements());
    }
    else
    {
      assertEquals(elements, s.elements());
    }
  }
  /**
   * Tests the <CODE>setElements</CODE> method.
   */
  @Test()
  public void testSetElements() {
    ASN1Set element = new ASN1Set();
    int numElementSets = testElementSets.size();
    for (int i = 0; i < numElementSets; i++) {
      ArrayList<ASN1Element> elementSet = testElementSets.get(i);
      ArrayList<ASN1Element> compareList;
      if (elementSet == null) {
        compareList = new ArrayList<ASN1Element>(0);
      } else {
        compareList = elementSet;
      }
      element.setElements(elementSet);
      assertTrue(listsAreEqual(compareList, element.elements()));
    }
  }
  /**
   * Tests the <CODE>setValue</CODE> method.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   * @param  elements  The list of elements to use to create the set.
   */
  @Test()
  public void testSetValue() throws Exception {
    ASN1Set element = new ASN1Set();
    int numElementSets = testElementSets.size();
    for (int i = 0; i < numElementSets; i++) {
      ArrayList<ASN1Element> elementSet = testElementSets.get(i);
      byte[] encodedElementSet = testEncodedElementSets.get(i);
      ArrayList<ASN1Element> compareList;
      if (elementSet == null) {
        compareList = new ArrayList<ASN1Element>(0);
      } else {
        compareList = elementSet;
      }
      element.setValue(encodedElementSet);
      assertTrue(listsAreEqual(compareList, element.elements()));
  @Test(dataProvider = "elementLists")
  public void testSetElements(ArrayList<ASN1Element> elements)
  {
    ASN1Set s = new ASN1Set();
    s.setElements(elements);
    if (elements == null)
    {
      assertEquals(new ArrayList<ASN1Element>(), s.elements());
    }
    else
    {
      assertEquals(elements, s.elements());
    }
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes an ASN.1
   * element argument.
   * Tests the <CODE>setValue</CODE> method with valid values.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   * @param  encodedElements  The byte array containing the encoded elements to
   *                          use in the value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeElementAsSet() throws Exception {
    int numElementSets = testElementSets.size();
    for (int i = 0; i < numElementSets; i++) {
      ArrayList<ASN1Element> elementSet = testElementSets.get(i);
      byte[] encodedElementSet = testEncodedElementSets.get(i);
      ArrayList<ASN1Element> compareList;
      if (elementSet == null) {
        compareList = new ArrayList<ASN1Element>(0);
      } else {
        compareList = elementSet;
      }
      ASN1Element element = new ASN1Element((byte) 0x00, encodedElementSet);
      assertTrue(listsAreEqual(compareList, ASN1Set.decodeAsSet(element)
          .elements()));
    }
  @Test(dataProvider = "elementArrays")
  public void testSetValueValid(byte[] encodedElements)
         throws Exception
  {
    ASN1Set s = new ASN1Set();
    s.setValue(encodedElements);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes a byte array
   * Tests the <CODE>setValue</CODE> method with a null array.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { ASN1Exception.class })
  public void testSetValueNull()
         throws Exception
  {
    ASN1Set s = new ASN1Set();
    s.setValue(null);
  }
  /**
   * Retrieves a set of byte arrays containing invalid element value encodings.
   *
   * @return  A set of byte arrays containing invalid element value encodings.
   */
  @DataProvider(name = "invalidElementArrays")
  public Object[][] getInvalidArrays()
  {
    return new Object[][]
    {
      new Object[] { new byte[] { 0x05 } },
      new Object[] { new byte[] { 0x05, 0x01 } },
      new Object[] { new byte[] { 0x05, (byte) 0x85, 0x00, 0x00, 0x00, 0x00,
                                  0x00 } },
      new Object[] { new byte[] { 0x05, (byte) 0x82, 0x00 } },
      new Object[] { new byte[] { 0x05, 0x00, 0x05 } },
      new Object[] { new byte[] { 0x05, 0x00, 0x05, 0x01 } },
    };
  }
  /**
   * Tests the <CODE>setValue</CODE> method with valid values.
   *
   * @param  encodedElements  The byte array containing the encoded elements to
   *                          use in the value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "invalidElementArrays",
        expectedExceptions = { ASN1Exception.class })
  public void testSetValueInvalid(byte[] invalidElements)
         throws Exception
  {
    ASN1Set s = new ASN1Set();
    s.setValue(invalidElements);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes an ASN1Element
   * argument with valid elements.
   *
   * @param  encodedElements  Byte arrays that may be used as valid values for
   *                          encoded elements.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "elementArrays")
  public void testDecodeValidElementAsSet(byte[] encodedElements)
         throws Exception
  {
    ASN1Element e = new ASN1Element(ASN1Constants.UNIVERSAL_SET_TYPE,
                                    encodedElements);
    ASN1Set.decodeAsSet(e);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes an ASN1Element
   * argument with valid elements.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { ASN1Exception.class })
  public void testDecodeNullElementAsSet()
         throws Exception
  {
    ASN1Element e = null;
    ASN1Set.decodeAsSet(e);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes a byte array argument
   * with valid arrays.
   *
   * @param  encodedElements  Byte arrays that may be used as valid values for
   *                          encoded elements.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "elementArrays")
  public void testDecodeValidArrayAsSet(byte[] encodedElements)
         throws Exception
  {
    byte[] encodedLength = ASN1Element.encodeLength(encodedElements.length);
    byte[] elementBytes  =
         new byte[1 + encodedLength.length + encodedElements.length];
    elementBytes[0] = ASN1Constants.UNIVERSAL_SET_TYPE;
    System.arraycopy(encodedLength, 0, elementBytes, 1, encodedLength.length);
    System.arraycopy(encodedElements, 0, elementBytes, 1+encodedLength.length,
                     encodedElements.length);
    ASN1Set.decodeAsSet(elementBytes);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes a byte array argument
   * with a null array.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { ASN1Exception.class })
  public void testDecodeNullArrayAsSet()
         throws Exception
  {
    byte[] b = null;
    ASN1Set.decodeAsSet(b);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes a byte array argument
   * with a short array.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { ASN1Exception.class })
  public void testDecodeShortArrayAsSet()
         throws Exception
  {
    byte[] b = new byte[1];
    ASN1Set.decodeAsSet(b);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes a byte array argument
   * with an array that takes too many bytes to encode the length.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { ASN1Exception.class })
  public void testDecodeLongLengthArrayAsSet()
         throws Exception
  {
    byte[] b = { 0x30, (byte) 0x85, 0x00, 0x00, 0x00, 0x00, 0x00 };
    ASN1Set.decodeAsSet(b);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes a byte array argument
   * with an array that doesn't fully describe the length.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { ASN1Exception.class })
  public void testDecodeTruncatedLengthArrayAsSet()
         throws Exception
  {
    byte[] b = { 0x30, (byte) 0x82, 0x00 };
    ASN1Set.decodeAsSet(b);
  }
  /**
   * Tests the <CODE>decodeAsSet</CODE> method that takes a byte array argument
   * with an array whose decoded length doesn't match the real length.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { ASN1Exception.class })
  public void testDecodeLengthMismatchArrayAsSet()
         throws Exception
  {
    byte[] b = { 0x30, 0x01 };
    ASN1Set.decodeAsSet(b);
  }
  /**
   * Tests the <CODE>toString</CODE> method that takes a string builder
   * argument.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   * @param  elements  The list of elements to use to create the set.
   */
  @Test()
  public void testDecodeBytesAsSet() throws Exception {
    int numElementSets = testElementSets.size();
    for (int i = 0; i < numElementSets; i++) {
      ArrayList<ASN1Element> elementSet = testElementSets.get(i);
      byte[] encodedElementSet = testEncodedElementSets.get(i);
  @Test(dataProvider = "elementLists")
  public void testToString1(ArrayList<ASN1Element> elements)
  {
    new ASN1Set(elements).toString(new StringBuilder());
  }
      ArrayList<ASN1Element> compareList;
      if (elementSet == null) {
        compareList = new ArrayList<ASN1Element>(0);
      } else {
        compareList = elementSet;
      }
      byte[] encodedLength = ASN1Element
          .encodeLength(encodedElementSet.length);
      byte[] encodedElement = new byte[1 + encodedLength.length
          + encodedElementSet.length];
      encodedElement[0] = 0x00;
      System.arraycopy(encodedLength, 0, encodedElement, 1,
          encodedLength.length);
      System.arraycopy(encodedElementSet, 0, encodedElement,
          1 + encodedLength.length, encodedElementSet.length);
      assertTrue(listsAreEqual(compareList, ASN1Set.decodeAsSet(
          encodedElement).elements()));
    }
  /**
   * Tests the <CODE>toString</CODE> method that takes string builder and
   * integer arguments.
   *
   * @param  elements  The list of elements to use to create the set.
   */
  @Test(dataProvider = "elementLists")
  public void testToString2(ArrayList<ASN1Element> elements)
  {
    new ASN1Set(elements).toString(new StringBuilder(), 1);
  }
}