diff options
author | Jim Hahn <jrh3@att.com> | 2019-06-26 11:00:18 -0400 |
---|---|---|
committer | Jim Hahn <jrh3@att.com> | 2019-06-26 18:59:18 -0400 |
commit | d8118c6638bb2440f89eae9d3f979bdfb0e013c3 (patch) | |
tree | 6f4122198b21438a9d41a47910381df17ef92d36 /controlloop/common/database/src/test/java | |
parent | d2ec3b974f116d87c6bd84dee13ea7fc2739f54e (diff) |
Fix sonar issues in drools-applications database
Refactored to eliminate duplicate code blocks.
Added coverage tests.
Change-Id: I99d2b6f68fee38a1dbbf038ad29d1dfe87fb4ae7
Issue-ID: POLICY-1791
Signed-off-by: Jim Hahn <jrh3@att.com>
Diffstat (limited to 'controlloop/common/database/src/test/java')
4 files changed, 664 insertions, 79 deletions
diff --git a/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/CountRecentOperationsPipTest.java b/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/CountRecentOperationsPipTest.java index e3cb17fd5..66b412028 100644 --- a/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/CountRecentOperationsPipTest.java +++ b/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/CountRecentOperationsPipTest.java @@ -19,31 +19,54 @@ package org.onap.policy.database.operationshistory; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.std.pip.StdPIPResponse; import java.io.FileInputStream; -import java.lang.reflect.Method; import java.sql.Date; import java.time.Instant; - +import java.util.Collection; import java.util.Properties; import java.util.UUID; - import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; - import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.onap.policy.database.ToscaDictionary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CountRecentOperationsPipTest { + private static final String ID = "issuer"; private static final Logger LOGGER = LoggerFactory.getLogger(CountRecentOperationsPipTest.class); - private static CountRecentOperationsPip pipEngine; + private static final String ISSUER = ToscaDictionary.GUARD_ISSUER_PREFIX + "-my-issuer:tw:1:HOUR"; + private static final String ACTOR = "Controller"; + private static final String RECIPE = "operationA"; + private static final String TARGET = "vnf-1"; + private static final String EXPECTED_EXCEPTION = "expected exception"; + + private static MyPip pipEngine; + private static Properties properties; + private static EntityManagerFactory emf; private static EntityManager em; + private PIPRequest req; + /** * Create an instance of our engine and also the persistence * factory. @@ -51,23 +74,23 @@ public class CountRecentOperationsPipTest { * @throws Exception connectivity issues */ @BeforeClass - public static void setup() throws Exception { + public static void setUpBeforeClass() throws Exception { LOGGER.info("Setting up PIP Testing"); // // Create instance // - pipEngine = new CountRecentOperationsPip(); + pipEngine = new MyPip(); // // Load our test properties to use // - Properties properties = new Properties(); + properties = new Properties(); try (FileInputStream is = new FileInputStream("src/test/resources/test.properties")) { properties.load(is); } // // Configure it using properties // - pipEngine.configure("issuer", properties); + pipEngine.configure(ID, properties); LOGGER.info("PIP configured now creating our entity manager"); LOGGER.info("properties {}", properties); // @@ -75,12 +98,18 @@ public class CountRecentOperationsPipTest { // String persistenceUnit = CountRecentOperationsPip.ISSUER_NAME + ".persistenceunit"; LOGGER.info("persistenceunit {}", persistenceUnit); - em = Persistence.createEntityManagerFactory(properties.getProperty(persistenceUnit), properties) - .createEntityManager(); + emf = Persistence.createEntityManagerFactory(properties.getProperty(persistenceUnit), properties); + em = emf.createEntityManager(); // // // - LOGGER.info("Configured own entity manager", em.toString()); + LOGGER.info("Configured own entity manager"); + } + + @Before + public void setUp() { + req = mock(PIPRequest.class); + when(req.getIssuer()).thenReturn(ISSUER); } private Dbao createEntry(String cl, String target, String outcome) { @@ -91,8 +120,8 @@ public class CountRecentOperationsPipTest { newEntry.setClosedLoopName(cl); newEntry.setTarget(target); newEntry.setOutcome(outcome); - newEntry.setActor("Controller"); - newEntry.setOperation("operationA"); + newEntry.setActor(ACTOR); + newEntry.setOperation(RECIPE); newEntry.setStarttime(Date.from(Instant.now().minusMillis(20000))); newEntry.setEndtime(Date.from(Instant.now())); newEntry.setRequestId(UUID.randomUUID().toString()); @@ -100,35 +129,64 @@ public class CountRecentOperationsPipTest { } @Test - public void testGetCountFromDb() throws Exception { - // - // Use reflection to run getCountFromDB - // - Method method = CountRecentOperationsPip.class.getDeclaredMethod("doDatabaseQuery", - String.class, - String.class, - String.class, - int.class, - String.class); - method.setAccessible(true); - // - // create entry - // - Dbao newEntry = createEntry("cl-foobar-1", "vnf-1", "SUCCESS"); - // - // Test pipEngine - // - int count = (int) method.invoke(pipEngine, newEntry.getActor(), newEntry.getOperation(), newEntry.getTarget(), - 1, "HOUR"); + public void testAttributesRequired() { + assertEquals(3, pipEngine.attributesRequired().size()); + } + + @Test + public void testGetAttributes_InvalidRequestInfo() throws PIPException { + // invalid request - null issuer + when(req.getIssuer()).thenReturn(null); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(req, null)); + + /* + * Make a valid issuer in the request, for subsequent tests. + */ + when(req.getIssuer()).thenReturn(ISSUER); + + // null actor + MyPip pip = new MyPip() { + @Override + protected String getActor(PIPFinder pipFinder) { + return null; + } + }; + pip.configure(ID, properties); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pip.getAttributes(req, null)); + + // null recipe + pip = new MyPip() { + @Override + protected String getRecipe(PIPFinder pipFinder) { + return null; + } + }; + pip.configure(ID, properties); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pip.getAttributes(req, null)); + + // null target + pip = new MyPip() { + @Override + protected String getTarget(PIPFinder pipFinder) { + return null; + } + }; + pip.configure(ID, properties); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pip.getAttributes(req, null)); + } + + @Test + public void testDoDatabaseQuery() throws Exception { + // // No entries yet // - assertEquals(0, count); + assertEquals(0, getCount(pipEngine.getAttributes(req, null))); // // Add entry // em.getTransaction().begin(); - em.persist(newEntry); + em.persist(createEntry("cl-foobar-1", TARGET, "SUCCESS")); em.getTransaction().commit(); // // Directly check ground truth @@ -137,14 +195,67 @@ public class CountRecentOperationsPipTest { .setParameter(1, 1); LOGGER.info("{} entries", queryCount.getSingleResult()); // - // Test pipEngine - // - count = (int) method.invoke(pipEngine, newEntry.getActor(), newEntry.getOperation(), newEntry.getTarget(), - 1, "HOUR"); - // // Should count 1 entry now // - assertEquals(1, count); + assertEquals(1, getCount(pipEngine.getAttributes(req, null))); + } + + @Test + public void testDoDatabaseQuery_InvalidTimeWindow() throws Exception { + when(req.getIssuer()).thenReturn(ISSUER + "invalid time window"); + + assertEquals(-1, getCount(pipEngine.getAttributes(req, null))); + } + + @Test + public void testDoDatabaseQuery_NullEm() throws Exception { + assertEquals(-1, getCount(new MyPip().getAttributes(req, null))); + } + + @Test + public void testDoDatabaseQuery_EmException() throws Exception { + MyPip pip = new MyPip() { + @Override + public void configure(String id, Properties properties) throws PIPException { + em = mock(EntityManager.class); + when(em.createNativeQuery(any())).thenThrow(new RuntimeException(EXPECTED_EXCEPTION)); + } + }; + pip.configure(ID, properties); + + assertEquals(-1, getCount(pip.getAttributes(req, null))); + } + + @Test + public void testDoDatabaseQuery_NonNumeric() throws Exception { + MyPip pip = new MyPip() { + @Override + public void configure(String id, Properties properties) throws PIPException { + em = mock(EntityManager.class); + Query query = mock(Query.class); + when(em.createNativeQuery(any())).thenReturn(query); + when(query.setParameter(anyInt(), any())).thenReturn(query); + when(query.getSingleResult()).thenReturn("200"); + } + }; + pip.configure(ID, properties); + + assertEquals(200, getCount(pip.getAttributes(req, null))); + } + + private int getCount(PIPResponse resp) { + Collection<Attribute> attrs = resp.getAttributes(); + assertEquals(1, attrs.size()); + + Attribute attr = attrs.iterator().next(); + assertEquals(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, attr.getCategory()); + assertEquals(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT, attr.getAttributeId()); + + Collection<AttributeValue<?>> values = attr.getValues(); + assertEquals(1, values.size()); + + AttributeValue<?> value = values.iterator().next(); + return ((Number) value.getValue()).intValue(); } /** @@ -152,9 +263,26 @@ public class CountRecentOperationsPipTest { */ @AfterClass public static void cleanup() { - if (em != null) { - em.close(); + if (emf != null) { + emf.close(); } } + private static class MyPip extends CountRecentOperationsPip { + + @Override + protected String getActor(PIPFinder pipFinder) { + return ACTOR; + } + + @Override + protected String getRecipe(PIPFinder pipFinder) { + return RECIPE; + } + + @Override + protected String getTarget(PIPFinder pipFinder) { + return TARGET; + } + } } diff --git a/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/GetOperationOutcomePipTest.java b/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/GetOperationOutcomePipTest.java index 7e7258c5f..5ab850722 100644 --- a/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/GetOperationOutcomePipTest.java +++ b/controlloop/common/database/src/test/java/org/onap/policy/database/operationshistory/GetOperationOutcomePipTest.java @@ -19,27 +19,57 @@ package org.onap.policy.database.operationshistory; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.std.pip.StdPIPResponse; import java.io.FileInputStream; -import java.lang.reflect.Method; import java.sql.Date; import java.time.Instant; +import java.util.Collection; import java.util.Properties; import java.util.UUID; import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.NoResultException; import javax.persistence.Persistence; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.onap.policy.database.ToscaDictionary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GetOperationOutcomePipTest { + private static final String ID = "issuer"; + private static final String TEST_CL1 = "testcl1"; + private static final String TEST_TARGET1 = "testtarget1"; + private static final String TEST_TARGET2 = "testtarget2"; + private static final String ACTOR = "Controller"; + private static final String RECIPE = "operationA"; + private static final String EXPECTED_EXCEPTION = "expected exception"; + private static final String ISSUER_PREFIX = ToscaDictionary.GUARD_ISSUER_PREFIX + "-my-issuer:clname:"; + private static final String ISSUER = ISSUER_PREFIX + TEST_CL1; private static final Logger LOGGER = LoggerFactory.getLogger(GetOperationOutcomePipTest.class); - private static GetOperationOutcomePip pipEngine; + private static MyPip pipEngine; + private static Properties properties; + + private static EntityManagerFactory emf; private static EntityManager em; + private PIPRequest req; + /** * Create an instance of our engine and also the persistence * factory. @@ -47,23 +77,23 @@ public class GetOperationOutcomePipTest { * @throws Exception connectivity issues */ @BeforeClass - public static void setup() throws Exception { + public static void setUpBeforeClass() throws Exception { LOGGER.info("Setting up PIP Testing"); // // Create instance // - pipEngine = new GetOperationOutcomePip(); + pipEngine = new MyPip(TEST_TARGET1); // // Load our test properties to use // - Properties properties = new Properties(); + properties = new Properties(); try (FileInputStream is = new FileInputStream("src/test/resources/test.properties")) { properties.load(is); } // // Configure it using properties // - pipEngine.configure("issuer", properties); + pipEngine.configure(ID, properties); LOGGER.info("PIP configured now creating our entity manager"); LOGGER.info("properties {}", properties); // @@ -71,14 +101,20 @@ public class GetOperationOutcomePipTest { // String persistenceUnit = GetOperationOutcomePip.ISSUER_NAME + ".persistenceunit"; LOGGER.info("persistenceunit {}", persistenceUnit); - em = Persistence.createEntityManagerFactory(properties.getProperty(persistenceUnit), properties) - .createEntityManager(); + emf = Persistence.createEntityManagerFactory(properties.getProperty(persistenceUnit), properties); + em = emf.createEntityManager(); // // // LOGGER.info("Configured own entity manager", em.toString()); } + @Before + public void setUp() { + req = mock(PIPRequest.class); + when(req.getIssuer()).thenReturn(ISSUER); + } + private void insertEntry(String cl, String target, String outcome) { // // Create entry @@ -87,8 +123,8 @@ public class GetOperationOutcomePipTest { newEntry.setClosedLoopName(cl); newEntry.setTarget(target); newEntry.setOutcome(outcome); - newEntry.setActor("Controller"); - newEntry.setOperation("operationA"); + newEntry.setActor(ACTOR); + newEntry.setOperation(RECIPE); newEntry.setStarttime(Date.from(Instant.now().minusMillis(20000))); newEntry.setEndtime(Date.from(Instant.now())); newEntry.setRequestId(UUID.randomUUID().toString()); @@ -102,43 +138,104 @@ public class GetOperationOutcomePipTest { @Test - public void testGetOutcomeFromDb() throws Exception { - // - // Use reflection to run getCountFromDB - // - Method method = GetOperationOutcomePip.class.getDeclaredMethod("doDatabaseQuery", - String.class, - String.class); - method.setAccessible(true); + public void testAttributesRequired() { + assertEquals(1, pipEngine.attributesRequired().size()); + } + + @Test + public void testGetAttributes_InvalidRequestInfo() throws PIPException { + // invalid request - null issuer + when(req.getIssuer()).thenReturn(null); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(req, null)); + + /* + * Make a valid issuer in the request, for subsequent tests. + */ + when(req.getIssuer()).thenReturn(ISSUER); + + // null target + MyPip pip = new MyPip(null); + pip.configure(ID, properties); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pip.getAttributes(req, null)); + } + + @Test + public void testDoDatabaseQuery() throws Exception { // // Insert entry // - insertEntry("testcl1", "testtarget1", "1"); - // - // Test pipEngine - // - String outcome = (String) method.invoke(pipEngine, "testcl1", "testtarget1"); + insertEntry(TEST_CL1, TEST_TARGET1, "1"); // // outcome should be "1" // - assertEquals("1", outcome); + assertEquals("1", getOutcome(pipEngine.getAttributes(req, null))); // // Insert more entries // - insertEntry("testcl1", "testtarget1", "2"); - insertEntry("testcl2", "testtarget2", "3"); - insertEntry("testcl1", "testtarget2", "4"); + insertEntry(TEST_CL1, TEST_TARGET1, "2"); + insertEntry("testcl2", TEST_TARGET2, "3"); + insertEntry(TEST_CL1, TEST_TARGET2, "4"); // // Test pipEngine // - outcome = (String) method.invoke(pipEngine, "testcl1", "testtarget1"); - assertEquals("2", outcome); + assertEquals("2", getOutcome(TEST_CL1, TEST_TARGET1)); - outcome = (String) method.invoke(pipEngine, "testcl2", "testtarget2"); - assertEquals("3", outcome); + assertEquals("3", getOutcome("testcl2", TEST_TARGET2)); - outcome = (String) method.invoke(pipEngine, "testcl1", "testtarget2"); - assertEquals("4", outcome); + assertEquals("4", getOutcome(TEST_CL1, TEST_TARGET2)); + } + + @Test + public void testDoDatabaseQuery_NoResult() throws Exception { + MyPip pip = new MyPip(TEST_TARGET1) { + @Override + public void configure(String id, Properties properties) throws PIPException { + em = mock(EntityManager.class); + when(em.createQuery(anyString())).thenThrow(new NoResultException()); + } + }; + pip.configure(ID, properties); + + assertNull(getOutcome(pip.getAttributes(req, null))); + } + + @Test + public void testDoDatabaseQuery_EmException() throws Exception { + MyPip pip = new MyPip(TEST_TARGET1) { + @Override + public void configure(String id, Properties properties) throws PIPException { + em = mock(EntityManager.class); + when(em.createQuery(anyString())).thenThrow(new RuntimeException(EXPECTED_EXCEPTION)); + } + }; + pip.configure(ID, properties); + + assertEquals(null, getOutcome(pip.getAttributes(req, null))); + } + + private String getOutcome(String clname, String target) throws PIPException { + req = mock(PIPRequest.class); + when(req.getIssuer()).thenReturn(ISSUER_PREFIX + clname); + + MyPip pip = new MyPip(target); + pip.configure(ID, properties); + + return getOutcome(pip.getAttributes(req, null)); + } + + private String getOutcome(PIPResponse resp) { + Collection<Attribute> attrs = resp.getAttributes(); + assertEquals(1, attrs.size()); + + Attribute attr = attrs.iterator().next(); + assertEquals(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, attr.getCategory()); + assertEquals(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONOUTCOME, attr.getAttributeId()); + + Collection<AttributeValue<?>> values = attr.getValues(); + assertEquals(1, values.size()); + + AttributeValue<?> value = values.iterator().next(); + return (String) value.getValue(); } /** @@ -146,9 +243,31 @@ public class GetOperationOutcomePipTest { */ @AfterClass public static void cleanup() { - if (em != null) { - em.close(); + if (emf != null) { + emf.close(); } } + private static class MyPip extends GetOperationOutcomePip { + private String target; + + public MyPip(String target) { + this.target = target; + } + + @Override + protected String getActor(PIPFinder pipFinder) { + return ACTOR; + } + + @Override + protected String getRecipe(PIPFinder pipFinder) { + return RECIPE; + } + + @Override + protected String getTarget(PIPFinder pipFinder) { + return target; + } + } } diff --git a/controlloop/common/database/src/test/java/org/onap/policy/database/std/DbaoTest.java b/controlloop/common/database/src/test/java/org/onap/policy/database/std/DbaoTest.java new file mode 100644 index 000000000..43c6157cf --- /dev/null +++ b/controlloop/common/database/src/test/java/org/onap/policy/database/std/DbaoTest.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.database.std; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Date; +import org.junit.Test; +import org.onap.policy.database.operationshistory.Dbao; + +public class DbaoTest { + + @Test + public void test() { + Dbao dao = new Dbao(); + + dao.setActor("my-actor"); + dao.setClosedLoopName("cl-name"); + Date endDate = new Date(); + dao.setEndtime(endDate); + dao.setId(100L); + dao.setMessage("my-message"); + dao.setOperation("my-operation"); + dao.setOutcome("my-outcome"); + dao.setRequestId("my-request"); + Date startDate = new Date(endDate.getTime() - 1); + dao.setStarttime(startDate); + dao.setSubrequestId("my-sub"); + dao.setTarget("my-target"); + + assertEquals("my-actor", dao.getActor()); + assertEquals("cl-name", dao.getClosedLoopName()); + assertEquals(endDate, dao.getEndtime()); + assertEquals(100L, dao.getId().longValue()); + assertEquals("my-message", dao.getMessage()); + assertEquals("my-operation", dao.getOperation()); + assertEquals("my-outcome", dao.getOutcome()); + assertEquals("my-request", dao.getRequestId()); + assertEquals(startDate, dao.getStarttime()); + assertEquals("my-sub", dao.getSubrequestId()); + assertEquals("my-target", dao.getTarget()); + + assertTrue(dao.toString().startsWith("Dbao")); + + int hc = dao.hashCode(); + dao.setId(101L); + assertTrue(hc != dao.hashCode()); + + assertTrue(dao.equals(dao)); + assertFalse(dao.equals(new Dbao())); + } +} diff --git a/controlloop/common/database/src/test/java/org/onap/policy/database/std/StdOnapPipTest.java b/controlloop/common/database/src/test/java/org/onap/policy/database/std/StdOnapPipTest.java new file mode 100644 index 000000000..de186c41d --- /dev/null +++ b/controlloop/common/database/src/test/java/org/onap/policy/database/std/StdOnapPipTest.java @@ -0,0 +1,268 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.database.std; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.std.datatypes.DataTypes; +import com.att.research.xacml.std.pip.StdMutablePIPResponse; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.database.ToscaDictionary; + +public class StdOnapPipTest { + private static final String EXPECTED_EXCEPTION = "expected exception"; + private static final String A_VALUE = "a-value"; + private static final String ISSUER = ToscaDictionary.GUARD_ISSUER_PREFIX + "-my-issuer"; + + private MyPip pip; + private PIPRequest req; + private PIPFinder finder; + private StdMutablePIPResponse resp; + + /** + * Initializes mocks and populates {@link #pip}. + */ + @Before + public void setUp() { + req = mock(PIPRequest.class); + finder = mock(PIPFinder.class); + resp = new StdMutablePIPResponse(); + + when(req.getIssuer()).thenReturn(ISSUER); + + pip = new MyPip(); + } + + @Test + public void testAttributesProvided() { + assertTrue(pip.attributesProvided().isEmpty()); + } + + @Test + public void testIsRequestInvalid() { + // valid issuer + when(req.getIssuer()).thenReturn(ISSUER); + assertFalse(pip.isRequestInvalid(req)); + + // invalid issuer + when(req.getIssuer()).thenReturn("bogus-issuer"); + assertTrue(pip.isRequestInvalid(req)); + + // null issuer + when(req.getIssuer()).thenReturn(null); + assertTrue(pip.isRequestInvalid(req)); + } + + @Test + public void testGetActor() { + testGetArbitraryAttribute(StdOnapPip.PIP_REQUEST_ACTOR, pip2 -> pip2.getActor(finder)); + } + + @Test + public void testGetRecipe() { + testGetArbitraryAttribute(StdOnapPip.PIP_REQUEST_RECIPE, pip2 -> pip2.getRecipe(finder)); + } + + @Test + public void testGetTarget() { + testGetArbitraryAttribute(StdOnapPip.PIP_REQUEST_TARGET, pip2 -> pip2.getTarget(finder)); + } + + private void testGetArbitraryAttribute(PIPRequest request, Function<StdOnapPip, String> getter) { + // target found + pip = new MyPip() { + @Override + protected PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) { + return resp; + } + + @Override + protected String findFirstAttributeValue(PIPResponse pipResponse) { + return A_VALUE; + } + }; + + pip = spy(pip); + + assertEquals(A_VALUE, getter.apply(pip)); + verify(pip).getAttribute(request, finder); + verify(pip).findFirstAttributeValue(resp); + + + // not found + pip = new MyPip() { + @Override + protected PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) { + return null; + } + + @Override + protected String findFirstAttributeValue(PIPResponse pipResponse) { + return A_VALUE; + } + }; + + pip = spy(pip); + + assertNull(getter.apply(pip)); + verify(pip).getAttribute(request, finder); + verify(pip, never()).findFirstAttributeValue(resp); + } + + @Test + public void testGetAttribute() throws PIPException { + when(finder.getMatchingAttributes(req, pip)).thenReturn(resp); + + Status status = mock(Status.class); + Identifier ident = mock(Identifier.class); + + when(ident.stringValue()).thenReturn("my-attr-id"); + when(req.getAttributeId()).thenReturn(ident); + + // status != OK + resp.setStatus(status); + when(status.isOk()).thenReturn(false); + assertNull(pip.getAttribute(req, finder)); + + // status OK, empty attributes + resp.setStatus(status); + when(status.isOk()).thenReturn(true); + assertNull(pip.getAttribute(req, finder)); + + // status OK, has attributes + resp.setStatus(status); + when(status.isOk()).thenReturn(true); + resp.setAttributes(Arrays.asList(mock(Attribute.class))); + assertSame(resp, pip.getAttribute(req, finder)); + + // null status, has attributes + resp.setStatus(null); + resp.setAttributes(Arrays.asList(mock(Attribute.class))); + assertSame(resp, pip.getAttribute(req, finder)); + + // with exception + when(finder.getMatchingAttributes(req, pip)).thenThrow(new PIPException()); + assertNull(pip.getAttribute(req, finder)); + } + + @Test + public void testFindFirstAttributeValue() { + + // no attributes + resp.setAttributes(Collections.emptyList()); + assertNull(pip.findFirstAttributeValue(resp)); + + // attribute that returns null + Attribute attr = mock(Attribute.class); + resp.setAttributes(Arrays.asList(attr, attr)); + assertNull(pip.findFirstAttributeValue(resp)); + + // attribute that returns a list of null values + Attribute attr2 = mock(Attribute.class); + resp.setAttributes(Arrays.asList(attr, attr2)); + List<AttributeValue<String>> lst = Arrays.asList(makeAttr(null), makeAttr(null)); + when(attr.findValues(DataTypes.DT_STRING)).thenReturn(lst.iterator()); + assertNull(pip.findFirstAttributeValue(resp)); + + // non-null value in the middle of the list + lst = Arrays.asList(makeAttr(null), makeAttr(A_VALUE), makeAttr(null)); + when(attr.findValues(DataTypes.DT_STRING)).thenReturn(lst.iterator()); + assertEquals(A_VALUE, pip.findFirstAttributeValue(resp)); + } + + private AttributeValue<String> makeAttr(String value) { + @SuppressWarnings("unchecked") + AttributeValue<String> attrval = mock(AttributeValue.class); + + when(attrval.getValue()).thenReturn(value); + + return attrval; + } + + @Test + public void testAddIntegerAttribute() { + resp = spy(resp); + + Identifier cat = mock(Identifier.class); + Identifier attrid = mock(Identifier.class); + + pip.addIntegerAttribute(resp, cat, attrid, 100, req); + + verify(resp).addAttribute(any()); + + // try with exception + doThrow(new RuntimeException(EXPECTED_EXCEPTION)).when(resp).addAttribute(any()); + pip.addIntegerAttribute(resp, cat, attrid, 100, req); + } + + @Test + public void testAddStringAttribute() { + resp = spy(resp); + + Identifier cat = mock(Identifier.class); + Identifier attrid = mock(Identifier.class); + + pip.addStringAttribute(resp, cat, attrid, A_VALUE, req); + + verify(resp).addAttribute(any()); + + // try with exception + doThrow(new RuntimeException(EXPECTED_EXCEPTION)).when(resp).addAttribute(any()); + pip.addStringAttribute(resp, cat, attrid, A_VALUE, req); + } + + private class MyPip extends StdOnapPip { + + @Override + public Collection<PIPRequest> attributesRequired() { + return Collections.emptyList(); + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException { + return null; + } + + } +} |