From e731118eca0540792a140803f18c298fb3be132d Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Tue, 10 Nov 2020 16:32:50 +0000 Subject: Adding & Testing method for breaking JSON Data into 'fragments' Improving Bookstore test model https://jira.onap.org/browse/CPS-32 Issue-ID: CPS-32 Change-Id: Ie03e03c041233aa908ab55902c1b387f96eb1c2e Signed-off-by: ToineSiebelink --- .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 4 +- .../groovy/org/onap/cps/utils/YangUtilsSpec.groovy | 47 +++++++++++++------ cps-service/src/test/resources/bookstore.json | 54 ++++++++++++++-------- cps-service/src/test/resources/bookstore.yang | 13 ++++-- 4 files changed, 82 insertions(+), 36 deletions(-) (limited to 'cps-service/src/test') diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index 709378ebee..2a3d5cbc5f 100755 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -67,7 +67,7 @@ class CpServiceImplSpec extends Specification { } def assertModule(SchemaContext schemaContext){ - def optionalModule = schemaContext.findModule('bookstore', Revision.of('2020-09-15')) + def optionalModule = schemaContext.findModule('stores', Revision.of('2020-09-15')) return schemaContext.modules.size() == 1 && optionalModule.isPresent() } @@ -167,4 +167,4 @@ class CpServiceImplSpec extends Specification { expect: 'anchor name is returned by service' objectUnderTest.createAnchor(anchorDetails) == 'dummyAnchorName' } -} \ No newline at end of file +} diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy index 8aabc48448..6a463ad6f5 100644 --- a/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy @@ -19,14 +19,16 @@ package org.onap.cps.utils -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode +import org.onap.cps.TestUtils import org.opendaylight.yangtools.yang.common.QName import org.opendaylight.yangtools.yang.common.Revision +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException import spock.lang.Specification import spock.lang.Unroll class YangUtilsSpec extends Specification{ + def 'Parsing a valid Yang Model'() { given: 'a yang model (file)' def file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) @@ -34,14 +36,14 @@ class YangUtilsSpec extends Specification{ def result = YangUtils.parseYangModelFile(file) then: 'the result contain 1 module of the correct name and revision' result.modules.size() == 1 - def optionalModule = result.findModule('bookstore', Revision.of('2020-09-15')) + def optionalModule = result.findModule('stores', Revision.of('2020-09-15')) optionalModule.isPresent() } @Unroll - def 'parsing invalid yang file (#description)'() { + def 'Parsing invalid yang file (#description).'() { given: 'a file with #description' - File file = new File(ClassLoader.getSystemClassLoader().getResource(filename).getFile()); + File file = new File(ClassLoader.getSystemClassLoader().getResource(filename).getFile()) when: 'the file is parsed' YangUtils.parseYangModelFile(file) then: 'an exception is thrown' @@ -52,29 +54,48 @@ class YangUtilsSpec extends Specification{ 'someOtherFile.txt' | 'no .yang extension' || IllegalArgumentException } - def 'Parsing a valid Json String'() { + def 'Parsing a valid Json String.'() { given: 'a yang model (file)' def jsonData = org.onap.cps.TestUtils.getResourceFileContent('bookstore.json') and: 'a model for that data' def file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) def schemaContext = YangUtils.parseYangModelFile(file) when: 'the json data is parsed' - NormalizedNode result = YangUtils.parseJsonData(jsonData, schemaContext); + NormalizedNode result = YangUtils.parseJsonData(jsonData, schemaContext) then: 'the result is a normalized node of the correct type' - result.nodeType == QName.create('org:onap:ccsdk:sample','2020-09-15','bookstore') + result.nodeType == QName.create('org:onap:ccsdk:sample', '2020-09-15', 'bookstore') } - def 'Parsing an invalid Json String'() { + @Unroll + def 'Parsing invalid data: #description.'() { given: 'a yang model (file)' - def jsonData = '{incomplete json' - and: 'a model' def file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) def schemaContext = YangUtils.parseYangModelFile(file) - when: 'the invalid json is parsed' - YangUtils.parseJsonData(jsonData, schemaContext); - then: ' an exception is thrown' + when: 'invalid data is parsed' + YangUtils.parseJsonData(invalidJson, schemaContext) + then: 'an exception is thrown' thrown(IllegalStateException) + where: 'the following invalid json is provided' + invalidJson | description + '{incomplete json' | 'incomplete json' + '{"test:bookstore": {"address": "Parnell st." }}' | 'json with un-modelled data' } + def 'Breaking a Json Data Object into fragments.'() { + given: 'a Yang module' + def file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) + def schemaContext = YangUtils.parseYangModelFile(file) + def module = schemaContext.findModule('stores', Revision.of('2020-09-15')).get() + and: 'a normalized node for that model' + def jsonData = TestUtils.getResourceFileContent('bookstore.json') + def normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext) + when: 'the json data is fragmented' + def result = YangUtils.fragmentNormalizedNode(normalizedNode, module) + then: 'the system creates a (root) fragment without a parent and 2 children (categories)' + result.parentFragment == null + result.childFragments.size() == 2 + and: 'each child (category) has the root fragment (result) as parent and in turn as 1 child (a list of books)' + result.childFragments.each { it.parentFragment == result && it.childFragments.size() == 1 } + } } diff --git a/cps-service/src/test/resources/bookstore.json b/cps-service/src/test/resources/bookstore.json index 44d5d424cd..d1b8d6882d 100644 --- a/cps-service/src/test/resources/bookstore.json +++ b/cps-service/src/test/resources/bookstore.json @@ -1,34 +1,52 @@ { "test:bookstore":{ - "categories":[ + "bookstore-name": "Chapters", + "categories": [ { - "name":"web", - "books":[ + "code": "01", + "name": "SciFi", + "books": [ { - "authors":[ - "Toine Siebelink","David Lang" + "authors": [ + "Iain M. Banks" ], - "lang":"en", - "price":"123456", - "pub_year":"2020", - "title":"My first book" + "lang": "en", + "price": "895", + "pub_year": "1994", + "title": "Feersum Endjinn" + }, + { + "authors": [ + "Ursula K. Le Guin", + "Joe Haldeman", + "Orson Scott Card", + "david Brin", + "Rober Silverberg", + "Dan Simmons", + "Greg Bear" + ], + "lang": "en", + "price": "1099", + "pub_year": "1999", + "title": "Far Horizons" } ] }, { - "name":"art", - "books":[ + "name": "kids", + "code": "02", + "books": [ { - "authors":[ - "Test" + "authors": [ + "Philip Pullman" ], - "lang":"en", - "price":"1234", - "pub_year":"2020", - "title":"My 2nd book" + "lang": "en", + "price": "699", + "pub_year": "1995", + "title": "The Golden Compass" } ] } ] } -} \ No newline at end of file +} diff --git a/cps-service/src/test/resources/bookstore.yang b/cps-service/src/test/resources/bookstore.yang index 01eac5f339..2179fb93d9 100644 --- a/cps-service/src/test/resources/bookstore.yang +++ b/cps-service/src/test/resources/bookstore.yang @@ -1,6 +1,5 @@ -module bookstore { +module stores { yang-version 1.1; - namespace "org:onap:ccsdk:sample"; prefix book-store; @@ -18,9 +17,17 @@ module bookstore { container bookstore { + leaf bookstore-name { + type string; + } + list categories { - key name; + key "code"; + + leaf code { + type string; + } leaf name { type string; -- cgit 1.2.3-korg