Add junit coverage to xacml-pdp
[policy/xacml-pdp.git] / applications / common / src / test / java / org / onap / policy / pdp / xacml / application / common / operationshistory / CountRecentOperationsPipTest.java
index 10b9d89..b01fa70 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * 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.
 package org.onap.policy.pdp.xacml.application.common.operationshistory;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+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.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.pip.StdPIPResponse;
 import java.io.FileInputStream;
-import java.lang.reflect.Method;
+import java.io.IOException;
 import java.sql.Date;
 import java.time.Instant;
-
+import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.Properties;
+import java.util.Queue;
 import java.util.UUID;
-
 import javax.persistence.EntityManager;
 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.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class CountRecentOperationsPipTest {
     private static final Logger LOGGER = LoggerFactory.getLogger(CountRecentOperationsPipTest.class);
-    private static CountRecentOperationsPip pipEngine;
+
+    private static final String ACTOR = "my-actor";
+    private static final String RECIPE = "my-recipe";
+    private static final String TARGET = "my-target";
+    private static final String TEST_PROPERTIES = "src/test/resources/test.properties";
 
     private static EntityManager em;
 
+    @Mock
+    private PIPRequest pipRequest;
+
+    @Mock
+    private PIPFinder pipFinder;
+
+    @Mock
+    private PIPResponse resp1;
+
+    @Mock
+    private PIPResponse resp2;
+
+    @Mock
+    private PIPResponse resp3;
+
+    @Mock
+    private Status okStatus;
+
+    private Properties properties;
+    private Queue<PIPResponse> responses;
+    private Queue<String> attributes;
+
+    private CountRecentOperationsPip pipEngine;
+
     /**
-     * Create an instance of our engine and also the persistence
-     * factory.
+     * Establishes a connection to the DB and keeps it open until all tests have
+     * completed.
      *
-     * @throws Exception connectivity issues
+     * @throws IOException if properties cannot be loaded
      */
     @BeforeClass
-    public static void setup() throws Exception {
-        LOGGER.info("Setting up PIP Testing");
-        //
-        // Create instance
-        //
-        pipEngine = new CountRecentOperationsPip();
+    public static void setUpBeforeClass() throws IOException {
         //
         // Load our test properties to use
         //
-        Properties properties = new Properties();
-        try (FileInputStream is = new FileInputStream("src/test/resources/test.properties")) {
-            properties.load(is);
+        Properties props2 = new Properties();
+        try (FileInputStream is = new FileInputStream(TEST_PROPERTIES)) {
+            props2.load(is);
         }
         //
-        // Configure it using properties
-        //
-        pipEngine.configure("issuer", properties);
-        LOGGER.info("PIP configured now creating our entity manager");
-        LOGGER.info("properties {}", properties);
-        //
         // Connect to in-mem db
         //
         String persistenceUnit = CountRecentOperationsPip.ISSUER_NAME + ".persistenceunit";
         LOGGER.info("persistenceunit {}", persistenceUnit);
-        em = Persistence.createEntityManagerFactory(properties.getProperty(persistenceUnit), properties)
-                .createEntityManager();
+        em = Persistence.createEntityManagerFactory(props2.getProperty(persistenceUnit), props2).createEntityManager();
         //
         //
         //
         LOGGER.info("Configured own entity manager", em.toString());
     }
 
+    /**
+     * Create an instance of our engine.
+     *
+     * @throws Exception if an error occurs
+     */
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(pipRequest.getIssuer()).thenReturn("urn:org:onap:xacml:guard:tw:1:hour");
+
+        pipEngine = new MyPip();
+
+        properties = new Properties();
+        try (FileInputStream is = new FileInputStream(TEST_PROPERTIES)) {
+            properties.load(is);
+        }
+
+        when(pipFinder.getMatchingAttributes(any(), eq(pipEngine))).thenReturn(resp1, resp2, resp3);
+
+        responses = new LinkedList<>(Arrays.asList(resp1, resp2, resp3));
+        attributes = new LinkedList<>(Arrays.asList(ACTOR, RECIPE, TARGET));
+
+        when(resp1.getStatus()).thenReturn(okStatus);
+        when(resp2.getStatus()).thenReturn(okStatus);
+        when(resp3.getStatus()).thenReturn(okStatus);
+
+        when(okStatus.isOk()).thenReturn(true);
+    }
+
     private Dbao createEntry(String cl, String target, String outcome) {
         //
         // Create entry
@@ -99,31 +159,63 @@ public class CountRecentOperationsPipTest {
         return newEntry;
     }
 
+    @Test
+    public void testAttributesRequired() {
+        assertEquals(3, pipEngine.attributesRequired().size());
+    }
+
+    @Test
+    public void testConfigure_DbException() throws Exception {
+        properties.put("javax.persistence.jdbc.url", "invalid");
+        pipEngine.configure("issuer", properties);
+    }
+
+    @Test
+    public void testGetAttributes_NullIssuer() throws PIPException {
+        when(pipRequest.getIssuer()).thenReturn(null);
+        assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(pipRequest, pipFinder));
+    }
+
+    @Test
+    public void testGetAttributes_WrongIssuer() throws PIPException {
+        when(pipRequest.getIssuer()).thenReturn("wrong-issuer");
+        assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(pipRequest, pipFinder));
+    }
+
+    @Test
+    public void testGetAttributes_NullActor() throws PIPException {
+        attributes = new LinkedList<>(Arrays.asList(null, RECIPE, TARGET));
+        assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(pipRequest, pipFinder));
+    }
+
+    @Test
+    public void testGetAttributes_NullRecipe() throws PIPException {
+        attributes = new LinkedList<>(Arrays.asList(ACTOR, null, TARGET));
+        assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(pipRequest, pipFinder));
+    }
+
+    @Test
+    public void testGetAttributes_NullTarget() throws PIPException {
+        attributes = new LinkedList<>(Arrays.asList(ACTOR, RECIPE, null));
+        assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(pipRequest, pipFinder));
+    }
+
     @Test
     public void testGetCountFromDb() throws Exception {
         //
-        // Use reflection to run getCountFromDB
+        // Configure it using properties
         //
-        Method method = CountRecentOperationsPip.class.getDeclaredMethod("doDatabaseQuery",
-                                                                            String.class,
-                                                                            String.class,
-                                                                            String.class,
-                                                                            int.class,
-                                                                            String.class);
-        method.setAccessible(true);
+        pipEngine.configure("issuer", properties);
+        LOGGER.info("PIP configured now creating our entity manager");
+        LOGGER.info("properties {}", properties);
         //
         // create entry
         //
         Dbao newEntry = createEntry("cl-foobar-1", "vnf-1", "SUCCESS");
         //
-        // Test pipEngine
-        //
-        long count = (long) method.invoke(pipEngine, newEntry.getActor(), newEntry.getOperation(), newEntry.getTarget(),
-                1, "HOUR");
-        //
         // No entries yet
         //
-        assertEquals(0, count);
+        assertEquals(0, getCount(newEntry));
         //
         // Add entry
         //
@@ -133,18 +225,53 @@ public class CountRecentOperationsPipTest {
         //
         // Directly check ground truth
         //
-        Query queryCount = em.createNativeQuery("select count(*) as numops from operationshistory")
-                .setParameter(1, 1);
+        Query queryCount = em.createNativeQuery("select count(*) as numops from operationshistory").setParameter(1, 1);
         LOGGER.info("{} entries", queryCount.getSingleResult());
         //
-        // Test pipEngine
-        //
-        count = (long) method.invoke(pipEngine, newEntry.getActor(), newEntry.getOperation(), newEntry.getTarget(),
-                1, "HOUR");
-        //
         // Should count 1 entry now
         //
-        assertEquals(1, count);
+        assertEquals(1, getCount(newEntry));
+    }
+
+    private long getCount(Dbao newEntry) throws PIPException {
+        responses = new LinkedList<>(Arrays.asList(resp1, resp2, resp3));
+        attributes = new LinkedList<>(
+                        Arrays.asList(newEntry.getActor(), newEntry.getOperation(), newEntry.getTarget()));
+
+        PIPResponse result = pipEngine.getAttributes(pipRequest, pipFinder);
+
+        Attribute attr = result.getAttributes().iterator().next();
+        AttributeValue<?> value = attr.getValues().iterator().next();
+
+        return ((Number) value.getValue()).longValue();
+    }
+
+    @Test
+    public void testStringToChronoUnit() throws PIPException {
+        // not configured yet
+        Dbao newEntry = createEntry("cl-foobar-1", "vnf-1", "SUCCESS");
+        assertEquals(-1, getCount(newEntry));
+
+        // now configure it
+        pipEngine.configure("issuer", properties);
+
+        String[] units = {"second", "minute", "hour", "day", "week", "month", "year"};
+
+        for (String unit : units) {
+            when(pipRequest.getIssuer()).thenReturn("urn:org:onap:xacml:guard:tw:1:" + unit);
+
+            /*
+             * It would be better to use assertEquals below, but the test DB doesn't
+             * support week, month, or year.
+             */
+
+            // should run without throwing an exception
+            getCount(newEntry);
+        }
+
+        // invalid time unit
+        when(pipRequest.getIssuer()).thenReturn("urn:org:onap:xacml:guard:tw:1:invalid");
+        assertEquals(-1, getCount(newEntry));
     }
 
     /**
@@ -157,4 +284,16 @@ public class CountRecentOperationsPipTest {
         }
     }
 
+    private class MyPip extends CountRecentOperationsPip {
+
+        @Override
+        protected PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
+            return responses.remove();
+        }
+
+        @Override
+        protected String findFirstAttributeValue(PIPResponse pipResponse) {
+            return attributes.remove();
+        }
+    }
 }