| /* |
| * 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.schema.syntaxes.parser; |
| |
| |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertFalse; |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| import static org.junit.jupiter.api.Assertions.fail; |
| |
| import java.text.ParseException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.directory.api.ldap.model.schema.SchemaObject; |
| import org.apache.directory.api.ldap.model.schema.parsers.AbstractSchemaParser; |
| import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro; |
| |
| |
| /** |
| * Utils for schema parser test. Contains tests that are common |
| * for many schema parsers like OID, name, desc, extension. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public class SchemaParserTestUtils |
| { |
| |
| /** |
| * Test numericoid |
| * |
| * @throws ParseException |
| */ |
| public static void testNumericOid( AbstractSchemaParser parser, String required ) throws ParseException |
| { |
| String value = null; |
| SchemaObject asd = null; |
| |
| // null test |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, null" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // no oid |
| value = "( )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, no NUMERICOID" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // simple |
| value = "( 0.1.2.3.4.5.6.7.8.9 " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( "0.1.2.3.4.5.6.7.8.9", asd.getOid() ); |
| |
| // simple |
| value = "( 1.2.4567.890 " + required + ")"; |
| asd = parser.parse( value ); |
| assertEquals( "1.2.4567.890", asd.getOid() ); |
| |
| // simple with multiple spaces |
| value = "( 0.1.2.3.4.5.6.7.8.9 " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( "0.1.2.3.4.5.6.7.8.9", asd.getOid() ); |
| |
| // simple w/o spaces |
| value = "(0.1.2.3.4.5.6.7.8.9 " + required + ")"; |
| asd = parser.parse( value ); |
| assertEquals( "0.1.2.3.4.5.6.7.8.9", asd.getOid() ); |
| |
| // simple with tabs, newline, comment. |
| value = "(\t0.1.2.3.4.5.6.7.8.9\n#comment\n" + required + "\r\n)\r"; |
| asd = parser.parse( value ); |
| assertEquals( "0.1.2.3.4.5.6.7.8.9", asd.getOid() ); |
| |
| // quoted OID |
| value = "( '0.1.2.3.4.5.6.7.8.9' " + required + " )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, OID should not be quoted" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // quoted OID in parentheses |
| value = "( ('0.1.2.3.4.5.6.7.8.9') " + required + " )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, OID should not be quoted" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // too short |
| if ( !parser.isQuirksMode() ) |
| { |
| value = "( 1 " + required + " )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NUMERICOID 1" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // dot only |
| value = "( . " + required + " )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NUMERICOID ." ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // ends with dot |
| value = "( 1.1. " + required + " )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NUMERICOID 1.1." ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| } |
| |
| // multiple not allowed |
| value = "( ( 1.2.3 4.5.6 ) " + required + " )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid multiple OIDs not allowed.)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // excpected |
| } |
| |
| // A descr |
| if ( parser.isQuirksMode() ) |
| { |
| value = "( test " + required + ")"; |
| asd = parser.parse( value ); |
| assertEquals( "test", asd.getOid() ); |
| |
| // With macro |
| OpenLdapObjectIdentifierMacro macro = new OpenLdapObjectIdentifierMacro(); |
| macro.setName( "macro" ); |
| macro.setRawOidOrNameSuffix( "0.1" ); |
| parser.getObjectIdentifiers().put( "macro", macro ); |
| value = "( macro:2.3.4 " + required + ")"; |
| asd = parser.parse( value ); |
| assertEquals( "0.1.2.3.4", asd.getOid() ); |
| } |
| |
| if ( !parser.isQuirksMode() ) |
| { |
| // leading 0 not allowed |
| value = "( 01.1 " + required + " )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NUMERICOID 01.1 (leading zero)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // alpha not allowed |
| value = "( 1.2.a.4 " + required + " )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NUMERICOID 1.2.a.4 (alpha not allowed)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // excpected |
| } |
| } |
| } |
| |
| |
| /** |
| * Tests NAME and its values |
| * |
| * @throws ParseException |
| */ |
| public static void testNamesStrict( AbstractSchemaParser parser, String oid, String required ) throws ParseException |
| { |
| String value = null; |
| SchemaObject asd = null; |
| |
| // No name |
| value = "( " + oid + " " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( 0, asd.getNames().size() ); |
| |
| // A name, no value |
| value = "( " + oid + " " + required + " NAME )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, value expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // A name, no space |
| value = "( " + oid + " " + required + " NAME'test' )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, value expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // alpha |
| value = "( " + oid + " " + required + " NAME 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", asd.getNames().get( 0 ) ); |
| |
| // alpha-num-hypen |
| value = "( " + oid + " " + required |
| + " NAME 'abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789", asd.getNames().get( 0 ) ); |
| |
| // with parentheses |
| value = "( " + oid + " " + required + " NAME ( 'a-z-0-9' ) )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "a-z-0-9", asd.getNames().get( 0 ) ); |
| |
| // Bad value |
| value = "(" + oid + " " + required + " NAME 'abc_de')"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, invalid chars in name" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // Bad NAME |
| value = "(" + oid + " " + required + " NAMEE 'abcde')"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, bad NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // with parentheses, without space |
| value = "(" + oid + " " + required + " NAME('a-z-0-9'))"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, spaces expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // multi with space |
| value = " ( " + oid + " " + required + " NAME ( 'test1' 'test2' ) ) "; |
| asd = parser.parse( value ); |
| assertEquals( 2, asd.getNames().size() ); |
| assertEquals( "test1", asd.getNames().get( 0 ) ); |
| assertEquals( "test2", asd.getNames().get( 1 ) ); |
| |
| // multi without space |
| value = "(" + oid + " " + required + " NAME('test1''test2''test3'))"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, space expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // multi with many spaces |
| value = "( " + oid + " " + required |
| + " NAME ( 'test1' 'test2' 'test3' ) )"; |
| asd = parser.parse( value ); |
| assertEquals( 3, asd.getNames().size() ); |
| assertEquals( "test1", asd.getNames().get( 0 ) ); |
| assertEquals( "test2", asd.getNames().get( 1 ) ); |
| assertEquals( "test3", asd.getNames().get( 2 ) ); |
| |
| // multi with tabs, newline, comment, etc. |
| value = "(\r\n" + oid + "\r" + required |
| + "\nNAME\t(\t\t\t'test1'\t\n\t'test2'\t\r\t'test3'\t\r\n\t)\n#comment\n)"; |
| asd = parser.parse( value ); |
| assertEquals( 3, asd.getNames().size() ); |
| assertEquals( "test1", asd.getNames().get( 0 ) ); |
| assertEquals( "test2", asd.getNames().get( 1 ) ); |
| assertEquals( "test3", asd.getNames().get( 2 ) ); |
| |
| // lowercase NAME |
| value = "( " + oid + " " + required + " name 'test' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "test", asd.getNames().get( 0 ) ); |
| |
| // unquoted NAME value |
| value = "( " + oid + " " + required + " NAME test )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, quoted values expected" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // multi unquoted NAME values |
| value = " ( " + oid + " " + required + " NAME (test1 test2) ) "; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, quoted values expected" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // NAM unknown |
| value = "( " + oid + " " + required + " NAM 'test' )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid token NAM" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // start with number |
| value = "( " + oid + " " + required + " NAME '1test' )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NAME 1test (starts with number)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // start with hypen |
| value = "( " + oid + " " + required + " NAME '-test' )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NAME -test (starts with hypen)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // invalid character |
| value = "( " + oid + " " + required + " NAME 'te_st' )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NAME te_st (contains invalid character)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // one valid, one invalid |
| value = "( " + oid + " " + required + " NAME ( 'test' 'te_st' ) )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid NAME te_st (contains invalid character)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| } |
| |
| |
| /** |
| * Tests NAME and its values in relaxed mode |
| * |
| * @throws ParseException |
| */ |
| public static void testNamesRelaxed( AbstractSchemaParser parser, String oid, String required ) throws ParseException |
| { |
| String value = null; |
| SchemaObject asd = null; |
| boolean isRelaxed = parser.isQuirksMode(); |
| parser.setQuirksMode( true ); |
| |
| try |
| { |
| // No name |
| value = "( " + oid + " " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( 0, asd.getNames().size() ); |
| |
| // A name, no value |
| value = "( " + oid + " " + required + " NAME )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, value expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // A name, no space |
| value = "( " + oid + " " + required + " NAME'test' )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, value expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // alpha |
| value = "( " + oid + " " + required + " NAME 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", asd.getNames().get( 0 ) ); |
| |
| // alpha-num-hypen |
| value = "( " + oid + " " + required |
| + " NAME 'abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789", asd.getNames().get( 0 ) ); |
| |
| // with parentheses |
| value = "( " + oid + " " + required + " NAME ( 'a-z-0-9' ) )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "a-z-0-9", asd.getNames().get( 0 ) ); |
| |
| // With extended chars |
| value = "(" + oid + " " + required + " NAME 'abc_de')"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "abc_de", asd.getNames().get( 0 ) ); |
| |
| // Bad NAME |
| value = "(" + oid + " " + required + " NAMEE 'abcde')"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, bad NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // with parentheses, without space |
| value = "(" + oid + " " + required + " NAME('a-z-0-9'))"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, spaces expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // multi with space |
| value = " ( " + oid + " " + required + " NAME ( 'test1' 'test2' ) ) "; |
| asd = parser.parse( value ); |
| assertEquals( 2, asd.getNames().size() ); |
| assertEquals( "test1", asd.getNames().get( 0 ) ); |
| assertEquals( "test2", asd.getNames().get( 1 ) ); |
| |
| // multi without space |
| value = "(" + oid + " " + required + " NAME('test1''test2''test3'))"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, space expected after NAME" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // multi with many spaces |
| value = "( " + oid + " " + required |
| + " NAME ( 'test1' 'test2' 'test3' ) )"; |
| asd = parser.parse( value ); |
| assertEquals( 3, asd.getNames().size() ); |
| assertEquals( "test1", asd.getNames().get( 0 ) ); |
| assertEquals( "test2", asd.getNames().get( 1 ) ); |
| assertEquals( "test3", asd.getNames().get( 2 ) ); |
| |
| // multi with tabs, newline, comment, etc. |
| value = "(\r\n" + oid + "\r" + required |
| + "\nNAME\t(\t\t\t'test1'\t\n\t'test2'\t\r\t'test3'\t\r\n\t)\n#comment\n)"; |
| asd = parser.parse( value ); |
| assertEquals( 3, asd.getNames().size() ); |
| assertEquals( "test1", asd.getNames().get( 0 ) ); |
| assertEquals( "test2", asd.getNames().get( 1 ) ); |
| assertEquals( "test3", asd.getNames().get( 2 ) ); |
| |
| // lowercase NAME |
| value = "( " + oid + " " + required + " name 'test' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "test", asd.getNames().get( 0 ) ); |
| |
| // unquoted NAME value |
| value = "( " + oid + " " + required + " NAME test )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "test", asd.getNames().get( 0 ) ); |
| |
| // multi unquoted NAME values |
| value = " ( " + oid + " " + required + " NAME (test1 test2) ) "; |
| asd = parser.parse( value ); |
| assertEquals( 2, asd.getNames().size() ); |
| assertEquals( "test1", asd.getNames().get( 0 ) ); |
| assertEquals( "test2", asd.getNames().get( 1 ) ); |
| |
| // NAM unknown |
| value = "( " + oid + " " + required + " NAM 'test' )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid token NAM" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // start with number |
| value = "( " + oid + " " + required + " NAME '1test' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "1test", asd.getNames().get( 0 ) ); |
| |
| // start with hypen |
| value = "( " + oid + " " + required + " NAME '-test' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "-test", asd.getNames().get( 0 ) ); |
| |
| // invalid character |
| value = "( " + oid + " " + required + " NAME 'te_st' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getNames().size() ); |
| assertEquals( "te_st", asd.getNames().get( 0 ) ); |
| |
| // one valid, one invalid |
| value = "( " + oid + " " + required + " NAME ( 'test' 'te_st' ) )"; |
| asd = parser.parse( value ); |
| assertEquals( 2, asd.getNames().size() ); |
| assertEquals( "test", asd.getNames().get( 0 ) ); |
| assertEquals( "te_st", asd.getNames().get( 1 ) ); |
| } |
| finally |
| { |
| parser.setQuirksMode( isRelaxed ); |
| } |
| } |
| |
| |
| /** |
| * Tests DESC |
| * |
| * @throws ParseException |
| */ |
| public static void testDescription( AbstractSchemaParser parser, String oid, String required ) |
| throws ParseException |
| { |
| String value = null; |
| SchemaObject asd = null; |
| |
| // simple |
| value = "(" + oid + " " + required + " DESC 'Description')"; |
| asd = parser.parse( value ); |
| assertEquals( "Description", asd.getDescription() ); |
| |
| // simple with tabs, newline, comment, etc. |
| value = "(" + oid + "\n" + required + "\tDESC#comment\n\n\r\n\r\t'Description')"; |
| asd = parser.parse( value ); |
| assertEquals( "Description", asd.getDescription() ); |
| |
| // simple w/o space |
| value = "(" + oid + " " + required + " DESC'Description')"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, DESC should have space" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // simple parentheses and quotes |
| value = "(" + oid + " " + required + " DESC ('Descripton') )"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, DESC should not have parentheses" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // unicode |
| value = "( " + oid + " " + required + " DESC 'Descripton \u00E4\u00F6\u00FC\u00DF \u90E8\u9577' )"; |
| asd = parser.parse( value ); |
| assertEquals( "Descripton \u00E4\u00F6\u00FC\u00DF \u90E8\u9577", asd.getDescription() ); |
| |
| // escaped characters |
| value = "( " + oid + " " + required + " DESC 'test\\5Ctest' )"; |
| asd = parser.parse( value ); |
| assertEquals( "test\\test", asd.getDescription() ); |
| value = "( " + oid + " " + required + " DESC 'test\\5ctest' )"; |
| asd = parser.parse( value ); |
| assertEquals( "test\\test", asd.getDescription() ); |
| value = "( " + oid + " " + required + " DESC 'test\\27test' )"; |
| asd = parser.parse( value ); |
| assertEquals( "test'test", asd.getDescription() ); |
| value = "( " + oid + " " + required + " DESC '\\5C\\27\\5c' )"; |
| asd = parser.parse( value ); |
| assertEquals( "\\'\\", asd.getDescription() ); |
| |
| // lowercase DESC |
| value = "( " + oid + " " + required + " desc 'Descripton' )"; |
| asd = parser.parse( value ); |
| assertEquals( "Descripton", asd.getDescription() ); |
| |
| // empty DESC |
| value = "( " + oid + " " + required + " DESC '' )"; |
| asd = parser.parse( value ); |
| assertEquals( "", asd.getDescription() ); |
| |
| // multiple not allowed |
| value = "(" + oid + " " + required + " DESC ( 'Descripton1' 'Description 2' ) )"; |
| try |
| { |
| parser.parse( value ); |
| fail( "Exception expected, invalid multiple DESC not allowed.)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| } |
| |
| |
| /** |
| * Test extensions. |
| * |
| * @throws ParseException |
| */ |
| public static void testExtensions( AbstractSchemaParser parser, String oid, String required ) throws ParseException |
| { |
| String value = null; |
| SchemaObject asd = null; |
| |
| // no extension |
| value = "( " + oid + " " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( 0, asd.getExtensions().size() ); |
| |
| // single extension with one value |
| value = "( " + oid + " " + required + " X-TEST 'test' )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getExtensions().size() ); |
| assertNotNull( asd.getExtension( "X-TEST" ) ); |
| assertEquals( 1, asd.getExtension( "X-TEST" ).size() ); |
| assertEquals( "test", asd.getExtension( "X-TEST" ).get( 0 ) ); |
| |
| // single extension with multiple values |
| value = "( " + oid + " " + required |
| + " X-TEST-ABC ('test1' 'test \u00E4\u00F6\u00FC\u00DF' 'test \u90E8\u9577' ) )"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getExtensions().size() ); |
| assertNotNull( asd.getExtension( "X-TEST-ABC" ) ); |
| assertEquals( 3, asd.getExtension( "X-TEST-ABC" ).size() ); |
| assertEquals( "test1", asd.getExtension( "X-TEST-ABC" ).get( 0 ) ); |
| assertEquals( "test \u00E4\u00F6\u00FC\u00DF", asd.getExtension( "X-TEST-ABC" ).get( 1 ) ); |
| assertEquals( "test \u90E8\u9577", asd.getExtension( "X-TEST-ABC" ).get( 2 ) ); |
| |
| // multiple extensions |
| value = "(" + oid + " " + required + " X-TEST-a ('test1-1' 'test1-2') X-TEST-b ('test2-1' 'test2-2'))"; |
| asd = parser.parse( value ); |
| assertEquals( 2, asd.getExtensions().size() ); |
| assertNotNull( asd.getExtension( "X-TEST-a" ) ); |
| assertEquals( 2, asd.getExtension( "X-TEST-a" ).size() ); |
| assertEquals( "test1-1", asd.getExtension( "X-TEST-a" ).get( 0 ) ); |
| assertEquals( "test1-2", asd.getExtension( "X-TEST-a" ).get( 1 ) ); |
| assertNotNull( asd.getExtension( "X-TEST-b" ) ); |
| assertEquals( 2, asd.getExtension( "X-TEST-b" ).size() ); |
| assertEquals( "test2-1", asd.getExtension( "X-TEST-b" ).get( 0 ) ); |
| assertEquals( "test2-2", asd.getExtension( "X-TEST-b" ).get( 1 ) ); |
| |
| // multiple extensions, no spaces |
| value = "(" + oid + " " + required + " X-TEST-a('test1-1''test1-2')X-TEST-b('test2-1''test2-2'))"; |
| |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, EXTENSION should have spaces" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // multiple extensions, tabs, newline, comments |
| value = "(" + oid + "\n#comment\n" + required |
| + "\nX-TEST-a\n(\t'test1-1'\t\n'test1-2'\n\r)\tX-TEST-b\n(\n'test2-1'\t'test2-2'\t)\r)"; |
| asd = parser.parse( value ); |
| assertEquals( 2, asd.getExtensions().size() ); |
| assertNotNull( asd.getExtension( "X-TEST-a" ) ); |
| assertEquals( 2, asd.getExtension( "X-TEST-a" ).size() ); |
| assertEquals( "test1-1", asd.getExtension( "X-TEST-a" ).get( 0 ) ); |
| assertEquals( "test1-2", asd.getExtension( "X-TEST-a" ).get( 1 ) ); |
| assertNotNull( asd.getExtension( "X-TEST-b" ) ); |
| assertEquals( 2, asd.getExtension( "X-TEST-b" ).size() ); |
| assertEquals( "test2-1", asd.getExtension( "X-TEST-b" ).get( 0 ) ); |
| assertEquals( "test2-2", asd.getExtension( "X-TEST-b" ).get( 1 ) ); |
| |
| // some more complicated |
| value = "(" + oid + " " + required |
| + " X-_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ('\\5C\\27\\5c'))"; |
| asd = parser.parse( value ); |
| assertEquals( 1, asd.getExtensions().size() ); |
| assertNotNull( asd.getExtension( "X-_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ) ); |
| assertEquals( 1, asd.getExtension( "X-_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ) |
| .size() ); |
| assertEquals( "\\'\\", asd.getExtension( |
| "X-_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ).get( 0 ) ); |
| |
| // invalid extension, no number allowed |
| value = "( " + oid + " " + required + " X-TEST1 'test' )"; |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, invalid extension X-TEST1 (no number allowed)" ); |
| } |
| catch ( ParseException pe ) |
| { |
| assertTrue( true ); |
| } |
| |
| } |
| |
| |
| /** |
| * Tests OBSOLETE |
| * |
| * @throws ParseException |
| */ |
| public static void testObsolete( AbstractSchemaParser parser, String oid, String required ) throws ParseException |
| { |
| String value = null; |
| SchemaObject asd = null; |
| |
| // not obsolete |
| value = "( " + oid + " " + required + " )"; |
| asd = parser.parse( value ); |
| assertFalse( asd.isObsolete() ); |
| |
| // not obsolete |
| value = "( " + oid + " " + required + " NAME 'test' DESC 'Description' )"; |
| asd = parser.parse( value ); |
| assertFalse( asd.isObsolete() ); |
| |
| // obsolete |
| value = "(" + oid + " " + required + " NAME 'test' DESC 'Description' OBSOLETE)"; |
| asd = parser.parse( value ); |
| assertTrue( asd.isObsolete() ); |
| |
| // obsolete |
| value = "(" + oid + " " + required + " OBSOLETE)"; |
| asd = parser.parse( value ); |
| assertTrue( asd.isObsolete() ); |
| |
| // lowercased obsolete |
| value = "(" + oid + " " + required + " obsolete)"; |
| asd = parser.parse( value ); |
| assertTrue( asd.isObsolete() ); |
| |
| // invalid |
| value = "(" + oid + " " + required + " NAME 'test' DESC 'Descripton' OBSOLET )"; |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, invalid OBSOLETE value" ); |
| } |
| catch ( ParseException pe ) |
| { |
| // expected |
| } |
| |
| // trailing value not allowed |
| value = "(" + oid + " " + required + " NAME 'test' DESC 'Descripton' OBSOLETE 'true' )"; |
| try |
| { |
| asd = parser.parse( value ); |
| fail( "Exception expected, trailing value ('true') now allowed" ); |
| } |
| catch ( ParseException pe ) |
| { |
| assertTrue( true ); |
| } |
| } |
| |
| |
| /** |
| * Tests for unique elements. |
| * |
| * @throws ParseException |
| */ |
| public static void testUnique( AbstractSchemaParser parser, String[] testValues ) |
| { |
| for ( int i = 0; i < testValues.length; i++ ) |
| { |
| String testValue = testValues[i]; |
| try |
| { |
| parser.parse( testValue ); |
| fail( "Exception expected, element appears twice in " + testValue ); |
| } |
| catch ( ParseException pe ) |
| { |
| assertTrue( true ); |
| } |
| } |
| |
| } |
| |
| |
| /** |
| * Tests the multithreaded use of a single parser. |
| */ |
| public static void testMultiThreaded( AbstractSchemaParser parser, String[] testValues ) |
| { |
| final boolean[] isSuccessMultithreaded = new boolean[1]; |
| isSuccessMultithreaded[0] = true; |
| |
| // start up and track all threads (40 threads) |
| List<Thread> threads = new ArrayList<Thread>(); |
| for ( int ii = 0; ii < 10; ii++ ) |
| { |
| for ( int i = 0; i < testValues.length; i++ ) |
| { |
| Thread t = new Thread( new ParseSpecification( parser, testValues[i], isSuccessMultithreaded ) ); |
| threads.add( t ); |
| t.start(); |
| } |
| } |
| |
| // wait until all threads have died |
| boolean hasLiveThreads = false; |
| do |
| { |
| hasLiveThreads = false; |
| |
| for ( int ii = 0; ii < threads.size(); ii++ ) |
| { |
| Thread t = threads.get( ii ); |
| hasLiveThreads = hasLiveThreads || t.isAlive(); |
| } |
| } |
| while ( hasLiveThreads ); |
| |
| // check that no one thread failed to parse and generate a SS object |
| assertTrue( isSuccessMultithreaded[0] ); |
| |
| } |
| |
| |
| /** |
| * Tests quirks mode. |
| */ |
| public static void testQuirksMode( AbstractSchemaParser parser, String required ) throws ParseException |
| { |
| try |
| { |
| String value = null; |
| SchemaObject asd = null; |
| |
| parser.setQuirksMode( true ); |
| |
| // alphanum OID |
| value = "( abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789 " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( "abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789", asd |
| .getOid() ); |
| |
| // start with hypen |
| value = "( -oid " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( "-oid", asd.getOid() ); |
| |
| // start with number |
| value = "( 1oid " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( "1oid", asd.getOid() ); |
| |
| // start with dot |
| value = "( .oid " + required + " )"; |
| asd = parser.parse( value ); |
| assertEquals( ".oid", asd.getOid() ); |
| } |
| finally |
| { |
| parser.setQuirksMode( false ); |
| } |
| } |
| |
| static class ParseSpecification implements Runnable |
| { |
| private final AbstractSchemaParser parser; |
| private final String value; |
| private final boolean[] isSuccessMultithreaded; |
| |
| private SchemaObject result; |
| |
| |
| public ParseSpecification( AbstractSchemaParser parser, String value, boolean[] isSuccessMultithreaded ) |
| { |
| this.parser = parser; |
| this.value = value; |
| this.isSuccessMultithreaded = isSuccessMultithreaded; |
| } |
| |
| |
| public void run() |
| { |
| try |
| { |
| result = parser.parse( value ); |
| } |
| catch ( ParseException e ) |
| { |
| e.printStackTrace(); |
| } |
| |
| isSuccessMultithreaded[0] = isSuccessMultithreaded[0] && ( result != null ); |
| } |
| } |
| |
| } |