Java 17 / Spring 6 / Spring Boot 3 Upgrade
[policy/pap.git] / main / src / test / java / org / onap / policy / pap / main / rest / TestPdpGroupCreateOrUpdateProvider.java
index 7666dc2..445a921 100644 (file)
-/*\r
- * ============LICENSE_START=======================================================\r
- * ONAP PAP\r
- * ================================================================================\r
- * Copyright (C) 2019-2021 Nordix Foundation.\r
- * Modifications Copyright (C) 2021 AT&T Intellectual Property.\r
- * Modifications Copyright (C) 2021-2022 Bell Canada. All rights reserved.\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- * ============LICENSE_END=========================================================\r
- */\r
-\r
-package org.onap.policy.pap.main.rest;\r
-\r
-import static org.assertj.core.api.Assertions.assertThatThrownBy;\r
-import static org.junit.Assert.assertEquals;\r
-import static org.junit.Assert.assertNull;\r
-import static org.junit.Assert.assertSame;\r
-import static org.mockito.ArgumentMatchers.any;\r
-import static org.mockito.Mockito.never;\r
-import static org.mockito.Mockito.verify;\r
-import static org.mockito.Mockito.when;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.List;\r
-import java.util.TreeMap;\r
-import javax.ws.rs.core.Response.Status;\r
-import org.assertj.core.api.Assertions;\r
-import org.junit.AfterClass;\r
-import org.junit.Before;\r
-import org.junit.Test;\r
-import org.onap.policy.common.utils.services.Registry;\r
-import org.onap.policy.models.base.PfModelException;\r
-import org.onap.policy.models.pdp.concepts.PdpGroup;\r
-import org.onap.policy.models.pdp.concepts.PdpGroups;\r
-import org.onap.policy.models.pdp.concepts.PdpStateChange;\r
-import org.onap.policy.models.pdp.concepts.PdpSubGroup;\r
-import org.onap.policy.models.pdp.concepts.PdpUpdate;\r
-import org.onap.policy.models.pdp.enums.PdpState;\r
-import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;\r
-import org.onap.policy.pap.main.PapConstants;\r
-\r
-public class TestPdpGroupCreateOrUpdateProvider extends ProviderSuper {\r
-    private static final String EXPECTED_EXCEPTION = "expected exception";\r
-\r
-    private static final String PDP2 = "pdpB";\r
-    private static final String PDP4 = "pdpD";\r
-\r
-    private PdpGroupCreateOrUpdateProvider prov;\r
-\r
-\r
-
-    @AfterClass\r
-    public static void tearDownAfterClass() {\r
-        Registry.newRegistry();\r
-    }\r
-\r
-    /**\r
-     * Configures mocks and objects.\r
-     *\r
-     * @throws Exception if an error occurs\r
-     */\r
-    @Before\r
-    @Override\r
-    public void setUp() throws Exception {\r        super.setUp();\r
-        prov = new PdpGroupCreateOrUpdateProvider();\r
-        super.initialize(prov);\r
-        when(toscaService.getPolicyTypeList("typeA", "100.2.3"))\r
-            .thenReturn(Arrays.asList(loadPolicyType("daoPolicyType.json")));\r    }\r
-\r
-    @Test\r
-    public void testCreateOrUpdateGroups() throws Exception {\r
-        prov.createOrUpdateGroups(loadPdpGroups("emptyGroups.json"));\r
-\r
-        // no groups, so no action should have been taken\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testCreateOrUpdateGroups_InvalidRequest() throws Exception {\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(new PdpGroups())).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("is null");\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testCreateOrUpdate_Invalid() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("pdpGroupState");\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testAddGroup() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup group = groups.getGroups().get(0);\r
-        group.setPdpGroupState(PdpState.PASSIVE);\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        // should not have updated the state\r
-        assertEquals(PdpState.PASSIVE, group.getPdpGroupState());\r
-\r
-        assertSame(group, getGroupCreates().get(0));\r
-    }\r
-\r
-    @Test\r
-    public void testAddGroup_Invalid() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("pdpGroupState");\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testAddGroup_InvalidSubGroup() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-\r
-        groups.getGroups().get(0).getPdpSubgroups().get(0).getSupportedPolicyTypes().get(0).setVersion("99.99.99");\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("unknown policy type");\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testValidateGroupOnly_NullState() {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        groups.getGroups().get(0).setPdpGroupState(null);\r
-        Assertions.assertThatCode(() -> prov.createOrUpdateGroups(groups)).doesNotThrowAnyException();\r
-    }\r
-\r
-    @Test\r
-    public void testValidateGroupOnly_Active() {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        groups.getGroups().get(0).setPdpGroupState(PdpState.ACTIVE);\r
-        Assertions.assertThatCode(() -> prov.createOrUpdateGroups(groups)).doesNotThrowAnyException();\r
-    }\r
-\r
-    @Test\r
-    public void testValidateGroupOnly_Passive() {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        groups.getGroups().get(0).setPdpGroupState(PdpState.PASSIVE);\r
-        Assertions.assertThatCode(() -> prov.createOrUpdateGroups(groups)).doesNotThrowAnyException();\r
-    }\r
-\r
-    @Test\r
-    public void testValidateGroupOnly_Invalid() {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("pdpGroupState");\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateGroup() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-\r
-        // DB group = new group\r
-        PdpGroup group = new PdpGroup(groups.getGroups().get(0));\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateGroup_PropertiesChanged() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-\r
-        PdpGroup group = new PdpGroup(groups.getGroups().get(0));\r
-        group.setProperties(new TreeMap<>());\r
-\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("properties");\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateGroup_NewDescription() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        group.setDescription("old description");\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertGroupUpdateOnly(group);\r
-\r
-        assertEquals("my description", group.getDescription());\r
-        assertEquals(newgrp.toString(), group.toString());\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateGroup_NewState() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        group.setPdpGroupState(PdpState.TEST);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertGroupUpdateOnly(group);\r
-\r
-        assertEquals(PdpState.ACTIVE, group.getPdpGroupState());\r
-        assertEquals(newgrp.toString(), group.toString());\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateGroup_NewSubGroup() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");\r
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        assertEquals(newgrp.toString(), group.toString());\r
-        assertGroupUpdateOnly(group);\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateGroup_UpdatedSubGroup() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        // something different in this subgroup\r
-        group.getPdpSubgroups().get(0).setDesiredInstanceCount(10);\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-        assertGroupUpdateOnly(group);\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateGroup_notifyPdpsDelSubGroups() throws Exception {\r
-        PdpGroup dbgroup = new PdpGroup(loadPdpGroups("createGroupsDelSub.json").getGroups().get(0));\r
-        when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));\r
-\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        // verify that DB group was updated\r
-        List<PdpGroup> updates = getGroupUpdates();\r
-        assertEquals(1, updates.size());\r
-        dbgroup = updates.get(0);\r
-\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-\r
-        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());\r
-        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());\r
-\r
-        assertEquals(newgrp.toString(), dbgroup.toString());\r
-\r
-        // no deployment notifications\r
-        checkEmptyNotification();\r
-\r
-        // this requires a PDP UPDATE message\r
-        List<PdpUpdate> pdpUpdates = getUpdateRequests(2);\r
-        assertEquals(2, pdpUpdates.size());\r
-\r
-        PdpUpdate pdpUpdate = pdpUpdates.get(0);\r
-        assertEquals(PapConstants.PAP_NAME, pdpUpdate.getSource());\r
-        assertEquals(PDP2, pdpUpdate.getName());\r
-        assertNull(pdpUpdate.getPdpGroup());\r
-\r
-        pdpUpdate = pdpUpdates.get(1);\r
-        assertEquals(PapConstants.PAP_NAME, pdpUpdate.getSource());\r
-        assertEquals(PDP4, pdpUpdate.getName());\r
-        assertNull(pdpUpdate.getPdpGroup());\r
-\r
-        // it also requires a PDP STATE-CHANGE message\r
-        List<PdpStateChange> changes = getStateChangeRequests(2);\r
-        assertEquals(2, changes.size());\r
-\r
-        PdpStateChange change = changes.get(0);\r
-        assertEquals(PapConstants.PAP_NAME, change.getSource());\r
-        assertEquals(PDP2, change.getName());\r
-        assertEquals(PdpState.PASSIVE, change.getState());\r
-\r
-        change = changes.get(1);\r
-        assertEquals(PapConstants.PAP_NAME, change.getSource());\r
-        assertEquals(PDP4, change.getName());\r
-        assertEquals(PdpState.PASSIVE, change.getState());\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateField_Unchanged() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateField_WasNull() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        group.setDescription(null);\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-        assertGroupUpdateOnly(group);\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateField_NowNull() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        newgrp.setDescription(null);\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-        assertGroupUpdateOnly(group);\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateField_Changed() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        newgrp.setDescription(group.getDescription() + "-changed");\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-        assertGroupUpdateOnly(group);\r
-    }\r
-\r
-    @Test\r
-    public void testAddSubGroup() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");\r
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-\r
-        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);\r
-        newsub.setCurrentInstanceCount(0);\r
-        newsub.setPdpInstances(new ArrayList<>(0));\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-        assertGroupUpdateOnly(group);\r
-    }\r
-\r
-    /**\r
-     * Tests addSubgroup() when the new subgroup has a wild-card policy type.\r
-     *\r
-     * @throws Exception if an error occurs\r
-     */\r
-    @Test\r
-    public void testAddSubGroupWildCardPolicyType() throws Exception {\r
-        when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCard.json"));\r
-        when(toscaService.getPolicyTypeList("some.*", "2.3.4")).thenReturn(Collections.emptyList());\r
-\r
-        PdpGroups groups = loadPdpGroups("createGroupsWildCard.json");\r
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-\r
-        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);\r
-        newsub.setCurrentInstanceCount(0);\r
-        newsub.setPdpInstances(new ArrayList<>(0));\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-    }\r
-\r
-    @Test\r
-    public void testAddSubGroup_ValidationPolicyTypeNotFound() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");\r
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        when(toscaService.getPolicyTypeList(any(), any())).thenReturn(Collections.emptyList());\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).hasMessageContaining("unknown policy type");\r
-    }\r
-\r
-    @Test\r
-    public void testAddSubGroup_ValidationPolicyTypeDaoEx() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");\r
-        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);\r
-        when(toscaService.getPolicyTypeList(any(), any())).thenThrow(exc);\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);\r
-    }\r
-\r
-    @Test\r
-    public void testAddSubGroup_ValidateVersionPrefixMatch() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup dbgroup = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));\r
-\r
-        when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))\r
-            .thenReturn(loadPolicies("daoPolicyList.json")).thenReturn(loadPolicies("createGroupNewPolicy.json"));\r
-\r
-        PdpGroups reqgroups = loadPdpGroups("createGroupsVersPrefix.json");\r
-\r
-        prov.createOrUpdateGroups(reqgroups);\r
-\r
-        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());\r
-        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());\r
-\r
-        assertEquals(newgrp.toString(), dbgroup.toString());\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateSubGroup_Invalid() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        // change properties\r
-        newgrp.getPdpSubgroups().get(0).setProperties(new TreeMap<>());\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("properties");\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateSubGroup_SupportedPolicies() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes()\r
-            .add(new ToscaConceptIdentifier("typeX.*", "9.8.7"));\r
-\r
-        // the group is updated with a new supported policy type in subgroup\r
-        assertEquals(2, newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes().size());\r
-        prov.createOrUpdateGroups(groups);\r
-        // PdpGroup update doesn't allow supported policy type modifications\r
-        // during pdp group update, the ones in db is maintained\r
-        assertEquals(1, newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes().size());\r
-        assertEquals(newgrp.toString(), group.toString());\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateSubGroup_DesiredCount() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        newgrp.getPdpSubgroups().get(0).setDesiredInstanceCount(20);\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-        assertGroupUpdateOnly(group);\r
-    }\r
-\r
-    @Test\r
-    public void testUpdateSubGroup_Unchanged() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        prov.createOrUpdateGroups(groups);\r
-\r
-        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());\r
-        Collections.sort(group.getPdpSubgroups().get(0).getPolicies());\r
-\r
-        assertEquals(newgrp.toString(), group.toString());\r
-\r
-        // no notifications\r
-        checkEmptyNotification();\r
-\r
-        // no group updates\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    @Test\r
-    public void testValidateSubGroup_PropertiesMismatch() throws Exception {\r
-        PdpGroups groups = loadPdpGroups("createGroups.json");\r
-        PdpGroup newgrp = groups.getGroups().get(0);\r
-        PdpGroup group = new PdpGroup(newgrp);\r
-        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));\r
-\r
-        newgrp.setProperties(new TreeMap<>());\r
-\r
-        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)\r
-            .hasMessageContaining("properties");\r
-\r
-        assertNoGroupAction();\r
-    }\r
-\r
-    private void assertNoGroupAction() throws Exception {\r
-        verify(pdpGroupService, never()).createPdpGroups(any());\r
-        verify(pdpGroupService, never()).updatePdpGroups(any());\r
-        verify(reqmap, never()).addRequest(any(), any());\r
-    }\r
-\r
-    private void assertGroupUpdateOnly(PdpGroup group) throws Exception {\r
-        verify(pdpGroupService, never()).createPdpGroups(any());\r
-        verify(reqmap, never()).addRequest(any(), any());\r
-\r
-        List<PdpGroup> updates = getGroupUpdates();\r
-        assertEquals(Arrays.asList(group), updates);\r
-    }\r
-}\r
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019-2021, 2023 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property.
+ * Modifications Copyright (C) 2021-2022 Bell Canada. 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.pap.main.rest;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import jakarta.ws.rs.core.Response.Status;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.TreeMap;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.pdp.concepts.PdpStateChange;
+import org.onap.policy.models.pdp.concepts.PdpSubGroup;
+import org.onap.policy.models.pdp.concepts.PdpUpdate;
+import org.onap.policy.models.pdp.enums.PdpState;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.pap.main.PapConstants;
+
+public class TestPdpGroupCreateOrUpdateProvider extends ProviderSuper {
+    private static final String EXPECTED_EXCEPTION = "expected exception";
+
+    private static final String PDP2 = "pdpB";
+    private static final String PDP4 = "pdpD";
+
+    private PdpGroupCreateOrUpdateProvider prov;
+
+
+    @AfterAll
+    public static void tearDownAfterClass() {
+        Registry.newRegistry();
+    }
+
+    /**
+     * Configures mocks and objects.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeEach
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        prov = new PdpGroupCreateOrUpdateProvider();
+        super.initialize(prov);
+        when(toscaService.getPolicyTypeList("typeA", "100.2.3"))
+            .thenReturn(Arrays.asList(loadPolicyType("daoPolicyType.json")));
+    }
+
+    @Test
+    void testCreateOrUpdateGroups() throws Exception {
+        prov.createOrUpdateGroups(loadPdpGroups("emptyGroups.json"));
+
+        // no groups, so no action should have been taken
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testCreateOrUpdateGroups_InvalidRequest() throws Exception {
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(new PdpGroups())).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("is null");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testCreateOrUpdate_Invalid() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("pdpGroupState");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testAddGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup group = groups.getGroups().get(0);
+        group.setPdpGroupState(PdpState.PASSIVE);
+
+        prov.createOrUpdateGroups(groups);
+
+        // should not have updated the state
+        assertEquals(PdpState.PASSIVE, group.getPdpGroupState());
+
+        assertSame(group, getGroupCreates().get(0));
+    }
+
+    @Test
+    void testAddGroup_Invalid() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("pdpGroupState");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testAddGroup_InvalidSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        groups.getGroups().get(0).getPdpSubgroups().get(0).getSupportedPolicyTypes().get(0).setVersion("99.99.99");
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("unknown policy type");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testValidateGroupOnly_NullState() {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(null);
+        Assertions.assertThatCode(() -> prov.createOrUpdateGroups(groups)).doesNotThrowAnyException();
+    }
+
+    @Test
+    void testValidateGroupOnly_Active() {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.ACTIVE);
+        Assertions.assertThatCode(() -> prov.createOrUpdateGroups(groups)).doesNotThrowAnyException();
+    }
+
+    @Test
+    void testValidateGroupOnly_Passive() {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.PASSIVE);
+        Assertions.assertThatCode(() -> prov.createOrUpdateGroups(groups)).doesNotThrowAnyException();
+    }
+
+    @Test
+    void testValidateGroupOnly_Invalid() {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        groups.getGroups().get(0).setPdpGroupState(PdpState.TERMINATED);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("pdpGroupState");
+    }
+
+    @Test
+    void testUpdateGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        // DB group = new group
+        PdpGroup group = new PdpGroup(groups.getGroups().get(0));
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testUpdateGroup_PropertiesChanged() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        PdpGroup group = new PdpGroup(groups.getGroups().get(0));
+        group.setProperties(new TreeMap<>());
+
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("properties");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testUpdateGroup_NewDescription() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        group.setDescription("old description");
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertGroupUpdateOnly(group);
+
+        assertEquals("my description", group.getDescription());
+        assertEquals(newgrp.toString(), group.toString());
+    }
+
+    @Test
+    void testUpdateGroup_NewState() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        group.setPdpGroupState(PdpState.TEST);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertGroupUpdateOnly(group);
+
+        assertEquals(PdpState.ACTIVE, group.getPdpGroupState());
+        assertEquals(newgrp.toString(), group.toString());
+    }
+
+    @Test
+    void testUpdateGroup_NewSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    void testUpdateGroup_UpdatedSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        // something different in this subgroup
+        group.getPdpSubgroups().get(0).setDesiredInstanceCount(10);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    void testUpdateGroup_notifyPdpsDelSubGroups() throws Exception {
+        PdpGroup dbgroup = new PdpGroup(loadPdpGroups("createGroupsDelSub.json").getGroups().get(0));
+        when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
+
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+
+        prov.createOrUpdateGroups(groups);
+
+        // verify that DB group was updated
+        List<PdpGroup> updates = getGroupUpdates();
+        assertEquals(1, updates.size());
+        dbgroup = updates.get(0);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());
+
+        assertEquals(newgrp.toString(), dbgroup.toString());
+
+        // no deployment notifications
+        checkEmptyNotification();
+
+        // this requires a PDP UPDATE message
+        List<PdpUpdate> pdpUpdates = getUpdateRequests(2);
+        assertEquals(2, pdpUpdates.size());
+
+        PdpUpdate pdpUpdate = pdpUpdates.get(0);
+        assertEquals(PapConstants.PAP_NAME, pdpUpdate.getSource());
+        assertEquals(PDP2, pdpUpdate.getName());
+        assertNull(pdpUpdate.getPdpGroup());
+
+        pdpUpdate = pdpUpdates.get(1);
+        assertEquals(PapConstants.PAP_NAME, pdpUpdate.getSource());
+        assertEquals(PDP4, pdpUpdate.getName());
+        assertNull(pdpUpdate.getPdpGroup());
+
+        // it also requires a PDP STATE-CHANGE message
+        List<PdpStateChange> changes = getStateChangeRequests(2);
+        assertEquals(2, changes.size());
+
+        PdpStateChange change = changes.get(0);
+        assertEquals(PapConstants.PAP_NAME, change.getSource());
+        assertEquals(PDP2, change.getName());
+        assertEquals(PdpState.PASSIVE, change.getState());
+
+        change = changes.get(1);
+        assertEquals(PapConstants.PAP_NAME, change.getSource());
+        assertEquals(PDP4, change.getName());
+        assertEquals(PdpState.PASSIVE, change.getState());
+    }
+
+    @Test
+    void testUpdateField_Unchanged() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testUpdateField_WasNull() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        group.setDescription(null);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    void testUpdateField_NowNull() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.setDescription(null);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    void testUpdateField_Changed() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.setDescription(group.getDescription() + "-changed");
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    void testAddSubGroup() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+
+        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);
+        newsub.setCurrentInstanceCount(0);
+        newsub.setPdpInstances(new ArrayList<>(0));
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    /**
+     * Tests addSubgroup() when the new subgroup has a wild-card policy type.
+     *
+     * @throws Exception if an error occurs
+     */
+    @Test
+    void testAddSubGroupWildCardPolicyType() throws Exception {
+        when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("daoPolicyListWildCard.json"));
+        when(toscaService.getPolicyTypeList("some.*", "2.3.4")).thenReturn(Collections.emptyList());
+
+        PdpGroups groups = loadPdpGroups("createGroupsWildCard.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        PdpGroup newgrp = groups.getGroups().get(0);
+
+        PdpSubGroup newsub = newgrp.getPdpSubgroups().get(1);
+        newsub.setCurrentInstanceCount(0);
+        newsub.setPdpInstances(new ArrayList<>(0));
+
+        assertEquals(newgrp.toString(), group.toString());
+    }
+
+    @Test
+    void testAddSubGroup_ValidationPolicyTypeNotFound() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        when(toscaService.getPolicyTypeList(any(), any())).thenReturn(Collections.emptyList());
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).hasMessageContaining("unknown policy type");
+    }
+
+    @Test
+    void testAddSubGroup_ValidationPolicyTypeDaoEx() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroupsNewSub.json");
+        PdpGroup group = loadPdpGroups("createGroups.json").getGroups().get(0);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        PfModelException exc = new PfModelException(Status.CONFLICT, EXPECTED_EXCEPTION);
+        when(toscaService.getPolicyTypeList(any(), any())).thenThrow(exc);
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isSameAs(exc);
+    }
+
+    @Test
+    void testAddSubGroup_ValidateVersionPrefixMatch() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup dbgroup = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(dbgroup.getName())).thenReturn(Arrays.asList(dbgroup));
+
+        when(toscaService.getFilteredPolicyList(any())).thenReturn(loadPolicies("createGroupNewPolicy.json"))
+            .thenReturn(loadPolicies("daoPolicyList.json")).thenReturn(loadPolicies("createGroupNewPolicy.json"));
+
+        PdpGroups reqgroups = loadPdpGroups("createGroupsVersPrefix.json");
+
+        prov.createOrUpdateGroups(reqgroups);
+
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(dbgroup.getPdpSubgroups().get(0).getPolicies());
+
+        assertEquals(newgrp.toString(), dbgroup.toString());
+    }
+
+    @Test
+    void testUpdateSubGroup_Invalid() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        // change properties
+        newgrp.getPdpSubgroups().get(0).setProperties(new TreeMap<>());
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("properties");
+
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testUpdateSubGroup_SupportedPolicies() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes()
+            .add(new ToscaConceptIdentifier("typeX.*", "9.8.7"));
+
+        // the group is updated with a new supported policy type in subgroup
+        assertEquals(2, newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes().size());
+        prov.createOrUpdateGroups(groups);
+        // PdpGroup update doesn't allow supported policy type modifications
+        // during pdp group update, the ones in db is maintained
+        assertEquals(1, newgrp.getPdpSubgroups().get(0).getSupportedPolicyTypes().size());
+        assertEquals(newgrp.toString(), group.toString());
+    }
+
+    @Test
+    void testUpdateSubGroup_DesiredCount() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.getPdpSubgroups().get(0).setDesiredInstanceCount(20);
+
+        prov.createOrUpdateGroups(groups);
+
+        assertEquals(newgrp.toString(), group.toString());
+        assertGroupUpdateOnly(group);
+    }
+
+    @Test
+    void testUpdateSubGroup_Unchanged() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        prov.createOrUpdateGroups(groups);
+
+        Collections.sort(newgrp.getPdpSubgroups().get(0).getPolicies());
+        Collections.sort(group.getPdpSubgroups().get(0).getPolicies());
+
+        assertEquals(newgrp.toString(), group.toString());
+
+        // no notifications
+        checkEmptyNotification();
+
+        // no group updates
+        assertNoGroupAction();
+    }
+
+    @Test
+    void testValidateSubGroup_PropertiesMismatch() throws Exception {
+        PdpGroups groups = loadPdpGroups("createGroups.json");
+        PdpGroup newgrp = groups.getGroups().get(0);
+        PdpGroup group = new PdpGroup(newgrp);
+        when(pdpGroupService.getPdpGroups(group.getName())).thenReturn(Arrays.asList(group));
+
+        newgrp.setProperties(new TreeMap<>());
+
+        assertThatThrownBy(() -> prov.createOrUpdateGroups(groups)).isInstanceOf(PfModelException.class)
+            .hasMessageContaining("properties");
+
+        assertNoGroupAction();
+    }
+
+    private void assertNoGroupAction() throws Exception {
+        verify(pdpGroupService, never()).createPdpGroups(any());
+        verify(pdpGroupService, never()).updatePdpGroups(any());
+        verify(reqmap, never()).addRequest(any(), any());
+    }
+
+    private void assertGroupUpdateOnly(PdpGroup group) throws Exception {
+        verify(pdpGroupService, never()).createPdpGroups(any());
+        verify(reqmap, never()).addRequest(any(), any());
+
+        List<PdpGroup> updates = getGroupUpdates();
+        assertEquals(Arrays.asList(group), updates);
+    }
+}