CiscoDevNet / ydk-gen

Generate model-driven APIs from YANG models
http://ciscodevnet.github.io/ydk-gen/
Apache License 2.0
135 stars 74 forks source link

Index error returned when converting an empty string from JSON to XML #1061

Closed ldacol closed 2 years ago

ldacol commented 2 years ago

Issue tracker is ONLY used for reporting bugs. Please use the YDK Community for any support issues.

Expected Behavior

Conversion from JSON to XML finalizes successfully

Current Behavior

An IndexError: basic_string::at is returned when attempting a conversion from JSON to XML with payload choice-value:"" The payload is correctly converted from XML to JSON to fail when converted back to XML.

Steps to Reproduce

Issue is shown when attempting to convert the following JSON payload

{
  "junos-conf-root:configuration": {
    "junos-conf-policy-options:policy-options": {
      "policy-statement": [
        {
          "name": "IPV4",
          "term": [
            {
              "name": "OSPF-ACCEPT",
              "from": {
                "protocol": [
                  "ospf"
                ],
                "route-filter": [
                  {
                    "address": "1.1.1.0/24",
                    "choice-ident": "orlonger",
                    "choice-value": ""
                  }
                ]
              },
              "then": {
                "accept": [null]
              }
            }
          ]
        }
      ]
    }
  }
}

Your Script

def yang_yaml_to_xml(json_file):
    config_json_yang = json.dumps(json.load(open(json_file)))
    print (config_json_yang)
    decoded_json_yang = CODEC.decode(JSON_PROVIDER, config_json_yang)
    yang_xml = CODEC.encode(XML_PROVIDER, decoded_json_yang)
    return yang_xml

Logs

Enable logging and post the logs below

Traceback (most recent call last):
  File "convert1.py", line 249, in <module>
    print(yang_yaml_to_xml(ARGS['yaml_file']))
  File "convert1.py", line 218, in yang_yaml_to_xml
    decoded_json_yang = CODEC.decode(JSON_PROVIDER, config_json_yang)
  File "/opt/neteng/lib/python3.6/site-packages/ydk/errors/error_handler.py", line 112, in helper
    return func(self, provider, entity, *args, **kwargs)
  File "/opt/neteng/lib/python3.6/site-packages/ydk/services/codec_service.py", line 140, in decode
    return self._decode(provider, payload_holder, subtree)
  File "/opt/neteng/lib/python3.6/site-packages/ydk/services/codec_service.py", line 174, in _decode
    root_data_node = codec_service.decode(root_schema, payload, provider.encoding)
IndexError: basic_string::at

System Information

Red Hat Enterprise Linux Server release 7.9 (Maipo) Python 3.6.9

ygorelik commented 2 years ago

Resolved in YDK-0.8.6.3; see this commit for details.

Test script:

import unittest
import logging

from test_utils import enable_logging

from ydk.providers import CodecServiceProvider
from ydk.services import CodecService

from ydk.models.ydktest import ydktest_sanity as ysanity

class SanityTest(unittest.TestCase):

    def setUp(self):
        self.codec_service = CodecService()
        self.json_provider = CodecServiceProvider(type='json')
        enable_logging(logging.DEBUG)

    def test_json_empty_string(self):
        r = ysanity.Runner()
        r.ytypes.built_in_t.name = ""

        payload = self.codec_service.encode(self.json_provider, r)
        expected = '''{
  "ydktest-sanity:runner": {
    "ytypes": {
      "built-in-t": {
        "name": ""
      }
    }
  }
}
'''
        self.assertEqual(expected, payload)
        entity = self.codec_service.decode(self.json_provider, payload)
        self.assertEqual(r, entity)

if __name__ == '__main__':
    suite = unittest.TestSuite()
    testloader = unittest.TestLoader()
    testnames = testloader.getTestCaseNames(SanityTest)
    for name in testnames:
        suite.addTest(SanityTest(name))
    ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()