diff options
Diffstat (limited to 'ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions')
23 files changed, 18027 insertions, 0 deletions
diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionAccessPermittedTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionAccessPermittedTest.java new file mode 100644 index 000000000..3e23ebca0 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionAccessPermittedTest.java @@ -0,0 +1,522 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.namespace.NamespaceContext; + +import org.junit.Ignore; +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdMutableRequest; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdEvaluationContext; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionAccessPermitted; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * NOT IMPLEMENTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * This function is not yet implemented so these tests intentionally fail. + * + * + */ +public class FunctionDefinitionAccessPermittedTest { + + // + // Strings for the Request contents + // + + String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" + + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"" + + " ReturnPolicyIdList=\"false\"" + + " CombinedDecision=\"false\"" + + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"" + + " xmlns:md=\"http://www.medico.com/schemas/record\"" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + "</Attributes>"; + + String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">"; + + String reqStrMdRecordSimpson = + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:department>Surgery</md:department>" + + "</md:hospital_info>" + + "<md:patient_info>" + + "<md:name>Bart Simpson</md:name>" + + "<md:age>60</md:age>" + + "<md:sex>male</md:sex>" + + "<md:health_insurance>123456</md:health_insurance>" + + "</md:patient_info>" + + "<md:diagnosis_info>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Gastric Cancer</md:item>" + + "<md:item type=\"secondary\">Hyper tension</md:item>" + + "</md:diagnosis>" + + "<md:pathological_diagnosis>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" + + "</md:diagnosis>" + + "<md:date>2000-10-05</md:date>" + + "<md:malignancy type=\"yes\"/>" + + "</md:pathological_diagnosis>" + + "</md:diagnosis_info>" + + " </md:record>"; + String reqStrContentMdRecordSimpson = "<Content>" + reqStrMdRecordSimpson + "</Content>"; + String reqStrMalformedContent = + " <Content>" + + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:malignancy type=\"yes\"/>" + + "</Content>"; + String reqStrMdRecordSpringer = + "<md:record>" + + "<md:hospital_info>" + + "<md:name>XYZ Hospital</md:name>" + + "<md:department>Surgery</md:department>" + + "</md:hospital_info>" + + "<md:patient_info>" + + "<md:name>Jerry Springer</md:name>" + + "<md:age>65</md:age>" + + "<md:sex>male</md:sex>" + + "<md:health_insurance>765432</md:health_insurance>" + + "</md:patient_info>" + + "<md:diagnosis_info>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Hyatal Hernia</md:item>" + + "<md:item type=\"secondary\">Diabetes</md:item>" + + "<md:item type=\"tertiary\">Neuronal Collapse</md:item>" + + "</md:diagnosis>" + + "<md:pathological_diagnosis>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">We have no idea</md:item>" + + "</md:diagnosis>" + + "<md:date>2012-07-22</md:date>" + + "<md:malignancy type=\"no\"/>" + + "</md:pathological_diagnosis>" + + "</md:diagnosis_info>" + + " </md:record>"; + String reqStrContentMdRecordSpringer = + "<Content>" + reqStrMdRecordSpringer + "</Content>"; + + String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>" + + " </Attribute>" + + "</Attributes> "; + String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">"; + + String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">" + + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>" + + "</Attribute>" + + "</Attributes> "; + String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />"; + String reqStrMainEnd = " </Request>"; + + + // combined strings for convenience + String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart; + String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd; + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // Name Spaces used in the XML as part of these examples - needed for compiling XPaths + NamespaceContext nameSpaceContext = new NamespaceContext() { + @Override + public Iterator<?> getPrefixes(String arg0) { return null;} + + @Override + public String getPrefix(String arg0) {return null;} + + @Override + public String getNamespaceURI(String arg0) { + if("md".equals(arg0)) { + return "http://www.medico.com/schemas/record"; + } else if ("xacml-context".equals(arg0)) { + return "urn:oasis:names:tc:xacml:3.0:context:schema:os"; + } else if ("xsi".equals(arg0)) { + return "http://www.w3.org/2001/XMLSchema-instance"; + } + return null; + } + }; + + + + // + // URIs for attribute categroies + // + + FunctionArgumentAttributeValue attrUriNull = null; + FunctionArgumentAttributeValue attrUriEmpty = null; + FunctionArgumentAttributeValue attrUriResources = null; + FunctionArgumentAttributeValue attrUriAction = null; + FunctionArgumentAttributeValue attrUriNotInRequest = null; + FunctionArgumentAttributeValue attrUriNotCategory = null; + + + + // + // XML Contents + // + + FunctionArgumentAttributeValue attrXnull = null; + FunctionArgumentAttributeValue attrXEmpty = null; + FunctionArgumentAttributeValue attrXSimpson = null; + FunctionArgumentAttributeValue attrXSpringer = null; + FunctionArgumentAttributeValue attrXContentSimpson = null; + FunctionArgumentAttributeValue attrXContentSpringer = null; + FunctionArgumentAttributeValue attrXBadXML = null; + + + + + + + // + // REQUEST objects available for use in tests + // + Request requestEmpty = new StdMutableRequest(); + Request requestMdRecord = null; + Request requestDoubleResources = null; + Request requestDoubleContent = null; + Request requestResourceActionContent = null; + Request requestContentInAction = null; + + + + + /** + * Set up all variables in one place because it is complicated (lots of steps needed for each attribute) + */ + public FunctionDefinitionAccessPermittedTest() { + try { + + + // create Function Attributes for URIs + attrUriNull = null; + attrUriEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrUriResources = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:resource")); + attrUriAction = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:action")); + attrUriNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("NoSuchURI")); + attrUriNotCategory = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:1.0:resource:resource-id")); + + // create Function Attributes for XML Strings + attrXnull = new FunctionArgumentAttributeValue(null); + attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrXSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSimpson)); + attrXSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSpringer)); + attrXContentSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSimpson)); + attrXContentSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSpringer)); + attrXBadXML = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMalformedContent)); + + + + // Request objects + // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it. + + // single Content in the Resources section (normal valid request) + String reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceAllEnd; + File tFile = File.createTempFile("functionJunit", "request"); + BufferedWriter bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestMdRecord = DOMRequest.load(tFile); + tFile.delete(); + + // Resources included twice + reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecordSimpson +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestDoubleResources = DOMRequest.load(tFile); + tFile.delete(); + + // Content included twice - error + reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrContentMdRecordSimpson +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestDoubleContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // content included in both Resource and Action - ok + reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestResourceActionContent = DOMRequest.load(tFile); + tFile.delete(); + + // Content included only in Action - missing content produces non-error result according to spec + reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestContentInAction = DOMRequest.load(tFile); + tFile.delete(); + + + + // Test that Bad XML is caught + @SuppressWarnings("unused") + Request requestContentMisplaced = null; + @SuppressWarnings("unused") + Request requestMalformedContent = null; + + + // Bad XML - Content not under a Category + reqString = reqStrMainStart + reqStrContentMdRecordSimpson + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestContentMisplaced = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // Bad XML - Content is not valid XML + reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestMalformedContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + } catch (Exception e) { + fail("Constructor initializing variables, e="+ e + " cause="+e.getCause()); + } + + } + + + + + + + + + @Ignore //@Test + public void testAccess_permitted() { + + ExpressionResult res = null; + Boolean resValue = null; + + FunctionDefinitionAccessPermitted fd = (FunctionDefinitionAccessPermitted) StdFunctions.FD_ACCESS_PERMITTED; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ACCESS_PERMITTED, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + // successful invoke returns true + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXEmpty); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + + // successful invoke returns false + + + // URI not in Request (ok - evaluate anyway) + + // test for infinite loop + + // second arg ok both with and without <Content> tag + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXContentSpringer); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXSpringer); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // second arg not valid XML + arguments.clear(); + arguments.add(attrUriResources); + arguments.add(attrXBadXML); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Parsing of XML string failed. Cause='The element type \"md:hospital_info\" must be terminated by the matching end-tag \"</md:hospital_info>\".'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Evaluation Context + arguments.clear(); + arguments.add(attrUriNotCategory); + arguments.add(attrXContentSimpson); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrUriAction); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first arg not uri + arguments.clear(); + arguments.add(attrUriNotCategory); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg not attribute-category urn + arguments.clear(); + arguments.add(attrXContentSimpson); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected data type 'anyURI' saw 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second arg not string + arguments.clear(); + arguments.add(attrUriAction); + arguments.add(attrUriAction); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // too few args + arguments.clear(); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // too many args + arguments.clear(); + arguments.add(attrUriEmpty); + arguments.add(attrXContentSimpson); + arguments.add(attrXContentSimpson); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:access-permitted Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionArithmeticTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionArithmeticTest.java new file mode 100644 index 000000000..95fcdb2d2 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionArithmeticTest.java @@ -0,0 +1,717 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionArithmetic; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionArithmeticTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testInteger_add() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attrBadType = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ADD; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_ADD, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + arguments.clear(); + arguments.add(attr1); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-add Expected data type 'integer' saw 'double' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testDouble_add() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ADD; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_ADD, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(4.0), resValue); + + } + + + @Test + public void testInteger_subtract() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(6)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_SUBTRACT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_SUBTRACT, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("5"), resValue); + + } + + + @Test + public void testDouble_subtract() { + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(8.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.3)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_SUBTRACT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_SUBTRACT, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(6.2), resValue); + + } + + + @Test + public void testInteger_multiply() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MULTIPLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_MULTIPLY, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("10"), resValue); + + + // test 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + } + + + @Test + public void testDouble_multiply() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_MULTIPLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_MULTIPLY, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(3.75), resValue); + + // test multiply by 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + } + + + @Test + public void testInteger_divide() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_DIVIDE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_DIVIDE, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + + // test 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-divide Divide by 0 error: 5, 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testDouble_divide() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.5)); + + } catch (Exception e) { + fail("creating attributes e="+e); + } + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_DIVIDE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_DIVIDE, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0.6), resValue); + + // test multiply by 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-divide Divide by 0 error: 1.5, 0.0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + @Test + public void testInteger_mod() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(28)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_MOD; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_MOD, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + arguments.add(attr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("3"), resValue); + + + // test 0 + arguments.clear(); + arguments.add(attr1); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-mod Divide by 0 error: 28, 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testInteger_abs() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attrM1 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + attrM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-7)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_INTEGER_ABS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_ABS, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("5"), resValue); + + arguments.clear(); + arguments.add(attrM1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("7"), resValue); + + arguments.clear(); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + } + + + @Test + public void testDouble_abs() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5)); + + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_DOUBLE_ABS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_ABS, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1.5), resValue); + + arguments.clear(); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(2.5), resValue); + + arguments.clear(); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + + } + + + @Test + public void testDouble_round() { + + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attr3 = null; + FunctionArgumentAttributeValue attr4 = null; + FunctionArgumentAttributeValue attr5 = null; + FunctionArgumentAttributeValue attr6 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49)); + attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51)); + attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5)); + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49)); + attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_ROUND; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ROUND, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr0); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + + arguments.clear(); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(2), resValue); + + arguments.clear(); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(2), resValue); + + arguments.clear(); + arguments.add(attr4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-2), resValue); + + arguments.clear(); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-2), resValue); + + arguments.clear(); + arguments.add(attr6); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + } + + + @Test + public void testDouble_floor() { + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attr3 = null; + FunctionArgumentAttributeValue attr4 = null; + FunctionArgumentAttributeValue attr5 = null; + FunctionArgumentAttributeValue attr6 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(0)); + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.5)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.49)); + attr3 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.51)); + attr4 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.5)); + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.49)); + attr6 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-2.51)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionArithmetic<?> fd = (FunctionDefinitionArithmetic<?>) StdFunctions.FD_FLOOR; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_FLOOR, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal + arguments.add(attr0); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(0), resValue); + + arguments.clear(); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(1), resValue); + + arguments.clear(); + arguments.add(attr4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + + arguments.clear(); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + + arguments.clear(); + arguments.add(attr6); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(-3), resValue); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagIsInTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagIsInTest.java new file mode 100644 index 000000000..f783254a9 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagIsInTest.java @@ -0,0 +1,221 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagIsIn; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionBagIsInTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + String notInBag = new String("lmnop"); + String sameValueV1 = new String("abc"); + Integer vOtherType = new Integer(11); + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrV2 = null; + FunctionArgumentAttributeValue attrNotInBag = null; + FunctionArgumentAttributeValue attrSameValueV1 = null; + FunctionArgumentAttributeValue attrOtherType = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2)); + attrNotInBag = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(notInBag)); + attrSameValueV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(sameValueV1)); + attrOtherType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(vOtherType)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2));; + + + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + + + + FunctionDefinitionBagIsIn<?> fd = (FunctionDefinitionBagIsIn<?>) StdFunctions.FD_STRING_IS_IN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_IS_IN, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // element is in bag + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBag2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // element not in bag + arguments.clear(); + arguments.add(attrNotInBag); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // different element with the same value is in bag + arguments.clear(); + arguments.add(attrSameValueV1); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty bag + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // missing arg + arguments.clear(); + arguments.add(attrSameValueV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 1st arg is bag + arguments.clear(); + arguments.add(attrBag1); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected a simple value, saw a bag", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2nd arg not bag + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg null + arguments.clear(); + arguments.add(null); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2nd arg null + arguments.clear(); + arguments.add(attrV1); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg type does not match bag elements + arguments.clear(); + arguments.add(attrOtherType); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-is-in Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag has mixed element types +// behavior not specified for this case in spec. It ASSUMES that all elements in bag are same type. + + } + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagOneAndOnlyTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagOneAndOnlyTest.java new file mode 100644 index 000000000..42a0aed75 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagOneAndOnlyTest.java @@ -0,0 +1,224 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.math.BigInteger; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagOneAndOnly; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionBagOneAndOnlyTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + BigInteger vOtherType = BigInteger.valueOf(11); + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2)); + Bag bagOtherType = new Bag(); + bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_INTEGER.getId(), vOtherType)); + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType); + + + FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_STRING_ONE_AND_ONLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + + // bag with only one + arguments.clear(); + arguments.add(attrBag1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals(v1, resValue); + + // null bag + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with exactly one but of other type in it + arguments.clear(); + arguments.add(attrBagOtherType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Element in bag of wrong type. Expected string got integer", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with none + arguments.clear(); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with multiple + arguments.clear(); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + @Test + public void testBoolean() { + Boolean v1 = new Boolean(true); + Boolean v2 = new Boolean(false); + BigInteger vOtherType = BigInteger.valueOf(11); + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v1)); + bag2.add(new StdAttributeValue<Boolean>(DataTypes.DT_BOOLEAN.getId(), v2)); + Bag bagOtherType = new Bag(); + bagOtherType.add(new StdAttributeValue<BigInteger>(DataTypes.DT_STRING.getId(), vOtherType)); + + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType); + + + FunctionDefinitionBagOneAndOnly<?> fd = (FunctionDefinitionBagOneAndOnly<?>) StdFunctions.FD_BOOLEAN_ONE_AND_ONLY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + + // bag with only one + arguments.clear(); + arguments.add(attrBag1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // null bag + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with exactly one but of other type in it + arguments.clear(); + arguments.add(attrBagOtherType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Element in bag of wrong type. Expected boolean got string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with none + arguments.clear(); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Expected 1 but Bag has 0 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with multiple + arguments.clear(); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-one-and-only Expected 1 but Bag has 2 elements", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagSizeTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagSizeTest.java new file mode 100644 index 000000000..cd08234f5 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagSizeTest.java @@ -0,0 +1,158 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBagSize; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionBagSizeTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + Integer vOtherType = new Integer(11); + + + + Bag bag0 = new Bag(); + Bag bag1 = new Bag(); + bag1.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + Bag bag2 = new Bag(); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v1)); + bag2.add(new StdAttributeValue<String>(DataTypes.DT_STRING.getId(), v2)); + Bag bagOtherType = new Bag(); + bagOtherType.add(new StdAttributeValue<Integer>(DataTypes.DT_INTEGER.getId(), vOtherType)); + + + FunctionArgumentBag attrBag0 = new FunctionArgumentBag(bag0); + FunctionArgumentBag attrBag1 = new FunctionArgumentBag(bag1); + FunctionArgumentBag attrBag2 = new FunctionArgumentBag(bag2); + FunctionArgumentBag attrBagOtherType = new FunctionArgumentBag(bagOtherType); + + + FunctionDefinitionBagSize<?> fd = (FunctionDefinitionBagSize<?>) StdFunctions.FD_STRING_BAG_SIZE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_BAG_SIZE, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + + + // bag with only one + arguments.clear(); + arguments.add(attrBag1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.math.BigInteger.class, res.getValue().getValue().getClass()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(1), resValue); + + // null bag + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-bag-size Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag with exactly one but of other type in it + arguments.clear(); + arguments.add(attrBagOtherType); + res = fd.evaluate(null, arguments); + // NOTE: Size does not care about content type! + assertTrue(res.isOk()); + assertEquals(java.math.BigInteger.class, res.getValue().getValue().getClass()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(1), resValue); + + // bag with none + arguments.clear(); + arguments.add(attrBag0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.math.BigInteger.class, res.getValue().getValue().getClass()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(0), resValue); + + // bag with multiple + arguments.clear(); + arguments.add(attrBag2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.math.BigInteger.class, res.getValue().getValue().getClass()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(2), resValue); + } + + + + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagTest.java new file mode 100644 index 000000000..925a09851 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBagTest.java @@ -0,0 +1,547 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBag; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionBagTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + FunctionArgumentAttributeValue attrInteger = null; + FunctionArgumentAttributeValue attrString = null; + + public FunctionDefinitionBagTest() { + try { + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1111111111)); + attrString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("a string value")); + } catch (Exception e) { + fail("creating attributes e="+e); + } + } + + @Test + public void testString() { + + String s1 = "abc"; + String s2 = "def"; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_BAG, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-bag Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + @Test + public void testBoolean() { + + Boolean s1 = true; + Boolean s2 = false; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_BOOLEAN_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_BAG, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-bag Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_BOOLEAN.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + + @Test + public void testInteger() { + + BigInteger s1 = new BigInteger("123"); + BigInteger s2 = new BigInteger("456"); + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_INTEGER_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_BAG, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrString); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-bag Expected data type 'integer' saw 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + + + @Test + public void testDouble() { + + Double s1 = 123.45; + Double s2 = 678.901; + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s1)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(s2)); + } catch (Exception e) { + fail("creating attributes e="+e); + } + + FunctionDefinitionBag<?> fd = (FunctionDefinitionBag<?>) StdFunctions.FD_DOUBLE_BAG; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_BAG, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // bag with only one + arguments.clear(); + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // zero args => empty bag + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + assertEquals(0, bag.size()); + + + // null argument + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-bag Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // argument of other type + arguments.clear(); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-bag Expected data type 'double' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args (check response is correct) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(2, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + + // duplicate args (verify return) + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + arguments.add(attr1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s2, attrValueObject.getValue()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_DOUBLE.getId(), attrValueObject.getDataTypeId()); + assertEquals(s1, attrValueObject.getValue()); + + // lots of args + arguments.clear(); + for (int i = 0; i < 1000; i++) { + arguments.add(attr1); + } + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1000, bag.size()); + + } + + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBaseTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBaseTest.java new file mode 100644 index 000000000..64881758e --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionBaseTest.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacmlatt.pdp.policy.FunctionDefinition; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionBag; + +/** + * Test functions in the abstract FunctionDefinitionSimpleTest class. + * Functions are tested by creating instances of other classes that should have appropriate properties to verify all variations of the responses expected. + * + * Note: we do not test getDataTypeId() because all it does is get the String out of the Identity object and we assume that the Data Type Identity objects + * are tested enough in everything else that any errors in them will be found and fixed quickly. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionBaseTest { + /** + * getId() is pretty trivial, so verifying one should be enough to check that the mechanism is working ok + */ + @Test + public void testGetId() { + FunctionDefinition fd = StdFunctions.FD_STRING_EQUAL; + Identifier id = fd.getId(); + assertTrue(XACML3.ID_FUNCTION_STRING_EQUAL.stringValue().equals(id.stringValue()) ); + } + + /** + * check an instance of every result type that we can deal with + */ + @Test + public void testGetDataType() { + +//?? Need functions that return each of these data types except for Boolean which is returned by any of the EQUAL functions + FunctionDefinition fdstring = StdFunctions.FD_STRING_NORMALIZE_SPACE; + assertEquals(XACML3.ID_DATATYPE_STRING, fdstring.getDataTypeId()); + + FunctionDefinition fdboolean = StdFunctions.FD_STRING_EQUAL; + assertEquals(XACML3.ID_DATATYPE_BOOLEAN, fdboolean.getDataTypeId()); + + FunctionDefinition fdinteger = StdFunctions.FD_INTEGER_ADD; + assertEquals(XACML3.ID_DATATYPE_INTEGER, fdinteger.getDataTypeId()); + + FunctionDefinition fddouble = StdFunctions.FD_DOUBLE_ADD; + assertEquals(XACML3.ID_DATATYPE_DOUBLE, fddouble.getDataTypeId()); + + FunctionDefinition fddate = StdFunctions.FD_DATE_BAG; + assertEquals(XACML3.ID_DATATYPE_DATE, fddate.getDataTypeId()); + + FunctionDefinition fdtime = StdFunctions.FD_TIME_BAG; + assertEquals(XACML3.ID_DATATYPE_TIME, fdtime.getDataTypeId()); + + FunctionDefinition fddateTime = StdFunctions.FD_DATETIME_BAG; + assertEquals(XACML3.ID_DATATYPE_DATETIME, fddateTime.getDataTypeId()); + + FunctionDefinition fddayTimeDuration = StdFunctions.FD_DAYTIMEDURATION_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_DAYTIMEDURATION, fddayTimeDuration.getDataTypeId()); + + FunctionDefinition fdyearMonthDuration = StdFunctions.FD_YEARMONTHDURATION_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_YEARMONTHDURATION, fdyearMonthDuration.getDataTypeId()); + + FunctionDefinition fdanyURI = StdFunctions.FD_ANYURI_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_ANYURI, fdanyURI.getDataTypeId()); + + FunctionDefinition fdhexBinary = StdFunctions.FD_HEXBINARY_UNION; + assertEquals(XACML3.ID_DATATYPE_HEXBINARY, fdhexBinary.getDataTypeId()); + + FunctionDefinition fdbase64Binary = StdFunctions.FD_BASE64BINARY_UNION; + assertEquals(XACML3.ID_DATATYPE_BASE64BINARY, fdbase64Binary.getDataTypeId()); + + FunctionDefinition fdrfc822Name = StdFunctions.FD_RFC822NAME_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_RFC822NAME, fdrfc822Name.getDataTypeId()); + + FunctionDefinition fdx500Name = StdFunctions.FD_X500NAME_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_X500NAME, fdx500Name.getDataTypeId()); + +//TODO - There are currently no functions that return XPathExpression objects +// FunctionDefinition fdxpathExpression = StdFunctions.FD_XPATHEXPRESSION_FROM_STRING; +// assertEquals(XACML3.ID_DATATYPE_XPATHEXPRESSION, fdxpathExpression.getDataTypeId()); + + FunctionDefinition fdipAddress = StdFunctions.FD_IPADDRESS_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_IPADDRESS, fdipAddress.getDataTypeId()); + + FunctionDefinition fddnsName = StdFunctions.FD_DNSNAME_FROM_STRING; + assertEquals(XACML3.ID_DATATYPE_DNSNAME, fddnsName.getDataTypeId()); + } + + /** + * check the type of return, single vs multiple values + */ + @Test + public void testReturnsBag() { + FunctionDefinition fdNotBag = StdFunctions.FD_BOOLEAN_EQUAL; + assertFalse(fdNotBag.returnsBag()); + + FunctionDefinitionBag<?> fdBag = (FunctionDefinitionBag<?>) StdFunctions.FD_STRING_BAG; + assertTrue(fdBag.returnsBag()); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionComparisonTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionComparisonTest.java new file mode 100644 index 000000000..b5b9c1453 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionComparisonTest.java @@ -0,0 +1,1367 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.ISO8601Date; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionComparison; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionTimeInRange; + +/** + * Test FunctionDefinitionComparison + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionComparisonTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr1a = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttrNeg1 = null; + + + FunctionArgumentAttributeValue intAttr1 = null; + FunctionArgumentAttributeValue intAttr1a = null; + FunctionArgumentAttributeValue intAttr2 = null; + FunctionArgumentAttributeValue intAttr0 = null; + FunctionArgumentAttributeValue intAttrNeg1 = null; + + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr1a = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attrNeg1 = null; + + FunctionArgumentAttributeValue attrDateToday = null; + FunctionArgumentAttributeValue attrDateSameDay = null; + FunctionArgumentAttributeValue attrDateTommorrow = null; + FunctionArgumentAttributeValue attrDateYesterday = null; + FunctionArgumentAttributeValue attrDateWithTimeZone = null; + FunctionArgumentAttributeValue attrDateNoTimeZone = null; + + + FunctionArgumentAttributeValue attrTimeToday = null; + FunctionArgumentAttributeValue attrTimeSameDay = null; + FunctionArgumentAttributeValue attrTimeTommorrow = null; + FunctionArgumentAttributeValue attrTimeYesterday = null; + FunctionArgumentAttributeValue attrTimeWithTimeZone = null; + FunctionArgumentAttributeValue attrTimeNoTimeZone = null; + + FunctionArgumentAttributeValue attrDateTimeToday = null; + FunctionArgumentAttributeValue attrDateTimeSameDay = null; + FunctionArgumentAttributeValue attrDateTimeTommorrow = null; + FunctionArgumentAttributeValue attrDateTimeYesterday = null; + FunctionArgumentAttributeValue attrDateTimeWithTimeZone = null; + FunctionArgumentAttributeValue attrDateTimeNoTimeZone = null; + + /** + * Set up some common variables on startup + */ + public FunctionDefinitionComparisonTest() { + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + stringAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("AAA")); + + + intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4)); + attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0)); + + // create dates + Calendar calendar = Calendar.getInstance(); + Date today = calendar.getTime(); + Date longAgo = new Date(1234); + // create a date that is different than "today" but within the same day (i.e. has a different hour) + if (calendar.get(Calendar.HOUR_OF_DAY) > 3) { + calendar.set(Calendar.HOUR_OF_DAY, 3); + } else { + calendar.set(Calendar.HOUR_OF_DAY, 5); + } + Date todayPlus = calendar.getTime(); + calendar.add(Calendar.DATE, 1); + Date tommorrow = calendar.getTime(); + attrDateToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today)); + attrDateSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus)); + attrDateTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(tommorrow)); + attrDateYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo)); + ISO8601Date isoDate = new ISO8601Date(1920, 5, 8); + attrDateNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate)); + isoDate = new ISO8601Date("GMT+00:02", 1920, 5, 8); + attrDateWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(isoDate)); + + // create Times + ISO8601Time isoTime = new ISO8601Time(14, 43, 12, 145); + attrTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + attrTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time(18, 53, 34, 423); + attrTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time(7, 34, 6,543); + attrTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time(12, 12, 12, 12); + attrTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12); + attrTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(isoTime)); + + // create DateTimes + isoDate = new ISO8601Date(1920, 5, 8); + isoTime = new ISO8601Time( 18, 53, 34, 423); + ISO8601DateTime isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 18, 53, 34, 423); + attrDateTimeToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + attrDateTimeSameDay = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time(20, 53, 34, 423); + isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 20, 53, 34, 423); + attrDateTimeTommorrow = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time(7, 34, 6,543); + isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 7, 34, 6, 543); + attrDateTimeYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time(12, 12, 12, 12); + isoDateTime = new ISO8601DateTime((String)null, 1920, 5, 8, 12, 12, 12, 12); + attrDateTimeNoTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + isoTime = new ISO8601Time("GMT:+00:03", 12, 12, 12, 12); + isoDate = new ISO8601Date("GMT:+00:03", 1920, 5, 8); + isoDateTime = new ISO8601DateTime("GMT:+00:03", 1920, 5, 8, 12, 12, 12, 12); + attrDateTimeWithTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(isoDateTime)); + + + + + } catch (Exception e) { + fail("Error creating values e="+ e); + } + } + + /** + * String + */ + @Test + public void testString_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(intAttr1); + arguments.add(stringAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + } + + @Test + public void testString_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testString_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testString_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_STRING_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(stringAttr1); + arguments.add(stringAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + /** + * Integer + */ + @Test + public void testInteger_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + } + + @Test + public void testInteger_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testInteger_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testInteger_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_INTEGER_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check first < second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + + /** + * Double + */ + @Test + public void testDouble_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + @Test + public void testDouble_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testDouble_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testDouble_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DOUBLE_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + /** + * Date + */ + + @Test + public void testDate_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? One with TimeZone and one without + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // test with TimeZone vs without + arguments.clear(); + arguments.add(attrDateWithTimeZone); + arguments.add(attrDateNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + @Test + public void testDate_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testDate_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testDate_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATE_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateToday); + arguments.add(attrDateSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateToday); + arguments.add(attrDateYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + + + + + /** + * Time + */ + + @Test + public void testTime_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? One with TimeZone and one without + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // test with TimeZone vs without + arguments.clear(); + arguments.add(attrTimeWithTimeZone); + arguments.add(attrTimeNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + @Test + public void testTime_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testTime_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testTime_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_TIME_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrTimeToday); + arguments.add(attrTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + + + + /** + * Time-in-range + */ + @Test + public void testTime_in_range() { + + FunctionDefinitionTimeInRange<?> fd = (FunctionDefinitionTimeInRange<?>) StdFunctions.FD_TIME_IN_RANGE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_IN_RANGE, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(3), fd.getNumArgs()); + + // arg 0 in range of others + arguments.add(attrTimeToday); + arguments.add(attrTimeYesterday); + arguments.add(attrTimeTommorrow); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // below range + arguments.clear(); + arguments.add(attrTimeYesterday); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // above range + arguments.clear(); + arguments.add(attrTimeTommorrow); + arguments.add(attrTimeYesterday); + arguments.add(attrTimeToday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // range bad + arguments.clear(); + arguments.add(attrTimeToday); + arguments.add(attrTimeTommorrow); + arguments.add(attrTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bad types + arguments.clear(); + arguments.add(attrDateTimeWithTimeZone); + arguments.add(attrDateTimeNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-in-range Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrDateTimeWithTimeZone); + arguments.add(attrDateTimeNoTimeZone); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-in-range Expected data type 'time' saw 'dateTime' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + /** + * DateTime + */ + + @Test + public void testDateTime_GT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? One with TimeZone and one without + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // test with TimeZone vs without + arguments.clear(); + arguments.add(attrDateTimeWithTimeZone); + arguments.add(attrDateTimeNoTimeZone); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-greater-than Cannot compare this ISO8601DateTime with non-time-zoned ISO8601DateTime", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + @Test + public void testDateTime_GTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_GREATER_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + } + + @Test + public void testDateTime_LT() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + @Test + public void testDateTime_LTE() { + + FunctionDefinitionComparison<?> fd = (FunctionDefinitionComparison<?>) StdFunctions.FD_DATETIME_LESS_THAN_OR_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // first == second + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeSameDay); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first < second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeTommorrow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first > second + arguments.clear(); + arguments.add(attrDateTimeToday); + arguments.add(attrDateTimeYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + } + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionDateTimeArithmeticTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionDateTimeArithmeticTest.java new file mode 100644 index 000000000..e11929e93 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionDateTimeArithmeticTest.java @@ -0,0 +1,1602 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.ISO8601Date; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacml.std.datatypes.ISO8601TimeZone; +import com.att.research.xacml.std.datatypes.XPathDayTimeDuration; +import com.att.research.xacml.std.datatypes.XPathYearMonthDuration; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionDateTimeArithmetic; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionDateTimeArithmeticTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + ExpressionResult res; + + + @Test + public void testDateTime_add_dayTimeDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2000, 12, 31), + new ISO8601Time(23, 59, 30, 1)); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + ISO8601DateTime dateTimeIIC102Result = null; + + // Durations + XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0); + XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 3.223); + XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + FunctionArgumentAttributeValue attrDateTimeIIC102 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + FunctionArgumentAttributeValue attrDurationIIC102 = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + attrDateTimeIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(DataTypes.DT_DATETIME.convert("2002-03-22T08:23:47-05:00"))); + + dateTimeIIC102Result = DataTypes.DT_DATETIME.convert("2002-03-27T10:23:47-05:00"); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover)); + attrDurationIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("P5DT2H0M0S")); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_DAYTIMEDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 17), + new ISO8601Time(19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 7), + new ISO8601Time(5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 17), + new ISO8601Time(19, 23, 18, 0) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2001, 1, 1), + new ISO8601Time(0, 0, 0, 0) ); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-2000, 1, 17), + new ISO8601Time(19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 17), + new ISO8601Time(timeZone0, 19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 17), + new ISO8601Time(timeZone5, 19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // conformance test IIC102 + arguments.clear(); + arguments.add(attrDateTimeIIC102); + arguments.add(attrDurationIIC102); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeIIC102Result, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + @Test + public void testDateTime_subtract_dayTimeDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2001, 1, 1), + new ISO8601Time(0, 0, 0, 0) ); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + + // Durations + XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0); + XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3); + XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 14.778); + XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_DAYTIMEDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 7), + new ISO8601Time(5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 17), + new ISO8601Time(19, 23, 17, 300) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 1, 7), + new ISO8601Time(5, 2, 59, 999) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2000, 12, 31), + new ISO8601Time(23, 59, 30, 1)); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-2000, 1, 7), + new ISO8601Time(5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 7), + new ISO8601Time(timeZone0, 5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 7), + new ISO8601Time(timeZone5, 5, 3, 10, 700) ); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + @Test + public void testDateTime_add_yearMonthDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2000, 12, 31), + new ISO8601Time(23, 59, 30, 1)); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2005, 8, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1994, 6, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2005, 8, 12), + new ISO8601Time(12, 13, 14, 777) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2001, 1, 31), + new ISO8601Time(23, 59, 30, 1) ); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-1995, 8, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 2005, 8, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 2005, 8, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + @Test + public void testDateTime_subtract_yearMonthDuration() { + // Date objects to be adjusted + ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 12), + new ISO8601Time(12, 13, 14, 777)); + ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, + new ISO8601Date(2000, 1, 1), + new ISO8601Time(23, 59, 30, 1)); + ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, + new ISO8601Date(-2000, 1, 12), + new ISO8601Time(12, 13, 14, 0)); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, + new ISO8601Date(timeZone0, 2000, 1, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0)); + ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, + new ISO8601Date(timeZone5, 2000, 1, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0)); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + ISO8601DateTime testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1994, 6, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(2005, 8, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1994, 6, 12), + new ISO8601Time(12, 13, 14, 777) ); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(1999, 12, 1), + new ISO8601Time(23, 59, 30, 1) ); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + null, + new ISO8601Date(-2006, 6, 12), + new ISO8601Time(12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone0, + new ISO8601Date(timeZone0, 1994, 6, 12), + new ISO8601Time(timeZone0, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + testResponse = new ISO8601DateTime( + timeZone5, + new ISO8601Date(timeZone5, 1994, 6, 12), + new ISO8601Time(timeZone5, 12, 13, 14, 0) ); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + + + @Test + public void testDate_add_yearMonthDuration() { + // Date objects to be adjusted + ISO8601Date dateTimeStdExample1 = new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeMsecs =new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 12, 31); + ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12); + ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_ADD_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + ISO8601Date resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + ISO8601Date testResponse = new ISO8601Date(2005, 8, 12); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(1994, 6, 12); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(2005, 8, 12); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(2001, 1, 31); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(-1995, 8, 12); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone0, 2005, 8, 12); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone5, 2005, 8, 12); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + @Test + public void testDate_subtract_yearMonthDuration() { + // Date objects to be adjusted + ISO8601Date dateTimeStdExample1 =new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeMsecs = new ISO8601Date(2000, 1, 12); + ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 1, 1); + ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12); + ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0); + ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60); + ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12); + ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12); + + // Durations + XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0); + XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7); + XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7); + XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1); + + // ARGS declarations + // Dates + FunctionArgumentAttributeValue attrDateTimeStdExample1 = null; + FunctionArgumentAttributeValue attrDateTimeMsecs = null; + FunctionArgumentAttributeValue attrDateTimeCrossover = null; + FunctionArgumentAttributeValue attrDateTimeBC = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null; + FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null; + + // Durations + FunctionArgumentAttributeValue attrDuration0 = null; + FunctionArgumentAttributeValue attrDurationStdExample1 = null; + FunctionArgumentAttributeValue attrDurationNStdExample1 = null; + FunctionArgumentAttributeValue attrDurationMsecs = null; + FunctionArgumentAttributeValue attrDurationCrossover = null; + + // misc bad + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + // set values + try { + // Date attrs + attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1)); + attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs)); + attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover)); + attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC)); + attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0)); + attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5)); + + // Duration attrs + attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0)); + attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1)); + attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1)); + attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs)); + attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover)); + + // misc bad + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_SUBTRACT_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // Duration = 0 => same as original + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDuration0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + ISO8601Date resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(dateTimeStdExample1, resValue); + + + // simple positive operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + ISO8601Date testResponse = new ISO8601Date(1994, 6, 12); + assertEquals(testResponse, resValue); + + // negative operation + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrDurationNStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(2005, 8, 12); + assertEquals(testResponse, resValue); + + // millisecs work correctly (not relevant to YearMonth, but should not break + arguments.clear(); + arguments.add(attrDateTimeMsecs); + arguments.add(attrDurationMsecs); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(1994, 6, 12); + assertEquals(testResponse, resValue); + + // cross minute => cross day => cross month => cross year + arguments.clear(); + arguments.add(attrDateTimeCrossover); + arguments.add(attrDurationCrossover); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(1999, 12, 1); + assertEquals(testResponse, resValue); + + // negative (BC) original date add goes the right direction + arguments.clear(); + arguments.add(attrDateTimeBC); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(-2006, 6, 12); + assertEquals(testResponse, resValue); + + // non-null timezone not changed + // original has timezone offset = 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone0); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone0, 1994, 6, 12); + assertEquals(testResponse, resValue); + + // original has timezone offset not 0 + arguments.clear(); + arguments.add(attrDateTimeTimeZone5); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass()); + resValue = (ISO8601Date)res.getValue().getValue(); + testResponse = new ISO8601Date(timeZone5, 1994, 6, 12); + assertEquals(testResponse, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrDurationStdExample1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrDateTimeStdExample1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionEqualityTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionEqualityTest.java new file mode 100644 index 000000000..52f065ff8 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionEqualityTest.java @@ -0,0 +1,1192 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML1; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.Base64Binary; +import com.att.research.xacml.std.datatypes.DataTypeRFC822Name; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.HexBinary; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacml.std.datatypes.XPathDayTimeDuration; +import com.att.research.xacml.std.datatypes.XPathYearMonthDuration; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionEquality; + +/** + * Test FunctionDefinitionEquality, all of its super-classes, and all XACML functions supported by that class. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-equal + * boolean-equal + * integer-equal + * double-equal + * date-equal + * time-equal + * dateTime-equal + * dayTimeDuration-equal + * yearMonthDuration-equal + * + * Each of these is put into a separate test method just to keep things organized. + * + * + */ +public class FunctionDefinitionEqualityTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttr3 = null; + FunctionArgumentAttributeValue stringAttr4 = null; + + FunctionArgumentAttributeValue booleanAttrT1 = null; + FunctionArgumentAttributeValue booleanAttrT2 = null; + FunctionArgumentAttributeValue booleanAttrF1 = null; + FunctionArgumentAttributeValue booleanAttrF2 = null; + + FunctionArgumentAttributeValue intAttr1 = null; + FunctionArgumentAttributeValue intAttr1a = null; + FunctionArgumentAttributeValue intAttr2 = null; + FunctionArgumentAttributeValue intAttr0 = null; + FunctionArgumentAttributeValue intAttrNeg1 = null; + + public FunctionDefinitionEqualityTest() { + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC")); + stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + + booleanAttrT1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + booleanAttrT2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + booleanAttrF1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + booleanAttrF2 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr1a = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + intAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + intAttr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + intAttrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + } + + + + + /** + * String (matching case) + */ + @Test + public void testString_Equal() { + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check "abc" with "abc" - separate string objects with same value + arguments.add(stringAttr1); + arguments.add(stringAttr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check "abc" with "ABC" (not same) + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * Boolean + */ + @Test + public void testBoolean_Equal() { + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BOOLEAN_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with same value + arguments.add(booleanAttrT1); + arguments.add(booleanAttrT2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check different values + arguments.clear(); + arguments.add(booleanAttrT1); + arguments.add(booleanAttrF1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * Integer + */ + @Test + public void testInteger_Equal() { + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_INTEGER_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with same value + arguments.add(intAttr1); + arguments.add(intAttr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(intAttr1); + arguments.add(intAttrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * Double + */ + @Test + public void testDouble_Equal() { + FunctionArgumentAttributeValue attr1 = null; + FunctionArgumentAttributeValue attr1a = null; + FunctionArgumentAttributeValue attr2 = null; + FunctionArgumentAttributeValue attrNeg1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr1a = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.0)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(2.4)); + attrNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(-1.0)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DOUBLE_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attr1); + arguments.add(attr1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attr1); + arguments.add(attr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attr1); + arguments.add(attrNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + + /** + * Date + */ + @Test + public void testDate_Equal() { + Calendar calendar = Calendar.getInstance(); + Date today = calendar.getTime(); + Date longAgo = new Date(1234); + // create a date that is different than "today" but within the same day (i.e. has a different hour) + if (calendar.get(Calendar.HOUR_OF_DAY) > 3) { + calendar.set(Calendar.HOUR_OF_DAY, 3); + } else { + calendar.set(Calendar.HOUR_OF_DAY, 5); + } + Date todayPlus = calendar.getTime(); + + + FunctionArgumentAttributeValue attrToday = null; + FunctionArgumentAttributeValue attrToday2 = null; + FunctionArgumentAttributeValue attrLaterToday = null; + FunctionArgumentAttributeValue attrYesterday = null; + try { + attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today)); + attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(today)); + attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(todayPlus)); + attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(longAgo)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATE_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrToday); + arguments.add(attrToday2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // Date objects with different times but within the same day should match + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrLaterToday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + /** + * Time + */ + @Test + public void testTime_Equal() { + + Date now = new Date(); + Date now2 = new Date(now.getTime()); + Date notNow = new Date(now.getTime() - 100000); + + FunctionArgumentAttributeValue attrNow = null; + FunctionArgumentAttributeValue attrNow2 = null; + FunctionArgumentAttributeValue attrNotNow = null; + try { + attrNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now)); + attrNow2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(now2)); + attrNotNow = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue(notNow)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_TIME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrNow); + arguments.add(attrNow2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrNow); + arguments.add(attrNotNow); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + /** + * DateTime + */ + @Test + public void testDateTime_Equal() { + Calendar calendar = Calendar.getInstance(); + Date today = calendar.getTime(); + Date longAgo = new Date(1234); + // create a dateTime that is different than "today" changing only the Timezone + if (calendar.get(Calendar.ZONE_OFFSET) > 3) { + calendar.set(Calendar.ZONE_OFFSET, 3); + } else { + calendar.set(Calendar.ZONE_OFFSET, 5); + } + Date todayPlus = calendar.getTime(); + + + FunctionArgumentAttributeValue attrToday = null; + FunctionArgumentAttributeValue attrToday2 = null; + FunctionArgumentAttributeValue attrLaterToday = null; + FunctionArgumentAttributeValue attrYesterday = null; + try { + attrToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today)); + attrToday2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(today)); + attrLaterToday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(todayPlus)); + attrYesterday = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(longAgo)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + // String exact match + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DATETIME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrToday); + arguments.add(attrToday2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrYesterday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // DateTime with different Zones should not match + arguments.clear(); + arguments.add(attrToday); + arguments.add(attrLaterToday); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * dayTimeDuration - Version1 + */ + @Test + public void testDayTimeDuration_Equal_V1() { + + XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL_VERSION1; + + // check identity and type of the thing created + assertEquals(XACML1.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * dayTimeDuration - Current version + */ + @Test + public void testDayTimeDuration_Equal() { + + XPathDayTimeDuration dur1 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration dur2 = new XPathDayTimeDuration(1, 3, 5, 12, 38); + XPathDayTimeDuration differentDur = new XPathDayTimeDuration(-1, 4, 7, 5, 33); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_DAYTIMEDURATION_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * dayTimeDuration - Version1 + */ + @Test + public void testYearMonthDuration_Equal_V1() { + + XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL_VERSION1; + + // check identity and type of the thing created + assertEquals(XACML1.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + + /** + * dayTimeDuration - Current version + */ + @Test + public void testYearMonthDuration_Equal() { + + XPathYearMonthDuration dur1 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration dur2 = new XPathYearMonthDuration(1, 3, 5); + XPathYearMonthDuration differentDur = new XPathYearMonthDuration(-1, 4, 7); + + FunctionArgumentAttributeValue attrDur1 = null; + FunctionArgumentAttributeValue attrDur2 = null; + FunctionArgumentAttributeValue attrDifferentDur = null; + try { + attrDur1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur1)); + attrDur2 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(dur2)); + attrDifferentDur = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(differentDur)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_YEARMONTHDURATION_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrDur1); + arguments.add(attrDur2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrDur1); + arguments.add(attrDifferentDur); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * URI + */ + @Test + public void testAnyURI_Equal() { + + URI uri1 = null; + URI uri2 = null; + URI uriNotThere = null; + try { + uri1 = new URI("http://someplace.com/gothere"); + uri2 = new URI("http://someplace.com/gothere"); + uriNotThere = new URI("http://someplace.com/notGoingThere"); + } catch (Exception e) { + fail(e.toString()); + } + + FunctionArgumentAttributeValue attrUri1 = null; + FunctionArgumentAttributeValue attrUri2 = null; + FunctionArgumentAttributeValue attrUriNotThere = null; + try { + attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1)); + attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2)); + attrUriNotThere = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uriNotThere)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_ANYURI_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrUri1); + arguments.add(attrUri2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrUri1); + arguments.add(attrUriNotThere); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * X500Name + */ + @Test + public void testX500Name_Equal() { + + X500Principal name1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"); + X500Principal name2 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"); + X500Principal name3 = new X500Principal("CN=NotDuke, OU=NotThere, O=Oracle, C=US"); + + + FunctionArgumentAttributeValue attrName1 = null; + FunctionArgumentAttributeValue attrName1a = null; + FunctionArgumentAttributeValue attrNotSameName = null; + try { + attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name1)); + attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name2)); + attrNotSameName = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(name3)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_X500NAME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrName1); + arguments.add(attrName1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrNotSameName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + + /** + * RFC822Name + */ + @Test + public void testRfc822Name_Equal() { + + RFC822Name name1 = null; + RFC822Name name1a = null; + RFC822Name differentLocalName = null; + RFC822Name differentDomainName = null; + RFC822Name localCaseName = null; + RFC822Name domainCaseName = null; + @SuppressWarnings("unused") + RFC822Name noAtName = null; + + try { + name1 = RFC822Name.newInstance("localPart@DomainPart"); + name1a = RFC822Name.newInstance("localPart@DomainPart"); + differentLocalName = RFC822Name.newInstance("differentlocalPart@DomainPart"); + differentDomainName = RFC822Name.newInstance("localPart@differentDomainPart"); + localCaseName = RFC822Name.newInstance("LOCALPart@DomainPart"); + domainCaseName = RFC822Name.newInstance("localPart@DOMAINPart"); + + + } catch (Exception e) { + fail(e.toString()); + } + + // should not be able to create a name without an @. If you try, newInstance returns null + Exception exSeen = null; + try { + noAtName = RFC822Name.newInstance("nameWithoutAnAtSign"); + } catch (Exception e) { + exSeen = e; + } + assertNotNull(exSeen); + + + FunctionArgumentAttributeValue attrName1 = null; + FunctionArgumentAttributeValue attrName1a = null; + FunctionArgumentAttributeValue attrDifferentLocalName = null; + FunctionArgumentAttributeValue attrDifferentDomainName = null; + FunctionArgumentAttributeValue attrLocalCaseName = null; + FunctionArgumentAttributeValue attrDomainCaseName = null; + try { + attrName1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1)); + attrName1a = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(name1a)); + attrDifferentLocalName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentLocalName)); + attrDifferentDomainName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(differentDomainName)); + attrLocalCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(localCaseName)); + attrDomainCaseName = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(domainCaseName)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_RFC822NAME_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_EQUAL, fd.getId()); + assertEquals(DataTypeRFC822Name.newInstance().getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrName1); + arguments.add(attrName1a); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same Local + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrDifferentLocalName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // check not same Domain + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrDifferentDomainName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test case-sensitivity in local part + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrLocalCaseName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test non-case-sensitivity in Domain part + arguments.clear(); + arguments.add(attrName1); + arguments.add(attrDomainCaseName); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * Hex Binary + */ + @Test + public void testHexBinary_Equal() { + HexBinary binary = null; + HexBinary sameBinary = null; + HexBinary differentBinary = null; + try { + binary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d"); + sameBinary = HexBinary.newInstance("e04fd020ea3a6910a2d808002b30309d"); + differentBinary = HexBinary.newInstance("f123a890ee3d"); + } catch (Exception e) { + fail(e.toString()); + } + + FunctionArgumentAttributeValue attrBinary = null; + FunctionArgumentAttributeValue attrSameBinary = null; + FunctionArgumentAttributeValue attrDifferentBinary = null;; + try { + attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(binary)); + attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(sameBinary)); + attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_HEXBINARY.createAttributeValue(differentBinary)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_HEXBINARY_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_HEXBINARY_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_HEXBINARY.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrBinary); + arguments.add(attrSameBinary); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrBinary); + arguments.add(attrDifferentBinary); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } + + + /** + * Base64 Binary + */ + @Test + public void testBase64Binary_Equal() { + Base64Binary binary = null; + Base64Binary sameBinary = null; + Base64Binary differentBinary = null; + try { + binary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"); + sameBinary = Base64Binary.newInstance("TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"); + differentBinary = Base64Binary.newInstance("f123a890ee3d"); + } catch (Exception e) { + fail(e.toString()); + } + + FunctionArgumentAttributeValue attrBinary = null; + FunctionArgumentAttributeValue attrSameBinary = null; + FunctionArgumentAttributeValue attrDifferentBinary = null; + try { + attrBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(binary)); + attrSameBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(sameBinary)); + attrDifferentBinary = new FunctionArgumentAttributeValue(DataTypes.DT_BASE64BINARY.createAttributeValue(differentBinary)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_BASE64BINARY_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BASE64BINARY_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_BASE64BINARY.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + // test normal equals and non-equals + // check separate objects with the same value + arguments.add(attrBinary); + arguments.add(attrSameBinary); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check not same + arguments.clear(); + arguments.add(attrBinary); + arguments.add(attrDifferentBinary); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + } +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionHigherOrderBagTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionHigherOrderBagTest.java new file mode 100644 index 000000000..64364e4b8 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionHigherOrderBagTest.java @@ -0,0 +1,2193 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionHigherOrderBag; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionHigherOrderBagTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // + // ANY-OF tests + // + + + @Test + public void testAny_of() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansTrue = null; + Bag bagStringBooleansFalse = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrb = null; + FunctionArgumentAttributeValue attrh = null; + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrb = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(b)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANY_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag in first position - match + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagabcdefg); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // multiple primitives + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrb); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // extra bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate error: function:string-equal Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + @Test + public void testAll_of() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + FunctionArgumentAttributeValue attrw = null; + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w)); + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ALL_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrw); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attra); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // extra bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + @Test + public void testAny_of_any() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + FunctionArgumentAttributeValue attrw = null; + + + FunctionArgumentAttributeValue attrInt4 = null; + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + FunctionArgumentAttributeValue attrPredicateNof = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w)); + + attrInt4 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(4)); + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + attrPredicateNof = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_N_OF)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse); + FunctionArgumentBag attrBagBooleansTrue = new FunctionArgumentBag(bagBooleansTrue); + FunctionArgumentBag attrBagBooleansFalse = new FunctionArgumentBag(bagBooleansFalse); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ANY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANY_OF_ANY, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrw); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attra); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // n-of with lots of bags - success + arguments.clear(); + arguments.add(attrPredicateNof); + arguments.add(attrInt4); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // n-of with lots of bags - fail + arguments.clear(); + arguments.add(attrPredicateNof); + arguments.add(attrInt4); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansTrue); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + arguments.add(attrBagBooleansFalse); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Bag is empty at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-any Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + + + @Test + public void testAll_of_any() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + String x = "x"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagawx = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringLessThan = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagawx = new Bag(); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringLessThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_LESS_THAN)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ANY; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ALL_OF_ANY, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringLessThan); + arguments.add(attrBagabcdefg); + arguments.add(attrBagawx); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagawx); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // primitive instead of bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagEmpty); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-any 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + @Test + public void testAny_of_all() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + String x = "x"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagewx = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThanOrEqual = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagewx = new Bag(); + bagewx.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagewx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagewx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThanOrEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagewx = new FunctionArgumentBag(bagewx); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ANY_OF_ALL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANY_OF_ALL, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThanOrEqual); + arguments.add(attrBagewx); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagewx); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // primitive instead of bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagEmpty); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:any-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + @Test + public void testAll_of_all() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + String w = "w"; + String x = "x"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagawx = null; + Bag bagwx = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagBooleansFalse = null; + Bag bagBooleansTrue = null; + + + // primitive attrs + FunctionArgumentAttributeValue attra = null; + FunctionArgumentAttributeValue attrh = null; + + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringEqual = null; + FunctionArgumentAttributeValue attrPredicateStringIntersection = null; + FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; + FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagawx = new Bag(); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagawx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagwx = new Bag(); + bagwx.add(DataTypes.DT_STRING.createAttributeValue(w)); + bagwx.add(DataTypes.DT_STRING.createAttributeValue(x)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagBooleansTrue = new Bag(); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansTrue.add(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + bagBooleansFalse = new Bag(); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + bagBooleansFalse.add(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + + + // create primitive attrs + attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + + + + // predicates passed as function arguments + attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); + attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); + attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); + attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagawx = new FunctionArgumentBag(bagawx); + FunctionArgumentBag attrBagwx = new FunctionArgumentBag(bagwx); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF_ALL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ALL_OF_ALL, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagwx); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // normal no-match + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagawx); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagwx); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // primitive instead of bag + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attra); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 2nd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrPredicateStringEqual); + arguments.add(attrBagace); + arguments.add(attra); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 3rd argument must be bag, got 'string'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no primitives - predicate expects only 1 arg + arguments.clear(); + arguments.add(attrPredicateBooleanFromString); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Predicate error: function:boolean-from-string Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagEmpty); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-boolean predicate + arguments.clear(); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate after first arg + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrPredicateStringIntersection); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 2nd argument must be bag, got 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagwx); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Predicate error: function:string-greater-than Expected data type 'string' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected at least 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected at least 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringGreaterThan); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:all-of-all 3rd argument must be bag, got 'null'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + @Test + public void testMap() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + Bag bagStringBooleansFalse = null; + Bag bagStringBooleansTrue = null; + Bag bagInt123 = null; + Bag bagInt789 = null; + + + // primitive attrs + FunctionArgumentAttributeValue attrh = null; + FunctionArgumentAttributeValue attrInt7 = null; + + + + // predicates passed as arguments + FunctionArgumentAttributeValue attrPredicateStringNormalizeToLowerCase = null; + FunctionArgumentAttributeValue attrPredicateIntegerEqual = null; + FunctionArgumentAttributeValue attrPredicateIntegerAdd = null; + + try { + + // Create Bag contents + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue("A")); + bagace.add(DataTypes.DT_STRING.createAttributeValue("C")); + bagace.add(DataTypes.DT_STRING.createAttributeValue("E")); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + bagStringBooleansTrue = new Bag(); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); + bagStringBooleansFalse = new Bag(); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); + bagInt123 = new Bag(); + bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(1)); + bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(2)); + bagInt123.add(DataTypes.DT_INTEGER.createAttributeValue(3)); + bagInt789 = new Bag(); + bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(7)); + bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(8)); + bagInt789.add(DataTypes.DT_INTEGER.createAttributeValue(9)); + + + + // create primitive attrs + attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); + attrInt7 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(7)); + + + // predicates passed as function arguments + attrPredicateStringNormalizeToLowerCase = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE)); + attrPredicateIntegerEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_EQUAL)); + attrPredicateIntegerAdd = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_INTEGER_ADD)); + + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); + FunctionArgumentBag attrBagInt789 = new FunctionArgumentBag(bagInt789); + + FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_MAP; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_MAP, fd.getId()); + assertNull( fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal match + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrBagace); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + Bag bag = res.getBag(); + assertEquals(3, bag.size()); + List<AttributeValue<?>> bagAttributes = bag.getAttributeValueList(); + try { + assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("a"))); + assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("A"))); + assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("c"))); + assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("C"))); + assertTrue(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("e"))); + assertFalse(bagAttributes.contains(DataTypes.DT_STRING.createAttributeValue("E"))); + } catch (Exception ex) { + fail("checking result e="+ex); + } + + // 2-input predicate + arguments.clear(); + arguments.add(attrPredicateIntegerAdd); + arguments.add(attrInt7); + arguments.add(attrBagInt789); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + bag = res.getBag(); + assertEquals(3, bag.size()); + bagAttributes = bag.getAttributeValueList(); + try { + assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("14"))); + assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("15"))); + assertTrue(bagAttributes.contains(DataTypes.DT_INTEGER.createAttributeValue("16"))); + } catch (Exception ex) { + fail("checking result e="+ex); + } + + + // predicate returns booleans + arguments.clear(); + arguments.add(attrPredicateIntegerEqual); + arguments.add(attrInt7); + arguments.add(attrBagInt789); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + bag = res.getBag(); + assertEquals(3, bag.size()); + bagAttributes = bag.getAttributeValueList(); + try { + assertEquals(bagAttributes.get(0), (DataTypes.DT_BOOLEAN.createAttributeValue(true))); + assertEquals(bagAttributes.get(1), (DataTypes.DT_BOOLEAN.createAttributeValue(false))); + assertEquals(bagAttributes.get(2), (DataTypes.DT_BOOLEAN.createAttributeValue(false))); + } catch (Exception ex) { + fail("checking result e="+ex); + } + + // predicate returns bag + + + + // no primitives - predicate function expects 2 + arguments.clear(); + arguments.add(attrPredicateIntegerAdd); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate error: function:integer-add Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bag is empty + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertTrue(res.isBag()); + bag = res.getBag(); + assertEquals(0, bag.size());; + + // no bag + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // extra bag + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + arguments.add(attrh); + arguments.add(attrBagStringBooleansTrue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad predicate + arguments.clear(); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map First argument expected URI, got http://www.w3.org/2001/XMLSchema#string", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate gets unexpected number of args + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // predicate gets bad primitive type + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate error: function:string-normalize-to-lower-case Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bags of different types + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrh); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrPredicateStringNormalizeToLowerCase); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:map Got null argument at index 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionHomogeneousSimpleTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionHomogeneousSimpleTest.java new file mode 100644 index 000000000..8e98793b9 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionHomogeneousSimpleTest.java @@ -0,0 +1,150 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionEquality; + +/** + * FunctionDefinitionHomogeneousSimple is an abstract class, so we have to test it by creating a sub-class. + * The constructor is tested by default when an instance of the sub-class is created for other tests. + * + * Each of these functions needs to be tested for each type of function to be sure the values are correct, + * so this is just a simple test to see that the mechanism works. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionHomogeneousSimpleTest { + + + + @Test + public void testGetDataTypeArgs() { + + // test a simple instance using the Equality class + FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + } + + @Test + public void testGetNumArgs() { + // test a simple instance using the Equality class + FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING); + assertEquals(new Integer(2), fd.getNumArgs()); + } + + @Test + public void testValidateArguments() { + // create some arguments to use later + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttr3 = null; + FunctionArgumentAttributeValue intAttr = null; + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ghi")); + intAttr = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionEquality<String> fd = new FunctionDefinitionEquality<String>(XACML3.ID_FUNCTION_STRING_EQUAL, DataTypes.DT_STRING); + List<String> convertedValues = new ArrayList<String>(); + List<FunctionArgument> listFunctionArguments = new ArrayList<FunctionArgument>(); + + // test correct # of args, both of them strings + listFunctionArguments.add(stringAttr1); + listFunctionArguments.add(stringAttr2); + Status status = fd.validateArguments(listFunctionArguments, convertedValues); + assertTrue(status.isOk()); + assertEquals(convertedValues.size(),2); + + // test too few args + listFunctionArguments.remove(1); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected 2 arguments, got 1", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test too many args + listFunctionArguments.add(stringAttr2); + listFunctionArguments.add(stringAttr3); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected 2 arguments, got 3", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test with null arg + listFunctionArguments.clear(); + listFunctionArguments.add(null); + listFunctionArguments.add(stringAttr1); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Got null argument at arg index 0", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test function that takes 0 args +//TODO test with func that specifies 0 args? ASSUME for now that there are no such functions since a function needs to operate on something +// fail("need to test function with 0 args and various inputs - see validateArguments code"); + + + // test with one is a bag + listFunctionArguments.clear(); + listFunctionArguments.add(stringAttr1); + Bag bag = new Bag(); + FunctionArgument bagArg = new FunctionArgumentBag(bag); + listFunctionArguments.add(bagArg); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected a simple value, saw a bag at arg index 1", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + + // test with string and int + listFunctionArguments.clear(); + listFunctionArguments.add(stringAttr1); + listFunctionArguments.add(intAttr); + status = fd.validateArguments(listFunctionArguments, convertedValues); + assertFalse(status.isOk()); + assertEquals("Expected data type 'string' saw 'integer' at arg index 1", status.getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", status.getStatusCode().getStatusCodeValue().stringValue()); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionLogicalTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionLogicalTest.java new file mode 100644 index 000000000..b70ed138c --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionLogicalTest.java @@ -0,0 +1,422 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionLogical; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionLogicalTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + // use the same args for each test + FunctionArgumentAttributeValue attrT = null; + FunctionArgumentAttributeValue attrF = null; + public FunctionDefinitionLogicalTest () { + try { + attrT = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(true)); + attrF = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(false)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + } + + + @Test + public void testOR() { + FunctionArgumentAttributeValue attr5 = null; + try { + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_OR; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_OR, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.add(attrT); + arguments.add(attrF); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + arguments.clear(); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // test no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // first true, second error + arguments.clear(); + arguments.add(attrT); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // first false, second error + arguments.clear(); + arguments.add(attrF); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // multiple false + arguments.clear(); + arguments.add(attrF); + arguments.add(attrF); + arguments.add(attrF); + arguments.add(attrF); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // non-boolean + arguments.clear(); + arguments.add(attrF); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:or Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg error + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:or Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAND() { + FunctionArgumentAttributeValue attr5 = null; + try { + attr5 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_AND; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_AND, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.add(attrT); + arguments.add(attrF); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + arguments.clear(); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // test no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // first true, second error + arguments.clear(); + arguments.add(attrT); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:and Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first false, second error + arguments.clear(); + arguments.add(attrF); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + // multiple true + arguments.clear(); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrT); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // non-boolean + arguments.clear(); + arguments.add(attrT); + arguments.add(attr5); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals("function:and Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // first arg error + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals("function:and Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testN_of() { + FunctionArgumentAttributeValue attr0 = null; + FunctionArgumentAttributeValue attr2 = null; + try { + attr0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attr2 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(2)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_N_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_N_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attrF); + arguments.add(attrT); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // normal fail + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + + // null count + arguments.clear(); + arguments.add(null); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // 0 count + arguments.clear(); + arguments.add(attr0); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // bad object type for count + arguments.clear(); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of For input string: \"true\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // count larger than list + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of Expected 2 arguments but only 1 arguments in list after the count", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // aborts after find ok + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attrT); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // error before find ok + arguments.clear(); + arguments.add(attr2); + arguments.add(null); + arguments.add(attrT); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // non-boolean in list + arguments.clear(); + arguments.add(attr2); + arguments.add(attrT); + arguments.add(attr0); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:n-of Expected data type 'boolean' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testNot() { + + FunctionDefinitionLogical fd = (FunctionDefinitionLogical) StdFunctions.FD_NOT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_NOT, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // test normal + arguments.clear(); + arguments.add(attrT); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(false), resValue); + + arguments.clear(); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + + // test null/0 args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:not Expected 1 argument, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // test 2 args + arguments.clear(); + arguments.add(attrT); + arguments.add(attrF); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:not Expected 1 argument, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionNumberTypeConversionTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionNumberTypeConversionTest.java new file mode 100644 index 000000000..17843292c --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionNumberTypeConversionTest.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionNumberTypeConversion; + +/** + * Tests for various classes containing only one function. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionNumberTypeConversionTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testDouble_to_integer() { + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(5.432)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_DOUBLE_TO_INTEGER; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(BigInteger.valueOf(5), resValue); + } + + + @Test + public void testInteger_to_double() { + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(5)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionNumberTypeConversion<?, ?> fd = (FunctionDefinitionNumberTypeConversion<?, ?>) StdFunctions.FD_INTEGER_TO_DOUBLE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(5.0), resValue); + } + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionRegexpMatchTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionRegexpMatchTest.java new file mode 100644 index 000000000..04fe8255e --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionRegexpMatchTest.java @@ -0,0 +1,511 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.IPAddress; +import com.att.research.xacml.std.datatypes.RFC2396DomainName; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRegexpMatch; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionRegexpMatchTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @Test + public void testString() { + String v1 = new String("abc"); + String v2 = new String("def"); + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrV2 = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2)); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_STRING_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // null regex + arguments.clear(); + arguments.add(null); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null object to match + arguments.clear(); + arguments.add(attrV1); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // regex not string + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // object to match not correct type + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-regexp-match Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + @Test + public void testAnyURI() { + String regexp = new String("abc"); + URI uri1 = null; + URI uri2 = null; + try { + uri1 = new URI("abc"); + uri2 = new URI("def"); + } catch (Exception e) { + fail("Unable to create URIs, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrUri1 = null; + FunctionArgumentAttributeValue attrUri2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrUri1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri1)); + attrUri2 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(uri2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_ANYURI_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrUri1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrUri2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-regexp-match Expected data type 'anyURI' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testIpAddress() { + String regexp = new String(".*123.*"); + IPAddress addr1 = null; + IPAddress addr2 = null; + try { + addr1 = IPAddress.newInstance("10.123.13.14"); + addr2 = IPAddress.newInstance("10.11.12.13"); + } catch (Exception e) { + fail("Unable to create IPAddresses, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_IPADDRESS_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-regexp-match Expected data type 'ipAddress' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testDnsName() { + String regexp = new String("abc"); + RFC2396DomainName addr1 = null; + RFC2396DomainName addr2 = null; + try { + addr1 = RFC2396DomainName.newInstance("abc"); + addr2 = RFC2396DomainName.newInstance("def"); + } catch (Exception e) { + fail("Unable to create DNSNames, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_DNSNAME_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-regexp-match Expected data type 'dnsName' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testRfc822Name() { + String regexp = new String(".*abc.*"); + RFC822Name addr1 = null; + RFC822Name addr2 = null; + try { + addr1 = RFC822Name.newInstance("abc@somewhere"); + addr2 = RFC822Name.newInstance("def@somewhere"); + } catch (Exception e) { + fail("Unable to create RFC822Names, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_RFC822NAME_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-regexp-match Expected data type 'rfc822Name' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testX500Name() { + String regexp = new String(".*Duke.*"); + X500Principal addr1 = null; + X500Principal addr2 = null; + try { + addr1 = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"); + addr2 = new X500Principal("CN=Policy Engine, OU=Research, O=ATT, C=US"); + } catch (Exception e) { + fail("Unable to create X500Name, e="+e); + } + + + FunctionArgumentAttributeValue attrRegexp = null; + FunctionArgumentAttributeValue attrAddr1 = null; + FunctionArgumentAttributeValue attrAddr2 = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrRegexp = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(regexp)); + attrAddr1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr1)); + attrAddr2 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(addr2)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionRegexpMatch<?> fd = (FunctionDefinitionRegexpMatch<?>) StdFunctions.FD_X500NAME_REGEXP_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrAddr2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // object to match not correct type + arguments.clear(); + arguments.add(attrRegexp); + arguments.add(attrInteger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:x500Name-regexp-match Expected data type 'x500Name' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionSetTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionSetTest.java new file mode 100644 index 000000000..99e27910a --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionSetTest.java @@ -0,0 +1,1903 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionSet; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionSetTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // + // INTERSECTION tests + // + + + @Test + public void testString_intersection() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_INTERSECTION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_INTERSECTION, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(7, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // first bag is empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // second bag is empty + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + @Test + public void testInteger_intersection() { + BigInteger a = new BigInteger("1"); + BigInteger b = new BigInteger("2"); + BigInteger c = new BigInteger("3"); + BigInteger d = new BigInteger("4"); + BigInteger e = new BigInteger("5"); + BigInteger f = new BigInteger("6"); + BigInteger g = new BigInteger("7"); + BigInteger h = new BigInteger("8"); + BigInteger j = new BigInteger("9"); + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_INTEGER.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_INTEGER.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagace.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagace.add(DataTypes.DT_INTEGER.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_INTEGER.createAttributeValue(b)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_INTEGER.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue("abc")); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(1)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_INTEGER_INTERSECTION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_INTERSECTION, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(7, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(f, attrValueObject.getValue() ); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(3, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // first bag is empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // second bag is empty + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(1, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_INTEGER.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-intersection Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + // + // AT_LEAST_ONE_MEMBER_OF tests + // + + @Test + public void testString_at_least_one_member_of() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaaccce = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaaccce = new Bag(); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_AT_LEAST_ONE_MEMBER_OF; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // 2 empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first non-empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-at-least-one-member-of Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + // + // UNION tests + // + + + + + + @Test + public void testString_union() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagaaacccef = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef = new Bag(); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagaaacccef = new FunctionArgumentBag(bagaaacccef); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_UNION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_UNION, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertTrue(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Bag bag = res.getBag(); + assertNotNull(bag); + Iterator<AttributeValue<?>> it = bag.getAttributeValues(); + assertEquals(7, bag.size()); + AttributeValue<?> attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // several but not all union + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(8, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // bag one has duplicates that do not match first bag + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(8, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // bag one has duplicates that do match first bag + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // bag 2 has duplicates that do not match first bag + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(8, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(b, attrValueObject.getValue() ); + + // bag 2 has duplicates that do match first bag + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(c, attrValueObject.getValue() ); + attrValueObject = it.next(); + assertEquals(e, attrValueObject.getValue() ); + + // two empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(0, bag.size()); + + // first bag empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaacccef); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + + // first bag not empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaacccef); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + bag = res.getBag(); + assertNotNull(bag); + it = bag.getAttributeValues(); + assertEquals(4, bag.size()); + attrValueObject = it.next(); + assertEquals(DataTypes.DT_STRING.getId(), attrValueObject.getDataTypeId()); + assertEquals(a, attrValueObject.getValue() ); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-union Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + // + // SUBSET tests + // + + @Test + public void testString_subset() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaaccce = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaaccce = new Bag(); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SUBSET; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_SUBSET, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // not subset + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // subset + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // Not + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // Subset + arguments.clear(); + arguments.add(attrBagb); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // 2 empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first non-empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrBagb); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-subset Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + // + // SET_EQUALS tests + // + + @Test + public void testString_set_equals() { + String a = "a"; + String b = "b"; + String c = "c"; + String d = "d"; + String e = "e"; + String f = "f"; + String g = "g"; + String h = "h"; + String j = "j"; + + + Bag bagabcdefg = null; + Bag bagbdfhj = null; + Bag bagace = null; + Bag bagb = null; + Bag bagaaaccce = null; + Bag bagInt = null; + Bag bagStringInt = null; + Bag bagEmpty = null; + + FunctionArgumentAttributeValue attrBadType = null; + + try { + bagabcdefg = new Bag(); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); + bagbdfhj = new Bag(); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); + bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); + bagace = new Bag(); + bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagb = new Bag(); + bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); + bagaaaccce = new Bag(); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(c)); + bagaaaccce.add(DataTypes.DT_STRING.createAttributeValue(e)); + bagInt = new Bag(); + bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagStringInt = new Bag(); + bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); + bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); + bagEmpty = new Bag(); + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(1.1)); + } catch (Exception ex) { + fail("creating attribute e="+ ex); + } + + // make into attributes + FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); + FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); + FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); + FunctionArgumentBag attrBagb = new FunctionArgumentBag(bagb); + FunctionArgumentBag attrBagaaaccce = new FunctionArgumentBag(bagaaaccce); + FunctionArgumentBag attrBagInt = new FunctionArgumentBag(bagInt); + FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); + FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); + + FunctionDefinitionSet<?,?> fd = (FunctionDefinitionSet<?,?>) StdFunctions.FD_STRING_SET_EQUALS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_SET_EQUALS, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + // normal intersection (everything in both bags, no duplicates) + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // several but not all intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // no intersection + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // one intersection + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagb); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagbdfhj); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag one has duplicates that do intersect + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagace); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // bag 2 has duplicates that do not intersect + arguments.clear(); + arguments.add(attrBagbdfhj); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bag 2 has duplicates that intersect + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // 2 empty bags + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first non-empty, 2nd empty + arguments.clear(); + arguments.add(attrBagaaaccce); + arguments.add(attrBagEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first empty, 2nd not empty + arguments.clear(); + arguments.add(attrBagEmpty); + arguments.add(attrBagaaaccce); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bags of different types + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagStringInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrBagace); + arguments.add(attrBagInt); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first not a bag + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second not a bag + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected a bag, saw a simple value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first null + arguments.clear(); + arguments.add(null); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // second null + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Got null argument", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + arguments.add(attrBagabcdefg); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-set-equals Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + // + // + // REST OF DATA TYPES OMITTED + // because they "should" all work the same + // + // + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionSpecialMatchTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionSpecialMatchTest.java new file mode 100644 index 000000000..3bce2f6cc --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionSpecialMatchTest.java @@ -0,0 +1,488 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.Bag; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentBag; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionRFC822NameMatch; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionX500NameMatch; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionSpecialMatchTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testX500NameMatch() { + // assume that the contents of the name components are not significant and we can treat them as simple blocks of "<name>=<value>" + String A = "cn=Some person"; + String B = "O=Medico Corp"; + String C = "C=US"; + String D = "DNQUALIFIER=d string"; + String E = "SURNAME=some name"; + String F = "INITIALS=inits"; + + + X500Principal abc = new X500Principal(A + "," + B + "," + C); + X500Principal dabc = new X500Principal(D + "," + A + "," + B + "," + C); + X500Principal abcd = new X500Principal(A + "," + B + "," + C + "," + D); + X500Principal adbc = new X500Principal(A + "," + D + "," + B + "," + C); + X500Principal dcab = new X500Principal(D + "," + C + "," + A + "," + B) ; + X500Principal def = new X500Principal(D + "," + E + "," + F) ; + + + FunctionArgumentAttributeValue attrABC = null; + FunctionArgumentAttributeValue attrDABC = null; + FunctionArgumentAttributeValue attrABCD = null; + FunctionArgumentAttributeValue attrADBC = null; + FunctionArgumentAttributeValue attrDCAB = null; + FunctionArgumentAttributeValue attrDEF = null; + + FunctionArgumentAttributeValue attrBad = null; + FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag()); + + + try { + attrABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abc)); + attrDABC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dabc)); + attrABCD = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(abcd)); + attrADBC = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(adbc)); + attrDCAB = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(dcab)); + attrDEF = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(def)); + + attrBad = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionX500NameMatch fd = (FunctionDefinitionX500NameMatch) StdFunctions.FD_X500NAME_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_MATCH, fd.getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal, first exact match for second + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrABC); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test first is end of second + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrDABC); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // first exact match for sub-section but not end of second + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrABCD); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // components of first match components in second but not contiguous + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrADBC); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // components of first match components in second but not in order + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrDCAB); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first does not match second at all + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrDEF); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first arg larger than 2nd arg + arguments.clear(); + arguments.add(attrABCD); + arguments.add(attrABC); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // bad arg types + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrBad); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected data type 'x500Name' saw 'integer' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrABC); + arguments.add(attrABC); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrABC); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg is bag + arguments.clear(); + arguments.add(attrABC); + arguments.add(attrBag); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null arg + arguments.clear(); + arguments.add(null); + arguments.add(attrBag); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:x500Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testRfc822NameMatch() { + + + + + FunctionArgumentAttributeValue attrStringabcxyz = null; + FunctionArgumentAttributeValue attrStringABCxyz = null; + FunctionArgumentAttributeValue attrStringabcXYZ = null; + FunctionArgumentAttributeValue attrStringcx = null; + FunctionArgumentAttributeValue attrStringwholedomainpart = null; + FunctionArgumentAttributeValue attrStringWholeDomainPart = null; + FunctionArgumentAttributeValue attrStringWholeDomain = null; + FunctionArgumentAttributeValue attrStringdomainpart = null; + FunctionArgumentAttributeValue attrStringDomainPart = null; + FunctionArgumentAttributeValue attrStringdotWholeDomain = null; + FunctionArgumentAttributeValue attrStringdomain = null; + + FunctionArgumentAttributeValue attrStringNoMatch = null; + FunctionArgumentAttributeValue attrStringMultipleAt = null; + FunctionArgumentAttributeValue attrStringMissingLocal = null; + FunctionArgumentAttributeValue attrStringMissingDomain = null; + + + FunctionArgumentAttributeValue attrRfcabcxyz = null; + FunctionArgumentAttributeValue attrRfcwholedomainpart = null; + FunctionArgumentAttributeValue attrRfcWholeDomainPart = null; + + FunctionArgumentBag attrBag = new FunctionArgumentBag(new Bag()); + + try { + attrStringabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@xyz")); + attrStringABCxyz = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC@xyz")); + attrStringabcXYZ = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc@XYZ")); + attrStringcx = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("c@x")); + attrStringwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("whole.domain.part")); + attrStringWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain.Part")); + attrStringWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Whole.Domain")); + attrStringdomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain.part")); + attrStringDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Domain.Part")); + attrStringdotWholeDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".Whole.Domain")); + attrStringdomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(".domain.")); + + attrStringNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("no match to any legal name")); + attrStringMultipleAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("name@with@multipleAts")); + attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@multipleAts")); + attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localpart@")); + + attrRfcabcxyz = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@xyz")); + attrRfcwholedomainpart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@whole.domain.part")); + attrRfcWholeDomainPart = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue("abc@Whole.Domain.Part")); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionRFC822NameMatch fd = (FunctionDefinitionRFC822NameMatch) StdFunctions.FD_RFC822NAME_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_MATCH, fd.getId()); + assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // string identical to name - exact match on whole search term + arguments.clear(); + arguments.add(attrStringabcxyz); + arguments.add(attrRfcabcxyz); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // no match local case different + arguments.clear(); + arguments.add(attrStringABCxyz); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // match domain case different + arguments.clear(); + arguments.add(attrStringabcXYZ); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + + // partial local + partial domain + arguments.clear(); + arguments.add(attrStringcx); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // whole domain + arguments.clear(); + arguments.add(attrStringwholedomainpart); + arguments.add(attrRfcwholedomainpart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // whole domain different case + arguments.clear(); + arguments.add(attrStringWholeDomainPart); + arguments.add(attrRfcwholedomainpart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + arguments.clear(); + arguments.add(attrStringwholedomainpart); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // whole domain fail + arguments.clear(); + arguments.add(attrStringWholeDomain); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // partial domain match + arguments.clear(); + arguments.add(attrStringDomainPart); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // partial domain different case + arguments.clear(); + arguments.add(attrStringdomainpart); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // partial domain fail + arguments.clear(); + arguments.add(attrStringdotWholeDomain); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + arguments.clear(); + arguments.add(attrStringdomain); + arguments.add(attrRfcWholeDomainPart); + res = fd.evaluate(null, arguments); + assertTrue(res.getStatus().isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // search term contains more than 1 @ + arguments.clear(); + arguments.add(attrStringMultipleAt); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match String contained more than 1 '@' in 'name@with@multipleAts'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // search term missing local part + arguments.clear(); + arguments.add(attrStringMissingLocal); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match String missing local part in '@multipleAts'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // search term missing domain part + arguments.clear(); + arguments.add(attrStringMissingDomain); + arguments.add(attrRfcabcxyz); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match String missing domain part in 'localpart@'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg types + arguments.clear(); + arguments.add(attrRfcabcxyz); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected data type 'string' saw 'rfc822Name' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrStringNoMatch); + arguments.add(attrStringNoMatch); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg is bag + arguments.clear(); + arguments.add(attrStringNoMatch); + arguments.add(attrBag); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Expected a simple value, saw a bag at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null arg + arguments.clear(); + arguments.add(null); + arguments.add(attrStringNoMatch); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:rfc822Name-match Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringConversionTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringConversionTest.java new file mode 100644 index 000000000..341da61d0 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringConversionTest.java @@ -0,0 +1,2504 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.IPAddress; +import com.att.research.xacml.std.datatypes.IPv4Address; +import com.att.research.xacml.std.datatypes.IPv6Address; +import com.att.research.xacml.std.datatypes.ISO8601Date; +import com.att.research.xacml.std.datatypes.ISO8601DateTime; +import com.att.research.xacml.std.datatypes.ISO8601Time; +import com.att.research.xacml.std.datatypes.ISO8601TimeZone; +import com.att.research.xacml.std.datatypes.PortRange; +import com.att.research.xacml.std.datatypes.RFC2396DomainName; +import com.att.research.xacml.std.datatypes.RFC822Name; +import com.att.research.xacml.std.datatypes.XPathDayTimeDuration; +import com.att.research.xacml.std.datatypes.XPathYearMonthDuration; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringConversion; + +/** + * Tests for converting objects to/from Strings. + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionStringConversionTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + /** + * Boolean + */ + @Test + public void testBoolean_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("true")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_BOOLEAN_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(new Boolean(true), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-from-string Cannot convert from \"java.lang.String\" with value \"not valid obj value\" to boolean", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:boolean-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_boolean() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "false"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_BOOLEAN.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_BOOLEAN; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-boolean Expected data type 'boolean' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + /** + * Integer + */ + @Test + public void testInteger_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("123456")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_INTEGER_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_INTEGER_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("123456"), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-from-string For input string: \"n\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:integer-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_integer() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "1234"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_INTEGER; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_INTEGER, fd.getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-integer Expected data type 'integer' saw 'double' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + /** + * Double + */ + @Test + public void testDouble_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5.432")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DOUBLE_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DOUBLE_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Double resValue = (Double)res.getValue().getValue(); + assertEquals(new Double(5.432), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-from-string For input string: \"not valid obj value\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:double-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_double() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObjBig = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "5.432"; + String objValueStringBig = "55555555555555555555.123455"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueString)); + attrObjBig = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(objValueStringBig)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DOUBLE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DOUBLE, fd.getId()); + assertEquals(DataTypes.DT_DOUBLE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + arguments.clear(); + arguments.add(attrObjBig); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("5.555555555555556E19", res.getValue().getValue()); + + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-double Expected data type 'double' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + /** + * Time + */ + @Test + public void testTime_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrString3 = null; + FunctionArgumentAttributeValue attrString4 = null; + FunctionArgumentAttributeValue attrStringTimeZone = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("5:12:34.323")); + attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12")); + attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34")); + attrStringTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("05:12:34.323+03:00")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_TIME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_TIME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + ISO8601Time resValue = (ISO8601Time)res.getValue().getValue(); + assertEquals(new ISO8601Time(5, 12, 34, 323), resValue); + + // check missing 0 in front + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // check missing seconds/msecs + arguments.clear(); + arguments.add(attrString3); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Time string too short", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // check missing just msecs + arguments.clear(); + arguments.add(attrString4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Time)res.getValue().getValue(); + assertEquals(new ISO8601Time(5, 12, 34, 0), resValue); + + // check TimeZone + arguments.clear(); + arguments.add(attrStringTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Time)res.getValue().getValue(); + assertEquals(new ISO8601Time(new ISO8601TimeZone(180), 5, 12, 34, 323), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Invalid hour of day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:time-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_time() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObj2 = null; + FunctionArgumentAttributeValue attrObjTimeZone = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323")); + attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:01:02.323")); + attrObjTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_TIME.createAttributeValue("05:12:34.323+03:00")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_TIME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_TIME, fd.getId()); + assertEquals(DataTypes.DT_TIME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("05:12:34.323", res.getValue().getValue()); + + // missing digits in string value? + arguments.clear(); + arguments.add(attrObj2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("05:01:02.323", res.getValue().getValue()); + + // include TimeZone + arguments.clear(); + arguments.add(attrObjTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("05:12:34.323+03:00", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-time Expected data type 'time' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + /** + * Date + */ + @Test + public void testDate_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrString3 = null; + FunctionArgumentAttributeValue attrString4 = null; + FunctionArgumentAttributeValue attrString5 = null; + FunctionArgumentAttributeValue attrString6 = null; + FunctionArgumentAttributeValue attrString7 = null; + FunctionArgumentAttributeValue attrString8 = null; + FunctionArgumentAttributeValue attrString9 = null; + FunctionArgumentAttributeValue attrStringDateZone = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12")); + attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12")); + attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12")); + attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12")); + attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12")); + attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2")); + attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12")); + attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45")); + attrStringDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12+03:00")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATE_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATE_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + ISO8601Date resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(2013, 5, 12), resValue); + + // check negative + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(-2013, 5, 12), resValue); + + // check big + arguments.clear(); + arguments.add(attrString3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(1232013, 5, 12), resValue); + + // check big negative + arguments.clear(); + arguments.add(attrString4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(-1232013, 5, 12), resValue); + + // bad year + arguments.clear(); + arguments.add(attrString5); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad month + arguments.clear(); + arguments.add(attrString6); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad day format + arguments.clear(); + arguments.add(attrString7); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // month out of range + arguments.clear(); + arguments.add(attrString8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // day out of range + arguments.clear(); + arguments.add(attrString9); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // check TimeZone + arguments.clear(); + arguments.add(attrStringDateZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601Date)res.getValue().getValue(); + assertEquals(new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Invalid year", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:date-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_date() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObj2 = null; + FunctionArgumentAttributeValue attrObjDateZone = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12")); + attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("0001-01-01")); + attrObjDateZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue("2013-05-12+03:00")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATE, fd.getId()); + assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12", res.getValue().getValue()); + + // missing digits in string value? + arguments.clear(); + arguments.add(attrObj2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("1-01-01", res.getValue().getValue()); + + // include DateZone + arguments.clear(); + arguments.add(attrObjDateZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12+03:00", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-date Expected data type 'date' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + /** + * DateTime + */ + @Test + public void testDateTime_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrString3 = null; + FunctionArgumentAttributeValue attrString4 = null; + FunctionArgumentAttributeValue attrString5 = null; + FunctionArgumentAttributeValue attrString6 = null; + FunctionArgumentAttributeValue attrString7 = null; + FunctionArgumentAttributeValue attrString8 = null; + FunctionArgumentAttributeValue attrString9 = null; + FunctionArgumentAttributeValue attrStringDateTimeZone = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-2013-05-12T12:14:15.323")); + attrString3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1232013-05-12T12:14:15.323")); + attrString4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-1232013-05-12T12:14:15.323")); + attrString5 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("213-05-12T12:14:15.323")); + attrString6 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-5-12T12:14:15.323")); + attrString7 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-2T12:14:15.323")); + attrString8 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-32-12T12:14:15.323")); + attrString9 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-45T12:14:15.323")); + attrStringDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2013-05-12T12:14:15.323+03:00")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DATETIME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DATETIME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + // check negative + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(-2013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + + // check big + arguments.clear(); + arguments.add(attrString3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + // check big negative + arguments.clear(); + arguments.add(attrString4); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(null, new ISO8601Date(-1232013, 5, 12), new ISO8601Time(12, 14, 15, 323)), resValue); + + // bad year + arguments.clear(); + arguments.add(attrString5); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid year (must be at least 4 digits)", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad month + arguments.clear(); + arguments.add(attrString6); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad day format + arguments.clear(); + arguments.add(attrString7); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // month out of range + arguments.clear(); + arguments.add(attrString8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid month", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // day out of range + arguments.clear(); + arguments.add(attrString9); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid day", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // check TimeZone + arguments.clear(); + arguments.add(attrStringDateTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (ISO8601DateTime)res.getValue().getValue(); + assertEquals(new ISO8601DateTime(new ISO8601TimeZone(180), new ISO8601Date(new ISO8601TimeZone(180), 2013, 5, 12), new ISO8601Time(new ISO8601TimeZone(180),12, 14, 15, 323)), resValue); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Invalid year", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dateTime-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_dateTime() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObj2 = null; + FunctionArgumentAttributeValue attrObjDateTimeZone = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323")); + attrObj2 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("0001-01-01T12:14:15.323")); + attrObjDateTimeZone = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue("2013-05-12T12:14:15.323+03:00")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DATETIME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DATETIME, fd.getId()); + assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12T12:14:15.323", res.getValue().getValue()); + + // missing digits in string value? + arguments.clear(); + arguments.add(attrObj2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("1-01-01T12:14:15.323", res.getValue().getValue()); + + // include DateTimeZone + arguments.clear(); + arguments.add(attrObjDateTimeZone); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("2013-05-12T12:14:15.323+03:00", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-dateTime Expected data type 'dateTime' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + /** + * URI + */ + @Test + public void testURI_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("http://someMachine.com/subdir")); + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_ANYURI_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + URI resValue = (URI)res.getValue().getValue(); + try { + assertEquals(new URI("http://someMachine.com/subdir"), resValue); + } catch (URISyntaxException e) { + fail("uri generation e="+e); + } + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-from-string Illegal character in path at index 3: not valid obj value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_anyURI() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "http://aMachine.com:8080/aRef"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_ANYURI; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_ANYURI, fd.getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-anyURI Expected data type 'anyURI' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + /** + * XPathDayTimeDuration + */ + @Test + public void testXPathDayTimeDuration_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringNeg1 = null; + FunctionArgumentAttributeValue attrStringNeg2 = null; + FunctionArgumentAttributeValue attrStringNoDay = null; + FunctionArgumentAttributeValue attrStringNoHour = null; + FunctionArgumentAttributeValue attrStringNoMin = null; + FunctionArgumentAttributeValue attrStringNoSec = null; + FunctionArgumentAttributeValue attrStringNoP = null; + FunctionArgumentAttributeValue attrStringSecondsDot = null; + FunctionArgumentAttributeValue attrStringMissingTOk = null; + FunctionArgumentAttributeValue attrStringMissingTBad = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23S")); + attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P3DT10H30M23S")); + attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-3DT10H30M23S")); + attrStringNoDay = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PT10H30M23S")); + attrStringNoHour = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT30M23S")); + attrStringNoMin = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H23S")); + attrStringNoSec = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M")); + attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("3DT10H30M")); + attrStringSecondsDot = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3DT10H30M23.456S")); + attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D")); + attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DAYTIMEDURATION_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + XPathDayTimeDuration resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23), resValue); + + + // negative values in front is allowed + arguments.clear(); + arguments.add(attrStringNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(-1, 3, 10, 30, 23), resValue); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringNeg2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid chunk \"P-3DT10H30M23S\" at position 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // omit parts that are 0 + arguments.clear(); + arguments.add(attrStringNoDay); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 0, 10, 30, 23), resValue); + + arguments.clear(); + arguments.add(attrStringNoHour); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 0, 30, 23), resValue); + + arguments.clear(); + arguments.add(attrStringNoMin); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 0, 23), resValue); + + arguments.clear(); + arguments.add(attrStringNoSec); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 0), resValue); + + // P must always be present + arguments.clear(); + arguments.add(attrStringNoP); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"3DT10H30M\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // seconds may contain decimal + arguments.clear(); + arguments.add(attrStringSecondsDot); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 10, 30, 23.456), resValue); + + // T must be absent iff all time items are absent + arguments.clear(); + arguments.add(attrStringMissingTOk); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathDayTimeDuration)res.getValue().getValue(); + assertEquals(new XPathDayTimeDuration(1, 3, 0, 0, 0), resValue); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringMissingTBad); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dayTimeDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_dayTimeDuration() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "P3DT10H30M23S"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DAYTIMEDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION, fd.getId()); + assertEquals(DataTypes.DT_DAYTIMEDURATION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-dayTimeDuration Expected data type 'dayTimeDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + /** + * XPathYearMonthDuration + */ + @Test + public void testXPathYearMonthDuration_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringNeg1 = null; + FunctionArgumentAttributeValue attrStringNeg2 = null; + FunctionArgumentAttributeValue attrStringNoYear1 = null; + FunctionArgumentAttributeValue attrStringNoYear2 = null; + FunctionArgumentAttributeValue attrStringNoMonth1 = null; + FunctionArgumentAttributeValue attrStringNoMonth2 = null; + FunctionArgumentAttributeValue attrStringNoValue = null; + FunctionArgumentAttributeValue attrStringNoP = null; + FunctionArgumentAttributeValue attrStringBigMonths = null; + FunctionArgumentAttributeValue attrStringMissingTOk = null; + FunctionArgumentAttributeValue attrStringMissingTBad = null; + FunctionArgumentAttributeValue attrStringZeroMonths = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y2M")); + attrStringNeg1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("-P1Y2M")); + attrStringNeg2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P-1Y2M")); + attrStringNoYear1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P2M")); + attrStringNoYear2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("PY2M")); + attrStringNoMonth1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y")); + attrStringNoMonth2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1YM")); + attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P")); + attrStringNoP = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("1Y2M")); + attrStringBigMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P1Y12M")); + attrStringMissingTOk = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D")); + attrStringMissingTBad = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P3D10H30M23S")); + attrStringZeroMonths = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("P0M")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_YEARMONTHDURATION_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + XPathYearMonthDuration resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1,1, 2), resValue); + + + // negative values in front is allowed + arguments.clear(); + arguments.add(attrStringNeg1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(-1, 1, 2), resValue); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringNeg2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P-1Y2M\" at position 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // omit parts that are 0 + arguments.clear(); + arguments.add(attrStringNoYear1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 0, 2), resValue); + + arguments.clear(); + arguments.add(attrStringNoYear2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid chunk \"PY2M\" at position 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + arguments.clear(); + arguments.add(attrStringNoMonth1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 1, 0), resValue); + + arguments.clear(); + arguments.add(attrStringNoMonth2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid chunk \"P1YM\" at position 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // No field with a value + arguments.clear(); + arguments.add(attrStringNoValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P\": No duration components following P", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // P must always be present + arguments.clear(); + arguments.add(attrStringNoP); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"1Y2M\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // Canonical Form of output may not have more than 12 months, but input as string is ok? + arguments.clear(); + arguments.add(attrStringBigMonths); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 1, 12), resValue); + + // Canonical representation of 0 Months + arguments.clear(); + arguments.add(attrStringZeroMonths); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (XPathYearMonthDuration)res.getValue().getValue(); + assertEquals(new XPathYearMonthDuration(1, 0, 0), resValue); + + // T must be absent iff all time items are absent + arguments.clear(); + arguments.add(attrStringMissingTOk); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid XPath yearMonthDuraiton \"{durationSign=1years=0months=0days=3hours=0minutes=0seconds=0millis=0}\": includes days, hours, minutes, or seconds", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // negative in middle of string not ok + arguments.clear(); + arguments.add(attrStringMissingTBad); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"P3D10H30M23S\" at position 6: out of order component", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Invalid ISO8601 duration string \"not valid obj value\" at position 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:yearMonthDuration-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_yearMonthDuration() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "P1Y2M"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_YEARMONTHDURATION; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION, fd.getId()); + assertEquals(DataTypes.DT_YEARMONTHDURATION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-yearMonthDuration Expected data type 'yearMonthDuration' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + /** + * X500Principal + * + * See http://www.ietf.org/rfc/rfc2253.txt and http://www.ietf.org/rfc/rfc2251.txt + */ + @Test + public void testX500Principal_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringNoComma = null; + FunctionArgumentAttributeValue attrStringEmpty = null; + FunctionArgumentAttributeValue attrStringNoValue = null; + FunctionArgumentAttributeValue attrStringOrder = null; + FunctionArgumentAttributeValue attrStringDottedDecimalOID = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local, ST=NJ, O=ATT, C=USA")); + attrStringNoComma = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=local ST=NJ, O=ATT, C=USA")); + attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrStringNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("CN=Name, L=, ST=NJ, O=ATT, C=USA")); + attrStringOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("L=local, ST=NJ, O=ATT, CN=Name, C=USA")); + attrStringDottedDecimalOID = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2.5.4.3=A. N. Other")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_X500NAME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_X500NAME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + X500Principal resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue); + + // no comma between components => next attribute/value is included as part of first value + arguments.clear(); + arguments.add(attrStringNoComma); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("CN=Name, L=local ST=NJ, O=ATT, C=USA"), resValue); + + // nothing in name (fail) + arguments.clear(); + arguments.add(attrStringEmpty); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal(""), resValue); + + // type value with no = + arguments.clear(); + arguments.add(attrStringNoValue); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("CN=Name, L=, ST=NJ, O=ATT, C=USA"), resValue); + + // different order + arguments.clear(); + arguments.add(attrStringOrder); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertNotEquals(new X500Principal("CN=Name, L=local, ST=NJ, O=ATT, C=USA"), resValue); + + // dotted-decimal name with numbers + arguments.clear(); + arguments.add(attrStringDottedDecimalOID); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (X500Principal)res.getValue().getValue(); + assertEquals(new X500Principal("2.5.4.3=A. N. Other"), resValue); + + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:x500Name-from-string improperly specified input name: not valid obj value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:x500Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_x500Name() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "CN=Name, L=local, ST=NJ, O=ATT, C=USA"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_X500NAME.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_X500NAME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_X500NAME, fd.getId()); + assertEquals(DataTypes.DT_X500NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-x500Name Expected data type 'x500Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + /** + * RFC822Name + */ + @Test + public void testRFC822Name_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringCapsDomain = null; + FunctionArgumentAttributeValue attrStringCapsLocal = null; + FunctionArgumentAttributeValue attrStringMissingAt = null; + FunctionArgumentAttributeValue attrStringMissingLocal = null; + FunctionArgumentAttributeValue attrStringMissingDomain = null; + FunctionArgumentAttributeValue attrStringEmpty = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@Domain")); + attrStringCapsDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@DOMAIN")); + attrStringCapsLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("LOCAL@Domain")); + attrStringMissingAt = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("localDomain")); + attrStringMissingLocal = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("@Domain")); + attrStringMissingDomain = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("local@")); + attrStringEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_RFC822NAME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + RFC822Name resValue = (RFC822Name)res.getValue().getValue(); + assertEquals(new RFC822Name("local", "domain"), resValue); + + // caps domain + arguments.clear(); + arguments.add(attrStringCapsDomain); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC822Name)res.getValue().getValue(); + assertEquals(new RFC822Name("local", "domain"), resValue); + + // caps local + arguments.clear(); + arguments.add(attrStringCapsLocal); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC822Name)res.getValue().getValue(); + assertNotEquals(new RFC822Name("local", "domain"), resValue); + + // missing at + arguments.clear(); + arguments.add(attrStringMissingAt); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"localDomain\": missing local part", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // missing local + arguments.clear(); + arguments.add(attrStringMissingLocal); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"@Domain\": empty parts", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // missing domain + arguments.clear(); + arguments.add(attrStringMissingDomain); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"local@\": empty parts", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // empty + arguments.clear(); + arguments.add(attrStringEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"\": missing local part", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Invalid RFC822Name \"not valid obj value\": missing local part", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:rfc822Name-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_rfc822Name() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "local@DOMAIN"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_RFC822NAME.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_RFC822NAME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME, fd.getId()); + assertEquals(DataTypes.DT_RFC822NAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals("local@domain", res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-rfc822Name Expected data type 'rfc822Name' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + /** + * IPAddress + */ + @Test + public void testIPAddress_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrStringFull = null; + FunctionArgumentAttributeValue attrStringMissingElement = null; + FunctionArgumentAttributeValue attrStringTooManyElement = null; + FunctionArgumentAttributeValue attrStringIllegalElement = null; + FunctionArgumentAttributeValue attrStringOutOfOrder = null; + + FunctionArgumentAttributeValue attrStringMask = null; + FunctionArgumentAttributeValue attrStringMissingMaskElement = null; + FunctionArgumentAttributeValue attrStringTooManyMaskElement = null; + FunctionArgumentAttributeValue attrStringIllegalMaskElement = null; + FunctionArgumentAttributeValue attrStringMaskNoValue = null; + + FunctionArgumentAttributeValue attrStringMinusPort = null; + FunctionArgumentAttributeValue attrStringPortMinus = null; + FunctionArgumentAttributeValue attrStringPortPort = null; + FunctionArgumentAttributeValue attrStringNoPort = null; + FunctionArgumentAttributeValue attrStringBadPort = null; + FunctionArgumentAttributeValue attrStringTooManyPorts = null; + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + + // set up for v4 address tests - this setup and the tests are repeated for V6 + short[] addrShorts= {123, 134, 156, 255 }; + short[] addrMaskShorts= {255, 255, 255, 255 }; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123")); + attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123/10.11.123.255:123-456")); + attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.255")); + attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123.222")); + attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.123.255")); + attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123:123-456/10.11.12.255")); + + attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123/10.11.12.255")); + attrStringMissingMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123/10.11.123")); + attrStringTooManyMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.255/10.11.12.123.222")); + attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123/10.11.12.255")); + attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123/")); + // optional mask + // "/" with no mask (fail) + + attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123:-123")); + attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123:123-")); + attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123:1234567-432")); + attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123:")); + attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123:12.34")); + attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("10.11.12.123:-123-456")); + + + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_IPADDRESS_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + IPAddress resValue = (IPAddress)res.getValue().getValue(); + assertEquals(new IPv4Address(addrShorts, null, null), resValue); + + // fully-loaded address + arguments.clear(); + arguments.add(attrStringFull); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, addrMaskShorts, PortRange.newInstance("123-456")), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // missing element + arguments.clear(); + arguments.add(attrStringMissingElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.123\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many elements + arguments.clear(); + arguments.add(attrStringTooManyElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.12.123.222\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal element + arguments.clear(); + arguments.add(attrStringIllegalElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.12.123\": invalid octet: \"256", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // Out of order + arguments.clear(); + arguments.add(attrStringOutOfOrder); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.12.123:123-456/10.11.12.255\": out of order components", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // simple mask + arguments.clear(); + arguments.add(attrStringMask); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, addrMaskShorts, null), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // missing mask element + arguments.clear(); + arguments.add(attrStringMissingMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.12.123\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many mask elements + arguments.clear(); + arguments.add(attrStringTooManyMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.12.123.222\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal Mask element + arguments.clear(); + arguments.add(attrStringIllegalMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.12.123\": invalid octet: \"256", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + //mask indicator without value + arguments.clear(); + arguments.add(attrStringMaskNoValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"\": invalid address", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // portrange (-port, port-, port-port) + arguments.clear(); + arguments.add(attrStringMinusPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("-123")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortMinus); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("123-")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv4Address(addrShorts, null, PortRange.newInstance("1234567-432")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + // ":" without port + arguments.clear(); + arguments.add(attrStringNoPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv4 address string \"10.11.12.123:\": no portrange given after ':'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad port number + arguments.clear(); + arguments.add(attrStringBadPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port range + arguments.clear(); + arguments.add(attrStringTooManyPorts); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Unknown IPAddress type for \"not valid obj value\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // + // V6 IP Addresses + // + + // reset the variable for IPv6 tests + FunctionArgumentAttributeValue attrStringAlternateFull = null; + FunctionArgumentAttributeValue attrStringEmptyElement = null; + FunctionArgumentAttributeValue attrString2xEmptyElement = null; + FunctionArgumentAttributeValue attrStringNoStartBracket = null; + FunctionArgumentAttributeValue attrStringNoEndBracket = null; + short[] addrv6Shorts = {(short)0x2001, (short)0xdb8, (short)0x85a3, (short)0x0, (short)0x0, (short)0x8a2e, (short)0x370, (short)0x1}; + Short prefix = new Short((short) 121); + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]")); + attrStringFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/121]:123-456")); + attrStringAlternateFull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]/121:123-456")); + attrStringEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e:370:1]")); + attrString2xEmptyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1]")); + attrStringNoStartBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("2002:db8:85a3::8a2e::1]")); + attrStringNoEndBracket = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3::8a2e::1")); + + attrStringMissingElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:1]")); + attrStringTooManyElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1:123]")); + attrStringIllegalElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1]")); + attrStringOutOfOrder = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:mnop:85a3:0:0:8a2e:370:1:123-456/121]")); + + attrStringMask = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/21]")); + attrStringIllegalMaskElement = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/130]")); + attrStringMaskNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1/]")); + + attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123")); + attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:123-")); + attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:1234567-432")); + attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:")); + attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:12.34")); + attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("[2001:db8:85a3:0:0:8a2e:370:1]:-123-456")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + + // test normal + arguments.clear(); + arguments.add(attrString1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + assertEquals(new IPv6Address(addrv6Shorts, null, null), resValue); + + // fully-loaded address - "prefix" is inside the brackets (not clear if this is correct) + arguments.clear(); + arguments.add(attrStringFull); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, new Short(prefix), PortRange.newInstance("123-456")), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // Alternate way of identifying "prefix" - outside the brackets + arguments.clear(); + arguments.add(attrStringAlternateFull); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, prefix, PortRange.newInstance("123-456")), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + + // consecutive zero elements removed + arguments.clear(); + arguments.add(attrStringEmptyElement); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // consecutive zero elements removed in two locations (no-no) + arguments.clear(); + arguments.add(attrString2xEmptyElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3::8a2e::1\": multiple zero runs", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // address must have [] on it + arguments.clear(); + arguments.add(attrStringNoStartBracket); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2002:db8:85a3::8a2e::1]\": missing opening bracket", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrStringNoEndBracket); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"[2001:db8:85a3::8a2e::1\": missing closing bracket", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // missing element + arguments.clear(); + arguments.add(attrStringMissingElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:1\": not enough address fields", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many elements + arguments.clear(); + arguments.add(attrStringTooManyElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:db8:85a3:0:0:8a2e:370:1:123\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal element + arguments.clear(); + arguments.add(attrStringIllegalElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address component \"mnop\": invalid hex", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // Out of order + arguments.clear(); + arguments.add(attrStringOutOfOrder); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6Address string \"2001:mnop:85a3:0:0:8a2e:370:1:123-456\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // simple mask + arguments.clear(); + arguments.add(attrStringMask); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, prefix, null), resValue); + } catch (Exception e) { + fail("port error e="+e); + } + + // illegal Mask element + arguments.clear(); + arguments.add(attrStringIllegalMaskElement); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/130]\": prefix is larger than 128", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + //mask indicator without value + arguments.clear(); + arguments.add(attrStringMaskNoValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid Ipv6Address string \"[2001:db8:85a3:0:0:8a2e:370:1/]\": prefix designation without value", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // portrange (-port, port-, port-port) + arguments.clear(); + arguments.add(attrStringMinusPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("-123")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortMinus); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("123-")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (IPAddress)res.getValue().getValue(); + try { + assertEquals(new IPv6Address(addrv6Shorts, null, PortRange.newInstance("1234567-432")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + // ":" without port + arguments.clear(); + arguments.add(attrStringNoPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid IPv6 address string \"[2001:db8:85a3:0:0:8a2e:370:1]:\": no portrange given after ':'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // bad port number + arguments.clear(); + arguments.add(attrStringBadPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"12.34\": invalid port number", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port range + arguments.clear(); + arguments.add(attrStringTooManyPorts); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:ipAddress-from-string Invalid PortRange \"-123-456\": too many ranges", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + + + } + + @Test + public void testString_from_ipAddress() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrObjV6 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "10.11.12.123"; + String objValueStringV6 = "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueString)); + attrObjV6 = new FunctionArgumentAttributeValue(DataTypes.DT_IPADDRESS.createAttributeValue(objValueStringV6)); + + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_IPADDRESS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS, fd.getId()); + assertEquals(DataTypes.DT_IPADDRESS.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal V4 + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // test normal V6 + arguments.clear(); + arguments.add(attrObjV6); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueStringV6.toLowerCase(), res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-ipAddress Expected data type 'ipAddress' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + + + + + /** + * RFC2396DomainName + */ + @Test + public void testRFC2396DomainName_from_string() { + FunctionArgumentAttributeValue attrString1 = null; + FunctionArgumentAttributeValue attrString2 = null; + FunctionArgumentAttributeValue attrStringMinusPort = null; + FunctionArgumentAttributeValue attrStringPortMinus = null; + FunctionArgumentAttributeValue attrStringPortPort = null; + FunctionArgumentAttributeValue attrStringNoPort = null; + FunctionArgumentAttributeValue attrStringBadPort = null; + FunctionArgumentAttributeValue attrStringTooManyPorts = null; + + FunctionArgumentAttributeValue attrStringBadValue = null; + FunctionArgumentAttributeValue attrStringBadType = null; + try { + attrString1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host")); + attrString2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host")); + + attrStringMinusPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123")); + attrStringPortMinus = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:123-")); + attrStringPortPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:1234567-432")); + attrStringNoPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:")); + attrStringBadPort = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:12.34")); + attrStringTooManyPorts = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("host.host:-123-456")); + + attrStringBadValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("not valid obj value")); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_DNSNAME_FROM_STRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_DNSNAME_FROM_STRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrString1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + RFC2396DomainName resValue = (RFC2396DomainName)res.getValue().getValue(); + assertEquals(new RFC2396DomainName("host", null), resValue); + + arguments.clear(); + arguments.add(attrString2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + assertEquals(new RFC2396DomainName("host.host", null), resValue); + + + // portrange (-port, port-, port-port) + arguments.clear(); + arguments.add(attrStringMinusPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + try { + assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("-123")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortMinus); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + try { + assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("123-")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + arguments.clear(); + arguments.add(attrStringPortPort); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (RFC2396DomainName)res.getValue().getValue(); + try { + assertEquals(new RFC2396DomainName("host.host", PortRange.newInstance("1234567-432")), resValue); + } catch (ParseException e) { + fail("port error e="+e); + } + + // ":" without port + arguments.clear(); + arguments.add(attrStringNoPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"host.host:\": no port numbers", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port number + arguments.clear(); + arguments.add(attrStringBadPort); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"12.34\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad port range + arguments.clear(); + arguments.add(attrStringTooManyPorts); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 port range \"-123-456\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad value + arguments.clear(); + arguments.add(attrStringBadValue); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Invalid RFC 2396 host name \"not valid obj value\"", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:dnsName-from-string Expected data type 'string' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + @Test + public void testString_from_dnsName() { + FunctionArgumentAttributeValue attrObj1 = null; + FunctionArgumentAttributeValue attrStringBadType = null; + String objValueString = "someName.com"; + try { + attrObj1 = new FunctionArgumentAttributeValue(DataTypes.DT_DNSNAME.createAttributeValue(objValueString)); + attrStringBadType = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(123)); + + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringConversion<?, ?> fd = (FunctionDefinitionStringConversion<?, ?>) StdFunctions.FD_STRING_FROM_DNSNAME; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_FROM_DNSNAME, fd.getId()); + assertEquals(DataTypes.DT_DNSNAME.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + // test normal + arguments.clear(); + arguments.add(attrObj1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(objValueString, res.getValue().getValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrStringBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-from-dnsName Expected data type 'dnsName' saw 'integer' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + } + + + + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java new file mode 100644 index 000000000..b01c49cc6 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringEqualIgnoreCaseTest.java @@ -0,0 +1,129 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionEquality; + +/** + * Only one function to test here. Code copy/pasted from FunctionDefinitionEqualityTest + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * In the first implementation of XACML we had separate files for each XACML Function. + * This release combines multiple Functions in fewer files to minimize code duplication. + * This file supports the following XACML codes: + * string-equal-ignore-case + * + * + */ +public class FunctionDefinitionStringEqualIgnoreCaseTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + FunctionArgumentAttributeValue stringAttr1 = null; + FunctionArgumentAttributeValue stringAttr2 = null; + FunctionArgumentAttributeValue stringAttr3 = null; + FunctionArgumentAttributeValue stringAttr4 = null; + + FunctionArgumentAttributeValue intAttr1 = null; + + public FunctionDefinitionStringEqualIgnoreCaseTest() { + try { + stringAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("abc")); + stringAttr3 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("ABC")); + stringAttr4 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("def")); + intAttr1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + } + + + /** + * String match even when Case is different + */ + @Test + public void testFunctionDefinitionStringEqualIgnoreCase() { + + FunctionDefinitionEquality<?> fd = (FunctionDefinitionEquality<?>) StdFunctions.FD_STRING_EQUAL_IGNORE_CASE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + + // test normal equals and non-equals + // check "abc" with "abc" + arguments.add(stringAttr1); + arguments.add(stringAttr2); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // check "abc" with "ABC" (should be same) + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(stringAttr3); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // test bad args data types? Not needed? + arguments.clear(); + arguments.add(stringAttr1); + arguments.add(intAttr1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + + +//TODO - null in either first or 2nd arg => NullPointerException + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringFunctionsTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringFunctionsTest.java new file mode 100644 index 000000000..736293580 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringFunctionsTest.java @@ -0,0 +1,1497 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringFunctions; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionStringFunctionsTest { + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + ExpressionResult res; + + + @Test + public void testConcatenate() { + String v1 = new String("abc"); + String v2 = new String("def"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrV2 = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrV2 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v2)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONCATENATE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_CONCATENATE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals(v1 + v2, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(v2, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(v1, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrV2); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-concatenate Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + @Test + public void testStringStartsWith() { + String v1 = new String("abc"); + String bigger = new String("abc some string"); + String biggerNoMatch = new String(" abc some string"); + String caps = new String("AbC"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_STARTS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_STARTS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAnyuriStartsWith() { + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlankString = null; + FunctionArgumentAttributeValue attrBlankURI = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + String v1 = new String("abc"); + URI bigger = new URI("abc.some.string"); + URI biggerNoMatch = new URI("Zabc.some.string"); + String caps = new String("AbC"); + String bigString = "thisIsSomeReallyBigStringToMatch"; + + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_STARTS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_STARTS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + + // two blanks + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // arguments reversed + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-starts-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testStringEndsWith() { + String v1 = new String("abc"); + String bigger = new String("abc some string abc"); + String biggerNoMatch = new String(" abc some string abc "); + String caps = new String("AbC"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_ENDS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_ENDS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAnyuriEndsWith() { + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlankString = null; + FunctionArgumentAttributeValue attrBlankURI = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + String v1 = new String("abc"); + URI bigger = new URI("abc.some.stringabc"); + URI biggerNoMatch = new URI("Zabc.some.stringabcZ"); + String caps = new String("AbC"); + String bigString = "thisIsSomeReallyBigStringToMatch"; + + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_ENDS_WITH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_ENDS_WITH, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + + // two blanks + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // arguments reversed + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-ends-with Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testStringSubstring() { + String bigString = new String("abc some string abc"); + + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrDouble = null; + + FunctionArgumentAttributeValue attrInteger0 = null; + FunctionArgumentAttributeValue attrInteger1 = null; + FunctionArgumentAttributeValue attrIntegerM1 = null; + FunctionArgumentAttributeValue attrInteger8 = null; + FunctionArgumentAttributeValue attrInteger19 = null; + FunctionArgumentAttributeValue attrInteger20 = null; + + + + try { + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8)); + attrInteger19 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(19)); + attrInteger20 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(20)); + attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_SUBSTRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_SUBSTRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals("bc some", resValue); + + // edge: start + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger0); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("abc some", resValue); + + // edge: end + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger19); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(" string abc", resValue); + + // from index to end of string + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrIntegerM1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals(" string abc", resValue); + + // first index too low + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrIntegerM1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Start point '-1' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // second index too big + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger20); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring End point '20' out of range 0-19 for string='abc some string abc'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes reversed + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring End point '1' less than start point 'null' for string='abc some string abc'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes the same + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // blank string with indexes both 0 + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrInteger0); + arguments.add(attrInteger0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // non-string first attribute + arguments.clear(); + arguments.add(attrDouble); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected data type 'string' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 2nd attr + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrDouble); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 3rd attr + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrDouble); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 4 args + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null 1st arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null 2nd arg + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrNull); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + } + + + + + @Test + public void testAnyURISubstring() { + String bigString = new String("http://company.com:8080/this/is/some/long/uri"); + + FunctionArgumentAttributeValue attrURI = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrDouble = null; + + FunctionArgumentAttributeValue attrInteger0 = null; + FunctionArgumentAttributeValue attrInteger1 = null; + FunctionArgumentAttributeValue attrIntegerM1 = null; + FunctionArgumentAttributeValue attrInteger8 = null; + FunctionArgumentAttributeValue attrInteger45 = null; + FunctionArgumentAttributeValue attrInteger46 = null; + + + + try { + attrURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigString)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(null)); + attrInteger0 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(0)); + attrInteger1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1)); + attrIntegerM1 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(-1)); + attrInteger8 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(8)); + attrInteger45 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(45)); + attrInteger46 = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(46)); + attrDouble = new FunctionArgumentAttributeValue(DataTypes.DT_DOUBLE.createAttributeValue(123.4)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_SUBSTRING; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_SUBSTRING, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + String resValue = (String)res.getValue().getValue(); + assertEquals("ttp://c", resValue); + + // edge: start + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger0); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("http://c", resValue); + + // edge: end + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger45); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("ompany.com:8080/this/is/some/long/uri", resValue); + + // from index to end of string + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrIntegerM1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("ompany.com:8080/this/is/some/long/uri", resValue); + + // first index too low + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrIntegerM1); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Start point '-1' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // second index too big + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger46); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring End point '46' out of range 0-45 for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes reversed + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring End point '1' less than start point 'null' for string='http://company.com:8080/this/is/some/long/uri'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // indexes the same + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // blank string with indexes both 0 + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrInteger0); + arguments.add(attrInteger0); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.String.class, res.getValue().getValue().getClass()); + resValue = (String)res.getValue().getValue(); + assertEquals("", resValue); + + // non-string first attribute + arguments.clear(); + arguments.add(attrDouble); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected data type 'anyURI' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 2nd attr + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrDouble); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // non-integer 3rd attr + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrDouble); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected data type 'integer' saw 'double'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 4 args + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected 3 arguments, got 4", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // 2 args + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrInteger8); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Expected 3 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null 1st arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrInteger8); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null 2nd arg + arguments.clear(); + arguments.add(attrURI); + arguments.add(attrNull); + arguments.add(attrInteger1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-substring Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + + + + + + + + + + + + + + + + + + @Test + public void testStringContains() { + String v1 = new String("abc"); + String bigger = new String("abc some string abc"); + String biggerNoMatch = new String(" abc some string abc "); + String caps = new String("AbC"); + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlank = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_STRING_CONTAINS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_CONTAINS, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrBiggerNoMatch); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // two blanks + arguments.clear(); + arguments.add(attrBlank); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlank); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:string-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testAnyuriContains() { + + + FunctionArgumentAttributeValue attrV1 = null; + FunctionArgumentAttributeValue attrBigger = null; + FunctionArgumentAttributeValue attrBiggerNoMatch = null; + FunctionArgumentAttributeValue attrCaps = null; + FunctionArgumentAttributeValue attrBigString = null; + FunctionArgumentAttributeValue attrNull = null; + FunctionArgumentAttributeValue attrBlankString = null; + FunctionArgumentAttributeValue attrBlankURI = null; + FunctionArgumentAttributeValue attrInteger = null; + try { + String v1 = new String("abc"); + URI bigger = new URI("abc.some.stringabc"); + URI biggerNoMatch = new URI("Zabc.some.stringabcZ"); + String caps = new String("AbC"); + String bigString = "thisIsSomeReallyBigStringToMatch"; + + attrV1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(v1)); + attrBigger = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(bigger)); + attrBiggerNoMatch = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(biggerNoMatch)); + attrCaps = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(caps)); + attrBigString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(bigString)); + attrBlankString = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrBlankURI = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("")); + attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(null)); + attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234)); + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + FunctionDefinitionStringFunctions<?,?> fd = (FunctionDefinitionStringFunctions<?,?>) StdFunctions.FD_ANYURI_CONTAINS; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_ANYURI_CONTAINS, fd.getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // match + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // no match + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBiggerNoMatch); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // caps no match + arguments.clear(); + arguments.add(attrCaps); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // bigger on the inside + arguments.clear(); + arguments.add(attrBigString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + // empty non-null first arg + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // empty non-null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(false, resValue); + + + // two blanks + arguments.clear(); + arguments.add(attrBlankString); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.lang.Boolean.class, res.getValue().getValue().getClass()); + resValue = (Boolean)res.getValue().getValue(); + assertEquals(true, resValue); + + // arguments reversed + arguments.clear(); + arguments.add(attrBigger); + arguments.add(attrV1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // null firat arg + arguments.clear(); + arguments.add(attrNull); + arguments.add(attrBlankURI); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null second arg + arguments.clear(); + arguments.add(attrV1); + arguments.add(attrNull); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Got null attribute", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // illegal arg type + arguments.clear(); + arguments.add(attrInteger); + arguments.add(attrBigger); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:anyURI-contains Expected data type 'string' saw 'integer'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringNormalizeTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringNormalizeTest.java new file mode 100644 index 000000000..0071a7020 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionStringNormalizeTest.java @@ -0,0 +1,118 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionStringNormalize; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionStringNormalizeTest { + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + @Test + public void testString_normalize_space() { + String initialString = " First and last are whitespace "; + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_SPACE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + String resValue = (String)res.getValue().getValue(); + assertEquals(initialString.length() - 4, resValue.length()); + assertTrue(initialString.trim().equals(resValue)); + } + + + @Test + public void testString_normalize_to_lower_case() { + String initialString = " First and last are whitespace "; + FunctionArgumentAttributeValue attr1 = null; + try { + attr1 = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(initialString)); + } catch (Exception e) { + fail("creating attribute e="+ e); + } + + FunctionDefinitionStringNormalize fd = (FunctionDefinitionStringNormalize) StdFunctions.FD_STRING_NORMALIZE_TO_LOWER_CASE; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE, fd.getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_STRING.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // test normal add + arguments.add(attr1); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + String resValue = (String)res.getValue().getValue(); + assertTrue(initialString.toLowerCase().equals(resValue)); + } + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionURIStringConcatenateTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionURIStringConcatenateTest.java new file mode 100644 index 000000000..e1e91a79e --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionURIStringConcatenateTest.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.att.research.xacml.api.XACML2; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionURIStringConcatenate; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionURIStringConcatenateTest { + + /* + * THE FUNCTION BEING TESTED BY THIS CLASS IS DEPRECATED + * uri-string-concatenate has been deprecated in XACML 3.0 + */ + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + @SuppressWarnings("deprecation") + @Test + public void testURI_string_concatenate() { + + // URI args + FunctionArgumentAttributeValue attrURI1 = null; + + + FunctionArgumentAttributeValue attrStrAbc = null; + FunctionArgumentAttributeValue attrStrSlashMno = null; + FunctionArgumentAttributeValue attrStrSlashInMiddle = null; + FunctionArgumentAttributeValue attrStrWithSpace = null; + + + try { + attrURI1 = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("http://someplace")); + + + attrStrAbc = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("Abc")); + attrStrSlashMno = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("/Mno")); + attrStrSlashInMiddle = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("hij/pqr")); + attrStrWithSpace = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("x y z")); + + + } catch (Exception e) { + fail("creating attributes e="+ e); + } + + // deprecation marking in the following line is correct - this function IS deprecated but still valid for XACML 3.0 + FunctionDefinitionURIStringConcatenate fd = (FunctionDefinitionURIStringConcatenate) StdFunctions.FD_URI_STRING_CONCATENATE; + + // check identity and type of the thing created + assertEquals(XACML2.ID_FUNCTION_URI_STRING_CONCATENATE, fd.getId()); + assertEquals(DataTypes.DT_ANYURI.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + + + // add one string to uri + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrAbc); + ExpressionResult res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.net.URI.class, res.getValue().getValue().getClass()); + URI resValue = (URI)res.getValue().getValue(); + assertEquals("http://someplaceAbc", resValue.toString()); + + + // add 2 strings to uri + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrAbc); + arguments.add(attrStrSlashMno); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.net.URI.class, res.getValue().getValue().getClass()); + resValue = (URI)res.getValue().getValue(); + assertEquals("http://someplaceAbc/Mno", resValue.toString()); + + // slash in middle of string + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrSlashInMiddle); + arguments.add(attrStrSlashMno); + res = fd.evaluate(null, arguments); + assertTrue(res.isOk()); + assertEquals(java.net.URI.class, res.getValue().getValue().getClass()); + resValue = (URI)res.getValue().getValue(); + assertEquals("http://someplacehij/pqr/Mno", resValue.toString()); + + // create bad uri + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrStrWithSpace); + arguments.add(attrStrSlashMno); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Final string 'http://someplacex y z/Mno' not URI, Illegal character in authority at index 7: http://someplacex y z/Mno", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // one arg + arguments.clear(); + arguments.add(attrURI1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected 2 or more arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // first arg not uri + arguments.clear(); + arguments.add(attrStrAbc); + arguments.add(attrURI1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected data type 'anyURI' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // 2nd arg not string + arguments.clear(); + arguments.add(attrURI1); + arguments.add(attrURI1); + res = fd.evaluate(null, arguments); + assertFalse(res.isOk()); + assertEquals("function:uri-string-concatenate Expected data type 'string' saw 'anyURI' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + +} diff --git a/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionXPathTest.java b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionXPathTest.java new file mode 100644 index 000000000..5b6c97de1 --- /dev/null +++ b/ECOMP-TEST/src/test/java/org/openecomp/policy/pdp/test/std/functions/FunctionDefinitionXPathTest.java @@ -0,0 +1,1127 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-TEST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pdp.test.std.functions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; + +import org.junit.Test; + +import com.att.research.xacml.api.Request; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdRequest; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.datatypes.XPathExpressionWrapper; +import com.att.research.xacml.std.dom.DOMRequest; +import com.att.research.xacmlatt.pdp.policy.ExpressionResult; +import com.att.research.xacmlatt.pdp.policy.FunctionArgument; +import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue; +import com.att.research.xacmlatt.pdp.std.StdEvaluationContext; +import com.att.research.xacmlatt.pdp.std.StdFunctions; +import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionXPath; + +/** + * Test of PDP Functions (See XACML core spec section A.3) + * + * TO RUN - use jUnit + * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test + * + * + */ +public class FunctionDefinitionXPathTest { + + // + // Strings for the Request contents + // + + String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" + + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\"" + + " ReturnPolicyIdList=\"false\"" + + " CombinedDecision=\"false\"" + + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\"" + + " xmlns:md=\"http://www.medico.com/schemas/record\"" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>" + + " </Attribute>" + + "</Attributes>"; + + String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">"; + + String reqStrContentMdRecord = + " <Content>" + + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:department>Surgery</md:department>" + + "</md:hospital_info>" + + "<md:patient_info>" + + "<md:name>Bart Simpson</md:name>" + + "<md:age>60</md:age>" + + "<md:sex>male</md:sex>" + + "<md:health_insurance>123456</md:health_insurance>" + + "</md:patient_info>" + + "<md:diagnosis_info>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Gastric Cancer</md:item>" + + "<md:item type=\"secondary\">Hyper tension</md:item>" + + "</md:diagnosis>" + + "<md:pathological_diagnosis>" + + "<md:diagnosis>" + + "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" + + "</md:diagnosis>" + + "<md:date>2000-10-05</md:date>" + + "<md:malignancy type=\"yes\"/>" + + "</md:pathological_diagnosis>" + + "</md:diagnosis_info> " + + " </md:record>" + + "</Content>"; + String reqStrMalformedContent = + " <Content>" + + "<md:record>" + + "<md:hospital_info>" + + "<md:name>ABC Hospital</md:name>" + + "<md:malignancy type=\"yes\"/>" + + "</Content>"; + String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">" + + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>" + + " </Attribute>" + + "</Attributes> "; + String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">"; + + String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">" + + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>" + + "</Attribute>" + + "</Attributes> "; + String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />"; + String reqStrMainEnd = " </Request>"; + + + // combined strings for convenience + String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart; + String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd; + + + /* + * variables useful in the following tests + */ + List<FunctionArgument> arguments = new ArrayList<FunctionArgument>(); + + + + // Name Spaces used in the XML as part of these examples (copied from the Conformance tests) - needed for compiling XPaths + NamespaceContext nameSpaceContext = new NamespaceContext() { + @Override + public Iterator<?> getPrefixes(String arg0) { return null;} + + @Override + public String getPrefix(String arg0) {return null;} + + @Override + public String getNamespaceURI(String arg0) { + if("md".equals(arg0)) { + return "http://www.medico.com/schemas/record"; + } else if ("xacml-context".equals(arg0)) { + return "urn:oasis:names:tc:xacml:3.0:context:schema:os"; + } else if ("xsi".equals(arg0)) { + return "http://www.w3.org/2001/XMLSchema-instance"; + } + return null; + } + }; + + + + // + // XPath Function Attributes available for use in tests (representing appropriate fragment of Policy) + // + + FunctionArgumentAttributeValue attrXnull = null; + FunctionArgumentAttributeValue attrXEmpty = null; + FunctionArgumentAttributeValue attrXNoCategory = null; + FunctionArgumentAttributeValue attrXNoValue = null; + FunctionArgumentAttributeValue attrXSlashSlashMdRecord = null; + FunctionArgumentAttributeValue attrXSlashSlashStar = null; + FunctionArgumentAttributeValue attrXSlashSlashMdName = null; + FunctionArgumentAttributeValue attrXSlashSlashMdMalignancy = null; + FunctionArgumentAttributeValue attrXNotInRequest = null; + FunctionArgumentAttributeValue attrXSlashSlashMdRecordSlashStar = null; + FunctionArgumentAttributeValue attrXMdPatientInfo = null; + + FunctionArgumentAttributeValue attrBadType = null; + + // String version of attrs for use in Deprecated functions + FunctionArgumentAttributeValue attrStrnull = null; + FunctionArgumentAttributeValue attrStrEmpty = null; + FunctionArgumentAttributeValue attrStrNoCategory = null; + FunctionArgumentAttributeValue attrStrNoValue = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdRecord = null; + FunctionArgumentAttributeValue attrStrSlashSlashStar = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdName = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdMalignancy = null; + FunctionArgumentAttributeValue attrStrNotInRequest = null; + FunctionArgumentAttributeValue attrStrSlashSlashMdRecordSlashStar = null; + FunctionArgumentAttributeValue attrStrMdPatientInfo = null; + + + // + // REQUEST objects available for use in tests + // + Request requestEmpty = new StdRequest(StdStatus.STATUS_OK); + Request requestMdRecord = null; + Request requestDoubleResources = null; + Request requestResourceActionContent = null; + Request requestContentInAction = null; + + + + + /** + * Set up all variables in one place because it is complicated (lots of steps needed for each attribute) + */ + public FunctionDefinitionXPathTest() { + try { + XPathFactory xPathFactory = XPathFactory.newInstance(); + XPath xpath = xPathFactory.newXPath(); + xpath.setNamespaceContext(nameSpaceContext); + + // Create XPaths to use in expressions + XPathExpressionWrapper xEmpty = new XPathExpressionWrapper(""); + XPathExpressionWrapper xSlashSlashMdRecord = new XPathExpressionWrapper(xpath.compile("//md:record")); + XPathExpressionWrapper xSlashSlashStar = new XPathExpressionWrapper(xpath.compile("//*")); + XPathExpressionWrapper xSlashSlashMdName = new XPathExpressionWrapper(xpath.compile("//md:name")); + XPathExpressionWrapper xSlashSlashMdMalignancy = new XPathExpressionWrapper(xpath.compile("//md:malignancy")); + XPathExpressionWrapper xNotInRequest = new XPathExpressionWrapper(xpath.compile("value_Not_in_request")); + XPathExpressionWrapper xSlashSlashMdRecordSlashStar = new XPathExpressionWrapper(xpath.compile("//md:record/*")); + XPathExpressionWrapper xMdPatientInfo = new XPathExpressionWrapper(xpath.compile("md:patient_info")); + + + + // create Function Attributes out of the XPathExpressions + attrXnull = new FunctionArgumentAttributeValue(null); + attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty)); + attrXNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord)); + attrXNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xEmpty, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecord, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashStar, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdName, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdMalignancy, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xNotInRequest, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + attrXSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xSlashSlashMdRecordSlashStar, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrXMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_XPATHEXPRESSION.createAttributeValue(xMdPatientInfo, + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + + // Deprecated versions of args + attrStrnull = new FunctionArgumentAttributeValue(null); + attrStrEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("")); + attrStrNoCategory = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record")); + attrStrNoValue = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashMdRecord = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//*", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashMdName = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:name", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrSlashSlashMdMalignancy = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:malignancy", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("value_Not_in_request", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + attrStrSlashSlashMdRecordSlashStar = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("//md:record/*", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + attrStrMdPatientInfo = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("md:patient_info", + new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource" ))); + + + + + attrBadType = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue("some string")); + + + + // Request objects + // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it. + + // single Content in the Resources section (normal valid request) + String reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceAllEnd; + File tFile = File.createTempFile("functionJunit", "request"); + BufferedWriter bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestMdRecord = DOMRequest.load(tFile); + tFile.delete(); + + // Resources included twice + reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecord +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestDoubleResources = DOMRequest.load(tFile); + tFile.delete(); + + + // content included in both Resource and Action - ok + reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestResourceActionContent = DOMRequest.load(tFile); + tFile.delete(); + + // Content included only in Action - missing content produces non-error result according to spec + reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecord + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + requestContentInAction = DOMRequest.load(tFile); + tFile.delete(); + + + + // Test that Bad XML is caught + @SuppressWarnings("unused") + Request requestContentMisplaced = null; + @SuppressWarnings("unused") + Request requestMalformedContent = null; + @SuppressWarnings("unused") + Request requestDoubleContent = null; + + + // Content included twice - error + reqString = reqStrMainResourceStart + reqStrContentMdRecord + reqStrContentMdRecord +reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestDoubleContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // Bad XML - Content not under a Category + reqString = reqStrMainStart + reqStrContentMdRecord + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestContentMisplaced = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + // Bad XML - Content is not valid XML + reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd; + tFile = File.createTempFile("functionJunit", "request"); + bw = new BufferedWriter(new FileWriter(tFile)); + bw.append(reqString); + bw.flush(); + bw.close(); + try { + requestMalformedContent = DOMRequest.load(tFile); + tFile.delete(); + } catch (com.att.research.xacml.std.dom.DOMStructureException e) { + // this is what it should do, so just continue + } catch (Exception e) { + fail("Unexpected exception for bad XML, e="+e); + } + + } catch (Exception e) { + fail("Constructor initializing variables, e="+ e + " cause="+e.getCause()); + } + + } + + + + + + + + + @Test + public void testXpath_node_count() { + + + + FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_COUNT; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_COUNT, fd.getId()); + assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_INTEGER.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(1), fd.getNumArgs()); + + + // match all elements within context + arguments.clear(); + arguments.add(attrXSlashSlashStar); + ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + BigInteger resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("18"), resValue); + + // match exactly 1 element + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("1"), resValue); + + // match a few but not all + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + + // verify variables using in other tests: count nodes immediately under md:record + arguments.clear(); + arguments.add(attrXSlashSlashMdRecordSlashStar); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("3"), resValue); + + // verify variables using in other tests: count number of records containing patient_info + arguments.clear(); + arguments.add(attrXMdPatientInfo); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("1"), resValue); + + // verify variables using in other tests: count number of records containing md:name + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + // verify variables using in other tests: count number of records containing md:malignancy + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("1"), resValue); + + + + + // match no element + arguments.clear(); + arguments.add(attrXNotInRequest); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + + // Resources included twice + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // Content in both Resource and Action categories (ok) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("2"), resValue); + + // Content only in Action category (missing in Resources -> 0 according to spec) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments); + assertTrue(res.isOk()); + resValue = (BigInteger)res.getValue().getValue(); + assertEquals(new BigInteger("0"), resValue); + + + + +//TODO - any other tests???? + + // null Evaluation Context + arguments.clear(); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null attribute + arguments.clear(); + arguments.add(attrXnull); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null attribute at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no value + arguments.clear(); + arguments.add(attrXNoValue); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no category + arguments.clear(); + arguments.add(attrXNoCategory); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null Category at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // too many args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Expected 1 arguments, got 2", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Expected 1 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null args + arguments.clear(); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-count Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + @Test + public void testXpath_node_equal() { + + + FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_EQUAL; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_EQUAL, fd.getId()); + assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal success - exactly the same set + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list is subset of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecordSlashStar); + arguments.add(attrXMdPatientInfo); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - first list is subset of second list + arguments.clear(); + arguments.add(attrXMdPatientInfo); + arguments.add(attrXSlashSlashMdRecordSlashStar); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list contains children of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // success - first list contains children of second list + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + + // two non-overlapping sets + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first list contains nothing + arguments.clear(); + arguments.add(attrXNotInRequest); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // second list contains nothing + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXNotInRequest); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + +//TODO + //????? + ///??????? add real tests + ////// + + + // Resources included twice + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + // Content in both Resource and Action categories (ok) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // Content only in Action category (missing in Resources -> 0 according to spec) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // null Evaluation Context + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null attribute + arguments.clear(); + arguments.add(attrXnull); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null attribute at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXnull); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null attribute at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no value + arguments.clear(); + arguments.add(attrXNoValue); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoValue); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no category + arguments.clear(); + arguments.add(attrXNoCategory); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null Category at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoCategory); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null argument at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(null); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-equal Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + } + + + + + @Test + public void testXpath_node_match() { + + + FunctionDefinitionXPath<?> fd = (FunctionDefinitionXPath<?>) StdFunctions.FD_XPATH_NODE_MATCH; + + // check identity and type of the thing created + assertEquals(XACML3.ID_FUNCTION_XPATH_NODE_MATCH, fd.getId()); + assertEquals(DataTypes.DT_XPATHEXPRESSION.getId(), fd.getDataTypeArgs().getId()); + assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); + + // just to be safe... If tests take too long these can probably be eliminated + assertFalse(fd.returnsBag()); + assertEquals(new Integer(2), fd.getNumArgs()); + + + // test normal success - exactly the same set + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + ExpressionResult res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + Boolean resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list is subset of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecordSlashStar); + arguments.add(attrXMdPatientInfo); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - first list is subset of second list + arguments.clear(); + arguments.add(attrXMdPatientInfo); + arguments.add(attrXSlashSlashMdRecordSlashStar); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - second list contains children of first list + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // success - first list contains children of second list + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + + // two non-overlapping sets + arguments.clear(); + arguments.add(attrXSlashSlashMdMalignancy); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // first list contains nothing + arguments.clear(); + arguments.add(attrXNotInRequest); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + // second list contains nothing + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXNotInRequest); + res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + +//TODO + //????? + ///??????? add real tests + ////// + + + // Resources included twice + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestDoubleResources, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match More than one Content section for id 'urn:oasis:names:tc:xacml:3.0:attribute-category:resource'", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + // Content in both Resource and Action categories (ok) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestResourceActionContent, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertTrue(resValue); + + // Content only in Action category (missing in Resources -> 0 according to spec) + arguments.clear(); + arguments.add(attrXSlashSlashMdName); + arguments.add(attrXSlashSlashMdName); + res = fd.evaluate(new StdEvaluationContext(requestContentInAction, null, null), arguments); + assertTrue(res.isOk()); + resValue = (Boolean)res.getValue().getValue(); + assertFalse(resValue); + + + // null Evaluation Context + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null Request + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null Request in EvaluationContext", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null attribute + arguments.clear(); + arguments.add(attrXnull); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null attribute at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXnull); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null attribute at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no value + arguments.clear(); + arguments.add(attrXNoValue); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoValue); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // no category + arguments.clear(); + arguments.add(attrXNoCategory); + arguments.add(attrXSlashSlashMdRecord); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null Category at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXSlashSlashMdRecord); + arguments.add(attrXNoCategory); + res = fd.evaluate(new StdEvaluationContext(requestEmpty, null, null), arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match XPathExpression returned null at index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too many args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected 2 arguments, got 3", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // too few args + arguments.clear(); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected 2 arguments, got 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // bad arg type + arguments.clear(); + arguments.add(attrBadType); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(attrBadType); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Expected data type 'xpathExpression' saw 'string' at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + // null args + arguments.clear(); + arguments.add(attrXEmpty); + arguments.add(null); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null argument at arg index 1", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + arguments.clear(); + arguments.add(null); + arguments.add(attrXEmpty); + res = fd.evaluate(null, arguments); + assertFalse(res.getStatus().isOk()); + assertEquals( "function:xpath-node-match Got null argument at arg index 0", res.getStatus().getStatusMessage()); + assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); + + + + } + + + + // + // DEPRECATED versions that use String arguments rather than XPATHEXPRESSIONs + // are NOT supported due to ambiguity in the semantics between 2.0 (<Request> is root and has only one <Content> in resources) + // and 3.0 (<Content> is root and there are multiple <Content> sections in any category) + // + + + +} |