Repository: incubator-ranger Updated Branches: refs/heads/master 96fd15e46 -> f721abec9
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f721abec/security-admin/src/test/java/org/apache/ranger/rest/TestRangerValidator.java ---------------------------------------------------------------------- diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestRangerValidator.java b/security-admin/src/test/java/org/apache/ranger/rest/TestRangerValidator.java new file mode 100644 index 0000000..d3ee6d6 --- /dev/null +++ b/security-admin/src/test/java/org/apache/ranger/rest/TestRangerValidator.java @@ -0,0 +1,333 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.ranger.rest; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerService; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef; +import org.apache.ranger.plugin.store.ServiceStore; +import org.apache.ranger.rest.RangerValidator.Action; +import org.junit.Before; +import org.junit.Test; + +public class TestRangerValidator { + + static class RangerValidatorForTest extends RangerValidator { + + public RangerValidatorForTest(ServiceStore store) { + super(store); + } + + boolean isValid(String behavior) { + boolean valid; + if (behavior.equals("valid")) { + valid = true; + } else { + valid = false; + } + return valid; + } + } + + @Before + public void before() { + _store = mock(ServiceStore.class); + _validator = new RangerValidatorForTest(_store); + } + + @Test + public void test_ctor_firewalling() { + try { + // service store can't be null during construction + new RangerValidatorForTest(null); + fail("Should have thrown exception!"); + } catch (IllegalArgumentException e) { + // expected exception + } + } + + @Test + public void test_validate() { + // default implementation should fail. This is abstract class. Sub-class must do something sensible with isValid + try { + _validator.validate(1L, Action.CREATE); + fail("Should have thrown exception!"); + } catch (Exception e) { + // ok expected exception + String message = e.getMessage(); + assertTrue(message.contains("internal error")); + } + } + + @Test + public void test_getServiceConfigParameters() { + // reasonable protection against null values + Set<String> parameters = _validator.getServiceConfigParameters(null); + assertNotNull(parameters); + assertTrue(parameters.isEmpty()); + + RangerService service = mock(RangerService.class); + when(service.getConfigs()).thenReturn(null); + parameters = _validator.getServiceConfigParameters(service); + assertNotNull(parameters); + assertTrue(parameters.isEmpty()); + + when(service.getConfigs()).thenReturn(new HashMap<String, String>()); + parameters = _validator.getServiceConfigParameters(service); + assertNotNull(parameters); + assertTrue(parameters.isEmpty()); + + String[] keys = new String[] { "a", "b", "c" }; + Map<String, String> map = _utils.createMap(keys); + when(service.getConfigs()).thenReturn(map); + parameters = _validator.getServiceConfigParameters(service); + for (String key: keys) { + assertTrue("key", parameters.contains(key)); + } + } + + @Test + public void test_getRequiredParameters() { + // reasonable protection against null things + Set<String> parameters = _validator.getRequiredParameters(null); + assertNotNull(parameters); + assertTrue(parameters.isEmpty()); + + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getConfigs()).thenReturn(null); + parameters = _validator.getRequiredParameters(null); + assertNotNull(parameters); + assertTrue(parameters.isEmpty()); + + List<RangerServiceConfigDef> configs = new ArrayList<RangerServiceDef.RangerServiceConfigDef>(); + when(serviceDef.getConfigs()).thenReturn(configs); + parameters = _validator.getRequiredParameters(null); + assertNotNull(parameters); + assertTrue(parameters.isEmpty()); + + Object[][] input = new Object[][] { + { "param1", false }, + { "param2", true }, + { "param3", true }, + { "param4", false }, + }; + configs = _utils.createServiceConditionDefs(input); + when(serviceDef.getConfigs()).thenReturn(configs); + parameters = _validator.getRequiredParameters(serviceDef); + assertTrue("result does not contain: param2", parameters.contains("param2")); + assertTrue("result does not contain: param3", parameters.contains("param3")); + } + + @Test + public void test_getServiceDef() { + try { + // if service store returns null or throws an exception then service is deemed invalid + when(_store.getServiceDefByName("return null")).thenReturn(null); + when(_store.getServiceDefByName("throw")).thenThrow(new Exception()); + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(_store.getServiceDefByName("good-service")).thenReturn(serviceDef); + } catch (Exception e) { + e.printStackTrace(); + fail("Unexpected exception during mocking!"); + } + + assertNull(_validator.getServiceDef("return null")); + assertNull(_validator.getServiceDef("throw")); + assertFalse(_validator.getServiceDef("good-service") == null); + } + + @Test + public void test_getPolicy() throws Exception { + // if service store returns null or throws an exception then return null policy + when(_store.getPolicy(1L)).thenReturn(null); + when(_store.getPolicy(2L)).thenThrow(new Exception()); + RangerPolicy policy = mock(RangerPolicy.class); + when(_store.getPolicy(3L)).thenReturn(policy); + + assertNull(_validator.getPolicy(1L)); + assertNull(_validator.getPolicy(2L)); + assertTrue(_validator.getPolicy(3L) != null); + } + + @Test + public void test_getService_byId() throws Exception { + // if service store returns null or throws an exception then service is deemed invalid + when(_store.getService(1L)).thenReturn(null); + when(_store.getService(2L)).thenThrow(new Exception()); + RangerService service = mock(RangerService.class); + when(_store.getService(3L)).thenReturn(service); + + assertNull(_validator.getService(1L)); + assertNull(_validator.getService(2L)); + assertTrue(_validator.getService(3L) != null); + } + + @Test + public void test_getService() { + try { + // if service store returns null or throws an exception then service is deemed invalid + when(_store.getServiceByName("return null")).thenReturn(null); + when(_store.getServiceByName("throw")).thenThrow(new Exception()); + RangerService service = mock(RangerService.class); + when(_store.getServiceByName("good-service")).thenReturn(service); + } catch (Exception e) { + e.printStackTrace(); + fail("Unexpected exception during mocking!"); + } + + assertNull(_validator.getService("return null")); + assertNull(_validator.getService("throw")); + assertFalse(_validator.getService("good-service") == null); + } + + @Test + public void test_getAccessTypes() { + // passing in null service def + Set<String> accessTypes = _validator.getAccessTypes((RangerServiceDef)null); + assertTrue(accessTypes.isEmpty()); + // that has null or empty access type def + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getAccessTypes()).thenReturn(null); + accessTypes = _validator.getAccessTypes(serviceDef); + assertTrue(accessTypes.isEmpty()); + + List<RangerAccessTypeDef> accessTypeDefs = new ArrayList<RangerServiceDef.RangerAccessTypeDef>(); + when(serviceDef.getAccessTypes()).thenReturn(accessTypeDefs); + accessTypes = _validator.getAccessTypes(serviceDef); + assertTrue(accessTypes.isEmpty()); + + // having null accesstypedefs + accessTypeDefs.add(null); + accessTypes = _validator.getAccessTypes(serviceDef); + assertTrue(accessTypes.isEmpty()); + + // access type defs with null empty blank names are skipped, spaces within names are preserved + String[] names = new String[] { null, "", "a", " ", "b ", " ", " c" }; + accessTypeDefs.addAll(_utils.createAccessTypeDefs(names)); + accessTypes = _validator.getAccessTypes(serviceDef); + assertEquals(3, accessTypes.size()); + assertTrue(accessTypes.contains("a")); + assertTrue(accessTypes.contains("b ")); + assertTrue(accessTypes.contains(" c")); + } + + @Test + public void test_getResourceNames() { + // passing in null service def + Set<String> accessTypes = _validator.getMandatoryResourceNames((RangerServiceDef)null); + assertTrue(accessTypes.isEmpty()); + // that has null or empty access type def + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getResources()).thenReturn(null); + accessTypes = _validator.getMandatoryResourceNames(serviceDef); + assertTrue(accessTypes.isEmpty()); + + List<RangerResourceDef> resourceDefs = new ArrayList<RangerResourceDef>(); + when(serviceDef.getResources()).thenReturn(resourceDefs); + accessTypes = _validator.getMandatoryResourceNames(serviceDef); + assertTrue(accessTypes.isEmpty()); + + // having null accesstypedefs + resourceDefs.add(null); + accessTypes = _validator.getMandatoryResourceNames(serviceDef); + assertTrue(accessTypes.isEmpty()); + + // access type defs with null empty blank names are skipped, spaces within names are preserved + Object[][] data = { + { "a", true }, // all good + null, // this should put a null element in the resource def! + { "b", null }, // mandatory field is null, i.e. false + { "c", false }, // mandatory field false + { "d", true }, // all good + }; + resourceDefs.addAll(_utils.createResourceDefs(data)); + accessTypes = _validator.getMandatoryResourceNames(serviceDef); + assertEquals(2, accessTypes.size()); + assertTrue(accessTypes.contains("a")); + assertTrue(accessTypes.contains("d")); + + accessTypes = _validator.getAllResourceNames(serviceDef); + assertEquals(4, accessTypes.size()); + assertTrue(accessTypes.contains("b")); + assertTrue(accessTypes.contains("c")); + } + + @Test + public void test_getValidationRegExes() { + // passing in null service def + Map<String, String> regExMap = _validator.getValidationRegExes((RangerServiceDef)null); + assertTrue(regExMap.isEmpty()); + // that has null or empty access type def + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getResources()).thenReturn(null); + regExMap = _validator.getValidationRegExes(serviceDef); + assertTrue(regExMap.isEmpty()); + + List<RangerResourceDef> resourceDefs = new ArrayList<RangerResourceDef>(); + when(serviceDef.getResources()).thenReturn(resourceDefs); + regExMap = _validator.getValidationRegExes(serviceDef); + assertTrue(regExMap.isEmpty()); + + // having null accesstypedefs + resourceDefs.add(null); + regExMap = _validator.getValidationRegExes(serviceDef); + assertTrue(regExMap.isEmpty()); + + // access type defs with null empty blank names are skipped, spaces within names are preserved + String[][] data = { + { "a", null }, // null-regex + null, // this should put a null element in the resource def! + { "b", "regex1" }, // valid + { "c", "" }, // empty regex + { "d", "regex2" }, // valid + { "e", " " }, // blank regex + { "f", "regex3" }, // all good + }; + resourceDefs.addAll(_utils.createResourceDefsWithRegEx(data)); + regExMap = _validator.getValidationRegExes(serviceDef); + assertEquals(3, regExMap.size()); + assertEquals("regex1", regExMap.get("b")); + assertEquals("regex2", regExMap.get("d")); + assertEquals("regex3", regExMap.get("f")); + } + + private RangerValidatorForTest _validator; + private ServiceStore _store; + private ValidationTestUtils _utils = new ValidationTestUtils(); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f721abec/security-admin/src/test/java/org/apache/ranger/rest/TestServiceRESTForValidation.java ---------------------------------------------------------------------- diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceRESTForValidation.java b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceRESTForValidation.java index 483e914..f2cbec2 100644 --- a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceRESTForValidation.java +++ b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceRESTForValidation.java @@ -31,8 +31,11 @@ import static org.mockito.Mockito.when; import javax.ws.rs.WebApplicationException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.ranger.biz.ServiceDBStore; import org.apache.ranger.common.RESTErrorUtil; +import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerService; import org.apache.ranger.rest.RangerValidator.Action; import org.junit.Before; @@ -40,6 +43,8 @@ import org.junit.Test; public class TestServiceRESTForValidation { + private static final Log LOG = LogFactory.getLog(TestServiceRESTForValidation.class); + @Before public void setUp() throws Exception { _serviceRest = new ServiceREST(); @@ -47,10 +52,11 @@ public class TestServiceRESTForValidation { _store = mock(ServiceDBStore.class); _serviceRest.svcStore = _store; // and our validator factory - _action = Action.CREATE; _factory = mock(RangerValidatorFactory.class); - _validator = mock(RangerServiceValidator.class); - when(_factory.getServiceValidator(_store, _action)).thenReturn(_validator); + _serviceValidator = mock(RangerServiceValidator.class); + when(_factory.getServiceValidator(_store)).thenReturn(_serviceValidator); + _policyValidator = mock(RangerPolicyValidator.class); + when(_factory.getPolicyValidator(_store)).thenReturn(_policyValidator); _serviceRest.validatorFactory = _factory; // and other things that are needed for service rest to work correctly _restErrorUtil = mock(RESTErrorUtil.class); @@ -59,19 +65,29 @@ public class TestServiceRESTForValidation { _serviceRest.restErrorUtil = _restErrorUtil; // other object of use in multiple tests _service = mock(RangerService.class); + _policy = mock(RangerPolicy.class); _exception = new Exception(); } + Action[] cu = new Action[] { Action.CREATE, Action.UPDATE }; + @Test - public final void testCreateService_happyPath() throws Exception { - // creation should succeed if neither validator nor dbstore throw exception - when(_store.createService(_service)).thenReturn(null); // return value isn't important - // by default validator mock would not throw exception! + public final void testService_happyPath() throws Exception { + /* + * Creation should succeed if neither validator nor dbstore throw exception. + * - by default mocks return null for unspecified methods, so no additional mocking needed. + * - We just assert that validator is called with right set of arguments. + * - db store would also have been excercised but that is not the focus of this test, so we don't assert about it!! + */ try { _serviceRest.createService(_service); - // validator must be excercised - verify(_validator).validate(_service); - // db store would also have been excercised but that is not the focus of this test!! + verify(_serviceValidator).validate(_service, Action.CREATE); + // + _serviceRest.updateService(_service); + verify(_serviceValidator).validate(_service, Action.UPDATE); + + _serviceRest.deleteService(3L); + verify(_serviceValidator).validate(3L, Action.DELETE); } catch (Throwable t) { t.printStackTrace(); fail("Unexpected exception thrown!"); @@ -79,51 +95,202 @@ public class TestServiceRESTForValidation { } @Test - public final void testCreateService_failureStore() throws Exception { - // creation should fail if either validator or dbstore throw exception - // first have only the dbstore throw and exception + public final void testService_storeFailure() throws Exception { + /* + * API operation should fail if either validator or dbstore throw exception. For this test we have first just the dbstore throw an exception + * - we assert that exception is thrown and that validate is called. + */ + // when(_store.createService(_service)).thenThrow(_exception); - // by default validator mock would not throw exception! try { _serviceRest.createService(_service); fail("Should have thrown an exception!"); } catch (WebApplicationException t) { + // expected exception - confirm that validator was excercised and that after that call fall through to the store + verify(_serviceValidator).validate(_service, Action.CREATE); + verify(_store).createService(_service); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception thrown!"); + } + + when(_store.updateService(_service)).thenThrow(_exception); + try { + _serviceRest.updateService(_service); + fail("Should have thrown an exception!"); + } catch (WebApplicationException t) { + // expected exception - confirm that validator was excercised + verify(_serviceValidator).validate(_service, Action.UPDATE); + verify(_store).updateService(_service); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception thrown!"); + } + + doThrow(_exception).when(_store).deleteService(4L); + try { + _serviceRest.deleteService(4L); + fail("Should have thrown an exception!"); + } catch (WebApplicationException t) { // expected exception - confirm that validator was excercised - verify(_validator).validate(_service); + verify(_serviceValidator).validate(4L, Action.DELETE); + verify(_store).deleteService(4L); } catch (Throwable t) { + LOG.debug(t); fail("Unexpected exception thrown!"); } } @Test - public final void testCreateService_failureValidator() throws Exception { - // creation should fail if either validator or dbstore throw exception - // Now we only have the - doThrow(_exception).when(_validator).validate(_service); - // by default validator mock would not throw exception! + public final void testService_validatorFailure() throws Exception { + /* + * If validator throws an exception then API itself should throw an exception. We need to validate two things: + * - That validator was exercised; accidentally call to validator should not get bypassed. + * - That dbstore was NOT exercised; we expect validator failure to short circuit that + */ + doThrow(_exception).when(_serviceValidator).validate(_service, Action.CREATE); try { _serviceRest.createService(_service); fail("Should have thrown an exception!"); } catch (WebApplicationException t) { - /* - * Expected exception - but we still need to validate two things: - * - That validator was exercised; accidentally call to validator should not get bypassed. - * - That dbstore was NOT exercised; we expect validator failure to short circuit that - */ - verify(_validator).validate(_service); - // And that db store was never called! We don't expect call to go to it if validator throws exception. + // Expected exception + verify(_serviceValidator).validate(_service, Action.CREATE); verify(_store, never()).createService(_service); } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception thrown!"); + } + + doThrow(_exception).when(_serviceValidator).validate(_service, Action.UPDATE); + try { + _serviceRest.updateService(_service); + fail("Should have thrown an exception!"); + } catch (WebApplicationException t) { + // Expected exception + verify(_serviceValidator).validate(_service, Action.UPDATE); + verify(_store, never()).updateService(_service); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception thrown!"); + } + + doThrow(_exception).when(_serviceValidator).validate(5L, Action.DELETE); + try { + _serviceRest.deleteService(5L); + fail("Should have thrown an exception!"); + } catch (WebApplicationException t) { + // Expected exception + verify(_serviceValidator).validate(5L, Action.DELETE); + verify(_store, never()).deleteService(5L); + } catch (Throwable t) { + LOG.debug(t); fail("Unexpected exception thrown!"); } } + @Test + public void testPolicy_happyPath() { + try { + _serviceRest.updatePolicy(_policy); + verify(_policyValidator).validate(_policy, Action.UPDATE); + + _serviceRest.deletePolicy(3L); + verify(_policyValidator).validate(3L, Action.DELETE); + + _serviceRest.createPolicy(_policy); + verify(_policyValidator).validate(_policy, Action.CREATE); + } catch (Exception e) { + LOG.debug(e); + fail("unexpected exception"); + } + } + + @Test + public void testPolicy_validatorFailure() throws Exception { + + doThrow(_exception).when(_policyValidator).validate(_policy, Action.CREATE); + try { + _serviceRest.createPolicy(_policy); + fail("Should have thrown exception!"); + } catch (WebApplicationException t) { + verify(_policyValidator).validate(_policy, Action.CREATE); + verify(_store, never()).createPolicy(_policy); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception!"); + } + + doThrow(_exception).when(_policyValidator).validate(_policy, Action.UPDATE); + try { + _serviceRest.updatePolicy(_policy); + fail("Should have thrown exception!"); + } catch (WebApplicationException t) { + verify(_policyValidator).validate(_policy, Action.UPDATE); + verify(_store, never()).updatePolicy(_policy); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception!"); + } + + doThrow(_exception).when(_policyValidator).validate(4L, Action.DELETE); + try { + _serviceRest.deletePolicy(4L); + fail("Should have thrown exception!"); + } catch (WebApplicationException t) { + verify(_policyValidator).validate(4L, Action.DELETE); + verify(_store, never()).deletePolicy(4L); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception!"); + } + } + + @Test + public void testPolicy_storeFailure() throws Exception { + doThrow(_exception).when(_store).createPolicy(_policy); + try { + _serviceRest.createPolicy(_policy); + fail("Should have thrown exception!"); + } catch (WebApplicationException e) { + verify(_policyValidator).validate(_policy, Action.CREATE); + verify(_store).createPolicy(_policy); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception!"); + } + + doThrow(_exception).when(_store).updatePolicy(_policy); + try { + _serviceRest.updatePolicy(_policy); + fail("Should have thrown exception!"); + } catch (WebApplicationException e) { + verify(_policyValidator).validate(_policy, Action.UPDATE); + verify(_store).updatePolicy(_policy); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception!"); + } + + doThrow(_exception).when(_store).deletePolicy(5L); + try { + _serviceRest.deletePolicy(5L); + fail("Should have thrown exception!"); + } catch (WebApplicationException e) { + verify(_policyValidator).validate(5L, Action.DELETE); + verify(_store).deletePolicy(5L); + } catch (Throwable t) { + LOG.debug(t); + fail("Unexpected exception!"); + } + } + RangerValidatorFactory _factory; - RangerServiceValidator _validator; + RangerServiceValidator _serviceValidator; + RangerPolicyValidator _policyValidator; ServiceDBStore _store; - Action _action; ServiceREST _serviceRest; RangerService _service; + RangerPolicy _policy; Exception _exception; RESTErrorUtil _restErrorUtil; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f721abec/security-admin/src/test/java/org/apache/ranger/rest/TestServiceValidator.java ---------------------------------------------------------------------- diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceValidator.java b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceValidator.java deleted file mode 100644 index a1879c4..0000000 --- a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceValidator.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -package org.apache.ranger.rest; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.ranger.plugin.model.RangerService; -import org.apache.ranger.plugin.model.RangerServiceDef; -import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef; -import org.apache.ranger.plugin.store.ServiceStore; -import org.apache.ranger.rest.RangerValidator.Action; -import org.junit.Before; -import org.junit.Test; - -public class TestServiceValidator { - - static class TestRangerValidator extends RangerValidator { - - public TestRangerValidator(ServiceStore store, Action action) { - super(store, action); - } - - boolean isValid(String behavior) { - if (behavior.equals("valid")) { - _valid = true; - } else { - _valid = false; - if (behavior.equals("reason")) { - _failures = new ArrayList<ValidationFailureDetails>(); - _failures.add(new ValidationFailureDetails("", "", false, false, false, "")); - } - } - return _valid; - } - } - - @Before - public void before() { - _store = mock(ServiceStore.class); - _validator = new TestRangerValidator(_store, Action.CREATE); - } - - @Test - public void test_ctor_firewalling() { - try { - // service store can't be null during construction - new TestRangerValidator(null, Action.CREATE); - fail("Should have thrown exception!"); - } catch (IllegalArgumentException e) { - // expected exception - } - try { - // action can't be null - new TestRangerValidator(_store, null); - fail("Should have thrown exception!"); - } catch (IllegalArgumentException e) { - // expected exception - } - } - - public void test_getFailures_firewalling() { - // it is illegal to query validator for reason without first having it check something! - try { - _validator.getFailures(); - fail("Should have thrown exception!"); - } catch (IllegalStateException e) { - // expected exception. - } - - try { - // we know this call will fail - _validator.isValid("invalid"); - _validator.getFailures(); - } catch (Throwable t) { - t.printStackTrace(); - fail("Unexpected exception!"); - } - } - - @Test - public void test_getServiceConfigParameters() { - // reasonable protection against null values - Set<String> parameters = _validator.getServiceConfigParameters(null); - assertNotNull(parameters); - assertTrue(parameters.isEmpty()); - - RangerService service = mock(RangerService.class); - when(service.getConfigs()).thenReturn(null); - parameters = _validator.getServiceConfigParameters(service); - assertNotNull(parameters); - assertTrue(parameters.isEmpty()); - - when(service.getConfigs()).thenReturn(new HashMap<String, String>()); - parameters = _validator.getServiceConfigParameters(service); - assertNotNull(parameters); - assertTrue(parameters.isEmpty()); - - String[] keys = new String[] { "a", "b", "c" }; - Map<String, String> map = _utils.createMap(keys); - when(service.getConfigs()).thenReturn(map); - parameters = _validator.getServiceConfigParameters(service); - for (String key: keys) { - assertTrue("key", parameters.contains(key)); - } - } - - @Test - public void test_getRequiredParameters() { - // reasonable protection against null things - Set<String> parameters = _validator.getRequiredParameters(null); - assertNotNull(parameters); - assertTrue(parameters.isEmpty()); - - RangerServiceDef serviceDef = mock(RangerServiceDef.class); - when(serviceDef.getConfigs()).thenReturn(null); - parameters = _validator.getRequiredParameters(null); - assertNotNull(parameters); - assertTrue(parameters.isEmpty()); - - List<RangerServiceConfigDef> configs = new ArrayList<RangerServiceDef.RangerServiceConfigDef>(); - when(serviceDef.getConfigs()).thenReturn(configs); - parameters = _validator.getRequiredParameters(null); - assertNotNull(parameters); - assertTrue(parameters.isEmpty()); - - Object[][] input = new Object[][] { - { "param1", false }, - { "param2", true }, - { "param3", true }, - { "param4", false }, - }; - configs = _utils.createServiceConditionDefs(input); - when(serviceDef.getConfigs()).thenReturn(configs); - parameters = _validator.getRequiredParameters(serviceDef); - assertTrue("result does not contain: param2", parameters.contains("param2")); - assertTrue("result does not contain: param3", parameters.contains("param3")); - } - - @Test - public void test_getServiceDef() { - try { - // if service store returns null or throws an exception then service is deemed invalid - when(_store.getServiceDefByName("return null")).thenReturn(null); - when(_store.getServiceDefByName("throw")).thenThrow(new Exception()); - RangerServiceDef serviceDef = mock(RangerServiceDef.class); - when(_store.getServiceDefByName("good-service")).thenReturn(serviceDef); - } catch (Exception e) { - e.printStackTrace(); - fail("Unexpected exception during mocking!"); - } - - assertNull(_validator.getServiceDef("return null")); - assertNull(_validator.getServiceDef("throw")); - assertFalse(_validator.getServiceDef("good-service") == null); - } - - @Test - public void test_getService() { - try { - // if service store returns null or throws an exception then service is deemed invalid - when(_store.getServiceByName("return null")).thenReturn(null); - when(_store.getServiceByName("throw")).thenThrow(new Exception()); - RangerService service = mock(RangerService.class); - when(_store.getServiceByName("good-service")).thenReturn(service); - } catch (Exception e) { - e.printStackTrace(); - fail("Unexpected exception during mocking!"); - } - - assertNull(_validator.getService("return null")); - assertNull(_validator.getService("throw")); - assertFalse(_validator.getService("good-service") == null); - } - - private TestRangerValidator _validator; - private ServiceStore _store; - private ValidationTestUtils _utils = new ValidationTestUtils(); -} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f721abec/security-admin/src/test/java/org/apache/ranger/rest/ValidationTestUtils.java ---------------------------------------------------------------------- diff --git a/security-admin/src/test/java/org/apache/ranger/rest/ValidationTestUtils.java b/security-admin/src/test/java/org/apache/ranger/rest/ValidationTestUtils.java index 0925aa1..b734763 100644 --- a/security-admin/src/test/java/org/apache/ranger/rest/ValidationTestUtils.java +++ b/security-admin/src/test/java/org/apache/ranger/rest/ValidationTestUtils.java @@ -19,17 +19,29 @@ package org.apache.ranger.rest; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef; +import com.google.common.collect.Lists; + public class ValidationTestUtils { Map<String, String> createMap(String[] keys) { @@ -54,4 +66,187 @@ public class ValidationTestUtils { return result; } + void checkFailureForSemanticError(List<ValidationFailureDetails> failures, String fieldName) { + checkFailure(failures, null, null, true, fieldName, null); + } + + void checkFailureForSemanticError(List<ValidationFailureDetails> failures, String fieldName, String subField) { + checkFailure(failures, null, null, true, fieldName, subField); + } + + void checkFailureForMissingValue(List<ValidationFailureDetails> failures, String field) { + checkFailure(failures, null, true, null, field, null); + } + + void checkFailureForMissingValue(List<ValidationFailureDetails> failures, String field, String subField) { + checkFailure(failures, null, true, null, field, subField); + } + + void checkFailureForInternalError(List<ValidationFailureDetails> failures, String fieldName) { + checkFailure(failures, true, null, null, fieldName, null); + } + + void checkFailureForInternalError(List<ValidationFailureDetails> failures) { + checkFailure(failures, true, null, null, null, null); + } + + void checkFailure(List<ValidationFailureDetails> failures, Boolean internalError, Boolean missing, Boolean semanticError, String field, String subField) { + if (CollectionUtils.isEmpty(failures)) { + fail("List of failures is null/empty!"); + } else { + boolean found = false; + for (ValidationFailureDetails f : failures) { + if ((internalError == null || internalError == f._internalError) && + (missing == null || missing == f._missing) && + (semanticError == null || semanticError == f._semanticError) && + (field == null || field.equals(f._fieldName)) && + (subField == null || subField.equals(f._subFieldName))) { + found = true; + } + } + assertTrue(found); + } + } + + List<RangerAccessTypeDef> createAccessTypeDefs(String[] names) { + assertFalse(names == null); // fail if null is passed in! + List<RangerAccessTypeDef> defs = new ArrayList<RangerServiceDef.RangerAccessTypeDef>(); + for (String name : names) { + RangerAccessTypeDef def = mock(RangerAccessTypeDef.class); + when(def.getName()).thenReturn(name); + defs.add(def); + } + return defs; + } + + RangerServiceDef createServiceDefWithAccessTypes(String[] accesses) { + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + List<RangerAccessTypeDef> accessTypeDefs = new ArrayList<RangerServiceDef.RangerAccessTypeDef>(); + for (String access : accesses) { + RangerAccessTypeDef accessTypeDef = mock(RangerAccessTypeDef.class); + when(accessTypeDef.getName()).thenReturn(access); + accessTypeDefs.add(accessTypeDef); + } + when(serviceDef.getAccessTypes()).thenReturn(accessTypeDefs); + return serviceDef; + } + + List<RangerPolicyItemAccess> createItemAccess(Object[][] data) { + List<RangerPolicyItemAccess> accesses = new ArrayList<RangerPolicyItemAccess>(); + for (Object[] row : data) { + RangerPolicyItemAccess access = mock(RangerPolicyItemAccess.class); + when(access.getType()).thenReturn((String)row[0]); + when(access.getIsAllowed()).thenReturn((Boolean)row[1]); + accesses.add(access); + } + return accesses; + } + + List<RangerPolicyItem> createPolicyItems(Object[] data) { + List<RangerPolicyItem> policyItems = new ArrayList<RangerPolicyItem>(); + for (Object object : data) { + @SuppressWarnings("unchecked") + Map<String, Object[]> map = (Map<String, Object[]>) object; + RangerPolicyItem policyItem = mock(RangerPolicyItem.class); + + List<String> usersList = null; + if (map.containsKey("users")) { + usersList = Arrays.asList((String[])map.get("users")); + } + when(policyItem.getUsers()).thenReturn(usersList); + + List<String> groupsList = null; + if (map.containsKey("groups")) { + groupsList = Arrays.asList((String[])map.get("groups")); + } + when(policyItem.getGroups()).thenReturn(groupsList); + + String[] accesses = (String[])map.get("accesses");; + Boolean[] isAllowedFlags = (Boolean[])map.get("isAllowed"); + List<RangerPolicyItemAccess> accessesList = null; + if (accesses != null && isAllowedFlags != null) { + accessesList = new ArrayList<RangerPolicyItemAccess>(); + for (int i = 0; i < accesses.length; i++) { + String access = accesses[i]; + Boolean isAllowed = isAllowedFlags[i]; + RangerPolicyItemAccess itemAccess = mock(RangerPolicyItemAccess.class); + when(itemAccess.getType()).thenReturn(access); + when(itemAccess.getIsAllowed()).thenReturn(isAllowed); + accessesList.add(itemAccess); + } + } + when(policyItem.getAccesses()).thenReturn(accessesList); + + policyItems.add(policyItem); + } + return policyItems; + } + + List<RangerResourceDef> createResourceDefs(Object[][] data) { + // if data itself is null then return null back + if (data == null) { + return null; + } + List<RangerResourceDef> defs = new ArrayList<RangerResourceDef>(); + for (Object[] row : data) { + RangerResourceDef aDef = null; + if (row != null) { + String name = null; + Boolean mandatory = null; + String regExPattern = null; + switch(row.length) { + case 3: + regExPattern = (String)row[2]; + case 2: + mandatory = (Boolean)row[1]; + case 1: + name = (String)row[0]; + } + aDef = mock(RangerResourceDef.class); + when(aDef.getName()).thenReturn(name); + when(aDef.getMandatory()).thenReturn(mandatory); + when(aDef.getValidationRegEx()).thenReturn(regExPattern); + } + defs.add(aDef); + } + return defs; + } + + List<RangerResourceDef> createResourceDefsWithRegEx(String[][] data) { + // if data itself is null then return null back + if (data == null) { + return null; + } + List<RangerResourceDef> defs = new ArrayList<RangerResourceDef>(); + for (String[] row : data) { + RangerResourceDef aDef = null; + if (row != null) { + String name = row[0]; + String regEx = row[1]; + aDef = mock(RangerResourceDef.class); + when(aDef.getName()).thenReturn(name); + when(aDef.getValidationRegEx()).thenReturn(regEx); + } + defs.add(aDef); + } + return defs; + } + + Map<String, RangerPolicyResource> createPolicyResourceMap(Map<String, String[]> input) { + if (input == null) { + return null; + } + Map<String, RangerPolicyResource> resourceMap = new HashMap<String, RangerPolicyResource>(); + for (Map.Entry<String, String[]> entry : input.entrySet()) { + String key = entry.getKey(); + String[] inputValues = entry.getValue(); + RangerPolicyResource policyResource = mock(RangerPolicyResource.class); + if (inputValues != null) { + List<String> values = Lists.newArrayList(inputValues); + when(policyResource.getValues()).thenReturn(values); + } + resourceMap.put(key, policyResource); + } + return resourceMap; + } }
