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

Go function EntityEqual result depends on parameters order #1053

Closed ygorelik closed 2 years ago

ygorelik commented 3 years ago

Expected Behavior

When comparing two entities e1 and e2, the following expression must be always true:

types.EntityEqual(e1, e2) == types.EntityEqual(e2, e1)

Current Behavior

When number of leafs set in the entities is different and values are equal, the result of function EntityEqual depends on the parameters order. To reproduce this issue, run this unit test:

package main

import (
    "fmt"

    "github.com/CiscoDevNet/ydk-go/ydk/types"
)

type Runner struct {
    EntityData types.CommonEntityData

    One Runner_One
}

func (runner *Runner) GetEntityData() *types.CommonEntityData {
    runner.EntityData.YangName = "runner"
    runner.EntityData.BundleName = "ydktest"
    runner.EntityData.ParentYangName = "ydktest-sanity"
    runner.EntityData.SegmentPath = "ydktest-sanity:runner"
    runner.EntityData.YListKeys = []string{}

    runner.EntityData.Children = types.NewOrderedMap()

    runner.EntityData.Children.Append("one", types.YChild{"One", &runner.One})
    //SetParent(&runner.One, runner)

    runner.EntityData.Leafs = types.NewOrderedMap()
    return &(runner.EntityData)
}

type Runner_One struct {
    EntityData types.CommonEntityData

    // integer value type. The type is interface{} with range:
    // -2147483648..2147483647.
    Number interface{}

    // this is string value. The type is string.
    Name interface{}
}

func (one *Runner_One) GetEntityData() *types.CommonEntityData {
    one.EntityData.YangName = "one"
    one.EntityData.BundleName = "ydktest"
    one.EntityData.ParentYangName = "runner"
    one.EntityData.SegmentPath = "one"

    one.EntityData.Children = types.NewOrderedMap()

    one.EntityData.Leafs = types.NewOrderedMap()
    one.EntityData.Leafs.Append("number", types.YLeaf{"Number", one.Number})
    one.EntityData.Leafs.Append("name", types.YLeaf{"Name", one.Name})

    one.EntityData.YListKeys = []string{}

    return &(one.EntityData)
}

func main() {
    e1 := Runner{}
    e1.One.Name = "test"
    types.SetAllParents(&e1)

    e2 := Runner{}
    types.SetAllParents(&e2)

    if types.EntityEqual(&e1, &e2) {
        fmt.Println("e1 is equal to e2")
    } else {
        fmt.Println("e1 is NOT equal to e2")
    }

    if types.EntityEqual(&e2, &e1) {
        fmt.Println("e2 is equal to e1")
    } else {
        fmt.Println("e2 is NOT equal to e1")
    }
}

The test gives the following output:

ygorelik$ go run unit-test-1053.go 
e1 is NOT equal to e2
e2 is equal to e1

This result points to the issue in the implementation of the function EntityEqual.

System Information

YDK 0.8.5.2

ygorelik commented 3 years ago

The code fix could be found here.