From 26fcaa4911f1c9b944361a27a1af57073188c71f Mon Sep 17 00:00:00 2001 From: dwight525 <76115221+dwight525@users.noreply.github.com> Date: Tue, 16 Aug 2022 20:51:25 -0400 Subject: [PATCH] Update usage.md --- docs/usage.md | 60 ++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index bd6e999..4c7bc48 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -11,9 +11,9 @@ It's worth pointing out that `jdiff` is focused on the comparison of the two obj ## exact_match -Check type `exact_match` is concerned with the value of the elements within the data structure. The key-value pairs should match between the reference and comparison data. A diff is generated between the two data sets and tested to see if all the keys and values match. +Check type `exact_match` is concerned with the value of the elements within the data structure. The key-value pairs should match between the reference and comparison data. A diff is generated between the two data sets and tested to see whether all the keys and values match. -As some outputs might be too verbose or include fields that constantly change (e.g. interface counter), it is possible to exclude a portion of data traversed by JMESPath by defining a keys exclusion list. +As some outputs might be too verbose or include fields that constantly change (e.g., interface counter), it is possible to exclude a portion of data traversed by JMESPath by defining a key's exclusion list. Examples: @@ -102,9 +102,9 @@ Use the evaluate method to return the result. False) ``` -As we can see, we return a tuple containing a diff between the pre and post data as well as a boolean for the overall test result. In this case a difference has been found so the status of the test is `False`. +As we can see, we return a tuple containing a diff between the pre and post data as well as a boolean for the overall test result. In this case a difference has been found, so the status of the test is `False`. -Let's see a better way to run `exact_match` for this specific case. Because there is a lot of extra key value pairs, some of which change all the time, we are only interested in `interfaceStatus`, so we can use a utility of jdiff: `extract_data_from_json`, which can extract the value from the keys we are interested in and discard the rest. +Let's see a better way to run `exact_match` for this specific case. Because there are a lot of extra key value pairs, some of which change all the time, we are interested only in `interfaceStatus`. So we can use a utility of jdiff: `extract_data_from_json`, which can extract the value from the keys we are interested in and discard the rest. ```python >>> my_jmspath = "result[*].interfaces.*.[$name$,interfaceStatus]" @@ -121,13 +121,13 @@ Let's see a better way to run `exact_match` for this specific case. Because ther False) ``` -In this case, we only want to compare the value of a single key, the `interfaceStatus` key, so we define the jmespath logic to take the name and the interfaceStatus values from the all the interface objects in the data object. +In this case, we only want to compare the value of a single key, the `interfaceStatus` key. So we define the JMESPath logic to take the name and the interfaceStatus values from all the interface objects in the data object. -This type of logic to extract keys and value from the object is called anchor logic and more [here](#extra_value_from_json). +This type of logic to extract keys and value from the object is called anchor logic. Find more about anchor logic [here](#extra_value_from_json). ### Tolerance -The `tolerance` test checks for the deviation between the value or count between the reference and comparison values. A `tolerance` is defined and passed to the check along with the comparison and reference values. +The `tolerance` test checks for the deviation between the value or count of the reference and comparison values. A `tolerance` is defined and passed to the check along with the comparison and reference values. The `tolerance` argument must be a `float > 0`. The calculation is percentage based, and the test of the values may be +/- the `tolerance` percentage. @@ -190,7 +190,7 @@ Let's have a look at a couple of examples: ... } >>> my_check = CheckType.create("tolerance") ``` -We will define a jmespath search for the values we want to test and extract from the reference and comparison objects. +We will define a JMESPath search for the values we want to test and extract from the reference and comparison objects. ```python >>> my_jmspath = "global.$peers$.*.*.ipv4.[accepted_prefixes,received_prefixes,sent_prefixes]" >>> reference_value = extract_data_from_json(reference_data, my_jmspath) @@ -231,13 +231,13 @@ Let's increase the tolerance: ({}, True) ``` -This check can test if the difference between two values is within a specified tolerance percentage. It could be useful in cases where values like route metrics or optical power levels fluctuate by a small amount. It might be desirable to treat these values as equal if the deviation is within a given range. You can pass in the result of len() to count the number of objects returned within your data. +This check can test whether the difference between two values is within a specified tolerance percentage. It could be useful in cases where values like route metrics or optical power levels fluctuate by a small amount. It might be desirable to treat these values as equal if the deviation is within a given range. You can pass in the result of len() to count the number of objects returned within your data. -### Parameter match +### Parameter Match The `parameter_match` check provides a way to test key/value pairs against baseline values. -The check defines baseline key/value pairs in a Python dictionary. Additionally, mode is set to one of `match` or `no-match`, which specifies if the data should match the baseline, or not. +The check defines baseline key/value pairs in a Python dictionary. Additionally, mode is set to one of `match` or `no-match`, which specifies whether the data should match the baseline, or not. The test fails if: @@ -282,7 +282,7 @@ For example, in network data: >>> comparison_value = extract_data_from_json(comparison_data, path=my_jmspath) ``` -This test requires a mode argument, match in this case matches the keys and values in the "params" to the keys and values in the data. +This test requires a mode argument; match in this case matches the keys and values in the "params" to the keys and values in the data. ```python >>> actual_results = my_check.evaluate( post_value, @@ -296,7 +296,7 @@ This test requires a mode argument, match in this case matches the keys and valu ({'Management1': {'interfaceStatus': 'down'}}, False) ``` -mode: no-match - return the keys and values from the test object that do not match the keys and values provides in "params" +mode: no-match - return the keys and values from the test object that do not match the keys and values provided in "params" ```python >>> my_parameter_match = >>> actual_results = my_check.evaluate( @@ -315,7 +315,7 @@ mode: no-match - return the keys and values from the test object that do not mat The `regex` check type evaluates data against a regular expression passed as an argument to the `evaluate` method. Similarly to `parameter_match` check, the `match` and `no-match` modes are supported. -Let's run an example where we want to check the `burnedInAddress` key has a string representing a MAC Address as value +Let's run an example where we want to check the `burnedInAddress` key has a string representing a MAC address as value. ```python >>> data = { @@ -344,7 +344,7 @@ Let's run an example where we want to check the `burnedInAddress` key has a stri ... } ... ] ... } ->>> # Python regex for matching MAC Address string +>>> # Python regex for matching MAC address string >>> regex_args = {"regex": "(?:[0-9a-fA-F]:?){12}", "mode": "match"} >>> path = "result[*].interfaces.*.[$name$,burnedInAddress]" >>> check = CheckType.create(check_type="regex") @@ -352,13 +352,13 @@ Let's run an example where we want to check the `burnedInAddress` key has a stri >>> value [{'Management1': {'burnedInAddress': '08:00:27:e6:b2:f8'}}] >>> result = check.evaluate(value, **regex_args) ->>> # The test is passed as the burnedInAddress value match our regex +>>> # The test is passed as the burnedInAddress value matches our regex >>> result ({}, True) >>> # What if we want "no-match"? >>> regex_args = {"regex": "(?:[0-9a-fA-F]:?){12}", "mode": "no-match"} >>> result = check.evaluate(value, **regex_args) ->>> # jdiff return the failing data as the regex match the value +>>> # jdiff returns the failing data, as the regex matches the value >>> result ({'Management1': {'burnedInAddress': '08:00:27:e6:b2:f8'}}, False) ``` @@ -371,7 +371,7 @@ The `operator` check is a collection of more specific checks divided into catego | Przemek: The below is not very readable? Indented sections are rendered as code blocks. I would suggest naming these groups "categories" or "groups" and explaing that each of the names is the name of the check that needs to be passed as the argument. -#### `in` operators +#### `in` Operators 1. is-in: Check if the specified element string value is included in a given list of strings. @@ -386,35 +386,37 @@ The `operator` check is a collection of more specific checks divided into catego - in-range: [20, 70] check if value is in range between 20 and 70 +|Dwight: delete the space between 5 and comma in #4, below? + 4. not-range: Check if the value of a specified element is outside of a given numeric range. - not-range: [5 , 40] checks if value is not in range between 5 and 40 -#### `bool` operators +#### `bool` Operators 1. all-same: Check if all content values for the specified element are the same. It can also be used to compare all content values against another specified element. - all-same: flap-count - checks if all values of node in given path is same or not. + checks if all values of node in given path are same or not. -#### `str` operators +#### `str` Operators - 1. contains: determines if an element string value contains the provided test-string value. + 1. contains: Determines if an element string value contains the provided test-string value. - contains: "underlay" checks if "underlay" is present in given data or not. - 2. not-contains: determines if an element string value does not contain the provided test-string value. + 2. not-contains: Determines if an element string value does not contain the provided test-string value. - not-contains: "overlay" checks if "overlay" is present in given node or not. -#### `int`, `float` operators +#### `int`, `float` Operators 1. is-gt: Check if the value of a specified element is greater than a given numeric value. - is-gt: 2 - checks if value should be greater than 2 + checks if value is greater than 2 2. is-lt: Check if the value of a specified element is lesser than a given numeric value. - is-lt: 55 - checks if value is lower than 55 or not. + checks if value is less than 55 Examples: @@ -473,7 +475,7 @@ Examples: ... ] ... } >>> path = "result[0].vrfs.default.peerList[*].[$peerAddress$,peerGroup,vrf,state]" ->>> # "operator" checks requires "mode" argument - which specify the operator logic to apply - +>>> # "operator" checks require "mode" argument - which specifies the operator logic to apply - >>> # and "operator_data" required for the mode defined. >>> check_args = {"params": {"mode": "all-same", "operator_data": True}} >>> check = CheckType.create("operator") @@ -481,7 +483,7 @@ Examples: >>> value [{'7.7.7.7': {'peerGroup': 'EVPN-OVERLAY-SPINE', 'vrf': 'default', 'state': 'Connected'}}, {'10.1.0.0': {'peerGroup': 'IPv4-UNDERLAY-SPINE', 'vrf': 'default', 'state': 'Idle'}}] >>> result = check.evaluate(value, check_args) ->>> # We are looking for peers that have the same peerGroup,vrf and state. If not, return those are not. +>>> # We are looking for peers that have the same peerGroup, vrf, and state. If not, return those that do not. >>> result ((False, [{'7.7.7.7': {'peerGroup': 'EVPN-OVERLAY-SPINE', 'vrf': 'default', 'state': 'Connected'}}, {'10.1.0.0': {'peerGroup': 'IPv4-UNDERLAY-SPINE', 'vrf': 'default', 'state': 'Idle'}}]), False) ``` @@ -513,7 +515,7 @@ What about `str` operator? ((True, [{'7.7.7.7': {'peerGroup': 'EVPN-OVERLAY-SPINE'}}]), False) ``` -Can you guess what would ne the outcome for an `int`, `float` operator? +Can you guess what would be the outcome for an `int`, `float` operator? ```python >>> path = "result[0].vrfs.default.peerList[*].[$peerAddress$,prefixesReceived]"