Closed ygorelik closed 1 year ago
Actually the correct way of reading the list would be this:
r2 = ysanity.Runner()
data = ysanity.Runner.OneList.Ldata()
data.number = YFilter.read # Assign read filter to the key leaf
r2.one_list.ldata.append(data)
runner_read = crud.read(ncc, r2)
With that approach applied to test script:
import sys
import unittest
import logging
from ydk.providers import NetconfServiceProvider
from ydk.services import CRUDService
from ydk.filters import YFilter
from ydk.models.ydktest import ydktest_sanity as ysanity
def test():
crud = CRUDService()
ncc = NetconfServiceProvider('127.0.0.1', 'admin', 'admin', 12022)
# Create the list
r1 = ysanity.Runner()
l1, l2 = ysanity.Runner.OneList.Ldata(), ysanity.Runner.OneList.Ldata()
l1.number, l2.number = 1, 2
l1.name, l2.name = 'a', 'b'
r1.one_list.ldata.extend([l1, l2])
crud.create(ncc, r1)
# Read the list ldata
r2 = ysanity.Runner()
data = ysanity.Runner.OneList.Ldata()
data.number = YFilter.read
r2.one_list.ldata.append(data)
runner_read = crud.read(ncc, r2)
assert len(runner_read.one_list.ldata) == 2, f"ldata list length is {len(runner_read.one_list.ldata)}"
assert runner_read.one_list.ldata['1'].name is None, "ldata.name is expected to be None"
# Read container one-list
r3 = ysanity.Runner()
r3.one_list.yfilter = YFilter.read
runner_read = crud.read(ncc, r3)
assert len(runner_read.one_list.ldata) == 2, \
f"expected ldata length is 2, but it is {len(runner_read.one_list.ldata)}"
assert runner_read.one_list.ldata['1'].name is not None, "ldata.name is expected to be not None"
if __name__ == '__main__':
log = logging.getLogger('ydk')
log.setLevel(logging.INFO)
handler = logging.StreamHandler()
log.addHandler(handler)
test()
And the result is showing correct RPC's and device responses:
Path where models are to be downloaded: /Users/ygorelik/.ydk/127.0.0.1
Connected to 127.0.0.1 on port 12022 using ssh with timeout of -1
Executing CRUD create operation on [ydktest-sanity:runner]
Executing 'edit-config' RPC on [ydktest-sanity:runner]
============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<target>
<candidate/>
</target>
<config><runner xmlns="http://cisco.com/ns/yang/ydktest-sanity" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="merge">
<one-list>
<ldata>
<number>1</number>
<name>a</name>
</ldata>
<ldata>
<number>2</number>
<name>b</name>
</ldata>
</one-list>
</runner>
</config>
</edit-config>
</rpc>
============= Received RPC from device =============
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
<ok/>
</rpc-reply>
Executing 'commit' RPC
============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><commit xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/>
</rpc>
============= Received RPC from device =============
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="3">
<ok/>
</rpc-reply>
Operation succeeded
Executing CRUD read operation on [ydktest-sanity:runner]
Executing 'get' RPC on [ydktest-sanity:runner]
============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><get xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<filter><runner xmlns="http://cisco.com/ns/yang/ydktest-sanity">
<one-list>
<ldata>
<number/>
</ldata>
</one-list>
</runner></filter>
</get>
</rpc>
============= Received RPC from device =============
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="4">
<data>
<runner xmlns="http://cisco.com/ns/yang/ydktest-sanity">
<one-list>
<ldata>
<number>1</number>
</ldata>
<ldata>
<number>2</number>
</ldata>
</one-list>
</runner>
</data>
</rpc-reply>
Executing CRUD read operation on [ydktest-sanity:runner]
Executing 'get' RPC on [ydktest-sanity:runner]
============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><get xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<filter><runner xmlns="http://cisco.com/ns/yang/ydktest-sanity">
<one-list/>
</runner></filter>
</get>
</rpc>
============= Received RPC from device =============
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="5">
<data>
<runner xmlns="http://cisco.com/ns/yang/ydktest-sanity">
<one-list>
<ldata>
<number>1</number>
<name>a</name>
</ldata>
<ldata>
<number>2</number>
<name>b</name>
</ldata>
</one-list>
</runner>
</data>
</rpc-reply>
Disconnected from device
Issue Description
Let's say we have this YANG model (taken from YDK unit test model ydktest-sanity.yang):
When entire list is requested over the Netconf, the RPC should explicitly include the list component, like this:
However the RPC in the below script run contains only top level container, which means the entire structure under the top level container will be retrieved:
Test Script
The test script uses YDK unit test environment including ydktest model bundle and confd.
Logs
Note, the unit test passes only because only one-list model component is present under runner.
System Information
YDK-0.8.6.4