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