@Test
public void testGetDomainDataCheck() {

    String tenantDomainName = "testGetDomainDataCheck";
    TopLevelDomain tenDom = createTopLevelDomainObject(tenantDomainName,
            "Test Provider Domain", "testOrg", adminUser);
    zms.postTopLevelDomain(mockDomRsrcCtx, auditRef, tenDom);
    // create roles
    Role role1 = createRoleObject(tenantDomainName, "Role1", null, "user.joe", "user.jane");
    zms.putRole(mockDomRsrcCtx, tenantDomainName, "Role1", auditRef, role1);
    Role role2 = createRoleObject(tenantDomainName, "Role2", null, "user.phil", "user.gil");
    zms.putRole(mockDomRsrcCtx, tenantDomainName, "Role2", auditRef, role2);
    // create policies
    Policy policy1 = createPolicyObject(tenantDomainName, "Policy1", "Role1",
            "UPDATE", tenantDomainName + ":resource1", AssertionEffect.ALLOW);
    zms.putPolicy(mockDomRsrcCtx, tenantDomainName, "Policy1", auditRef, policy1);
    Policy policy2 = createPolicyObject(tenantDomainName, "Policy2", "Role2",
            "READ", tenantDomainName + ":resource1", AssertionEffect.ALLOW);
    zms.putPolicy(mockDomRsrcCtx, tenantDomainName, "Policy2", auditRef, policy2);
    //
    // test valid setup domain
    DomainDataCheck ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(3, ddc.getPolicyCount());
    assertEquals(3, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // set valid wildcard role
    Assertion assertion = new Assertion();
    assertion.setAction("MANAGE");
    assertion.setEffect(AssertionEffect.ALLOW);
    assertion.setResource(tenantDomainName + ":wildlife");
    assertion.setRole(tenantDomainName + ":role.Role*");
    
    Policy policy = zms.getPolicy(mockDomRsrcCtx, tenantDomainName, "Policy2");
    List<Assertion> assertList = policy.getAssertions();
    assertList.add(assertion);
    policy.setAssertions(assertList);
    zms.putPolicy(mockDomRsrcCtx, tenantDomainName, "Policy2", auditRef, policy);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(3, ddc.getPolicyCount());
    assertEquals(4, ddc.getAssertionCount());
    assertEquals(1, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // test dangling policy with wildcard role
    assertion = new Assertion();
    assertion.setAction("MANAGE");
    assertion.setEffect(AssertionEffect.ALLOW);
    assertion.setResource(tenantDomainName + ":wildlife");
    assertion.setRole(tenantDomainName + ":role.Wild*");
    
    policy = zms.getPolicy(mockDomRsrcCtx, tenantDomainName, "Policy2");
    assertList = policy.getAssertions();
    assertList.add(assertion);
    policy.setAssertions(assertList);
    zms.putPolicy(mockDomRsrcCtx, tenantDomainName, "Policy2", auditRef, policy);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(3, ddc.getPolicyCount());
    assertEquals(5, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertEquals(1, ddc.getDanglingPolicies().size());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // add a dangling role 
    Role role3 = createRoleObject(tenantDomainName, "Role3", null, "user.user1", "user.user3");
    zms.putRole(mockDomRsrcCtx, tenantDomainName, "Role3", auditRef, role3);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(3, ddc.getPolicyCount());
    assertEquals(5, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(1, ddc.getDanglingPolicies().size());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // test more dangling policies
    // create policy with assertion using unknown role
    assertion = new Assertion();
    assertion.setAction("snorkel");
    assertion.setEffect(AssertionEffect.ALLOW);
    assertion.setResource(tenantDomainName + ":molokoni");
    assertion.setRole(tenantDomainName + ":role.snorkeler");
    
    policy = zms.getPolicy(mockDomRsrcCtx, tenantDomainName, "Policy2");
    assertList = policy.getAssertions();
    assertList.add(assertion);
    policy.setAssertions(assertList);
    zms.putPolicy(mockDomRsrcCtx, tenantDomainName, "Policy2", auditRef, policy);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(3, ddc.getPolicyCount());
    assertEquals(6, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // create provider domain
    String provDomainTop = "testGetDomainDataCheckProvider";
    TopLevelDomain provDom = createTopLevelDomainObject(provDomainTop,
            "Test Provider Domain", "testOrg", adminUser);
    zms.postTopLevelDomain(mockDomRsrcCtx, auditRef, provDom);
    String provDomainSub = provDomainTop + ".sub";
    SubDomain subDom = createSubDomainObject("sub", provDomainTop, null, null, adminUser);
    subDom.setAuditEnabled(true);
    zms.postSubDomain(mockDomRsrcCtx, provDomainTop, auditRef, subDom);
    // test incomplete tenancy setup
    // put tenancy for provider
    String provEndPoint = "http://localhost:8090/provider";
    String provSvc      = "storage";
    ServiceIdentity service = createServiceObject(
            provDomainSub, provSvc, provEndPoint,
            "/usr/bin/java", "root", "users", "localhost");
    zms.putServiceIdentity(mockDomRsrcCtx, provDomainSub, provSvc, auditRef, service);
    Tenancy tenant = createTenantObject(tenantDomainName, provDomainSub + "." + provSvc);
    zms.putTenancy(mockDomRsrcCtx, tenantDomainName, provDomainSub + "." + provSvc, auditRef, tenant);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(4, ddc.getPolicyCount());
    assertEquals(9, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertTrue(ddc.getDanglingRoles().contains("role3"));
    boolean danglingPolicy1Found = false;
    boolean danglingPolicy2Found = false;
    for (DanglingPolicy danglingPolicy : ddc.getDanglingPolicies()) {
        if (danglingPolicy.getPolicyName().equals("policy2") && danglingPolicy.getRoleName().equals("wild*")) {
            danglingPolicy1Found = true;
        } else if (danglingPolicy.getPolicyName().equals("policy2") && danglingPolicy.getRoleName().equals("snorkeler")) {
            danglingPolicy2Found = true;
        }
    }
    assertTrue(danglingPolicy1Found);
    assertTrue(danglingPolicy2Found);
    assertEquals(1, ddc.getProvidersWithoutTrust().size());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // test that now all is hunky dory between the tenant and provider
    // provider gets the trust role(s)
    List<TenantRoleAction> roleActions = new ArrayList<>();
    for (Struct.Field f : TABLE_PROVIDER_ROLE_ACTIONS) {
        roleActions.add(new TenantRoleAction().setRole(f.name()).setAction((String) f.value()));
    }
    TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles().setDomain(provDomainSub)
            .setService(provSvc).setTenant(tenantDomainName)
            .setRoles(roleActions).setResourceGroup("set1");
    zms.putTenantResourceGroupRoles(mockDomRsrcCtx, provDomainSub, provSvc, tenantDomainName,
            "set1", auditRef, tenantRoles);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(4, ddc.getPolicyCount());
    assertEquals(9, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, provDomainSub);
    assertNotNull(ddc);
    assertEquals(5, ddc.getPolicyCount());
    assertEquals(5, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNotNull(ddc.getTenantsWithoutAssumeRole());
    // test provider should report tenant is missing
    // remove the assume_role policies from the tenant
    zms.deleteTenancy(mockDomRsrcCtx, tenantDomainName,  provDomainSub + "." + provSvc, auditRef);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, provDomainSub);
    assertNotNull(ddc);
    assertEquals(5, ddc.getPolicyCount());
    assertEquals(5, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertNull(ddc.getProvidersWithoutTrust());
     assertEquals(1, ddc.getTenantsWithoutAssumeRole().size());
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(3, ddc.getPolicyCount());
    assertEquals(6, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(2, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // test service name with resource group
    // setup up the top level domain+service with resource group
    String provSvcTop = "shelter";
    service = createServiceObject(
            provDomainTop, provSvcTop, provEndPoint,
            "/usr/bin/java", "root", "users", "localhost");
    zms.putServiceIdentity(mockDomRsrcCtx, provDomainTop, provSvcTop, auditRef, service);
    TenantResourceGroupRoles tenantGroupRoles = new TenantResourceGroupRoles()
            .setDomain(provDomainTop)
            .setService(provSvcTop).setTenant(tenantDomainName)
            .setRoles(roleActions).setResourceGroup("ravers");
    // put the trust roles with resource group into top level provider domain
    // - tenant is not yet supporting the top level domain
    zms.putTenantResourceGroupRoles(mockDomRsrcCtx, provDomainTop, provSvcTop, tenantDomainName, "ravers",
            auditRef, tenantGroupRoles);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, provDomainTop);
    assertNotNull(ddc);
    assertEquals(5, ddc.getPolicyCount());
    assertEquals(5, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertNull(ddc.getProvidersWithoutTrust());
    assertEquals(1, ddc.getTenantsWithoutAssumeRole().size());
    // now set up the tenant for the sub domain provider
    ProviderResourceGroupRoles providerRoles = new ProviderResourceGroupRoles()
            .setDomain(provDomainSub).setService(provSvc)
            .setTenant(tenantDomainName).setRoles(roleActions)
            .setResourceGroup("ravers");
    // this sets up the assume roles in the tenant for the sub domain
    // if it is an authorized service, then it will setup the provider roles too
    zms.putProviderResourceGroupRoles(mockDomRsrcCtx, tenantDomainName, provDomainSub, provSvc,
            "ravers", auditRef, providerRoles);
    // tenant sees that the subdomain provider isn't provisioned yet
    // for the resource group: testgetdomaindatacheckprovider.sub.storage.ravers
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc, ddc.toString());
    assertEquals(7, ddc.getPolicyCount());
    assertEquals(12, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertEquals(1, ddc.getProvidersWithoutTrust().size());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // setup tenancy in the tenant domain for the provider subdomain
    zms.putTenancy(mockDomRsrcCtx, tenantDomainName, provDomainSub + "." + provSvc, auditRef, tenant);
    // the subdomain provider believes it is in sync with tenant
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, provDomainSub);
    assertNotNull(ddc);
    assertEquals(5, ddc.getPolicyCount());
    assertEquals(5, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNotNull(ddc.getTenantsWithoutAssumeRole());
    // but the tenant sees the sub provider is not setup 
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(7, ddc.getPolicyCount());
    assertEquals(12, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertEquals(1, ddc.getProvidersWithoutTrust().size());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // now set up the sub domain provider for the tenant with resource groups
    // so tenant and the sub domain provider are in sync again
    // add resource groups to provider
    tenantGroupRoles = new TenantResourceGroupRoles()
            .setDomain(provDomainSub)
            .setService(provSvc).setTenant(tenantDomainName)
            .setRoles(roleActions).setResourceGroup("ravers");
    // put the trust roles into sub domain provider
    zms.putTenantResourceGroupRoles(mockDomRsrcCtx, provDomainSub, provSvc, tenantDomainName, "ravers",
            auditRef, tenantGroupRoles);
    // now tenant sees the sub domain has provisioned it
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(7, ddc.getPolicyCount());
    assertEquals(12, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // now set up the tenant for the top level domain provider
    // so tenant and the top level domain provider are in sync again
    providerRoles = new ProviderResourceGroupRoles()
            .setDomain(provDomainTop).setService(provSvcTop)
            .setTenant(tenantDomainName).setRoles(roleActions)
            .setResourceGroup("ravers");
    // this sets up the assume roles in the tenant for the top level domain
    zms.putProviderResourceGroupRoles(mockDomRsrcCtx, tenantDomainName, provDomainTop, provSvcTop,
            "ravers", auditRef, providerRoles);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(11, ddc.getPolicyCount());
    assertEquals(18, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // delete the resource group tenancy support from sub domain
    // this means the tenant domain should show both the sub domain and
    // the top domain is without trust roles
    zms.deleteTenantResourceGroupRoles(mockDomRsrcCtx, provDomainSub, provSvc,
            tenantDomainName, "ravers", auditRef);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(11, ddc.getPolicyCount());
    assertEquals(18, ddc.getAssertionCount());
    assertEquals(2, ddc.getRoleWildCardCount());
    assertEquals(1, ddc.getDanglingRoles().size());
    assertEquals(2, ddc.getDanglingPolicies().size());
    assertEquals(1, ddc.getProvidersWithoutTrust().size());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // delete the dangling policies and dangling role
    zms.deletePolicy(mockDomRsrcCtx, tenantDomainName, "Policy2", auditRef);
    zms.deleteRole(mockDomRsrcCtx, tenantDomainName, "Role3", auditRef);
    zms.deleteRole(mockDomRsrcCtx, tenantDomainName, "Role2", auditRef);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(10, ddc.getPolicyCount());
    assertEquals(14, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertEquals(1, ddc.getProvidersWithoutTrust().size());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // add the tenancy support for top domain
    // - now tenant will see that it is all setup
    tenantRoles = new TenantResourceGroupRoles().setDomain(provDomainTop)
            .setService(provSvcTop).setTenant(tenantDomainName)
            .setRoles(roleActions).setResourceGroup("set1");
    zms.putTenantResourceGroupRoles(mockDomRsrcCtx, provDomainTop, provSvcTop,
            tenantDomainName, "set1", auditRef, tenantRoles);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(10, ddc.getPolicyCount());
    assertEquals(14, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertEquals(1, ddc.getProvidersWithoutTrust().size());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    // delete the provider resource group roles for the sub domain provider
    // then everything in sync for this tenant
    zms.deleteProviderResourceGroupRoles(mockDomRsrcCtx, tenantDomainName, provDomainSub, provSvc,
            "ravers", auditRef);
    ddc = zms.getDomainDataCheck(mockDomRsrcCtx, tenantDomainName);
    assertNotNull(ddc);
    assertEquals(7, ddc.getPolicyCount());
    assertEquals(11, ddc.getAssertionCount());
    assertEquals(0, ddc.getRoleWildCardCount());
    assertNull(ddc.getDanglingRoles());
    assertNull(ddc.getDanglingPolicies());
    assertNull(ddc.getProvidersWithoutTrust());
    assertNull(ddc.getTenantsWithoutAssumeRole());
    zms.deleteTopLevelDomain(mockDomRsrcCtx, tenantDomainName, auditRef);
    zms.deleteSubDomain(mockDomRsrcCtx, provDomainTop, "sub", auditRef);
    zms.deleteTopLevelDomain(mockDomRsrcCtx, provDomainTop, auditRef);
}