Commit includes ControlLoopPolicy API and bugfixes
[policy/engine.git] / ECOMP-PDP / src / test / java / org / openecomp / policy / pdp / test / FunctionDefinitionDateTimeArithmeticTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-PDP
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.policy.pdp.test;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import org.junit.Test;
32
33 import com.att.research.xacml.api.XACML3;
34 import com.att.research.xacml.std.datatypes.DataTypes;
35 import com.att.research.xacml.std.datatypes.ISO8601Date;
36 import com.att.research.xacml.std.datatypes.ISO8601DateTime;
37 import com.att.research.xacml.std.datatypes.ISO8601Time;
38 import com.att.research.xacml.std.datatypes.ISO8601TimeZone;
39 import com.att.research.xacml.std.datatypes.XPathDayTimeDuration;
40 import com.att.research.xacml.std.datatypes.XPathYearMonthDuration;
41 import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
42 import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
43 import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;
44 import com.att.research.xacmlatt.pdp.std.StdFunctions;
45 import com.att.research.xacmlatt.pdp.std.functions.*;
46
47 /**
48  * Test of PDP Functions (See XACML core spec section A.3)
49  * 
50  * TO RUN - use jUnit
51  * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
52  * 
53  *
54  */
55 public class FunctionDefinitionDateTimeArithmeticTest {
56
57
58         /*
59          * variables useful in the following tests
60          */
61         List<FunctionArgument> arguments = new ArrayList<>();
62         
63         ExpressionResult res;
64
65         
66         @Test
67         public void testDateTime_add_dayTimeDuration() {
68                 // Date objects to be adjusted
69                 ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 
70                                 new ISO8601Date(2000, 1, 12), 
71                                 new ISO8601Time(12, 13, 14, 0));
72                 ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 
73                                 new ISO8601Date(2000, 1, 12), 
74                                 new ISO8601Time(12, 13, 14, 777));
75                 ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 
76                                 new ISO8601Date(2000, 12, 31), 
77                                 new ISO8601Time(23, 59, 30, 1));
78                 ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 
79                                 new ISO8601Date(-2000, 1, 12), 
80                                 new ISO8601Time(12, 13, 14, 0));
81                 ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
82                 ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
83                 ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 
84                                 new ISO8601Date(timeZone0, 2000, 1, 12), 
85                                 new ISO8601Time(timeZone0, 12, 13, 14, 0));
86                 ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 
87                                 new ISO8601Date(timeZone5, 2000, 1, 12), 
88                                 new ISO8601Time(timeZone5, 12, 13, 14, 0));
89                 ISO8601DateTime dateTimeIIC102Result = null;
90                 
91                 // Durations
92                 XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0);
93                 XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3);
94                 XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3);
95                 XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 3.223);
96                 XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999);
97
98                 // ARGS declarations
99                 // Dates
100                 FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
101                 FunctionArgumentAttributeValue attrDateTimeMsecs = null;
102                 FunctionArgumentAttributeValue attrDateTimeCrossover = null;
103                 FunctionArgumentAttributeValue attrDateTimeBC = null;
104                 FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
105                 FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
106                 FunctionArgumentAttributeValue attrDateTimeIIC102 = null;
107
108                 // Durations
109                 FunctionArgumentAttributeValue attrDuration0 = null;
110                 FunctionArgumentAttributeValue attrDurationStdExample1 = null;
111                 FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
112                 FunctionArgumentAttributeValue attrDurationMsecs = null;
113                 FunctionArgumentAttributeValue attrDurationCrossover = null;
114                 FunctionArgumentAttributeValue attrDurationIIC102 = null;
115
116                 // misc bad
117                 FunctionArgumentAttributeValue attrNull = null;
118                 FunctionArgumentAttributeValue attrBlank = null;
119                 FunctionArgumentAttributeValue attrInteger = null;
120                 // set values
121                 try {
122                         // Date attrs
123                         attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
124                         attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
125                         attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
126                         attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
127                         attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
128                         attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
129                         attrDateTimeIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(DataTypes.DT_DATETIME.convert("2002-03-22T08:23:47-05:00")));
130
131                         dateTimeIIC102Result = DataTypes.DT_DATETIME.convert("2002-03-27T10:23:47-05:00");
132                         
133                         // Duration attrs
134                         attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0));
135                         attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1));
136                         attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1));
137                         attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs));
138                         attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover));
139                         attrDurationIIC102 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue("P5DT2H0M0S"));
140
141                         // misc bad
142                         attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(""));
143                         attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null));
144                         attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
145                 } catch (Exception e) {
146                         fail("creating attributes e="+ e);
147                 }
148                 
149                 FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_DAYTIMEDURATION;
150
151                 // check identity and type of the thing created
152                 assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION, fd.getId());
153                 assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
154                 
155                 // just to be safe...  If tests take too long these can probably be eliminated
156                 assertFalse(fd.returnsBag());
157                 
158                 // Duration = 0 => same as original
159                 arguments.clear();
160                 arguments.add(attrDateTimeStdExample1);
161                 arguments.add(attrDuration0);
162                 res = fd.evaluate(null, arguments);
163                 assertTrue(res.isOk());
164                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
165                 ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
166                 assertEquals(dateTimeStdExample1, resValue);
167
168                 
169                 // simple positive operation
170                 arguments.clear();
171                 arguments.add(attrDateTimeStdExample1);
172                 arguments.add(attrDurationStdExample1);
173                 res = fd.evaluate(null, arguments);
174                 assertTrue(res.isOk());
175                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
176                 resValue = (ISO8601DateTime)res.getValue().getValue();
177                 ISO8601DateTime testResponse = new ISO8601DateTime(
178                                 null,
179                                 new ISO8601Date(2000, 1, 17),
180                                 new ISO8601Time(19, 23, 17, 300) );
181                 assertEquals(testResponse, resValue);   
182                 
183                 // negative operation
184                 arguments.clear();
185                 arguments.add(attrDateTimeStdExample1);
186                 arguments.add(attrDurationNStdExample1);
187                 res = fd.evaluate(null, arguments);
188                 assertTrue(res.isOk());
189                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
190                 resValue = (ISO8601DateTime)res.getValue().getValue();
191                 testResponse = new ISO8601DateTime(
192                                 null,
193                                 new ISO8601Date(2000, 1, 7),
194                                 new ISO8601Time(5, 3, 10, 700) );
195                 assertEquals(testResponse, resValue);
196                 
197                 // millisecs work correctly
198                 arguments.clear();
199                 arguments.add(attrDateTimeMsecs);
200                 arguments.add(attrDurationMsecs);
201                 res = fd.evaluate(null, arguments);
202                 assertTrue(res.isOk());
203                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
204                 resValue = (ISO8601DateTime)res.getValue().getValue();
205                 testResponse = new ISO8601DateTime(
206                                 null,
207                                 new ISO8601Date(2000, 1, 17),
208                                 new ISO8601Time(19, 23, 18, 0) );
209                 assertEquals(testResponse, resValue);
210         
211                 // cross minute => cross day => cross month => cross year
212                 arguments.clear();
213                 arguments.add(attrDateTimeCrossover);
214                 arguments.add(attrDurationCrossover);
215                 res = fd.evaluate(null, arguments);
216                 assertTrue(res.isOk());
217                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
218                 resValue = (ISO8601DateTime)res.getValue().getValue();
219                 testResponse = new ISO8601DateTime(
220                                 null,
221                                 new ISO8601Date(2001, 1, 1),
222                                 new ISO8601Time(0, 0, 0, 0) );
223                 assertEquals(testResponse, resValue);
224                 
225                 // negative (BC) original date add goes the right direction
226                 arguments.clear();
227                 arguments.add(attrDateTimeBC);
228                 arguments.add(attrDurationStdExample1);
229                 res = fd.evaluate(null, arguments);
230                 assertTrue(res.isOk());
231                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
232                 resValue = (ISO8601DateTime)res.getValue().getValue();
233                 testResponse = new ISO8601DateTime(
234                                 null,
235                                 new ISO8601Date(-2000, 1, 17),
236                                 new ISO8601Time(19, 23, 17, 300) );
237                 assertEquals(testResponse, resValue);   
238                 
239                 // non-null timezone not changed
240                 // original has timezone offset = 0
241                 arguments.clear();
242                 arguments.add(attrDateTimeTimeZone0);
243                 arguments.add(attrDurationStdExample1);
244                 res = fd.evaluate(null, arguments);
245                 assertTrue(res.isOk());
246                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
247                 resValue = (ISO8601DateTime)res.getValue().getValue();
248                 testResponse = new ISO8601DateTime(
249                                 timeZone0,
250                                 new ISO8601Date(timeZone0, 2000, 1, 17),
251                                 new ISO8601Time(timeZone0, 19, 23, 17, 300) );
252                 assertEquals(testResponse, resValue);
253                 
254                 // original has timezone offset not 0
255                 arguments.clear();
256                 arguments.add(attrDateTimeTimeZone5);
257                 arguments.add(attrDurationStdExample1);
258                 res = fd.evaluate(null, arguments);
259                 assertTrue(res.isOk());
260                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
261                 resValue = (ISO8601DateTime)res.getValue().getValue();
262                 testResponse = new ISO8601DateTime(
263                                 timeZone5,
264                                 new ISO8601Date(timeZone5, 2000, 1, 17),
265                                 new ISO8601Time(timeZone5, 19, 23, 17, 300) );
266                 assertEquals(testResponse, resValue);
267                 
268                 // conformance test IIC102
269                 arguments.clear();
270                 arguments.add(attrDateTimeIIC102);
271                 arguments.add(attrDurationIIC102);
272                 res = fd.evaluate(null, arguments);
273                 assertTrue(res.isOk());
274                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
275                 resValue = (ISO8601DateTime)res.getValue().getValue();
276                 assertEquals(dateTimeIIC102Result, resValue);
277
278                 // empty non-null first arg
279                 arguments.clear();
280                 arguments.add(attrBlank);
281                 arguments.add(attrDurationStdExample1);
282                 res = fd.evaluate(null, arguments);
283                 assertFalse(res.isOk());
284                 assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
285                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
286
287                 // empty non-null second arg
288                 arguments.clear();
289                 arguments.add(attrDateTimeStdExample1);
290                 arguments.add(attrBlank);
291                 res = fd.evaluate(null, arguments);
292                 assertFalse(res.isOk());
293                 assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
294                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
295
296                 // two blanks
297                 arguments.clear();
298                 arguments.add(attrBlank);
299                 arguments.add(attrBlank);
300                 res = fd.evaluate(null, arguments);
301                 assertFalse(res.isOk());
302                 assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
303                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
304                         
305                 // null firat arg
306                 arguments.clear();
307                 arguments.add(attrNull);
308                 arguments.add(attrBlank);
309                 res = fd.evaluate(null, arguments);
310                 assertFalse(res.isOk());
311                 assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
312                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
313
314                 // null second arg
315                 arguments.clear();
316                 arguments.add(attrDateTimeStdExample1);
317                 arguments.add(attrNull);
318                 res = fd.evaluate(null, arguments);
319                 assertFalse(res.isOk());
320                 assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
321                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
322                 
323                 // bad arg type
324                 arguments.clear();
325                 arguments.add(attrInteger);
326                 arguments.add(attrDurationStdExample1);
327                 res = fd.evaluate(null, arguments);
328                 assertFalse(res.isOk());
329                 assertEquals("function:dateTime-add-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
330                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
331                 
332                 // null second arg
333                 arguments.clear();
334                 arguments.add(attrDateTimeStdExample1);
335                 arguments.add(attrNull);
336                 res = fd.evaluate(null, arguments);
337                 assertFalse(res.isOk());
338                 assertEquals("function:dateTime-add-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
339                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
340         }
341         
342
343         
344         @Test
345         public void testDateTime_subtract_dayTimeDuration() {
346                 // Date objects to be adjusted
347                 ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 
348                                 new ISO8601Date(2000, 1, 12), 
349                                 new ISO8601Time(12, 13, 14, 0));
350                 ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 
351                                 new ISO8601Date(2000, 1, 12), 
352                                 new ISO8601Time(12, 13, 14, 777));
353                 ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 
354                                 new ISO8601Date(2001, 1, 1),
355                                 new ISO8601Time(0, 0, 0, 0) );
356                 ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 
357                                 new ISO8601Date(-2000, 1, 12), 
358                                 new ISO8601Time(12, 13, 14, 0));
359                 ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
360                 ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
361                 ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 
362                                 new ISO8601Date(timeZone0, 2000, 1, 12), 
363                                 new ISO8601Time(timeZone0, 12, 13, 14, 0));
364                 ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 
365                                 new ISO8601Date(timeZone5, 2000, 1, 12), 
366                                 new ISO8601Time(timeZone5, 12, 13, 14, 0));
367                 
368                 // Durations
369                 XPathDayTimeDuration duration0 = new XPathDayTimeDuration(1, 0, 0, 0, 0);
370                 XPathDayTimeDuration durationStdExample1 = new XPathDayTimeDuration(1, 5, 7, 10, 3.3);
371                 XPathDayTimeDuration durationNStdExample1 = new XPathDayTimeDuration(-1, 5, 7, 10, 3.3);
372                 XPathDayTimeDuration durationMsecs = new XPathDayTimeDuration(1, 5, 7, 10, 14.778);
373                 XPathDayTimeDuration durationCrossover = new XPathDayTimeDuration(1, 0, 0, 0, 29.999);
374
375                 // ARGS declarations
376                 // Dates
377                 FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
378                 FunctionArgumentAttributeValue attrDateTimeMsecs = null;
379                 FunctionArgumentAttributeValue attrDateTimeCrossover = null;
380                 FunctionArgumentAttributeValue attrDateTimeBC = null;
381                 FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
382                 FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
383         
384                 // Durations
385                 FunctionArgumentAttributeValue attrDuration0 = null;
386                 FunctionArgumentAttributeValue attrDurationStdExample1 = null;
387                 FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
388                 FunctionArgumentAttributeValue attrDurationMsecs = null;
389                 FunctionArgumentAttributeValue attrDurationCrossover = null;
390         
391                 // misc bad
392                 FunctionArgumentAttributeValue attrNull = null;
393                 FunctionArgumentAttributeValue attrBlank = null;
394                 FunctionArgumentAttributeValue attrInteger = null;
395                 // set values
396                 try {
397                         // Date attrs
398                         attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
399                         attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
400                         attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
401                         attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
402                         attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
403                         attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
404                         
405                         // Duration attrs
406                         attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(duration0));
407                         attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationStdExample1));
408                         attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationNStdExample1));
409                         attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationMsecs));
410                         attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(durationCrossover));
411
412                         // misc bad
413                         attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(""));
414                         attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_DAYTIMEDURATION.createAttributeValue(null));
415                         attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
416                 } catch (Exception e) {
417                         fail("creating attributes e="+ e);
418                 }
419                 
420                 FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_DAYTIMEDURATION;
421
422                 // check identity and type of the thing created
423                 assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION, fd.getId());
424                 assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
425                 
426                 // just to be safe...  If tests take too long these can probably be eliminated
427                 assertFalse(fd.returnsBag());
428                 
429                 // Duration = 0 => same as original
430                 arguments.clear();
431                 arguments.add(attrDateTimeStdExample1);
432                 arguments.add(attrDuration0);
433                 res = fd.evaluate(null, arguments);
434                 assertTrue(res.isOk());
435                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
436                 ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
437                 assertEquals(dateTimeStdExample1, resValue);
438
439                 
440                 // simple positive operation
441                 arguments.clear();
442                 arguments.add(attrDateTimeStdExample1);
443                 arguments.add(attrDurationStdExample1);
444                 res = fd.evaluate(null, arguments);
445                 assertTrue(res.isOk());
446                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
447                 resValue = (ISO8601DateTime)res.getValue().getValue();
448                 ISO8601DateTime testResponse = new ISO8601DateTime(
449                                 null,   
450                                 new ISO8601Date(2000, 1, 7),
451                                 new ISO8601Time(5, 3, 10, 700) );
452                 assertEquals(testResponse, resValue);   
453
454                 
455                 // negative operation
456                 arguments.clear();
457                 arguments.add(attrDateTimeStdExample1);
458                 arguments.add(attrDurationNStdExample1);
459                 res = fd.evaluate(null, arguments);
460                 assertTrue(res.isOk());
461                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
462                 resValue = (ISO8601DateTime)res.getValue().getValue();
463                 testResponse = new ISO8601DateTime(
464                                 null,
465                                 new ISO8601Date(2000, 1, 17),
466                                 new ISO8601Time(19, 23, 17, 300) );
467                 assertEquals(testResponse, resValue);
468                 
469                 // millisecs work correctly
470                 arguments.clear();
471                 arguments.add(attrDateTimeMsecs);
472                 arguments.add(attrDurationMsecs);
473                 res = fd.evaluate(null, arguments);
474                 assertTrue(res.isOk());
475                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
476                 resValue = (ISO8601DateTime)res.getValue().getValue();
477                 testResponse = new ISO8601DateTime(
478                                 null,
479                                 new ISO8601Date(2000, 1, 7),
480                                 new ISO8601Time(5, 2, 59, 999) );
481                 assertEquals(testResponse, resValue);
482         
483                 // cross minute => cross day => cross month => cross year
484                 arguments.clear();
485                 arguments.add(attrDateTimeCrossover);
486                 arguments.add(attrDurationCrossover);
487                 res = fd.evaluate(null, arguments);
488                 assertTrue(res.isOk());
489                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
490                 resValue = (ISO8601DateTime)res.getValue().getValue();
491                 testResponse = new ISO8601DateTime(
492                                 null,
493                                 new ISO8601Date(2000, 12, 31), 
494                                 new ISO8601Time(23, 59, 30, 1));
495                 assertEquals(testResponse, resValue);
496                 
497                 // negative (BC) original date add goes the right direction
498                 arguments.clear();
499                 arguments.add(attrDateTimeBC);
500                 arguments.add(attrDurationStdExample1);
501                 res = fd.evaluate(null, arguments);
502                 assertTrue(res.isOk());
503                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
504                 resValue = (ISO8601DateTime)res.getValue().getValue();
505                 testResponse = new ISO8601DateTime(
506                                 null,
507                                 new ISO8601Date(-2000, 1, 7),
508                                 new ISO8601Time(5, 3, 10, 700) );
509                 assertEquals(testResponse, resValue);   
510                 
511                 // non-null timezone not changed
512                 // original has timezone offset = 0
513                 arguments.clear();
514                 arguments.add(attrDateTimeTimeZone0);
515                 arguments.add(attrDurationStdExample1);
516                 res = fd.evaluate(null, arguments);
517                 assertTrue(res.isOk());
518                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
519                 resValue = (ISO8601DateTime)res.getValue().getValue();
520                 testResponse = new ISO8601DateTime(
521                                 timeZone0,
522                                 new ISO8601Date(timeZone0, 2000, 1, 7),
523                                 new ISO8601Time(timeZone0, 5, 3, 10, 700) );
524                 assertEquals(testResponse, resValue);
525                 
526                 // original has timezone offset not 0
527                 arguments.clear();
528                 arguments.add(attrDateTimeTimeZone5);
529                 arguments.add(attrDurationStdExample1);
530                 res = fd.evaluate(null, arguments);
531                 assertTrue(res.isOk());
532                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
533                 resValue = (ISO8601DateTime)res.getValue().getValue();
534                 testResponse = new ISO8601DateTime(
535                                 timeZone5,
536                                 new ISO8601Date(timeZone5, 2000, 1, 7),
537                                 new ISO8601Time(timeZone5, 5, 3, 10, 700) );
538                 assertEquals(testResponse, resValue);
539
540                 // empty non-null first arg
541                 arguments.clear();
542                 arguments.add(attrBlank);
543                 arguments.add(attrDurationStdExample1);
544                 res = fd.evaluate(null, arguments);
545                 assertFalse(res.isOk());
546                 assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
547                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
548
549                 // empty non-null second arg
550                 arguments.clear();
551                 arguments.add(attrDateTimeStdExample1);
552                 arguments.add(attrBlank);
553                 res = fd.evaluate(null, arguments);
554                 assertFalse(res.isOk());
555                 assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
556                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
557
558                 // two blanks
559                 arguments.clear();
560                 arguments.add(attrBlank);
561                 arguments.add(attrBlank);
562                 res = fd.evaluate(null, arguments);
563                 assertFalse(res.isOk());
564                 assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
565                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
566                         
567                 // null firat arg
568                 arguments.clear();
569                 arguments.add(attrNull);
570                 arguments.add(attrBlank);
571                 res = fd.evaluate(null, arguments);
572                 assertFalse(res.isOk());
573                 assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
574                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
575
576                 // null second arg
577                 arguments.clear();
578                 arguments.add(attrDateTimeStdExample1);
579                 arguments.add(attrNull);
580                 res = fd.evaluate(null, arguments);
581                 assertFalse(res.isOk());
582                 assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
583                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
584                 
585                 // bad arg type
586                 arguments.clear();
587                 arguments.add(attrInteger);
588                 arguments.add(attrDurationStdExample1);
589                 res = fd.evaluate(null, arguments);
590                 assertFalse(res.isOk());
591                 assertEquals("function:dateTime-subtract-dayTimeDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
592                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
593                 
594                 // null second arg
595                 arguments.clear();
596                 arguments.add(attrDateTimeStdExample1);
597                 arguments.add(attrNull);
598                 res = fd.evaluate(null, arguments);
599                 assertFalse(res.isOk());
600                 assertEquals("function:dateTime-subtract-dayTimeDuration Got null attribute", res.getStatus().getStatusMessage());
601                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
602         }
603         
604
605
606         
607         
608         
609         
610         
611         
612         @Test
613         public void testDateTime_add_yearMonthDuration() {
614                 // Date objects to be adjusted
615                 ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 
616                                 new ISO8601Date(2000, 1, 12), 
617                                 new ISO8601Time(12, 13, 14, 0));
618                 ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 
619                                 new ISO8601Date(2000, 1, 12), 
620                                 new ISO8601Time(12, 13, 14, 777));
621                 ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 
622                                 new ISO8601Date(2000, 12, 31), 
623                                 new ISO8601Time(23, 59, 30, 1));
624                 ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 
625                                 new ISO8601Date(-2000, 1, 12), 
626                                 new ISO8601Time(12, 13, 14, 0));
627                 ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
628                 ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
629                 ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 
630                                 new ISO8601Date(timeZone0, 2000, 1, 12), 
631                                 new ISO8601Time(timeZone0, 12, 13, 14, 0));
632                 ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 
633                                 new ISO8601Date(timeZone5, 2000, 1, 12), 
634                                 new ISO8601Time(timeZone5, 12, 13, 14, 0));
635                 
636                 // Durations
637                 XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
638                 XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
639                 XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
640                 XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
641                 XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
642
643                 // ARGS declarations
644                 // Dates
645                 FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
646                 FunctionArgumentAttributeValue attrDateTimeMsecs = null;
647                 FunctionArgumentAttributeValue attrDateTimeCrossover = null;
648                 FunctionArgumentAttributeValue attrDateTimeBC = null;
649                 FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
650                 FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
651         
652                 // Durations
653                 FunctionArgumentAttributeValue attrDuration0 = null;
654                 FunctionArgumentAttributeValue attrDurationStdExample1 = null;
655                 FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
656                 FunctionArgumentAttributeValue attrDurationMsecs = null;
657                 FunctionArgumentAttributeValue attrDurationCrossover = null;
658         
659                 // misc bad
660                 FunctionArgumentAttributeValue attrNull = null;
661                 FunctionArgumentAttributeValue attrBlank = null;
662                 FunctionArgumentAttributeValue attrInteger = null;
663                 // set values
664                 try {
665                         // Date attrs
666                         attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
667                         attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
668                         attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
669                         attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
670                         attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
671                         attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
672                         
673                         // Duration attrs
674                         attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
675                         attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
676                         attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
677                         attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
678                         attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
679
680                         // misc bad
681                         attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
682                         attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
683                         attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
684                 } catch (Exception e) {
685                         fail("creating attributes e="+ e);
686                 }
687                 
688                 FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_ADD_YEARMONTHDURATION;
689
690                 // check identity and type of the thing created
691                 assertEquals(XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION, fd.getId());
692                 assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
693                 
694                 // just to be safe...  If tests take too long these can probably be eliminated
695                 assertFalse(fd.returnsBag());
696                 
697                 // Duration = 0 => same as original
698                 arguments.clear();
699                 arguments.add(attrDateTimeStdExample1);
700                 arguments.add(attrDuration0);
701                 res = fd.evaluate(null, arguments);
702                 assertTrue(res.isOk());
703                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
704                 ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
705                 assertEquals(dateTimeStdExample1, resValue);
706
707                 
708                 // simple positive operation
709                 arguments.clear();
710                 arguments.add(attrDateTimeStdExample1);
711                 arguments.add(attrDurationStdExample1);
712                 res = fd.evaluate(null, arguments);
713                 assertTrue(res.isOk());
714                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
715                 resValue = (ISO8601DateTime)res.getValue().getValue();
716                 ISO8601DateTime testResponse = new ISO8601DateTime(
717                                 null,
718                                 new ISO8601Date(2005, 8, 12),
719                                 new ISO8601Time(12, 13, 14, 0) );
720                 assertEquals(testResponse, resValue);   
721                 
722                 // negative operation
723                 arguments.clear();
724                 arguments.add(attrDateTimeStdExample1);
725                 arguments.add(attrDurationNStdExample1);
726                 res = fd.evaluate(null, arguments);
727                 assertTrue(res.isOk());
728                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
729                 resValue = (ISO8601DateTime)res.getValue().getValue();
730                 testResponse = new ISO8601DateTime(
731                                 null,
732                                 new ISO8601Date(1994, 6, 12),
733                                 new ISO8601Time(12, 13, 14, 0) );
734                 assertEquals(testResponse, resValue);
735                 
736                 // millisecs work correctly (not relevant to YearMonth, but should not break
737                 arguments.clear();
738                 arguments.add(attrDateTimeMsecs);
739                 arguments.add(attrDurationMsecs);
740                 res = fd.evaluate(null, arguments);
741                 assertTrue(res.isOk());
742                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
743                 resValue = (ISO8601DateTime)res.getValue().getValue();
744                 testResponse = new ISO8601DateTime(
745                                 null,
746                                 new ISO8601Date(2005, 8, 12),
747                                 new ISO8601Time(12, 13, 14, 777) );
748                 assertEquals(testResponse, resValue);
749         
750                 // cross minute => cross day => cross month => cross year
751                 arguments.clear();
752                 arguments.add(attrDateTimeCrossover);
753                 arguments.add(attrDurationCrossover);
754                 res = fd.evaluate(null, arguments);
755                 assertTrue(res.isOk());
756                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
757                 resValue = (ISO8601DateTime)res.getValue().getValue();
758                 testResponse = new ISO8601DateTime(
759                                 null,
760                                 new ISO8601Date(2001, 1, 31),
761                                 new ISO8601Time(23, 59, 30, 1) );
762                 assertEquals(testResponse, resValue);
763                 
764                 // negative (BC) original date add goes the right direction
765                 arguments.clear();
766                 arguments.add(attrDateTimeBC);
767                 arguments.add(attrDurationStdExample1);
768                 res = fd.evaluate(null, arguments);
769                 assertTrue(res.isOk());
770                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
771                 resValue = (ISO8601DateTime)res.getValue().getValue();
772                 testResponse = new ISO8601DateTime(
773                                 null,
774                                 new ISO8601Date(-1995, 8, 12),
775                                 new ISO8601Time(12, 13, 14, 0) );
776                 assertEquals(testResponse, resValue);   
777                 
778                 // non-null timezone not changed
779                 // original has timezone offset = 0
780                 arguments.clear();
781                 arguments.add(attrDateTimeTimeZone0);
782                 arguments.add(attrDurationStdExample1);
783                 res = fd.evaluate(null, arguments);
784                 assertTrue(res.isOk());
785                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
786                 resValue = (ISO8601DateTime)res.getValue().getValue();
787                 testResponse = new ISO8601DateTime(
788                                 timeZone0,
789                                 new ISO8601Date(timeZone0, 2005, 8, 12),
790                                 new ISO8601Time(timeZone0, 12, 13, 14, 0) );
791                 assertEquals(testResponse, resValue);
792                 
793                 // original has timezone offset not 0
794                 arguments.clear();
795                 arguments.add(attrDateTimeTimeZone5);
796                 arguments.add(attrDurationStdExample1);
797                 res = fd.evaluate(null, arguments);
798                 assertTrue(res.isOk());
799                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
800                 resValue = (ISO8601DateTime)res.getValue().getValue();
801                 testResponse = new ISO8601DateTime(
802                                 timeZone5,
803                                 new ISO8601Date(timeZone5, 2005, 8, 12),
804                                 new ISO8601Time(timeZone5, 12, 13, 14, 0) );
805                 assertEquals(testResponse, resValue);
806
807                 // empty non-null first arg
808                 arguments.clear();
809                 arguments.add(attrBlank);
810                 arguments.add(attrDurationStdExample1);
811                 res = fd.evaluate(null, arguments);
812                 assertFalse(res.isOk());
813                 assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
814                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
815
816                 // empty non-null second arg
817                 arguments.clear();
818                 arguments.add(attrDateTimeStdExample1);
819                 arguments.add(attrBlank);
820                 res = fd.evaluate(null, arguments);
821                 assertFalse(res.isOk());
822                 assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
823                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
824
825                 // two blanks
826                 arguments.clear();
827                 arguments.add(attrBlank);
828                 arguments.add(attrBlank);
829                 res = fd.evaluate(null, arguments);
830                 assertFalse(res.isOk());
831                 assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
832                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
833                         
834                 // null firat arg
835                 arguments.clear();
836                 arguments.add(attrNull);
837                 arguments.add(attrBlank);
838                 res = fd.evaluate(null, arguments);
839                 assertFalse(res.isOk());
840                 assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
841                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
842
843                 // null second arg
844                 arguments.clear();
845                 arguments.add(attrDateTimeStdExample1);
846                 arguments.add(attrNull);
847                 res = fd.evaluate(null, arguments);
848                 assertFalse(res.isOk());
849                 assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
850                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
851                 
852                 // bad arg type
853                 arguments.clear();
854                 arguments.add(attrInteger);
855                 arguments.add(attrDurationStdExample1);
856                 res = fd.evaluate(null, arguments);
857                 assertFalse(res.isOk());
858                 assertEquals("function:dateTime-add-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
859                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
860                 
861                 // null second arg
862                 arguments.clear();
863                 arguments.add(attrDateTimeStdExample1);
864                 arguments.add(attrNull);
865                 res = fd.evaluate(null, arguments);
866                 assertFalse(res.isOk());
867                 assertEquals("function:dateTime-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
868                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
869         }
870         
871
872         
873         
874         @Test
875         public void testDateTime_subtract_yearMonthDuration() {
876                 // Date objects to be adjusted
877                 ISO8601DateTime dateTimeStdExample1 = new ISO8601DateTime(null, 
878                                 new ISO8601Date(2000, 1, 12), 
879                                 new ISO8601Time(12, 13, 14, 0));
880                 ISO8601DateTime dateTimeMsecs = new ISO8601DateTime(null, 
881                                 new ISO8601Date(2000, 1, 12), 
882                                 new ISO8601Time(12, 13, 14, 777));
883                 ISO8601DateTime dateTimeCrossover = new ISO8601DateTime(null, 
884                                 new ISO8601Date(2000, 1, 1), 
885                                 new ISO8601Time(23, 59, 30, 1));
886                 ISO8601DateTime dateTimeBC = new ISO8601DateTime(null, 
887                                 new ISO8601Date(-2000, 1, 12), 
888                                 new ISO8601Time(12, 13, 14, 0));
889                 ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
890                 ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
891                 ISO8601DateTime dateTimeTimeZone0 = new ISO8601DateTime(timeZone0, 
892                                 new ISO8601Date(timeZone0, 2000, 1, 12), 
893                                 new ISO8601Time(timeZone0, 12, 13, 14, 0));
894                 ISO8601DateTime dateTimeTimeZone5 = new ISO8601DateTime(timeZone5, 
895                                 new ISO8601Date(timeZone5, 2000, 1, 12), 
896                                 new ISO8601Time(timeZone5, 12, 13, 14, 0));
897                 
898                 // Durations
899                 XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
900                 XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
901                 XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
902                 XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
903                 XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
904
905                 // ARGS declarations
906                 // Dates
907                 FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
908                 FunctionArgumentAttributeValue attrDateTimeMsecs = null;
909                 FunctionArgumentAttributeValue attrDateTimeCrossover = null;
910                 FunctionArgumentAttributeValue attrDateTimeBC = null;
911                 FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
912                 FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
913         
914                 // Durations
915                 FunctionArgumentAttributeValue attrDuration0 = null;
916                 FunctionArgumentAttributeValue attrDurationStdExample1 = null;
917                 FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
918                 FunctionArgumentAttributeValue attrDurationMsecs = null;
919                 FunctionArgumentAttributeValue attrDurationCrossover = null;
920         
921                 // misc bad
922                 FunctionArgumentAttributeValue attrNull = null;
923                 FunctionArgumentAttributeValue attrBlank = null;
924                 FunctionArgumentAttributeValue attrInteger = null;
925                 // set values
926                 try {
927                         // Date attrs
928                         attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeStdExample1));
929                         attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeMsecs));
930                         attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeCrossover));
931                         attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeBC));
932                         attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone0));
933                         attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATETIME.createAttributeValue(dateTimeTimeZone5));
934                         
935                         // Duration attrs
936                         attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
937                         attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
938                         attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
939                         attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
940                         attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
941
942                         // misc bad
943                         attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
944                         attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
945                         attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
946                 } catch (Exception e) {
947                         fail("creating attributes e="+ e);
948                 }
949                 
950                 FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATETIME_SUBTRACT_YEARMONTHDURATION;
951
952                 // check identity and type of the thing created
953                 assertEquals(XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION, fd.getId());
954                 assertEquals(DataTypes.DT_DATETIME.getId(), fd.getDataTypeId());
955                 
956                 // just to be safe...  If tests take too long these can probably be eliminated
957                 assertFalse(fd.returnsBag());
958                 
959                 // Duration = 0 => same as original
960                 arguments.clear();
961                 arguments.add(attrDateTimeStdExample1);
962                 arguments.add(attrDuration0);
963                 res = fd.evaluate(null, arguments);
964                 assertTrue(res.isOk());
965                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
966                 ISO8601DateTime resValue = (ISO8601DateTime)res.getValue().getValue();
967                 assertEquals(dateTimeStdExample1, resValue);
968
969                 
970                 // simple positive operation
971                 arguments.clear();
972                 arguments.add(attrDateTimeStdExample1);
973                 arguments.add(attrDurationStdExample1);
974                 res = fd.evaluate(null, arguments);
975                 assertTrue(res.isOk());
976                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
977                 resValue = (ISO8601DateTime)res.getValue().getValue();
978                 ISO8601DateTime testResponse = new ISO8601DateTime(
979                                 null,
980                                 new ISO8601Date(1994, 6, 12),
981                                 new ISO8601Time(12, 13, 14, 0) );
982                 assertEquals(testResponse, resValue);   
983                 
984                 // negative operation
985                 arguments.clear();
986                 arguments.add(attrDateTimeStdExample1);
987                 arguments.add(attrDurationNStdExample1);
988                 res = fd.evaluate(null, arguments);
989                 assertTrue(res.isOk());
990                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
991                 resValue = (ISO8601DateTime)res.getValue().getValue();
992                 testResponse = new ISO8601DateTime(
993                                 null,
994                                 new ISO8601Date(2005, 8, 12),
995                                 new ISO8601Time(12, 13, 14, 0) );
996                 assertEquals(testResponse, resValue);
997                 
998                 // millisecs work correctly (not relevant to YearMonth, but should not break
999                 arguments.clear();
1000                 arguments.add(attrDateTimeMsecs);
1001                 arguments.add(attrDurationMsecs);
1002                 res = fd.evaluate(null, arguments);
1003                 assertTrue(res.isOk());
1004                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
1005                 resValue = (ISO8601DateTime)res.getValue().getValue();
1006                 testResponse = new ISO8601DateTime(
1007                                 null,
1008                                 new ISO8601Date(1994, 6, 12),
1009                                 new ISO8601Time(12, 13, 14, 777) );
1010                 assertEquals(testResponse, resValue);
1011         
1012                 // cross minute => cross day => cross month => cross year
1013                 arguments.clear();
1014                 arguments.add(attrDateTimeCrossover);
1015                 arguments.add(attrDurationCrossover);
1016                 res = fd.evaluate(null, arguments);
1017                 assertTrue(res.isOk());
1018                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
1019                 resValue = (ISO8601DateTime)res.getValue().getValue();
1020                 testResponse = new ISO8601DateTime(
1021                                 null,
1022                                 new ISO8601Date(1999, 12, 1),
1023                                 new ISO8601Time(23, 59, 30, 1) );
1024                 assertEquals(testResponse, resValue);
1025                 
1026                 // negative (BC) original date add goes the right direction
1027                 arguments.clear();
1028                 arguments.add(attrDateTimeBC);
1029                 arguments.add(attrDurationStdExample1);
1030                 res = fd.evaluate(null, arguments);
1031                 assertTrue(res.isOk());
1032                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
1033                 resValue = (ISO8601DateTime)res.getValue().getValue();
1034                 testResponse = new ISO8601DateTime(
1035                                 null,
1036                                 new ISO8601Date(-2006, 6, 12),
1037                                 new ISO8601Time(12, 13, 14, 0) );
1038                 assertEquals(testResponse, resValue);   
1039                 
1040                 // non-null timezone not changed
1041                 // original has timezone offset = 0
1042                 arguments.clear();
1043                 arguments.add(attrDateTimeTimeZone0);
1044                 arguments.add(attrDurationStdExample1);
1045                 res = fd.evaluate(null, arguments);
1046                 assertTrue(res.isOk());
1047                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
1048                 resValue = (ISO8601DateTime)res.getValue().getValue();
1049                 testResponse = new ISO8601DateTime(
1050                                 timeZone0,
1051                                 new ISO8601Date(timeZone0, 1994, 6, 12),
1052                                 new ISO8601Time(timeZone0, 12, 13, 14, 0) );
1053                 assertEquals(testResponse, resValue);
1054                 
1055                 // original has timezone offset not 0
1056                 arguments.clear();
1057                 arguments.add(attrDateTimeTimeZone5);
1058                 arguments.add(attrDurationStdExample1);
1059                 res = fd.evaluate(null, arguments);
1060                 assertTrue(res.isOk());
1061                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601DateTime.class, res.getValue().getValue().getClass());
1062                 resValue = (ISO8601DateTime)res.getValue().getValue();
1063                 testResponse = new ISO8601DateTime(
1064                                 timeZone5,
1065                                 new ISO8601Date(timeZone5, 1994, 6, 12),
1066                                 new ISO8601Time(timeZone5, 12, 13, 14, 0) );
1067                 assertEquals(testResponse, resValue);
1068
1069                 // empty non-null first arg
1070                 arguments.clear();
1071                 arguments.add(attrBlank);
1072                 arguments.add(attrDurationStdExample1);
1073                 res = fd.evaluate(null, arguments);
1074                 assertFalse(res.isOk());
1075                 assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1076                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1077
1078                 // empty non-null second arg
1079                 arguments.clear();
1080                 arguments.add(attrDateTimeStdExample1);
1081                 arguments.add(attrBlank);
1082                 res = fd.evaluate(null, arguments);
1083                 assertFalse(res.isOk());
1084                 assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1085                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1086
1087                 // two blanks
1088                 arguments.clear();
1089                 arguments.add(attrBlank);
1090                 arguments.add(attrBlank);
1091                 res = fd.evaluate(null, arguments);
1092                 assertFalse(res.isOk());
1093                 assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1094                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1095                         
1096                 // null firat arg
1097                 arguments.clear();
1098                 arguments.add(attrNull);
1099                 arguments.add(attrBlank);
1100                 res = fd.evaluate(null, arguments);
1101                 assertFalse(res.isOk());
1102                 assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1103                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1104
1105                 // null second arg
1106                 arguments.clear();
1107                 arguments.add(attrDateTimeStdExample1);
1108                 arguments.add(attrNull);
1109                 res = fd.evaluate(null, arguments);
1110                 assertFalse(res.isOk());
1111                 assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1112                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1113                 
1114                 // bad arg type
1115                 arguments.clear();
1116                 arguments.add(attrInteger);
1117                 arguments.add(attrDurationStdExample1);
1118                 res = fd.evaluate(null, arguments);
1119                 assertFalse(res.isOk());
1120                 assertEquals("function:dateTime-subtract-yearMonthDuration Expected data type 'dateTime' saw 'integer'", res.getStatus().getStatusMessage());
1121                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1122                 
1123                 // null second arg
1124                 arguments.clear();
1125                 arguments.add(attrDateTimeStdExample1);
1126                 arguments.add(attrNull);
1127                 res = fd.evaluate(null, arguments);
1128                 assertFalse(res.isOk());
1129                 assertEquals("function:dateTime-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1130                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1131         }
1132         
1133         
1134         
1135         
1136         
1137         
1138         
1139         
1140         
1141         
1142         
1143         @Test
1144         public void testDate_add_yearMonthDuration() {
1145                 // Date objects to be adjusted
1146                 ISO8601Date dateTimeStdExample1 = new ISO8601Date(2000, 1, 12);
1147                 ISO8601Date dateTimeMsecs =new ISO8601Date(2000, 1, 12);
1148                 ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 12, 31);
1149                 ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12);
1150                 ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
1151                 ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
1152                 ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12);
1153                 ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12);
1154                 
1155                 // Durations
1156                 XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
1157                 XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
1158                 XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
1159                 XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
1160                 XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
1161
1162                 // ARGS declarations
1163                 // Dates
1164                 FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
1165                 FunctionArgumentAttributeValue attrDateTimeMsecs = null;
1166                 FunctionArgumentAttributeValue attrDateTimeCrossover = null;
1167                 FunctionArgumentAttributeValue attrDateTimeBC = null;
1168                 FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
1169                 FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
1170         
1171                 // Durations
1172                 FunctionArgumentAttributeValue attrDuration0 = null;
1173                 FunctionArgumentAttributeValue attrDurationStdExample1 = null;
1174                 FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
1175                 FunctionArgumentAttributeValue attrDurationMsecs = null;
1176                 FunctionArgumentAttributeValue attrDurationCrossover = null;
1177         
1178                 // misc bad
1179                 FunctionArgumentAttributeValue attrNull = null;
1180                 FunctionArgumentAttributeValue attrBlank = null;
1181                 FunctionArgumentAttributeValue attrInteger = null;
1182                 // set values
1183                 try {
1184                         // Date attrs
1185                         attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1));
1186                         attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs));
1187                         attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover));
1188                         attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC));
1189                         attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0));
1190                         attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5));
1191                         
1192                         // Duration attrs
1193                         attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
1194                         attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
1195                         attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
1196                         attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
1197                         attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
1198
1199                         // misc bad
1200                         attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
1201                         attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
1202                         attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
1203                 } catch (Exception e) {
1204                         fail("creating attributes e="+ e);
1205                 }
1206                 
1207                 FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_ADD_YEARMONTHDURATION;
1208
1209                 // check identity and type of the thing created
1210                 assertEquals(XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION, fd.getId());
1211                 assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());
1212                 
1213                 // just to be safe...  If tests take too long these can probably be eliminated
1214                 assertFalse(fd.returnsBag());
1215                 
1216                 // Duration = 0 => same as original
1217                 arguments.clear();
1218                 arguments.add(attrDateTimeStdExample1);
1219                 arguments.add(attrDuration0);
1220                 res = fd.evaluate(null, arguments);
1221                 assertTrue(res.isOk());
1222                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1223                 ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();
1224                 assertEquals(dateTimeStdExample1, resValue);
1225
1226                 
1227                 // simple positive operation
1228                 arguments.clear();
1229                 arguments.add(attrDateTimeStdExample1);
1230                 arguments.add(attrDurationStdExample1);
1231                 res = fd.evaluate(null, arguments);
1232                 assertTrue(res.isOk());
1233                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1234                 resValue = (ISO8601Date)res.getValue().getValue();
1235                 ISO8601Date testResponse = new ISO8601Date(2005, 8, 12);
1236                 assertEquals(testResponse, resValue);   
1237                 
1238                 // negative operation
1239                 arguments.clear();
1240                 arguments.add(attrDateTimeStdExample1);
1241                 arguments.add(attrDurationNStdExample1);
1242                 res = fd.evaluate(null, arguments);
1243                 assertTrue(res.isOk());
1244                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1245                 resValue = (ISO8601Date)res.getValue().getValue();
1246                 testResponse = new ISO8601Date(1994, 6, 12);
1247                 assertEquals(testResponse, resValue);
1248                 
1249                 // millisecs work correctly (not relevant to YearMonth, but should not break
1250                 arguments.clear();
1251                 arguments.add(attrDateTimeMsecs);
1252                 arguments.add(attrDurationMsecs);
1253                 res = fd.evaluate(null, arguments);
1254                 assertTrue(res.isOk());
1255                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1256                 resValue = (ISO8601Date)res.getValue().getValue();
1257                 testResponse = new ISO8601Date(2005, 8, 12);
1258                 assertEquals(testResponse, resValue);
1259         
1260                 // cross minute => cross day => cross month => cross year
1261                 arguments.clear();
1262                 arguments.add(attrDateTimeCrossover);
1263                 arguments.add(attrDurationCrossover);
1264                 res = fd.evaluate(null, arguments);
1265                 assertTrue(res.isOk());
1266                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1267                 resValue = (ISO8601Date)res.getValue().getValue();
1268                 testResponse = new ISO8601Date(2001, 1, 31);
1269                 assertEquals(testResponse, resValue);
1270                 
1271                 // negative (BC) original date add goes the right direction
1272                 arguments.clear();
1273                 arguments.add(attrDateTimeBC);
1274                 arguments.add(attrDurationStdExample1);
1275                 res = fd.evaluate(null, arguments);
1276                 assertTrue(res.isOk());
1277                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1278                 resValue = (ISO8601Date)res.getValue().getValue();
1279                 testResponse = new ISO8601Date(-1995, 8, 12);
1280                 assertEquals(testResponse, resValue);   
1281                 
1282                 // non-null timezone not changed
1283                 // original has timezone offset = 0
1284                 arguments.clear();
1285                 arguments.add(attrDateTimeTimeZone0);
1286                 arguments.add(attrDurationStdExample1);
1287                 res = fd.evaluate(null, arguments);
1288                 assertTrue(res.isOk());
1289                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1290                 resValue = (ISO8601Date)res.getValue().getValue();
1291                 testResponse = new ISO8601Date(timeZone0, 2005, 8, 12);
1292                 assertEquals(testResponse, resValue);
1293                 
1294                 // original has timezone offset not 0
1295                 arguments.clear();
1296                 arguments.add(attrDateTimeTimeZone5);
1297                 arguments.add(attrDurationStdExample1);
1298                 res = fd.evaluate(null, arguments);
1299                 assertTrue(res.isOk());
1300                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1301                 resValue = (ISO8601Date)res.getValue().getValue();
1302                 testResponse = new ISO8601Date(timeZone5, 2005, 8, 12);
1303                 assertEquals(testResponse, resValue);
1304
1305                 // empty non-null first arg
1306                 arguments.clear();
1307                 arguments.add(attrBlank);
1308                 arguments.add(attrDurationStdExample1);
1309                 res = fd.evaluate(null, arguments);
1310                 assertFalse(res.isOk());
1311                 assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1312                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1313
1314                 // empty non-null second arg
1315                 arguments.clear();
1316                 arguments.add(attrDateTimeStdExample1);
1317                 arguments.add(attrBlank);
1318                 res = fd.evaluate(null, arguments);
1319                 assertFalse(res.isOk());
1320                 assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1321                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1322
1323                 // two blanks
1324                 arguments.clear();
1325                 arguments.add(attrBlank);
1326                 arguments.add(attrBlank);
1327                 res = fd.evaluate(null, arguments);
1328                 assertFalse(res.isOk());
1329                 assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1330                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1331                         
1332                 // null firat arg
1333                 arguments.clear();
1334                 arguments.add(attrNull);
1335                 arguments.add(attrBlank);
1336                 res = fd.evaluate(null, arguments);
1337                 assertFalse(res.isOk());
1338                 assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1339                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1340
1341                 // null second arg
1342                 arguments.clear();
1343                 arguments.add(attrDateTimeStdExample1);
1344                 arguments.add(attrNull);
1345                 res = fd.evaluate(null, arguments);
1346                 assertFalse(res.isOk());
1347                 assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1348                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1349                 
1350                 // bad arg type
1351                 arguments.clear();
1352                 arguments.add(attrInteger);
1353                 arguments.add(attrDurationStdExample1);
1354                 res = fd.evaluate(null, arguments);
1355                 assertFalse(res.isOk());
1356                 assertEquals("function:date-add-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage());
1357                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1358                 
1359                 // null second arg
1360                 arguments.clear();
1361                 arguments.add(attrDateTimeStdExample1);
1362                 arguments.add(attrNull);
1363                 res = fd.evaluate(null, arguments);
1364                 assertFalse(res.isOk());
1365                 assertEquals("function:date-add-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1366                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1367         }
1368         
1369         
1370         
1371         
1372         
1373         
1374         @Test
1375         public void testDate_subtract_yearMonthDuration() {
1376                 // Date objects to be adjusted
1377                 ISO8601Date dateTimeStdExample1 =new ISO8601Date(2000, 1, 12);
1378                 ISO8601Date dateTimeMsecs = new ISO8601Date(2000, 1, 12);
1379                 ISO8601Date dateTimeCrossover = new ISO8601Date(2000, 1, 1);
1380                 ISO8601Date dateTimeBC = new ISO8601Date(-2000, 1, 12);
1381                 ISO8601TimeZone timeZone0 = new ISO8601TimeZone(0);
1382                 ISO8601TimeZone timeZone5 = new ISO8601TimeZone(5 * 60);
1383                 ISO8601Date dateTimeTimeZone0 = new ISO8601Date(timeZone0, 2000, 1, 12);
1384                 ISO8601Date dateTimeTimeZone5 = new ISO8601Date(timeZone5, 2000, 1, 12);
1385                 
1386                 // Durations
1387                 XPathYearMonthDuration duration0 = new XPathYearMonthDuration(1, 0, 0);
1388                 XPathYearMonthDuration durationStdExample1 = new XPathYearMonthDuration(1, 5, 7);
1389                 XPathYearMonthDuration durationNStdExample1 = new XPathYearMonthDuration(-1, 5, 7);
1390                 XPathYearMonthDuration durationMsecs = new XPathYearMonthDuration(1, 5, 7);
1391                 XPathYearMonthDuration durationCrossover = new XPathYearMonthDuration(1, 0, 1);
1392
1393                 // ARGS declarations
1394                 // Dates
1395                 FunctionArgumentAttributeValue attrDateTimeStdExample1 = null;
1396                 FunctionArgumentAttributeValue attrDateTimeMsecs = null;
1397                 FunctionArgumentAttributeValue attrDateTimeCrossover = null;
1398                 FunctionArgumentAttributeValue attrDateTimeBC = null;
1399                 FunctionArgumentAttributeValue attrDateTimeTimeZone0 = null;
1400                 FunctionArgumentAttributeValue attrDateTimeTimeZone5 = null;
1401         
1402                 // Durations
1403                 FunctionArgumentAttributeValue attrDuration0 = null;
1404                 FunctionArgumentAttributeValue attrDurationStdExample1 = null;
1405                 FunctionArgumentAttributeValue attrDurationNStdExample1 = null;
1406                 FunctionArgumentAttributeValue attrDurationMsecs = null;
1407                 FunctionArgumentAttributeValue attrDurationCrossover = null;
1408         
1409                 // misc bad
1410                 FunctionArgumentAttributeValue attrNull = null;
1411                 FunctionArgumentAttributeValue attrBlank = null;
1412                 FunctionArgumentAttributeValue attrInteger = null;
1413                 // set values
1414                 try {
1415                         // Date attrs
1416                         attrDateTimeStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeStdExample1));
1417                         attrDateTimeMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeMsecs));
1418                         attrDateTimeCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeCrossover));
1419                         attrDateTimeBC = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeBC));
1420                         attrDateTimeTimeZone0 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone0));
1421                         attrDateTimeTimeZone5 = new FunctionArgumentAttributeValue(DataTypes.DT_DATE.createAttributeValue(dateTimeTimeZone5));
1422                         
1423                         // Duration attrs
1424                         attrDuration0 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(duration0));
1425                         attrDurationStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationStdExample1));
1426                         attrDurationNStdExample1 = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationNStdExample1));
1427                         attrDurationMsecs = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationMsecs));
1428                         attrDurationCrossover = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(durationCrossover));
1429
1430                         // misc bad
1431                         attrBlank = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(""));
1432                         attrNull = new FunctionArgumentAttributeValue(DataTypes.DT_YEARMONTHDURATION.createAttributeValue(null));
1433                         attrInteger = new FunctionArgumentAttributeValue(DataTypes.DT_INTEGER.createAttributeValue(1234));
1434                 } catch (Exception e) {
1435                         fail("creating attributes e="+ e);
1436                 }
1437                 
1438                 FunctionDefinitionDateTimeArithmetic<?,?> fd = (FunctionDefinitionDateTimeArithmetic<?,?>) StdFunctions.FD_DATE_SUBTRACT_YEARMONTHDURATION;
1439
1440                 // check identity and type of the thing created
1441                 assertEquals(XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION, fd.getId());
1442                 assertEquals(DataTypes.DT_DATE.getId(), fd.getDataTypeId());
1443                 
1444                 // just to be safe...  If tests take too long these can probably be eliminated
1445                 assertFalse(fd.returnsBag());
1446                 
1447                 // Duration = 0 => same as original
1448                 arguments.clear();
1449                 arguments.add(attrDateTimeStdExample1);
1450                 arguments.add(attrDuration0);
1451                 res = fd.evaluate(null, arguments);
1452                 assertTrue(res.isOk());
1453                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1454                 ISO8601Date resValue = (ISO8601Date)res.getValue().getValue();
1455                 assertEquals(dateTimeStdExample1, resValue);
1456
1457                 
1458                 // simple positive operation
1459                 arguments.clear();
1460                 arguments.add(attrDateTimeStdExample1);
1461                 arguments.add(attrDurationStdExample1);
1462                 res = fd.evaluate(null, arguments);
1463                 assertTrue(res.isOk());
1464                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1465                 resValue = (ISO8601Date)res.getValue().getValue();
1466                 ISO8601Date testResponse = new ISO8601Date(1994, 6, 12);
1467                 assertEquals(testResponse, resValue);   
1468                 
1469                 // negative operation
1470                 arguments.clear();
1471                 arguments.add(attrDateTimeStdExample1);
1472                 arguments.add(attrDurationNStdExample1);
1473                 res = fd.evaluate(null, arguments);
1474                 assertTrue(res.isOk());
1475                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1476                 resValue = (ISO8601Date)res.getValue().getValue();
1477                 testResponse = new ISO8601Date(2005, 8, 12);
1478                 assertEquals(testResponse, resValue);
1479                 
1480                 // millisecs work correctly (not relevant to YearMonth, but should not break
1481                 arguments.clear();
1482                 arguments.add(attrDateTimeMsecs);
1483                 arguments.add(attrDurationMsecs);
1484                 res = fd.evaluate(null, arguments);
1485                 assertTrue(res.isOk());
1486                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1487                 resValue = (ISO8601Date)res.getValue().getValue();
1488                 testResponse = new ISO8601Date(1994, 6, 12);
1489                 assertEquals(testResponse, resValue);
1490         
1491                 // cross minute => cross day => cross month => cross year
1492                 arguments.clear();
1493                 arguments.add(attrDateTimeCrossover);
1494                 arguments.add(attrDurationCrossover);
1495                 res = fd.evaluate(null, arguments);
1496                 assertTrue(res.isOk());
1497                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1498                 resValue = (ISO8601Date)res.getValue().getValue();
1499                 testResponse = new ISO8601Date(1999, 12, 1);
1500                 assertEquals(testResponse, resValue);
1501                 
1502                 // negative (BC) original date add goes the right direction
1503                 arguments.clear();
1504                 arguments.add(attrDateTimeBC);
1505                 arguments.add(attrDurationStdExample1);
1506                 res = fd.evaluate(null, arguments);
1507                 assertTrue(res.isOk());
1508                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1509                 resValue = (ISO8601Date)res.getValue().getValue();
1510                 testResponse = new ISO8601Date(-2006, 6, 12);
1511                 assertEquals(testResponse, resValue);   
1512                 
1513                 // non-null timezone not changed
1514                 // original has timezone offset = 0
1515                 arguments.clear();
1516                 arguments.add(attrDateTimeTimeZone0);
1517                 arguments.add(attrDurationStdExample1);
1518                 res = fd.evaluate(null, arguments);
1519                 assertTrue(res.isOk());
1520                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1521                 resValue = (ISO8601Date)res.getValue().getValue();
1522                 testResponse = new ISO8601Date(timeZone0, 1994, 6, 12);
1523                 assertEquals(testResponse, resValue);
1524                 
1525                 // original has timezone offset not 0
1526                 arguments.clear();
1527                 arguments.add(attrDateTimeTimeZone5);
1528                 arguments.add(attrDurationStdExample1);
1529                 res = fd.evaluate(null, arguments);
1530                 assertTrue(res.isOk());
1531                 assertEquals(com.att.research.xacml.std.datatypes.ISO8601Date.class, res.getValue().getValue().getClass());
1532                 resValue = (ISO8601Date)res.getValue().getValue();
1533                 testResponse = new ISO8601Date(timeZone5, 1994, 6, 12);
1534                 assertEquals(testResponse, resValue);
1535
1536                 // empty non-null first arg
1537                 arguments.clear();
1538                 arguments.add(attrBlank);
1539                 arguments.add(attrDurationStdExample1);
1540                 res = fd.evaluate(null, arguments);
1541                 assertFalse(res.isOk());
1542                 assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1543                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1544
1545                 // empty non-null second arg
1546                 arguments.clear();
1547                 arguments.add(attrDateTimeStdExample1);
1548                 arguments.add(attrBlank);
1549                 res = fd.evaluate(null, arguments);
1550                 assertFalse(res.isOk());
1551                 assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1552                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1553
1554                 // two blanks
1555                 arguments.clear();
1556                 arguments.add(attrBlank);
1557                 arguments.add(attrBlank);
1558                 res = fd.evaluate(null, arguments);
1559                 assertFalse(res.isOk());
1560                 assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1561                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1562                         
1563                 // null firat arg
1564                 arguments.clear();
1565                 arguments.add(attrNull);
1566                 arguments.add(attrBlank);
1567                 res = fd.evaluate(null, arguments);
1568                 assertFalse(res.isOk());
1569                 assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1570                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1571
1572                 // null second arg
1573                 arguments.clear();
1574                 arguments.add(attrDateTimeStdExample1);
1575                 arguments.add(attrNull);
1576                 res = fd.evaluate(null, arguments);
1577                 assertFalse(res.isOk());
1578                 assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1579                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1580                 
1581                 // bad arg type
1582                 arguments.clear();
1583                 arguments.add(attrInteger);
1584                 arguments.add(attrDurationStdExample1);
1585                 res = fd.evaluate(null, arguments);
1586                 assertFalse(res.isOk());
1587                 assertEquals("function:date-subtract-yearMonthDuration Expected data type 'date' saw 'integer'", res.getStatus().getStatusMessage());
1588                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1589                 
1590                 // null second arg
1591                 arguments.clear();
1592                 arguments.add(attrDateTimeStdExample1);
1593                 arguments.add(attrNull);
1594                 res = fd.evaluate(null, arguments);
1595                 assertFalse(res.isOk());
1596                 assertEquals("function:date-subtract-yearMonthDuration Got null attribute", res.getStatus().getStatusMessage());
1597                 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
1598         }
1599         
1600         
1601         
1602 }