diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml index 271bdc7..2e8205f 100644 --- a/.github/workflows/demo.yml +++ b/.github/workflows/demo.yml @@ -29,8 +29,37 @@ jobs: - name: Demo output on openconfig/public continue-on-error: true + id: demo run: | - OCDIR=~/tmp/public pytests/pattern_test.sh + title="### XSD Demo Test Results on openconfig/public" + status=0 + out=$(OCDIR=~/tmp/public pytests/pattern_test.sh 2>&1) || status=$? + if [ "$status" -eq "0" ]; then + out="all tests passed" + fi + message="${title}"$'\n'"${out}" + # https://github.community/t/set-output-truncates-multiline-strings/16852 + message="${message//'%'/'%25'}" + message="${message//$'\n'/'%0A'}" + message="${message//$'\r'/'%0D'}" + echo "::set-output name=message::$message" + + - name: Find Comment + uses: peter-evans/find-comment@v1 + id: fc-xsd + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: XSD Demo Test Results on openconfig/public + + - name: Create or update comment + uses: peter-evans/create-or-update-comment@v1 + with: + comment-id: ${{ steps.fc-xsd.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ${{ steps.demo.outputs.message }} + edit-mode: replace posix-pattern: name: posix-pattern statement @@ -59,5 +88,34 @@ jobs: - name: Demo output on openconfig/public continue-on-error: true + id: demo run: | - go run gotests/main.go -model-root ~/tmp/public testdata/regexp-test.yang + title="### POSIX Demo Test Results on openconfig/public" + status=0 + out=$(go run gotests/main.go -model-root ~/tmp/public testdata/*.yang 2>&1) || status=$? + if [ "$status" -eq "0" ]; then + out="all tests passed" + fi + message="${title}"$'\n'"${out}" + # https://github.community/t/set-output-truncates-multiline-strings/16852 + message="${message//'%'/'%25'}" + message="${message//$'\n'/'%0A'}" + message="${message//$'\r'/'%0D'}" + echo "::set-output name=message::$message" + + - name: Find Comment + uses: peter-evans/find-comment@v1 + id: fc-posix + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: POSIX Demo Test Results on openconfig/public + + - name: Create or update comment + uses: peter-evans/create-or-update-comment@v1 + with: + comment-id: ${{ steps.fc-posix.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ${{ steps.demo.outputs.message }} + edit-mode: replace diff --git a/README.md b/README.md index 0adfda1..1c550b4 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,29 @@ using a [pyang](https://github.com/mbj4668/pyang) plugin and [oc-ext:posix-pattern](https://github.com/openconfig/public/blob/master/release/models/openconfig-extensions.yang#L114) using [goyang](https://github.com/openconfig/goyang). -## Demo CI Workflow +## How to Contribute to this Repository -There is a demo CI workflow that runs on Pull Requests. They are used to demo -the result of running the tests on the current YANG models. If they cause an -expected test failure (perhaps because you added an uncaught corner case), it -will not block merge and a minor version increment will be given. +Pattern statement tests reside in various modules in the [testdata](testdata) +folder. When adding tests, group pattern tests in test modules named after where +the patterns are found. + +### Workflow for Fixing a Bad Pattern in [openconfig/public](https://github.com/openconfig/public) + +1. Add new pattern tests under [testdata](testdata) and post a PR demonstrating + the failure on openconfig/public. +2. In the PR, note to the reviewers that the failure is expected due to an + incorrect existing pattern. +3. After merge, increment the new minor version of + openconfig/pattern-regex-tests. +4. Open a PR in openconfig/public that updates the new version of + openconfig/pattern-regex-tests in its CI config + https://github.com/openconfig/public/blob/master/cloudbuild.yaml, while + making the corresponding pattern fix in the YANG model. + +### Limitations + +Only typedef tests are currently supported. The current OpenConfig models only +contain patterns in typedef statements. ## Releases @@ -21,6 +38,13 @@ pattern regex), then the minor version must be incremented. At this time, major version updates are not anticipated, but could occur as a result of major changes to the repository. +### Demo CI Workflow + +There is a demo CI workflow that runs on Pull Requests. They are used to demo +the result of running the tests on the current openconfig/public YANG models. +It's possible test failure are expected (e.g. wrong existing pattern). If this +is the case a minor version increment should be given. + -------------------------------------------------------------------------------- [OpenConfig YANG models](https://github.com/openconfig/public/blob/master/README.md) diff --git a/pytests/pattern_test.sh b/pytests/pattern_test.sh index 22a7dc6..12ff472 100755 --- a/pytests/pattern_test.sh +++ b/pytests/pattern_test.sh @@ -10,7 +10,7 @@ TEST_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" REPO_DIR="$TEST_DIR/.." tmpstderr=$(mktemp) -pyang -p $OCDIR -p "$REPO_DIR/testdata" --msg-template="| {line} | {msg} |" --plugindir "$REPO_DIR/pytests/plugins" --check-patterns "$REPO_DIR/testdata/regexp-test.yang" 2> $tmpstderr +pyang -p $OCDIR -p "$REPO_DIR/testdata" --msg-template="| {line} | {msg} |" --plugindir "$REPO_DIR/pytests/plugins" --check-patterns "$REPO_DIR"/testdata/*.yang 2> $tmpstderr retcode=$? if [ $retcode -ne 0 ]; then >&2 echo "| Line # | typedef | error |" diff --git a/testdata/openconfig-bgp-types-test.yang b/testdata/openconfig-bgp-types-test.yang new file mode 100644 index 0000000..e33d487 --- /dev/null +++ b/testdata/openconfig-bgp-types-test.yang @@ -0,0 +1,73 @@ +module openconfig-bgp-types-test { + prefix "rt"; + namespace "urn:openconfig-bgp-types-test"; + + import pattern-test { prefix "pt"; } + import openconfig-bgp-types { prefix "ocbgpt"; } + + leaf bgp-std-community { + type ocbgpt:bgp-std-community-type; + pt:pattern-test-pass "15169:42"; + pt:pattern-test-pass "6643:21438"; + pt:pattern-test-pass "29636:4444"; + pt:pattern-test-pass "65535:65535"; + pt:pattern-test-pass "0:0"; + pt:pattern-test-fail "65536:1"; + pt:pattern-test-fail "1:65536"; + pt:pattern-test-fail "425353:comm"; + } + leaf bgp-ext-community { + type ocbgpt:bgp-ext-community-type; + // Type 1 extended communities (2b AS: 4b integer) + pt:pattern-test-pass "29636:10"; + pt:pattern-test-pass "5413:4294967295"; + pt:pattern-test-pass "4445:0"; + pt:pattern-test-fail "1273:4294967296"; + pt:pattern-test-pass "2856:400"; + pt:pattern-test-fail "5400:invalid"; + pt:pattern-test-fail "i6643:10"; + pt:pattern-test-pass "15169:22432"; + // Type 2 extended communities: (4b IP: 2b integer) + pt:pattern-test-fail "1.1.1.1:4294967296"; + pt:pattern-test-fail "1.2.3.4.5:10"; + pt:pattern-test-pass "82.42.12.35:65535"; + pt:pattern-test-fail "82.42.12.35:66536"; + pt:pattern-test-fail "254.254.256.254:10"; + pt:pattern-test-pass "0.0.0.0:200"; + pt:pattern-test-fail "leading192.0.2.1:65535"; + // 4b AS : 2b integer + pt:pattern-test-fail "4294967296:65535"; + pt:pattern-test-pass "4294967295:65535"; + pt:pattern-test-pass "0:65535"; + pt:pattern-test-pass "4294967295:0"; + pt:pattern-test-fail "4294967296:0"; + // Route Target Type 1 - route-target:<2b AS>:<4b local> + pt:pattern-test-fail "route-target:64"; + pt:pattern-test-pass "route-target:65535:10"; + pt:pattern-test-fail "route-TARGET:65535:10"; + pt:pattern-test-fail "route-target:15169:4294967296"; + pt:pattern-test-pass "route-target:15169:4294967295"; + // Route Target Type 2 - route-target::<2b local> + pt:pattern-test-fail "route-target:256.0.2.36:10"; + pt:pattern-test-pass "route-target:192.0.2.1:10"; + pt:pattern-test-fail "route-target:192.0.2.1:65536"; + // Route Target w/ 4B AS:<2b local> + pt:pattern-test-pass "route-target:4294967295:10"; + pt:pattern-test-fail "route-target:4294967296:10"; + pt:pattern-test-pass "route-target:5413:65535"; + // Route Origin Type 1 - route-target:<2b AS>:<4b local> + pt:pattern-test-fail "route-origin:53"; + pt:pattern-test-pass "route-origin:65535:10"; + pt:pattern-test-fail "route-ORIGINTRAIL:65535:10"; + pt:pattern-test-fail "route-origin:15169:4294967296"; + pt:pattern-test-pass "route-origin:15169:4294967295"; + // Route Origin Type 2 - route-target::<2b local> + pt:pattern-test-fail "route-origin:512.0.2.36:10"; + pt:pattern-test-pass "route-origin:10.18.253.24:10"; + pt:pattern-test-fail "route-origin:192.168.1.1:65536"; + // Route Origin w/ 4B AS:<2b local> + pt:pattern-test-pass "route-origin:4294967295:5353"; + pt:pattern-test-fail "route-origin:4294967296:9009"; + pt:pattern-test-pass "route-origin:5413:65535"; + } +} diff --git a/testdata/openconfig-inet-types-test.yang b/testdata/openconfig-inet-types-test.yang new file mode 100644 index 0000000..7287de8 --- /dev/null +++ b/testdata/openconfig-inet-types-test.yang @@ -0,0 +1,80 @@ +module openconfig-inet-types-test { + prefix "ocinet-t"; + namespace "urn:openconfig-inet-types-test"; + + import pattern-test { prefix "pt"; } + import openconfig-inet-types { prefix "ocinet"; } + + leaf ipv4-address { + type ocinet:ipv4-address; + pt:pattern-test-pass "255.255.255.255"; + pt:pattern-test-pass "0.0.0.0"; + pt:pattern-test-pass "1.1.1.1"; + pt:pattern-test-fail "256.255.255.255"; + pt:pattern-test-fail "1.1.1.256"; + pt:pattern-test-fail "256.1.1.1%eth0"; + } + leaf ipv4-address-zoned { + type ocinet:ipv4-address-zoned; + pt:pattern-test-pass "255.1.1.1%eth0"; + pt:pattern-test-pass "255.255.255.255%eth1"; + pt:pattern-test-pass "0.0.0.0%PoRt3"; + pt:pattern-test-pass "1.1.1.1%FOX10_mouse5"; + pt:pattern-test-fail "255.1.1.1%"; + pt:pattern-test-fail "255.255.255.255"; + pt:pattern-test-fail "0.0.0.0"; + pt:pattern-test-fail "1.1.1.1"; + pt:pattern-test-fail "256.255.255.255"; + pt:pattern-test-fail "1.1.1.256"; + pt:pattern-test-fail "256.1.1.1%eth0"; + } + leaf ip-address { + type ocinet:ip-address; + pt:pattern-test-pass "255.255.255.255"; + pt:pattern-test-pass "2001:db8::1"; + pt:pattern-test-fail "invalid-data"; + pt:pattern-test-pass "::1"; + } + leaf ipv6-address { + type ocinet:ipv6-address; + pt:pattern-test-pass "2620::1000:3202:23e:e1ff:fec7:7112"; + pt:pattern-test-pass "fe80::23e:e1ff:fec7:7112"; + pt:pattern-test-fail "fe80::23e:NOTVALID:fec7:7112"; + pt:pattern-test-fail "FFFF::NOTE::FFFF"; + pt:pattern-test-fail "FFFF::1::42"; + } + leaf ipv4-prefix { + type ocinet:ipv4-prefix; + pt:pattern-test-pass "0.0.0.0/0"; + pt:pattern-test-pass "255.255.255.255/32"; + pt:pattern-test-fail "256.0.0.0/31"; + pt:pattern-test-pass "1.2.3.0/24"; + pt:pattern-test-fail "1.2.3.4/33"; + } + leaf ipv6-prefix { + type ocinet:ipv6-prefix; + pt:pattern-test-pass "::/0"; + pt:pattern-test-pass "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF/128"; + pt:pattern-test-fail "FFFF:FFFF:FFFF:NOTVALID:FFFF:FFFF:FFFF:FFFF/64"; + pt:pattern-test-pass "2001:DB8::/32"; + pt:pattern-test-fail "2001:4C20::/129"; + } + leaf ip-prefix { + type ocinet:ip-prefix; + pt:pattern-test-pass "0.0.0.0/0"; + pt:pattern-test-pass "192.0.2.1/32"; + pt:pattern-test-fail "192.0.2.2/33"; + pt:pattern-test-pass "FE80::CAFE/128"; + pt:pattern-test-fail "FE81::CAFE:DEAD:BEEF/129"; + } + leaf domain-name { + type ocinet:domain-name; + pt:pattern-test-pass "ambroseesorbma"; + pt:pattern-test-fail "ambrose esorbma"; + pt:pattern-test-pass "claire."; + pt:pattern-test-fail "~~~-+=."; + pt:pattern-test-fail "ambrose esorbma"; + pt:pattern-test-pass "012345678901234567890123456789012345678901234567890123456789012."; + pt:pattern-test-fail "0123456789012345678901234567890123456789012345678901234567890123"; + } +} diff --git a/testdata/openconfig-packet-match-types-test.yang b/testdata/openconfig-packet-match-types-test.yang new file mode 100644 index 0000000..d386af0 --- /dev/null +++ b/testdata/openconfig-packet-match-types-test.yang @@ -0,0 +1,29 @@ +module openconfig-packet-match-types-test { + prefix "openconfig-packet-match-types-test"; + namespace "urn:openconfig-packet-match-types-test"; + + import pattern-test { prefix "pt"; } + import openconfig-packet-match-types { prefix "oc-pkt-match-types"; } + + leaf port-num-range { + type oc-pkt-match-types:port-num-range; + pt:pattern-test-pass "0..0"; + pt:pattern-test-pass "00000..00000"; + pt:pattern-test-pass "00..00"; + pt:pattern-test-pass "01..01"; + pt:pattern-test-pass "0..65535"; + pt:pattern-test-pass "01111..09999"; + pt:pattern-test-pass "9999..59999"; + pt:pattern-test-pass "60536..60999"; + pt:pattern-test-pass "60999..61999"; + pt:pattern-test-pass "62999..63999"; + pt:pattern-test-pass "64999..65535"; + pt:pattern-test-fail "65535..66646"; + pt:pattern-test-fail "65535..65536"; + pt:pattern-test-fail "65535..65545"; + pt:pattern-test-fail "65535..65635"; + pt:pattern-test-fail "66535..65535"; + pt:pattern-test-fail "66999..67890"; + pt:pattern-test-fail "70000..70000"; + } +} diff --git a/testdata/regexp-test.yang b/testdata/regexp-test.yang deleted file mode 100644 index 36940e5..0000000 --- a/testdata/regexp-test.yang +++ /dev/null @@ -1,168 +0,0 @@ -module regexp-test { - prefix "rt"; - namespace "urn:openconfig-regexp-test"; - - import pattern-test { prefix "pt"; } - import openconfig-bgp-types { prefix "ocbgpt"; } - import openconfig-inet-types { prefix "ocinet"; } - import openconfig-packet-match-types { prefix "oc-pkt-match-types"; } - - leaf ipv4-address { - type ocinet:ipv4-address; - pt:pattern-test-pass "255.255.255.255"; - pt:pattern-test-pass "0.0.0.0"; - pt:pattern-test-pass "1.1.1.1"; - pt:pattern-test-fail "256.255.255.255"; - pt:pattern-test-fail "1.1.1.256"; - pt:pattern-test-fail "256.1.1.1%eth0"; - } - leaf ipv4-address-zoned { - type ocinet:ipv4-address-zoned; - pt:pattern-test-pass "255.1.1.1%eth0"; - pt:pattern-test-pass "255.255.255.255%eth1"; - pt:pattern-test-pass "0.0.0.0%PoRt3"; - pt:pattern-test-pass "1.1.1.1%FOX10_mouse5"; - pt:pattern-test-fail "255.1.1.1%"; - pt:pattern-test-fail "255.255.255.255"; - pt:pattern-test-fail "0.0.0.0"; - pt:pattern-test-fail "1.1.1.1"; - pt:pattern-test-fail "256.255.255.255"; - pt:pattern-test-fail "1.1.1.256"; - pt:pattern-test-fail "256.1.1.1%eth0"; - } - leaf ip-address { - type ocinet:ip-address; - pt:pattern-test-pass "255.255.255.255"; - pt:pattern-test-pass "2001:db8::1"; - pt:pattern-test-fail "invalid-data"; - pt:pattern-test-pass "::1"; - } - leaf bgp-std-community { - type ocbgpt:bgp-std-community-type; - pt:pattern-test-pass "15169:42"; - pt:pattern-test-pass "6643:21438"; - pt:pattern-test-pass "29636:4444"; - pt:pattern-test-pass "65535:65535"; - pt:pattern-test-pass "0:0"; - pt:pattern-test-fail "65536:1"; - pt:pattern-test-fail "1:65536"; - pt:pattern-test-fail "425353:comm"; - } - leaf bgp-ext-community { - type ocbgpt:bgp-ext-community-type; - // Type 1 extended communities (2b AS: 4b integer) - pt:pattern-test-pass "29636:10"; - pt:pattern-test-pass "5413:4294967295"; - pt:pattern-test-pass "4445:0"; - pt:pattern-test-fail "1273:4294967296"; - pt:pattern-test-pass "2856:400"; - pt:pattern-test-fail "5400:invalid"; - pt:pattern-test-fail "i6643:10"; - pt:pattern-test-pass "15169:22432"; - // Type 2 extended communities: (4b IP: 2b integer) - pt:pattern-test-fail "1.1.1.1:4294967296"; - pt:pattern-test-fail "1.2.3.4.5:10"; - pt:pattern-test-pass "82.42.12.35:65535"; - pt:pattern-test-fail "82.42.12.35:66536"; - pt:pattern-test-fail "254.254.256.254:10"; - pt:pattern-test-pass "0.0.0.0:200"; - pt:pattern-test-fail "leading192.0.2.1:65535"; - // 4b AS : 2b integer - pt:pattern-test-fail "4294967296:65535"; - pt:pattern-test-pass "4294967295:65535"; - pt:pattern-test-pass "0:65535"; - pt:pattern-test-pass "4294967295:0"; - pt:pattern-test-fail "4294967296:0"; - // Route Target Type 1 - route-target:<2b AS>:<4b local> - pt:pattern-test-fail "route-target:64"; - pt:pattern-test-pass "route-target:65535:10"; - pt:pattern-test-fail "route-TARGET:65535:10"; - pt:pattern-test-fail "route-target:15169:4294967296"; - pt:pattern-test-pass "route-target:15169:4294967295"; - // Route Target Type 2 - route-target::<2b local> - pt:pattern-test-fail "route-target:256.0.2.36:10"; - pt:pattern-test-pass "route-target:192.0.2.1:10"; - pt:pattern-test-fail "route-target:192.0.2.1:65536"; - // Route Target w/ 4B AS:<2b local> - pt:pattern-test-pass "route-target:4294967295:10"; - pt:pattern-test-fail "route-target:4294967296:10"; - pt:pattern-test-pass "route-target:5413:65535"; - // Route Origin Type 1 - route-target:<2b AS>:<4b local> - pt:pattern-test-fail "route-origin:53"; - pt:pattern-test-pass "route-origin:65535:10"; - pt:pattern-test-fail "route-ORIGINTRAIL:65535:10"; - pt:pattern-test-fail "route-origin:15169:4294967296"; - pt:pattern-test-pass "route-origin:15169:4294967295"; - // Route Origin Type 2 - route-target::<2b local> - pt:pattern-test-fail "route-origin:512.0.2.36:10"; - pt:pattern-test-pass "route-origin:10.18.253.24:10"; - pt:pattern-test-fail "route-origin:192.168.1.1:65536"; - // Route Origin w/ 4B AS:<2b local> - pt:pattern-test-pass "route-origin:4294967295:5353"; - pt:pattern-test-fail "route-origin:4294967296:9009"; - pt:pattern-test-pass "route-origin:5413:65535"; - } - leaf ipv6-address { - type ocinet:ipv6-address; - pt:pattern-test-pass "2620::1000:3202:23e:e1ff:fec7:7112"; - pt:pattern-test-pass "fe80::23e:e1ff:fec7:7112"; - pt:pattern-test-fail "fe80::23e:NOTVALID:fec7:7112"; - pt:pattern-test-fail "FFFF::NOTE::FFFF"; - pt:pattern-test-fail "FFFF::1::42"; - } - leaf ipv4-prefix { - type ocinet:ipv4-prefix; - pt:pattern-test-pass "0.0.0.0/0"; - pt:pattern-test-pass "255.255.255.255/32"; - pt:pattern-test-fail "256.0.0.0/31"; - pt:pattern-test-pass "1.2.3.0/24"; - pt:pattern-test-fail "1.2.3.4/33"; - } - leaf ipv6-prefix { - type ocinet:ipv6-prefix; - pt:pattern-test-pass "::/0"; - pt:pattern-test-pass "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF/128"; - pt:pattern-test-fail "FFFF:FFFF:FFFF:NOTVALID:FFFF:FFFF:FFFF:FFFF/64"; - pt:pattern-test-pass "2001:DB8::/32"; - pt:pattern-test-fail "2001:4C20::/129"; - } - leaf ip-prefix { - type ocinet:ip-prefix; - pt:pattern-test-pass "0.0.0.0/0"; - pt:pattern-test-pass "192.0.2.1/32"; - pt:pattern-test-fail "192.0.2.2/33"; - pt:pattern-test-pass "FE80::CAFE/128"; - pt:pattern-test-fail "FE81::CAFE:DEAD:BEEF/129"; - } - leaf domain-name { - type ocinet:domain-name; - pt:pattern-test-pass "ambroseesorbma"; - pt:pattern-test-fail "ambrose esorbma"; - pt:pattern-test-pass "claire."; - pt:pattern-test-fail "~~~-+=."; - pt:pattern-test-fail "ambrose esorbma"; - pt:pattern-test-pass "012345678901234567890123456789012345678901234567890123456789012."; - pt:pattern-test-fail "0123456789012345678901234567890123456789012345678901234567890123"; - } - leaf port-num-range { - type oc-pkt-match-types:port-num-range; - pt:pattern-test-pass "0..0"; - pt:pattern-test-pass "00000..00000"; - pt:pattern-test-pass "00..00"; - pt:pattern-test-pass "01..01"; - pt:pattern-test-pass "0..65535"; - pt:pattern-test-pass "01111..09999"; - pt:pattern-test-pass "9999..59999"; - pt:pattern-test-pass "60536..60999"; - pt:pattern-test-pass "60999..61999"; - pt:pattern-test-pass "62999..63999"; - pt:pattern-test-pass "64999..65535"; - pt:pattern-test-fail "65535..66646"; - pt:pattern-test-fail "65535..65536"; - pt:pattern-test-fail "65535..65545"; - pt:pattern-test-fail "65535..65635"; - pt:pattern-test-fail "66535..65535"; - pt:pattern-test-fail "66999..67890"; - pt:pattern-test-fail "70000..70000"; - } -}