2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.policy.xacml.test.json;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.fail;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.List;
31 import org.junit.Test;
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;
44 * Test JSON Response convert to object - Conformance tests
47 * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
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.
55 public class ResponseConformanceTest {
57 // where to find the conformance test XML files
58 private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4";
60 // The request object output from each test conversion from JSON string
67 // test just one of each top-level element.
68 // For simple elements also test for incorrect type
70 public void testConformanceResponses() {
72 List<File> filesInDirectory = null;
74 File conformanceDirectory = null;
76 File currentFile = null;
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);
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;
93 for (File f : filesInDirectory) {
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; }
99 // during debugging it is helpful to know what file it is starting to work on
100 // System.out.println("starting file="+currentFile.getName());
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);
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);
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);
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));
125 jsonResponse = JSONResponse.load(jsonResponseString);
129 //System.out.println(JSONResponse.toString(xmlResponse, true));
134 // compare the two Response objects
137 assertEquals(xmlResponse.getResults().size(), jsonResponse.getResults().size());
139 if (xmlResponse.getResults().size() == 0) {
140 fail("neither XML nor JSON response have any Results");
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)) {
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());
166 fail("JSON Response has no match for XML Result: " + xmlResult.toString());
168 // we've done the best we can for multiple decisions, so go to next file
172 // single Result in each
173 Result xmlResult = xmlResponse.getResults().iterator().next();
174 Result jsonResult = jsonResponse.getResults().iterator().next();
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());
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);
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);
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);
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);
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);
218 if (xmlAttributes != null) {
220 if (xmlAttributes.size() != jsonAttributes.size()) {
221 String xmlAttributesString = "XML categorys=";
222 for (AttributeCategory ac : xmlAttributes) {
223 xmlAttributesString += " " + ac.getCategory().stringValue();
225 String jsonAttributesString = "JSON categorys=";
226 for (AttributeCategory ac : jsonAttributes) {
227 jsonAttributesString += " " + ac.getCategory().stringValue();
229 fail(f.getName() + " XML and JSON have different number of Category elements: " + xmlAttributesString + ", " + jsonAttributesString);
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;
242 // not an exact match, but if same CategoryId then need to check individual Attribute objects
243 if (xmlAttributeCategory.getCategory().equals(jsonAttributeCategory.getCategory())) {
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());
251 for (Attribute xmlAttr : xmlAttributeCategory.getAttributes()) {
252 boolean attributeFound = false;
253 for (Attribute jsonAttr : jsonAttributeCategory.getAttributes()) {
254 if (xmlAttr.equals(jsonAttr)) {
255 attributeFound = true;
260 if (attributeFound) {
261 // check next XML attribute
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());
276 if (attributeCategoryFound) {
279 fail("XML Category not found in JSON; xml="+xmlAttributeCategory.toString());
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);
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);
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);
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);
315 } catch (Exception e) {
316 fail ("Failed test with '" + currentFile.getName() + "', e=" + e);
323 // HELPER to get list of all Request files in the given directory
326 private List<File> getRequestsInDirectory(File directory) {
327 List<File> fileList = new ArrayList<File>();
329 File[] fileArray = directory.listFiles();
330 for (File f : fileArray) {
331 if (f.isDirectory()) {
332 List<File> subDirList = getRequestsInDirectory(f);
333 fileList.addAll(subDirList);
335 if (f.getName().endsWith("Response.xml")) {
351 This is a place to copy the really long output from test rigs that need to be manually edited for readability....
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"}]}