Initial OpenECOMP policy/engine commit
[policy/engine.git] / ECOMP-XACML / src / test / java / org / openecomp / policy / xacml / test / json / ResponseConformanceTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-XACML
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.xacml.test.json;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.fail;
25
26 import java.io.File;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.List;
30
31 import org.junit.Test;
32
33 import com.att.research.xacml.api.Advice;
34 import com.att.research.xacml.api.Attribute;
35 import com.att.research.xacml.api.AttributeCategory;
36 import com.att.research.xacml.api.IdReference;
37 import com.att.research.xacml.api.Obligation;
38 import com.att.research.xacml.api.Response;
39 import com.att.research.xacml.api.Result;
40 import com.att.research.xacml.std.dom.DOMResponse;
41 import com.att.research.xacml.std.json.JSONResponse;
42 import com.att.research.xacml.util.ListUtil;
43 /**
44  * Test JSON Response convert to object - Conformance tests
45  * 
46  * TO RUN - use jUnit
47  * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
48  * 
49  * Note: some of the validation tests comparing the XML-derived Results to the JSON-derived Results are high-level comparisons of Collections.
50  *              When this class was first created that was sufficient to pass all Conformance tests.
51  *              However if this sees a failure in a Conformance test, those validations may need to be upgraded to look at the individual data elements to see what is wrong.
52  * 
53  *
54  */
55 public class ResponseConformanceTest {
56         
57         // where to find the conformance test XML files
58         private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4";
59         
60         // The request object output from each test conversion from JSON string
61         Response response;
62
63
64         
65         
66         
67         // test just one of each top-level element.
68         // For simple elements also test for incorrect type
69         @Test
70         public void testConformanceResponses() {
71                 
72                 List<File> filesInDirectory = null;
73                 
74                 File conformanceDirectory = null;
75                 
76                 File currentFile = null;
77                 
78                 try {
79                         conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH);
80                         filesInDirectory = getRequestsInDirectory(conformanceDirectory);
81                 } catch (Exception e) {
82                         fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()+"' e="+ e);
83                 }
84                 
85                 // run through each XML file
86                 //      - load the file from XML into an internal Response object
87                 //      - generate the JSON representation of that Response object
88                 //      - load that JSON representation into a new Response object
89                 //      - compare the 2 Request objects
90                 Response xmlResponse = null;
91                 Response jsonResponse = null;
92                 try {
93                         for (File f : filesInDirectory) {
94                                 currentFile = f;
95
96 //// This is a simple way to select just one file for debugging - comment out when not being used
97 //if ( ! f.getName().equals("IIIA030Response.xml") && ! f.getName().equals("IIIA330Response.xml")) {   continue;  }
98
99 // during debugging it is helpful to know what file it is starting to work on
100 //                              System.out.println("starting file="+currentFile.getName());
101                                 
102                                 try {
103                                         // load XML into a Response object
104                                         xmlResponse = DOMResponse.load(f);
105                                 } catch (Exception e) {
106                                         // if XML does not load, just note it and continue with next file
107                                         System.out.println("XML file did not load: '" + f.getName() + "  e=" + e);
108                                         continue;
109                                 }
110                                 
111                                 // some tests have JSON response files to load, most do not
112                                 String jsonFileName = f.getName().replace(".xml", ".json");
113                                 File jsonFile = new File(conformanceDirectory, jsonFileName);
114                                 
115                                 if (jsonFile.exists()) {
116 //System.out.println("found file "+jsonFile.getName());
117                                         // json version exists in file, so load it
118                                         jsonResponse = JSONResponse.load(jsonFile);
119                                 } else {
120                                         // json does not exist in file, so create it from the XML response using a String intermediate version
121                                         String jsonResponseString = JSONResponse.toString(xmlResponse, false);
122 //System.out.println(jsonResponseString);       
123 //System.out.println(JSONResponse.toString(xmlResponse, true));
124                                         
125                                         jsonResponse = JSONResponse.load(jsonResponseString);
126                                 }                       
127                                 
128                                 
129 //System.out.println(JSONResponse.toString(xmlResponse, true));
130
131
132
133                                 
134                                 // compare the two Response objects
135                                 
136                                 // compare results
137                                 assertEquals(xmlResponse.getResults().size(), jsonResponse.getResults().size());
138                                 
139                                 if (xmlResponse.getResults().size() == 0) {
140                                         fail("neither XML nor JSON response have any Results");
141                                 }
142                                 
143                                 
144                                 // Results are an un-ordered Collection.
145                                 // There is no identifying information that is unique to a specific Result.
146                                 // If there are more than one we cannot be sure which one corresponds with which.
147                                 // The best we can do is say that one or more in the first list do not match any in the second list
148                                 if (xmlResponse.getResults().size() > 1) {
149                                         for (Result xmlResult : xmlResponse.getResults()) {
150                                                 boolean found = false;
151                                                 for (Result jsonResult : jsonResponse.getResults()) {
152                                                         if (xmlResult.equals(jsonResult)) {
153                                                                 found = true;
154                                                                 break;
155                                                         }
156                                                 }
157                                                 if (found) {
158                                                         continue;
159                                                 }
160                                                 // no match found
161                                                 System.out.println("No match for XML in " + f.getName());
162                                                 System.out.println("XML =" + xmlResult.toString());
163                                                 for (Result jsonResult : jsonResponse.getResults()) {
164                                                         System.out.println("JSON="+ jsonResult.toString());
165                                                 }
166                                                 fail("JSON Response has no match for XML Result: " + xmlResult.toString());
167                                         }
168                                         // we've done the best we can for multiple decisions, so go to next file
169                                         continue;
170                                 }
171                                 
172                                 // single Result in each
173                                 Result xmlResult = xmlResponse.getResults().iterator().next();
174                                 Result jsonResult = jsonResponse.getResults().iterator().next();
175                                 
176                                 // The following sections have not given us trouble, so checking is very high-level.
177                                 // If we see a problem in one of these elements, the single line will need to be replaced with detailed examination of the objects.
178                                 assertEquals(f.getName() + " Decision", xmlResult.getDecision(), jsonResult.getDecision());
179                                 assertEquals(f.getName() + " Status", xmlResult.getStatus(), jsonResult.getStatus());
180                                 
181                                 // Obligations
182                                 if (xmlResult.getObligations() != jsonResult.getObligations()) {
183                                         Collection<Obligation> xmlObligations = xmlResult.getObligations();
184                                         Collection<Obligation> jsonObligations = jsonResult.getObligations();
185                                         // if both are null we do not get here
186                                         if (xmlObligations == null || jsonObligations == null) {
187                                                 fail(f.getName() + " Obligations has null \nXML="+xmlObligations + "\nJSON="+jsonObligations);
188                                         }
189                                         if (ListUtil.equalsAllowNulls(xmlObligations, jsonObligations) == false) {
190                                                 // collections are not equal, so need to examine further
191 fail(f.getName() + " Obligation collections not equal\nXML="+xmlObligations + "\nJSON="+jsonObligations);
192                                         }
193                                 }
194                                 
195                                 // AssociatedAdvice
196                                 if (xmlResult.getAssociatedAdvice() != jsonResult.getAssociatedAdvice()) {
197                                         Collection<Advice> xmlAdvice = xmlResult.getAssociatedAdvice();
198                                         Collection<Advice> jsonAdvice = jsonResult.getAssociatedAdvice();
199                                         // if both are null we do not get here
200                                         if (xmlAdvice == null || jsonAdvice == null) {
201                                                 fail(f.getName() + " Advice has null \nXML="+xmlAdvice + "\nJSON="+jsonAdvice);
202                                         }
203                                         if (ListUtil.equalsAllowNulls(xmlAdvice, jsonAdvice) == false) {
204                                                 // collections are not equal, so need to examine further
205 fail(f.getName() + " Advice collections not equal\nXML="+xmlAdvice + "\nJSON="+jsonAdvice);
206                                         }
207                                 }
208                                 
209                                 
210                                 
211                                 // check Attributes in more detail
212                                 Collection<AttributeCategory> xmlAttributes = xmlResult.getAttributes();
213                                 Collection<AttributeCategory> jsonAttributes = jsonResult.getAttributes();
214                                 if (xmlAttributes == null && jsonAttributes != null || 
215                                                 xmlAttributes != null && jsonAttributes == null) {
216                                         fail(f.getName() + " XML Attributes="+xmlAttributes + "  but JSON Attributes=" + jsonAttributes);
217                                 }
218                                 if (xmlAttributes != null) {
219                                         // both are non-null
220                                         if (xmlAttributes.size() != jsonAttributes.size()) {
221                                                 String xmlAttributesString = "XML categorys=";
222                                                 for (AttributeCategory ac : xmlAttributes) {
223                                                         xmlAttributesString += " " + ac.getCategory().stringValue();
224                                                 }
225                                                 String jsonAttributesString = "JSON categorys=";
226                                                 for (AttributeCategory ac : jsonAttributes) {
227                                                         jsonAttributesString += " " + ac.getCategory().stringValue();
228                                                 }
229                                                 fail(f.getName() + " XML and JSON have different number of Category elements: " + xmlAttributesString + ", " + jsonAttributesString);
230                                         }
231                                         
232                                         // Attribute collections are the same size but may be in different orders.
233                                         // for each XML category try to find the corresponding JSON category.
234                                         // ASSUME that each category only shows up once!!!!
235                                         for (AttributeCategory xmlAttributeCategory : xmlAttributes) {
236                                                 boolean attributeCategoryFound = false;
237                                                 for (AttributeCategory jsonAttributeCategory : jsonAttributes) {
238                                                         if (xmlAttributeCategory.equals(jsonAttributeCategory)) {
239                                                                 attributeCategoryFound = true;
240                                                                 break;
241                                                         }
242                                                         // not an exact match, but if same CategoryId then need to check individual Attribute objects
243                                                         if (xmlAttributeCategory.getCategory().equals(jsonAttributeCategory.getCategory())) {
244                                                                 // same category
245                                                                 if (xmlAttributeCategory.getAttributes().size() != jsonAttributeCategory.getAttributes().size()) {
246                                                                         System.out.println("XML =" + xmlAttributeCategory.getAttributes());
247                                                                         System.out.println("JSON=" + jsonAttributeCategory.getAttributes());
248                                                                         fail(f.getName() + " Attributes Category '" + xmlAttributeCategory.getCategory().stringValue() + "' size mismatch; XML="+
249                                                                                         xmlAttributeCategory.getAttributes().size() +", JSON=" + jsonAttributeCategory.getAttributes().size());
250                                                                 }
251                                                                 for (Attribute xmlAttr : xmlAttributeCategory.getAttributes()) {
252                                                                         boolean attributeFound = false;
253                                                                         for (Attribute jsonAttr : jsonAttributeCategory.getAttributes()) {
254                                                                                 if (xmlAttr.equals(jsonAttr)) {
255                                                                                         attributeFound = true;
256                                                                                         break;
257                                                                                 }
258                                                                         }
259
260                                                                         if (attributeFound) {
261                                                                                 // check next XML attribute
262                                                                                 continue;
263                                                                         }
264                                                                         System.out.println("Attribute not found in JSON, Category="+xmlAttributeCategory.getCategory());
265                                                                         System.out.println("XML Attribute ="+ xmlAttr);
266                                                                         System.out.println("JSON Attributes=" + jsonAttributeCategory.toString());
267                                                                         fail(f.getName() + " Attribute not found in JSON, Category=" + xmlAttributeCategory.getCategory() +
268                                                                                         "/nXML Attribute="+xmlAttr+
269                                                                                         "\nJSON Category Attributes="+jsonAttributeCategory.toString());
270                                                                 }
271                                                                 
272
273
274                                                         }
275                                                 }
276                                                 if (attributeCategoryFound) {
277                                                         continue;
278                                                 }
279                                                 fail("XML Category not found in JSON; xml="+xmlAttributeCategory.toString());
280                                         }
281                                         
282                                 }
283                                 
284                                 // PolicyIdentifiers
285                                 if (xmlResult.getPolicyIdentifiers() != jsonResult.getPolicyIdentifiers()) {
286                                         Collection<IdReference> xmlIdReferences = xmlResult.getPolicyIdentifiers();
287                                         Collection<IdReference> jsonIdReferences = jsonResult.getPolicyIdentifiers();
288                                         // if both are null we do not get here
289                                         if (xmlIdReferences == null || jsonIdReferences == null) {
290                                                 fail(f.getName() + " PolicyIdentifiers has null \nXML="+xmlIdReferences + "\nJSON="+jsonIdReferences);
291                                         }
292                                         if (ListUtil.equalsAllowNulls(xmlIdReferences, jsonIdReferences) == false) {
293                                                 // collections are not equal, so need to examine further
294 fail(f.getName() + " PolicyIdentifiers collections not equal\nXML="+xmlIdReferences+ "\nJSON="+jsonIdReferences);
295                                         }
296                                 }
297                                 
298                                 // PolicySetIdentifiers
299                                 if (xmlResult.getPolicySetIdentifiers() != jsonResult.getPolicySetIdentifiers()) {
300                                         Collection<IdReference> xmlIdReferences = xmlResult.getPolicySetIdentifiers();
301                                         Collection<IdReference> jsonIdReferences = jsonResult.getPolicySetIdentifiers();
302                                         // if both are null we do not get here
303                                         if (xmlIdReferences == null || jsonIdReferences == null) {
304                                                 fail(f.getName() + " PolicySetIdentifiers has null \nXML="+xmlIdReferences + "\nJSON="+jsonIdReferences);
305                                         }
306                                         if (ListUtil.equalsAllowNulls(xmlIdReferences, jsonIdReferences) == false) {
307                                                 // collections are not equal, so need to examine further
308 fail(f.getName() + " PolicySetIdentifiers collections not equal\nXML="+xmlIdReferences + "\nJSON="+jsonIdReferences);
309                                         }
310                                 }
311                                                                 
312
313                         }                       
314
315                 } catch (Exception e) {
316                         fail ("Failed test with '" + currentFile.getName() + "', e=" + e);
317                 }
318
319                 
320         }
321         
322         //
323         // HELPER to get list of all Request files in the given directory
324         //
325         
326         private List<File> getRequestsInDirectory(File directory) {
327                 List<File> fileList = new ArrayList<File>();
328                 
329                 File[] fileArray = directory.listFiles();
330                 for (File f : fileArray) {
331                         if (f.isDirectory()) {
332                                 List<File> subDirList = getRequestsInDirectory(f);
333                                 fileList.addAll(subDirList);
334                         }
335                         if (f.getName().endsWith("Response.xml")) {
336                                 fileList.add(f);
337                         }
338                 }
339                 return fileList;
340                 
341         }
342         
343 }
344
345
346
347
348
349 /*
350  * 
351 This is a place to copy the really long output from test rigs that need to be manually edited for readability....
352
353
354
355 {"Response":[{"Status":{"StatusCode":{"Value":"urn:oasis:names:tc:xacml:1.0:status:ok"}},"Obligations":[{"Id":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:obligation-1","AttributeAssignment":[
356 {"Value":"assignment1","DataType":"string","AttributeId":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:assignment1"},
357 {"Value":{"Namespaces":[{"Namespace":"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"},{"Namespace":"http://www.w3.org/2001/XMLSchema-instance","Prefix":"xsi"}],
358                 "XPathCategory":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource",
359                 "XPath":"//md:records/md:record"},
360         "DataType":"xpathExpression",
361         "AttributeId":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:assignment2"}]}],"Decision":"Permit"}]}
362
363
364
365 */
366
367
368
369
370