openconfig / ygot

A YANG-centric Go toolkit - Go/Protobuf Code Generation; Validation; Marshaling/Unmarshaling
Apache License 2.0
286 stars 107 forks source link

Couldn't get correct leafref which under the list #185

Closed liuqu closed 4 years ago

liuqu commented 6 years ago

Hi, guys, I tried the basic workflow of ygot for openconfig-telemetry yang model, but it fails to validate the contents of Go struct. I think the the contents of struct is complete. It looks like validate module couldn't get correct leafref which under the list.

Here is the schema tree and struct contents.

telemetry-system (container)
  destination-groups (container)
    destination-group (list)
      config (container)
        group-id (leaf)
      destinations (container)
        destination (list)
          config (container)
            destination-address (leaf)
            destination-port (leaf)
          destination-address (leaf)
          destination-port (leaf)
          state (container)
            destination-address (leaf)
            destination-port (leaf)
      group-id (leaf)
      state (container)
        group-id (leaf)
  sensor-groups (container)
    sensor-group (list)
      config (container)
        sensor-group-id (leaf)
      sensor-group-id (leaf)
      sensor-paths (container)
        sensor-path (list)
          config (container)
            exclude-filter (leaf)
            path (leaf)
          path (leaf)
          state (container)
            exclude-filter (leaf)
            path (leaf)
      state (container)
        sensor-group-id (leaf)
  subscriptions (container)
    persistent (container)
      subscription (list)
        config (container)
          encoding (leaf)
          local-source-address (leaf)
          originated-qos-marking (leaf)
          protocol (leaf)
          subscription-name (leaf)
        destination-groups (container)
          destination-group (list)
            state (container)
              group-id (leaf)
            config (container)
              group-id (leaf)
            group-id (leaf)
        sensor-profiles (container)
          sensor-profile (list)
            config (container)
              heartbeat-interval (leaf)
              sample-interval (leaf)
              sensor-group (leaf)
              suppress-redundant (leaf)
            sensor-group (leaf)
            state (container)
              heartbeat-interval (leaf)
              sample-interval (leaf)
              sensor-group (leaf)
              suppress-redundant (leaf)
        state (container)
          protocol (leaf)
          subscription-id (leaf)
          subscription-name (leaf)
          encoding (leaf)
          local-source-address (leaf)
          originated-qos-marking (leaf)
        subscription-name (leaf)
    dynamic (container)
      subscription (list)
        sensor-paths (container)
          sensor-path (list)
            path (leaf)
            state (container)
              exclude-filter (leaf)
              path (leaf)
        state (container)
          encoding (leaf)
          subscription-id (leaf)
          sample-interval (leaf)
          suppress-redundant (leaf)
          destination-address (leaf)
          destination-port (leaf)
          heartbeat-interval (leaf)
          originated-qos-marking (leaf)
          protocol (leaf)
        subscription-id (leaf)
     [device (container)]
      TelemetrySystem [telemetry-system (container)]
        DestinationGroups [destination-groups (container)]
          DestinationGroup [destination-group (list)]
          HS
            Config [config (container)]
                GroupId : "HS" [group-id (leaf)]
            Destinations [destinations (container)]
              Destination [destination (list)]
              {20.20.20.20 2345}
                Config [config (container)]
                    DestinationAddress : "20.20.20.20" [destination-address (leaf)]
                    DestinationPort : 2345 [destination-port (leaf)]
                  DestinationAddress : "20.20.20.20" [destination-address (leaf)]
                  DestinationPort : 2345 [destination-port (leaf)]
                State [state (container)]
                    DestinationAddress : "20.20.20.20" [destination-address (leaf)]
                    DestinationPort : 2345 [destination-port (leaf)]
              GroupId : "HS" [group-id (leaf)]
        SensorGroups [sensor-groups (container)]
          SensorGroup [sensor-group (list)]
          HS_PORT_COUNTERS
            Config [config (container)]
                SensorGroupId : "HS_PORT_COUNTERS" [sensor-group-id (leaf)]
              SensorGroupId : "HS_PORT_COUNTERS" [sensor-group-id (leaf)]
            SensorPaths [sensor-paths (container)]
              SensorPath [sensor-path (list)]
              /counters/pfc
                Config [config (container)]
                    Path : "/counters/pfc" [path (leaf)]
                  Path : "/counters/pfc" [path (leaf)]
                State [state (container)]
                    Path : "/counters/pfc" [path (leaf)]
            State [state (container)]
                SensorGroupId : "HS_PORT_COUNTERS" [sensor-group-id (leaf)]
        Subscriptions [subscriptions (container)]
                  Encoding : 0 [encoding (leaf)]
                  Protocol : 0 [protocol (leaf)]
          Persistent [persistent (container)]
            Subscription [subscription (list)]
            HS_PORT
              Config [config (container)]
                  Encoding : 1 [encoding (leaf)]
                  LocalSourceAddress : "10.10.10.10" [local-source-address (leaf)]
                  Protocol : 1 [protocol (leaf)]
                  SubscriptionName : "HS_PORT" [subscription-name (leaf)]
              DestinationGroups [destination-groups (container)]
                DestinationGroup [destination-group (list)]
                HS
                  Config [config (container)]
                      GroupId : "HS" [group-id (leaf)]
                    GroupId : "HS" [group-id (leaf)]
                  State [state (container)]
                      GroupId : "HS" [group-id (leaf)]
              SensorProfiles [sensor-profiles (container)]
                SensorProfile [sensor-profile (list)]
                HS_PORT_COUNTERS
                  Config [config (container)]
                      HeartbeatInterval : 30000 [heartbeat-interval (leaf)]
                      SampleInterval : 1000 [sample-interval (leaf)]
                      SensorGroup : "HS_PORT_COUNTERS" [sensor-group (leaf)]
                      SuppressRedundant : true [suppress-redundant (leaf)]
                    SensorGroup : "HS_PORT_COUNTERS" [sensor-group (leaf)]
                  State [state (container)]
                      HeartbeatInterval : 30000 [heartbeat-interval (leaf)]
                      SampleInterval : 1000 [sample-interval (leaf)]
                      SensorGroup : "HS_PORT_COUNTERS" [sensor-group (leaf)]
                      SuppressRedundant : true [suppress-redundant (leaf)]
              State [state (container)]
                  Encoding : 1 [encoding (leaf)]
                  LocalSourceAddress : "10.10.10.10" [local-source-address (leaf)]
                  Protocol : 1 [protocol (leaf)]
                  SubscriptionName : "HS_PORT" [subscription-name (leaf)]
                SubscriptionName : "HS_PORT" [subscription-name (leaf)]

"openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup_Config" should get the root path node "openconfig.OpenconfigTelemetry_TelemetrySystem" not "openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent".

DataNodeAtPath got leafref with path elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" >  from node path /device/telemetry-system/subscriptions/persistent/subscription/destination-groups/destination-group/config/group-id, field name GroupId
going up data tree from type *string to *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup_Config, schema path from parent is [group-id], remaining path elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
going up data tree from type *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup_Config to *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup, schema path from parent is [config], remaining path elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
going up data tree from type *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup to map[string]*openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup, schema path from parent is [destination-group], remaining path elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
going up data tree from type map[string]*openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup to *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups, schema path from parent is [destination-group], remaining path elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
going up data tree from type *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups to *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription, schema path from parent is [destination-groups], remaining path elem:<name:".." > elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
going up data tree from type *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription to map[string]*openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription, schema path from parent is [subscription], remaining path elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
going up data tree from type map[string]*openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription to *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent, schema path from parent is [subscription], remaining path elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
root element type *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent with remaining path elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
. GetNode next path name:"destination-groups" , value { map[HS_PORT:0xc4202bdf50] (map ptr) }
. getNodesContainer: schema persistent, next path name:"destination-groups" , value { map[HS_PORT:0xc4202bdf50] (map ptr) }
. check field name subscription, paths [[subscription]]
. ERR: could not find path in tree beyond schema node persistent, (type *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent), remaining path elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 

It looks like get the wrong data type this step

going up data tree from type map[string]*openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups_DestinationGroup to *openconfig.OpenconfigTelemetry_TelemetrySystem_Subscriptions_Persistent_Subscription_DestinationGroups, schema path from parent is [destination-group], remaining path elem:<name:".." > elem:<name:".." > elem:<name:".." > elem:<name:"destination-groups" > elem:<name:"destination-group" > elem:<name:"group-id" > 
robshakir commented 6 years ago

Hi,

Thanks for the issue. Can you please provide the command that you used to generate the output package with generator please? It's useful for us to understand exactly the combination of options used for debugging.

Thanks, r.

liuqu commented 6 years ago

Thanks for your reply. Here is the command.

go run $GOPATH/src/github.com/openconfig/ygot/generator/generator.go -generate_fakeroot -path=yang -output_file=oc-telemetry/oc-telemetry.go -package_name=openconfig -exclude_modules=ietf-interfaces yang/oc-telemetry/openconfig-telemetry.yang
robshakir commented 6 years ago

Thanks -- I have an example that reproduces the bug - and agree with your diagnosis. It looks like when we do the walk to handle .., we don't cleanly handle being inside a list. This is meaning that we are consuming two .. elements of the path such that the specified leafref path doesn't get us to the relevant jumping off point to resolve the rest of the path.

Working to debug why now.

robshakir commented 6 years ago

Sorry -- this dropped off my radar. The https://github.com/openconfig/ygot/tree/debug-185 branch fixes this issue. Apologies for the delay in fixing it!

wenovus commented 4 years ago

Rob's #214 fixed this.