diff --git a/features/api/api.feature b/features/api/api.feature index 0ed5ffdfd0..809d426e07 100644 --- a/features/api/api.feature +++ b/features/api/api.feature @@ -21,7 +21,7 @@ Feature: Client behaviour for the API endpoints When I run `python3 -c "from uaclient.api.u.pro.services.list.v1 import list"` as non-root When I run `python3 -c "from uaclient.api.u.pro.status.enabled_services.v1 import enabled_services"` as non-root When I run `python3 -c "from uaclient.api.u.pro.status.is_attached.v1 import is_attached"` as non-root - When I run `python3 -c "from uaclient.api.u.pro.token_info.v1 import get_token_info` as non-root + When I run `python3 -c "from uaclient.api.u.pro.token_info.v1 import get_token_info"` as non-root When I run `python3 -c "from uaclient.api.u.pro.version.v1 import version"` as non-root When I run `python3 -c "from uaclient.api.u.security.package_manifest.v1 import package_manifest"` as non-root When I run `python3 -c "from uaclient.api.u.unattended_upgrades.status.v1 import status"` as non-root diff --git a/features/api/token_info.feature b/features/api/token_info.feature new file mode 100644 index 0000000000..bbc49956db --- /dev/null +++ b/features/api/token_info.feature @@ -0,0 +1,142 @@ +Feature: api.u.pro.token_info.v1 + + @uses.config.contract_token + Scenario Outline: Get token info from api + Given a `` `` machine with ubuntu-advantage-tools installed + When I verify root and non-root `pro api u.pro.token_info.v1 --args token=$behave_var{contract_token}` calls have the same output + When I run `pro api u.pro.token_info.v1 --args token=$behave_var{contract_token}` as non-root + Then stdout is a json matching the `api_response` schema + And the json API response data matches the `api_token_info_response` schema + When I apply this jq filter `.attributes.services[] | {name: .name, available: .available}` to the API data field output + Then if `` in `xenial or bionic` then output is: + """ + {"name": "anbox-cloud", "available": false} + {"name": "cc-eal", "available": true} + {"name": "cis", "available": true} + {"name": "esm-apps", "available": true} + {"name": "esm-infra", "available": true} + {"name": "fips", "available": true} + {"name": "fips-preview", "available": false} + {"name": "fips-updates", "available": true} + {"name": "landscape", "available": false} + {"name": "livepatch", "available": true} + {"name": "realtime-kernel", "available": false} + {"name": "ros", "available": true} + {"name": "ros-updates", "available": true} + """ + And if `` in `focal` then output is: + """ + {"name": "anbox-cloud", "available": true} + {"name": "cc-eal", "available": false} + {"name": "esm-apps", "available": true} + {"name": "esm-infra", "available": true} + {"name": "fips", "available": true} + {"name": "fips-preview", "available": false} + {"name": "fips-updates", "available": true} + {"name": "landscape", "available": false} + {"name": "livepatch", "available": true} + {"name": "realtime-kernel", "available": false} + {"name": "ros", "available": true} + {"name": "ros-updates", "available": false} + {"name": "usg", "available": true} + """ + And if `` in `jammy` then output is: + """ + {"name": "anbox-cloud", "available": true} + {"name": "cc-eal", "available": false} + {"name": "esm-apps", "available": true} + {"name": "esm-infra", "available": true} + {"name": "fips", "available": false} + {"name": "fips-preview", "available": true} + {"name": "fips-updates", "available": true} + {"name": "landscape", "available": false} + {"name": "livepatch", "available": true} + {"name": "realtime-kernel", "available": true} + {"name": "ros", "available": false} + {"name": "ros-updates", "available": false} + {"name": "usg", "available": true} + """ + And if `` in `noble` then output is: + """ + {"name": "anbox-cloud", "available": true} + {"name": "cc-eal", "available": false} + {"name": "esm-apps", "available": true} + {"name": "esm-infra", "available": true} + {"name": "fips", "available": false} + {"name": "fips-preview", "available": false} + {"name": "fips-updates", "available": false} + {"name": "landscape", "available": true} + {"name": "livepatch", "available": true} + {"name": "realtime-kernel", "available": true} + {"name": "ros", "available": false} + {"name": "ros-updates", "available": false} + {"name": "usg", "available": false} + """ + And if `release` in `oracular` then output is: + """ + {"name": "anbox-cloud", "available": true} + {"name": "cc-eal", "available": false} + {"name": "esm-apps", "available": true} + {"name": "esm-infra", "available": true} + {"name": "fips", "available": true} + {"name": "fips-preview", "available": false} + {"name": "fips-updates", "available": true} + {"name": "landscape", "available": false} + {"name": "livepatch", "available": true} + {"name": "realtime-kernel", "available": false} + {"name": "ros", "available": true} + {"name": "ros-updates", "available": false} + {"name": "usg", "available": true} + """ + When I verify that running `pro api u.pro.token_info.v1` `with sudo` exits `1` + Then API errors field output matches regexp: + """ + [ + { + "code": "api-missing-argument", + "meta": { + "arg": "token", + "endpoint": "u.pro.token_info.v1" + }, + "title": "Missing argument 'token' for endpoint u.pro.token_info.v1" + } + ] + """ + + Examples: ubuntu release + | release | machine_type | + | xenial | lxd-container | + | bionic | lxd-container | + | focal | lxd-container | + | jammy | lxd-container | + | noble | lxd-container | + | oracular | lxd-container | + + @uses.config.contract_token_staging_expired + Scenario Outline: Check api with an expired contract token + Given a `` `` machine with ubuntu-advantage-tools installed + When I change contract to staging with sudo + Then I verify that running `pro api u.pro.token_info.v1 --args token=$behave_var{contract_token_staging_expired}` `as non-root` exits `1` + Then API errors field output matches regexp: + """ + [ + { + "code": "token-forbidden-expired", + "meta": { + "contract_expiry_date": "08-21-2022", + "contract_id": ".*", + "date": "August 21, 2022" + }, + "title": "Contract .* expired on .*" + } + ] + """ + + Examples: ubuntu release + | release | machine_type | + | xenial | lxd-container | + | bionic | lxd-container | + | focal | lxd-container | + | jammy | lxd-container | + | noble | lxd-container | + | oracular | lxd-container | diff --git a/features/environment.py b/features/environment.py index e01897a36d..4dc53e3d16 100644 --- a/features/environment.py +++ b/features/environment.py @@ -46,6 +46,8 @@ class UAClientBehaveConfig: A valid contract token to use during attach scenarios :param contract_token_staging: A valid staging contract token to use during attach scenarios + :param contract_token_staging_expired: + An expired staging contract token to use during attach scenarios :param machine_types: A comma-separated string of machine_types to test: lxd-container, lxd-vm, azure.pro, azure.pro-fips, azure.generic, aws.pro, diff --git a/features/util.py b/features/util.py index d6093c2c7e..0d24ec0bf0 100644 --- a/features/util.py +++ b/features/util.py @@ -413,6 +413,13 @@ def process_template_vars( dt_str, logger_fn, ) + elif function_name == "contract_token_staging_expired": + processed_template = _replace_and_log( + processed_template, + match.group(0), + context.pro_config.contract_token_staging_expired, + logger_fn, + ) elif function_name == "contract_token_staging": processed_template = _replace_and_log( processed_template,