summaryrefslogtreecommitdiffstats
path: root/cps-ri/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'cps-ri/src/test')
-rwxr-xr-xcps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy37
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy36
2 files changed, 59 insertions, 14 deletions
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
index acc243b5b4..5e15ca795f 100755
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
@@ -27,6 +27,7 @@ import org.onap.cps.cpspath.parser.PathParsingException
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.entities.FragmentEntity
import org.onap.cps.spi.exceptions.AlreadyDefinedException
+import org.onap.cps.spi.exceptions.AlreadyDefinedExceptionBatch
import org.onap.cps.spi.exceptions.AnchorNotFoundException
import org.onap.cps.spi.exceptions.CpsAdminException
import org.onap.cps.spi.exceptions.CpsPathException
@@ -48,6 +49,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
CpsDataPersistenceService objectUnderTest
static final JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+ static final DataNodeBuilder dataNodeBuilder = new DataNodeBuilder()
static final String SET_DATA = '/data/fragment.sql'
static final int DATASPACE_1001_ID = 1001L
@@ -165,7 +167,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
def grandChild = buildDataNode('/parent-201/child-204[@key="NEW1"]/grand-child-204[@key2="NEW1-CHILD"]', [leave:'value'], [])
listElements[0].childDataNodes = [grandChild]
when: 'the new data node (list elements) are added to an existing parent node'
- objectUnderTest.addListElementsBatch(DATASPACE_NAME, ANCHOR_NAME3, '/parent-201', [listElements])
+ objectUnderTest.addMultipleLists(DATASPACE_NAME, ANCHOR_NAME3, '/parent-201', [listElements])
then: 'new entries are successfully persisted, parent node now contains 5 children (2 new + 3 existing before)'
def parentFragment = fragmentRepository.getById(LIST_DATA_NODE_PARENT201_FRAGMENT_ID)
def allChildXpaths = parentFragment.childFragments.collect { it.xpath }
@@ -179,17 +181,41 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
}
@Sql([CLEAR_DATA, SET_DATA])
+ def 'Add multiple list with a mix of existing and new elements'() {
+ given: 'two new child list elements for an existing parent'
+ def existingDataNode = dataNodeBuilder.withXpath('/parent-100/child-001').withLeaves(['id': '001']).build()
+ def newDataNode1 = dataNodeBuilder.withXpath('/parent-100/child-new1').withLeaves(['id': 'new1']).build()
+ def newDataNode2 = dataNodeBuilder.withXpath('/parent-200/child-new2').withLeaves(['id': 'new2']).build()
+ def dataNodeList1 = [existingDataNode, newDataNode1]
+ def dataNodeList2 = [newDataNode2]
+ when: 'duplicate data node is requested to be added'
+ objectUnderTest.addMultipleLists(DATASPACE_NAME, ANCHOR_NAME3, '/', [dataNodeList1,dataNodeList2])
+ then: 'already defined batch exception is thrown'
+ def thrown = thrown(AlreadyDefinedExceptionBatch)
+ and: 'it only contains the xpath(s) of the duplicated elements'
+ assert thrown.alreadyDefinedXpaths.size() == 1
+ assert thrown.alreadyDefinedXpaths.contains('/parent-100/child-001')
+ and: 'it does NOT contains the xpaths of the new element that were not combined with existing elements'
+ assert !thrown.alreadyDefinedXpaths.contains('/parent-100/child-new1')
+ assert !thrown.alreadyDefinedXpaths.contains('/parent-100/child-new1')
+ and: 'the new entity is inserted correctly'
+ def dataspaceEntity = dataspaceRepository.getByName(DATASPACE_NAME)
+ def anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, ANCHOR_NAME3)
+ fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, '/parent-200/child-new2').isPresent()
+ }
+
+ @Sql([CLEAR_DATA, SET_DATA])
def 'Add list element error scenario: #scenario.'() {
given: 'list element as a collection of data nodes'
- def listElementCollection = toDataNodes(listElementXpaths)
+ def listElements = toDataNodes(listElementXpaths)
when: 'attempt to add list elements to parent node'
- objectUnderTest.addListElements(DATASPACE_NAME, ANCHOR_NAME3, parentNodeXpath, listElementCollection)
+ objectUnderTest.addListElements(DATASPACE_NAME, ANCHOR_NAME3, parentNodeXpath, listElements)
then: 'a #expectedException is thrown'
thrown(expectedException)
where: 'following parameters were used'
scenario | parentNodeXpath | listElementXpaths || expectedException
'parent node does not exist' | '/unknown' | ['irrelevant'] || DataNodeNotFoundException
- 'data fragment already exists' | '/parent-201' | ["/parent-201/child-204[@key='A']"] || AlreadyDefinedException
+ 'data fragment already exists' | '/parent-201' | ["/parent-201/child-204[@key='A']"] || AlreadyDefinedExceptionBatch
}
@Sql([CLEAR_DATA, SET_DATA])
@@ -559,8 +585,9 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
return xpaths.collect { new DataNodeBuilder().withXpath(it).build() }
}
+
static DataNode buildDataNode(xpath, leaves, childDataNodes) {
- return new DataNodeBuilder().withXpath(xpath).withLeaves(leaves).withChildDataNodes(childDataNodes).build()
+ return dataNodeBuilder.withXpath(xpath).withLeaves(leaves).withChildDataNodes(childDataNodes).build()
}
static Map<String, Object> getLeavesMap(FragmentEntity fragmentEntity) {
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy
index 1bbf358e54..470b03afdf 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy
@@ -86,17 +86,25 @@ class CpsDataPersistenceServiceSpec extends Specification {
assert concurrencyException.getDetails().contains('/some/xpath')
}
- def 'Handling of StaleStateException (caused by concurrent updates) during update data nodes and descendants.'() {
- given: 'the fragment repository returns a list of fragment entities'
- mockFragmentRepository.getByDataspaceAndAnchorAndXpath(*_) >> new FragmentEntity()
- and: 'a data node is concurrently updated by another transaction'
+ def 'Handling of StaleStateException (caused by concurrent updates) during update data nodes and descendants.'() {
+ given: 'the system contains and can update one datanode'
+ def dataNode1 = mockDataNodeAndFragmentEntity('/node1', 'OK')
+ and: 'the system contains two more datanodes that throw an exception while updating'
+ def dataNode2 = mockDataNodeAndFragmentEntity('/node2', 'EXCEPTION')
+ def dataNode3 = mockDataNodeAndFragmentEntity('/node3', 'EXCEPTION')
+ and: 'the batch update will therefore also fail'
mockFragmentRepository.saveAll(*_) >> { throw new StaleStateException("concurrent updates") }
- when: 'attempt to update data node with submitted data nodes'
- objectUnderTest.updateDataNodesAndDescendants('some-dataspace', 'some-anchor', [])
+ when: 'attempt batch update data nodes'
+ objectUnderTest.updateDataNodesAndDescendants('some-dataspace', 'some-anchor', [dataNode1, dataNode2, dataNode3])
then: 'concurrency exception is thrown'
- def concurrencyException = thrown(ConcurrencyException)
- assert concurrencyException.getDetails().contains('some-dataspace')
- assert concurrencyException.getDetails().contains('some-anchor')
+ def thrown = thrown(ConcurrencyException)
+ assert thrown.message == 'Concurrent Transactions'
+ and: 'it does not contain the successfull datanode'
+ assert !thrown.details.contains('/node1')
+ and: 'it contains the failed datanodes'
+ assert thrown.details.contains('/node2')
+ assert thrown.details.contains('/node3')
+
}
def 'Retrieving a data node with a property JSON value of #scenario'() {
@@ -193,4 +201,14 @@ class CpsDataPersistenceServiceSpec extends Specification {
assert fragmentEntities.size() == 2
}})
}
+
+ def mockDataNodeAndFragmentEntity(xpath, scenario) {
+ def dataNode = new DataNodeBuilder().withXpath(xpath).build()
+ def fragmentEntity = new FragmentEntity(xpath: xpath, childFragments: [])
+ mockFragmentRepository.getByDataspaceAndAnchorAndXpath(_, _, xpath) >> fragmentEntity
+ if ('EXCEPTION' == scenario) {
+ mockFragmentRepository.save(fragmentEntity) >> { throw new StaleStateException("concurrent updates") }
+ }
+ return dataNode
+ }
} \ No newline at end of file