blob: 2ca18c0053dc2ae590ad71766eaa18010078f99b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* https://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.directory.api.ldap.model.entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.Normalizer;
import org.apache.directory.api.ldap.model.schema.PrepareString;
import org.apache.directory.api.ldap.model.schema.comparators.ByteArrayComparator;
import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OctetStringSyntaxChecker;
import org.apache.directory.api.util.Strings;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
/**
* Tests that the Value class works properly as expected.
*
* Some notes while conducting tests:
*
* <ul>
* <li>comparing values with different types - how does this behave</li>
* <li>exposing access to at from value or to a comparator?</li>
* </ul>
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
@Execution(ExecutionMode.CONCURRENT)
public class BinaryValueAttributeTypeTest
{
private LdapSyntax s;
private AttributeType at;
private MatchingRule mr;
private static final byte[] BYTES1 = new byte[]
{ 0x01, 0x02, 0x03, 0x04 };
private static final byte[] BYTES2 = new byte[]
{ ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83, ( byte ) 0x84 };
/**
* Initialize an AttributeType and the associated MatchingRule
* and Syntax
*/
@BeforeEach
public void initAT()
{
s = EntryUtils.syntaxFactory( "1.1.1.1", false );
s.setSyntaxChecker( OctetStringSyntaxChecker.INSTANCE );
mr = EntryUtils.matchingRuleFactory( "1.1.2.1" );
mr.setSyntax( s );
mr.setLdapComparator( new ByteArrayComparator( "1.1.1" ) );
mr.setNormalizer( new Normalizer( "1.1.1" )
{
public static final long serialVersionUID = 1L;
public String normalize( String value ) throws LdapException
{
return normalize( value, PrepareString.AssertionType.ATTRIBUTE_VALUE );
}
public String normalize( String value, PrepareString.AssertionType assertionType ) throws LdapException
{
byte[] val = Strings.getBytesUtf8( value );
// each byte will be changed to be > 0, and spaces will be trimmed
byte[] newVal = new byte[val.length];
int i = 0;
for ( byte b : val )
{
newVal[i++] = ( byte ) ( b & 0x007F );
}
return Strings.utf8ToString( Strings.trim( newVal ) );
}
} );
at = new AttributeType( "1.1.3.1" );
at.setEquality( mr );
at.setOrdering( mr );
at.setSubstring( mr );
at.setSyntax( s );
}
/**
* Serialize a Value
*/
private ByteArrayOutputStream serializeValue( Value value ) throws IOException
{
ObjectOutputStream oOut = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try
{
oOut = new ObjectOutputStream( out );
value.writeExternal( oOut );
}
catch ( IOException ioe )
{
throw ioe;
}
finally
{
try
{
if ( oOut != null )
{
oOut.flush();
oOut.close();
}
}
catch ( IOException ioe )
{
throw ioe;
}
}
return out;
}
/**
* Deserialize a Value
*/
private Value deserializeValue( ByteArrayOutputStream out, AttributeType at ) throws IOException,
ClassNotFoundException
{
ObjectInputStream oIn = null;
ByteArrayInputStream in = new ByteArrayInputStream( out.toByteArray() );
try
{
oIn = new ObjectInputStream( in );
Value value = Value.createValue( ( AttributeType ) null );
value.readExternal( oIn );
return value;
}
finally
{
try
{
if ( oIn != null )
{
oIn.close();
}
}
catch ( IOException ioe )
{
throw ioe;
}
}
}
/**
* Test the constructor with bad AttributeType
* @throws LdapInvalidAttributeValueException
*/
@Test
public void testBadConstructor()
{
// create a AT with no syntax
AttributeType attribute = new AttributeType( "1.1.3.1" );
Value value = Value.createValue( attribute );
assertTrue( value.isHumanReadable() );
}
/**
* Test the constructor with a null value
*/
@Test
public void testServerBinaryValueNullValue() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value value = new Value( attribute, ( byte[] ) null );
assertNull( value.getBytes() );
assertTrue( value.isNull() );
}
/**
* Test the constructor with an empty value
*/
@Test
public void testServerBinaryValueEmptyValue() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value value = new Value( attribute, Strings.EMPTY_BYTES );
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) );
assertFalse( value.isNull() );
}
/**
* Test the constructor with a value
* @throws LdapInvalidAttributeValueException
*/
@Test
public void testServerBinaryValueNoValue() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
byte[] val = new byte[]
{ 0x01 };
Value bv = new Value( attribute, val );
assertTrue( Arrays.equals( val, bv.getBytes() ) );
assertFalse( bv.isNull() );
}
/**
* Test the constructor with a value
*/
@Test
public void testServerBinaryValue() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
byte[] val = new byte[]
{ 0x01 };
Value value = new Value( attribute, val );
assertTrue( Arrays.equals( val, value.getBytes() ) );
assertFalse( value.isNull() );
assertTrue( Arrays.equals( val, value.getBytes() ) );
}
/**
* Test the clone method
*/
@Test
public void testClone() throws LdapException
{
AttributeType at1 = EntryUtils.getBytesAttributeType();
Value bv = new Value( at1, ( byte[] ) null );
Value bv1 = bv.clone();
assertEquals( bv, bv1 );
bv = new Value( Strings.EMPTY_BYTES );
assertNotSame( bv, bv1 );
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) );
bv = new Value( at, BYTES2 );
bv1 = bv.clone();
assertEquals( bv, bv1 );
}
/**
* Test the equals method
*/
@Test
public void testEquals() throws LdapInvalidAttributeValueException
{
AttributeType at1 = EntryUtils.getBytesAttributeType();
Value value1 = new Value( at1, new byte[]
{ 0x01, ( byte ) 0x02 } );
Value value2 = new Value( at1, new byte[]
{ 0x01, ( byte ) 0x02 } );
Value value3 = new Value( at1, new byte[]
{ 0x01, ( byte ) 0x82 } );
Value value4 = new Value( at1, new byte[]
{ 0x01 } );
Value value5 = new Value( at1, ( byte[] ) null );
Value value6 = new Value( at, new byte[]
{ 0x01, 0x02 } );
Value value7 = new Value( EntryUtils.getIA5StringAttributeType(),
"test" );
assertTrue( value1.equals( value1 ) );
assertTrue( value1.equals( value2 ) );
assertFalse( value1.equals( value3 ) );
assertFalse( value1.equals( value4 ) );
assertFalse( value1.equals( value5 ) );
assertFalse( value1.equals( "test" ) );
assertFalse( value1.equals( null ) );
assertTrue( value1.equals( value6 ) );
assertFalse( value1.equals( value7 ) );
}
/**
* Test the getNormValue method
*/
@Test
public void testGetNormalizedValue() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value value = new Value( attribute, ( byte[] ) null );
assertNull( value.getBytes() );
value = new Value( attribute, Strings.EMPTY_BYTES );
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) );
value = new Value( attribute, BYTES2 );
assertTrue( Arrays.equals( BYTES2, value.getBytes() ) );
}
/**
* Test the getNormValue method
*/
@Test
public void testGetNormalizedValueCopy() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value value = new Value( attribute, ( byte[] ) null );
assertNull( value.getBytes() );
value = new Value( attribute, Strings.EMPTY_BYTES );
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) );
value = new Value( attribute, BYTES2 );
assertTrue( Arrays.equals( BYTES2, value.getBytes() ) );
}
/**
* Test the getNormValue method
*/
@Test
public void testGetNormalizedValueReference() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value value = new Value( attribute, ( byte[] ) null );
assertNull( value.getBytes() );
value = new Value( attribute, Strings.EMPTY_BYTES );
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) );
value = new Value( attribute, BYTES2 );
assertTrue( Arrays.equals( BYTES2, value.getBytes() ) );
}
/**
* Test the getAttributeType method
* @throws LdapInvalidAttributeValueException
*/
@Test
public void testgetAttributeType() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value sbv = Value.createValue( attribute );
assertEquals( attribute, sbv.getAttributeType() );
}
/**
* Test the isValid method
*
* The SyntaxChecker does not accept values longer than 5 chars.
*/
@Test
public void testIsValid() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
new Value( attribute, ( byte[] ) null );
new Value( attribute, Strings.EMPTY_BYTES );
new Value( attribute, new byte[]
{ 0x01, 0x02 } );
try
{
new Value( attribute, new byte[]
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 } );
fail();
}
catch ( LdapInvalidAttributeValueException liave )
{
assertTrue( true );
}
}
/**
* Tests to make sure the hashCode method is working properly.
* @throws Exception on errors
*/
@Test
public void testHashCode() throws LdapInvalidAttributeValueException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value v0 = new Value( attribute, new byte[]
{ 0x01, 0x02 } );
Value v1 = new Value( attribute, new byte[]
{ ( byte ) 0x81, ( byte ) 0x82 } );
Value v2 = new Value( attribute, new byte[]
{ 0x01, 0x02 } );
assertNotSame( v0.hashCode(), v1.hashCode() );
assertNotSame( v1.hashCode(), v2.hashCode() );
assertEquals( v0.hashCode(), v2.hashCode() );
assertNotSame( v0, v1 );
assertEquals( v0, v2 );
assertNotSame( v1, v2 );
Value v3 = new Value( attribute, new byte[]
{ 0x01, 0x03 } );
assertFalse( v3.equals( v0 ) );
assertFalse( v3.equals( v1 ) );
assertFalse( v3.equals( v2 ) );
}
/**
* Test the instanceOf method
*/
@Test
public void testInstanceOf() throws LdapException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value sbv = Value.createValue( attribute );
assertTrue( sbv.isInstanceOf( attribute ) );
attribute = EntryUtils.getIA5StringAttributeType();
assertFalse( sbv.isInstanceOf( attribute ) );
}
/**
* Test the normalize method
*/
@Test
public void testNormalize() throws LdapException
{
AttributeType attribute = EntryUtils.getBytesAttributeType();
Value bv = Value.createValue( attribute );
assertEquals( null, bv.getBytes() );
bv = new Value( attribute, Strings.EMPTY_BYTES );
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) );
bv = new Value( attribute, BYTES2 );
assertTrue( Arrays.equals( BYTES2, bv.getBytes() ) );
}
/**
* Test the compareTo method
*/
@Test
public void testCompareTo() throws LdapInvalidAttributeValueException
{
AttributeType at1 = EntryUtils.getBytesAttributeType();
Value v0 = new Value( at1, BYTES1 );
Value v1 = new Value( at1, BYTES1 );
assertEquals( 0, v0.compareTo( v1 ) );
assertEquals( 0, v1.compareTo( v0 ) );
Value v2 = new Value( at1, ( byte[] ) null );
assertEquals( 1, v0.compareTo( v2 ) );
assertEquals( -1, v2.compareTo( v0 ) );
}
/**
* Test serialization of a Value which normalized value is the same
* than the value
*/
@Test
public void testNormalizedBinarySameValueSerialization() throws LdapException, IOException, ClassNotFoundException
{
byte[] v1 = Strings.getBytesUtf8( "Test Test" );
// First check with a value which will be normalized
Value sbv = new Value( at, v1 );
Value sbvSer = deserializeValue( serializeValue( sbv ), at );
assertEquals( sbv, sbvSer );
}
/**
* Test serialization of a Value which does not have a normalized value
*/
@Test
public void testNoNormalizedBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException
{
byte[] v1 = Strings.getBytesUtf8( "test" );
byte[] v1Norm = Strings.getBytesUtf8( "test" );
// First check with a value which will be normalized
Value sbv = new Value( at, v1 );
byte[] normalized = sbv.getBytes();
assertTrue( Arrays.equals( v1Norm, normalized ) );
assertTrue( Arrays.equals( v1, sbv.getBytes() ) );
Value sbvSer = deserializeValue( serializeValue( sbv ), at );
assertEquals( sbv, sbvSer );
}
/**
* Test serialization of a null Value
*/
@Test
public void testNullBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException
{
// First check with a value which will be normalized
Value sbv = Value.createValue( at );
byte[] normalized = sbv.getBytes();
assertEquals( null, normalized );
assertEquals( "", sbv.getString() );
Value sbvSer = deserializeValue( serializeValue( sbv ), at );
assertEquals( sbv, sbvSer );
}
/**
* Test serialization of an empty Value
*/
@Test
public void testEmptyBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException
{
// First check with a value which will be normalized
Value sbv = new Value( at, Strings.EMPTY_BYTES );
byte[] normalized = sbv.getBytes();
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, normalized ) );
assertTrue( Arrays.equals( Strings.EMPTY_BYTES, sbv.getBytes() ) );
Value sbvSer = deserializeValue( serializeValue( sbv ), at );
assertEquals( sbv, sbvSer );
}
/**
* Test serialization of a Value which is the same than the value
*/
@Test
public void testSameNormalizedBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException
{
byte[] v1 = Strings.getBytesUtf8( "test" );
byte[] v1Norm = Strings.getBytesUtf8( "test" );
// First check with a value which will be normalized
Value sbv = new Value( at, v1 );
byte[] normalized = sbv.getBytes();
assertTrue( Arrays.equals( v1Norm, normalized ) );
assertTrue( Arrays.equals( v1, sbv.getBytes() ) );
Value sbvSer = deserializeValue( serializeValue( sbv ), at );
assertEquals( sbv, sbvSer );
}
}