CZ-NIC / yangson

GNU Lesser General Public License v3.0
53 stars 20 forks source link

'when' statement not properly evaluated in case nodes #112

Closed christian-herber closed 3 years ago

christian-herber commented 3 years ago

I have a suspicion that when and case in combination are not handled properly. I have a proprietary model in which a case node is conditional with a when statement.

The condition is always evaluated as false. If I move the when statement inside of the nodes contained within the case statement, validation works. Hoping there is something obvious that could be fixed.

llhotka commented 3 years ago

I don't see it. I used example 4 for testing, and just added a when statement under case in example-4-a.yang (and also removed config false from leaf bar):

module example-4-a {

  yang-version "1.1";

  namespace "http://example.com/example-4-a";

  prefix "ex4a";

  import ietf-netconf-acm {
    prefix "nacm";
    revision-date 2018-02-14;
  }

  container bag {
    description "Top-level container.";
    presence "true";
    leaf foo {
      type uint8;
      units "foondela";
      mandatory "true";
      nacm:default-deny-write;
    }
    leaf bar {
      type boolean;
      default "true";
    }
    choice opts {
      default "a";
      case a {
        when "bar = 'true'";
        leaf baz {
          type empty;
        }
      }
    }
  }
}

Now, the following instance data doesn't validate:

(yangson) $ cat example-data.json 
{
  "example-4-a:bag": {
    "foo": 42,
    "bar": false,
    "baz": [null]
  },
  "example-4-b:quux": [
    "3.1415",
    "0"
  ]
}
(yangson) $ yangson -p .:../../../yang-modules/ietf -v example-data.json yang-library-ex4.json
Schema error: {/example-4-a:bag} config member-not-allowed: baz

With "bar": true, the data validates.

Without seeing your module I can't tell what's wrong. Are you sure that your when expression is correct?

christian-herber commented 3 years ago

thanks for providing the model. I can confirm that this indeed works. You might be right that my when condition is not correct. In your scenario, the logic I used would have been when "bar = 'true'"; Personally, I have a hard time judging from the YANG specification which one is right.

I am editing YANG models in vscode using this extension: https://marketplace.visualstudio.com/items?itemName=typefox.yang-vscode / https://github.com/theia-ide/yang-vscode

The extension can show references to a node, e.g. from a when statement, but it will only do this with my version. I.e. one of the tools must be incorrect, either yangson or yang-vscode.

llhotka commented 3 years ago

You might be right that my when condition is not correct. In your scenario, the logic I used would have been when "bar = 'true'";

Hmm, isn't it the same what I have in that when statement? Did you perhaps mean something like "../bar = 'true'"?

christian-herber commented 3 years ago

yes, you are right, that is what I meant to write.

llhotka commented 3 years ago

OK, that's what I suspected.:-) The thing is that the data tree used for XPath evaluation only has instances of data nodes, but choice and case aren't data nodes. If when is on case, then the context node for XPath evaluation is example-4-a:bag, and bar is its child. On the other hand, if when was on leaf baz statements, then the context node is this leaf, because it is a data node.

This is explained in sec. 7.21.5 of RFC 7950, second bullet.

christian-herber commented 3 years ago

thanks for the clarification and the reference. It is clear to me your implementation is correct.