diff --git a/README.md b/README.md
index b911774..768722c 100644
--- a/README.md
+++ b/README.md
@@ -1,49 +1,68 @@
-# Test Center CLI (Beta)
+
+#Test Center CLI
+
+
- [Get started with the Test Center CLI](#get-started-with-the-test-center-cli)
- - [Install Test Center CLI](#install-test-center-cli)
- - [Stay up to date](#stay-up-to-date)
- - [API credentials](#api-credentials)
+ - [Install Test Center CLI](#install-test-center-cli)
+ - [Stay up to date](#stay-up-to-date)
+ - [API credentials](#api-credentials)
- [Concepts](#concepts)
- [CLI workflows](#cli-workflows)
- - [Run a test](#run-a-test)
- - [Manage Test Center objects using JSON](#manage-test-center-objects-using-json)
- - [Manage Test Center objects using granular commands](#manage-test-center-objects-using-granular-commands)
+ - [Run a test](#run-a-test)
+ - [Manage Test Center objects using JSON](#manage-test-center-objects-using-json)
+ - [Manage Test Center objects using granular commands](#manage-test-center-objects-using-granular-commands)
- [Available operations and commands](#available-operations-and-commands)
- - [Help](#help)
- - [List test suites](#list-test-suites)
- - [Create a test suite](#create-a-test-suite)
- - [Import a test suite](#import-a-test-suite)
- - [Add a test case to a test suite](#add-a-test-case-to-a-test-suite)
- - [Generate a default test suite for a property](#generate-a-default-test-suite-for-a-property)
- - [Edit a test suite](#edit-a-test-suite)
- - [Edit a test suite using JSON](#edit-a-test-suite-using-json)
- - [Remove a test suite](#remove-a-test-suite)
- - [Remove a test case from a test suite](#remove-a-test-case-from-a-test-suite)
- - [Restore a test suite](#restore-a-test-suite)
- - [Get a test suite's details](#get-a-test-suites-details)
- - [List supported conditions](#list-supported-conditions)
- - [Run a test](#run-a-test-1)
- - [Run a test using JSON](#run-a-test-using-json)
+ - [Help](#help)
+ - [Run a test](#run-a-test)
+ - [Run a test using JSON](#run-a-test-using-json)
+ - [List test runs](#list-test-runs)
+ - [Get a test run](#get-a-test-run)
+ - [List test suites](#list-test-suites)
+ - [Get raw request and response for a test run or test case execution](#get-raw-request-and-response-for-a-test-run-or-test-case-execution)
+ - [Get log lines for a test case execution](#get-log-lines-for-a-test-case-execution)
+ - [Create a test suite](#create-a-test-suite)
+ - [Import a test suite](#import-a-test-suite)
+ - [Generate a default test suite for a property](#generate-a-default-test-suite-for-a-property)
+ - [Edit a test suite](#edit-a-test-suite)
+ - [Edit a test suite using JSON](#edit-a-test-suite-using-json)
+ - [Remove a test suite](#remove-a-test-suite)
+ - [Restore a test suite](#restore-a-test-suite)
+ - [Get a test suite's overview](#get-a-test-suites-overview)
+ - [Get a test suite with child objects](#get-a-test-suite-with-child-objects)
+ - [Add a test case to a test suite](#add-a-test-case-to-a-test-suite)
+ - [Remove a test case from a test suite](#remove-a-test-case-from-a-test-suite)
+ - [Edit a test case in a test suite](#edit-a-test-case-in-a-test-suite)
+ - [List test cases](#list-test-cases)
+ - [Get a specific test case](#get-a-specific-test-case)
+ - [Create variables](#create-variables)
+ - [Edit a variable](#edit-a-variable)
+ - [List variables](#list-variables)
+ - [Get a specific variable](#get-a-specific-variable)
+ - [Remove a specific variable](#remove-a-specific-variable)
+ - [Check how functions work using JSON](#check-how-functions-work-using-json)
+ - [List created test requests](#list-created-test-requests)
+ - [List supported conditions](#list-supported-conditions)
+ - [List created conditions](#list-created-conditions)
- [Available flags](#available-flags)
- - [edgerc](#edgerc)
- - [section](#section)
- - [account-key](#account-key)
- - [force-color](#force-color)
- - [help](#help-1)
- - [version](#version)
- - [json](#json)
+ - [edgerc](#edgerc)
+ - [section](#section)
+ - [account-key](#account-key)
+ - [force-color](#force-color)
+ - [help](#help)
+ - [version](#version)
+ - [json](#json)
- [Exit codes](#exit-codes)
- [Windows 10 2018 version](#windows-10-2018-version)
- [Notice](#notice)
-
+
# Get started with the Test Center CLI
Test Center is a testing tool that checks the effect of configuration changes on your web property. Use this CLI as part of your testing protocol to increase your confidence in the safety and accuracy of your configuration changes.
-> **_Breaking changes_**: Due to the active development of the new Test Center experience, we implemented the following changes to the CLI:
1. In the `clientProfile` object, the `clientType` field is changed to `client` with values `CHROME` and `CURL`.
2. In a test suite object, the `testCaseCount` field changed to `executableTestCaseCount`. This change is caused by the [Variables group](https://techdocs.akamai.com/test-ctr/v3/reference/variables-overview) feature.
Impacted operations:
- [List test suites](#list-test-suites),
- [Add a test case to a test suite](#add-a-test-case-to-a-test-suite),
- [Generate a default test suite for a property](#generate-a-default-test-suite-for-a-property),
- [Import a test suite](#import-a-test-suite).
Implement necessary changes in your objects before running these operations.
+> **_Breaking changes_**: Due to the active development of the new Test Center experience, we implemented the following changes to the CLI:
1. The `--section` flag default value changed from `test-center` to `default`.
2. The `conditions` command changes into `condition`; the parent command for all operations related to conditions. To get the template, you need to run the `condition template` command.
3. The `test` command changes into the parent command for all operations related to test runs. You can now [get](#get-a-test-run), [list](#list-test-runs), or [create](#run-a-test) a test run.
4. The subcommands for test suites changed their names:
- The `add` command got renamed to `create`.
- The `edit` command got renamed to `update`.
- The `view` command got renamed to `get-with-child-objects`.
- The `import` command got renamed to `create-with-child-objects`.
- The `manage` command got renamed to `update-with-child-objects`.
5. The `--group-by` flag for test suite now accepts the `test-request`, `condition`, or `client-profile` value.
6. The `add-test-case` and `remove-test-case` commands got moved under the `test-case` command and renamed to `create` and `remove`.
7. The `-v` shorthand for the `--version` flag got removed.
8. The `-i` shorthand for the `--ip-version` flag got removed.
9. The `--property` flag got renamed to `--property-name` with shorthand `-p`.
10. The `--propver` flag got renamed to `--property-version` with shorthand `-v`.
## Install Test Center CLI
@@ -69,7 +88,7 @@ To set up your `.edgerc` file, see [Get started with APIs](https://techdocs.akam
- **Test suite**. Test suites act as containers for test cases. You can add a name and description to a test suite to provide more details about the test suite and included test cases. You can also set if the test suite needs to be locked or stateful. Test suites can be tested as test objects associated with a property version or on their own.
-- **Locked test suite**. Locked test suites can be modified only by their editors and owners. Test Center users who create locked test suites automatically become their owners. Owners can designate owners or editors and other users can request edit access. To learn how, see [Give the edit access to a locked test suite](https://techdocs.akamai.com/test-ctr/docs/test-suite-edit-access).
+- **Locked test suite**. Locked test suites can be modified only by their editors and owners. Test Center users who create locked test suites automatically become their owners. Owners can designate owners or editors and other users can request edit access. To learn how, see [Give the edit access to a locked test suite](https://techdocs.akamai.com/test-ctr/docs/functional-objects#give-the-edit-access-to-a-locked-test-suite).
- **Stateful test suite**. Stateful test suites are test suites within which test cases are executed based on the order number defined for each test case. Cookies and session information are retained for subsequent test cases.
@@ -77,7 +96,9 @@ To set up your `.edgerc` file, see [Get started with APIs](https://techdocs.akam
- **Property version**. Property version refers to a Property Manager property version.
-- **Test results**. A test result for functional testing is a comparison of the expected value with the actual value. It can be either *Passed* or *Failed*. *Passed* means that the *Expected* result of the test was the same as the *Actual* result. *Failed* means that the *Expected* result of the test was different from the *Actual* result. To learn more about Functional testing results, see [Test results concepts](https://techdocs.akamai.com/test-ctr/docs/results-concepts) and [How to read test run results](https://techdocs.akamai.com/test-ctr/docs/view-results#functional-testing).
+- **Test results**. A test result for functional testing is a comparison of the expected value with the actual value. It can be either *Passed* or *Failed*. *Passed* means that the *Expected* result of the test was the same as the *Actual* result. *Failed* means that the *Expected* result of the test was different from the *Actual* result. To learn more about Functional testing results, see [Test results concepts](https://techdocs.akamai.com/test-ctr/docs/glossary) and [Functional testing results](https://techdocs.akamai.com/test-ctr/docs/test-run-results#functional-testing-results).
+
+- **Variables and functions**. Variables allow you to reuse specific values in test cases' input fields. They enable you to create test cases with complex metadata and run very specific tests. Variables can be assigned statically or dynamically. To extract the value from the test case response and assign it to a variable dynamically, you need to use functions. To learn more, see [Variables](https://techdocs.akamai.com/test-ctr/reference/variables-overview).
# CLI workflows
@@ -90,37 +111,177 @@ You can run a test for a property version, test suite, or test case using a [CLI
Here are the commands supporting JSON input:
- [Generate a default test suite for a property](#generate-a-default-test-suite-for-a-property). Generates a default test suite for a property version for you to [import](#import-a-test-suite).
- [Import a test suite](#import-a-test-suite). Imports to Test Center a test suite with test cases, variables, and property version association.
- - [Get a test suite's details](#get-a-test-suites-details). Fetches, or exports, test suite's details that you can save and import on a different account or [edit](#edit-a-test-suite-using-json). You can also use this operation to clone test suites within your account.
+ - [Get a test suite with child objects](#get-a-test-suite-with-child-objects). Fetches, or exports, test suite's details that you can save and import on a different account or [edit](#edit-a-test-suite-using-json). You can also use this operation to clone test suites within your account.
- [Edit a test suite using JSON](#edit-a-test-suite-using-json).
- [Run a test using JSON](#run-a-test-using-json).
## Manage Test Center objects using granular commands
Here are the commands you can use to manage Test Center objects from the CLI:
- - [List test suites](#list-test-suites).
- - [Create a test suite](#create-a-test-suite).
- - [Add a test case to a test suite](#add-a-test-case-to-a-test-suite).
- - [Edit a test suite](#edit-a-test-suite).
- - [Remove a test suite](#remove-a-test-suite).
- - [Remove a test case from a test suite](#remove-a-test-case-from-a-test-suite).
- - [Restore a test suite](#restore-a-test-suite).
- - [Get a test suite's details](#get-a-test-suites-details).
- - [List supported conditions](#list-supported-conditions).
- - [Run a test](#run-a-test).
+ - [Run a test](#run-a-test)
+ - [List test runs](#list-test-runs)
+ - [Get a test run](#get-a-test-run)
+ - [Get raw request and response for a test run or test case execution](#get-raw-request-and-response-for-a-test-run-or-test-case-execution)
+ - [Get log lines for a test case execution](#get-log-lines-for-a-test-case-execution)
+ - [List test suites](#list-test-suites)
+ - [Create a test suite](#create-a-test-suite)
+ - [Edit a test suite](#edit-a-test-suite)
+ - [Remove a test suite](#remove-a-test-suite)
+ - [Restore a test suite](#restore-a-test-suite)
+ - [Get a test suite's overview](#get-a-test-suites-overview)
+ - [Get a test suite with child objects](#get-a-test-suite-with-child-objects)
+ - [Add a test case to a test suite](#add-a-test-case-to-a-test-suite)
+ - [Remove a test case from a test suite](#remove-a-test-case-from-a-test-suite)
+ - [Edit a test case in a test suite](#edit-a-test-case-in-a-test-suite)
+ - [List test cases](#list-test-cases)
+ - [Get a specific test case](#get-a-specific-test-case)
+ - [Create variables](#create-variables)
+ - [Edit a variable](#edit-a-variable)
+ - [List variables](#list-variables)
+ - [Get a specific variable](#get-a-specific-variable)
+ - [Remove a specific variable](#remove-a-specific-variable)
+ - [List created test requests](#list-created-test-requests)
+ - [List supported conditions](#list-supported-conditions)
+ - [List created conditions](#list-created-conditions)
# Available operations and commands
## Help
The `help` command returns an overview of available commands and flags.
+## Run a test
+The `test run` command runs a test for a specific test suite, single test case, or a property version.
+
+**Command**:
+- To run a test for a test suite: `test run [--test-suite-id ID | --test-suite-name 'NAME'] --env STAGING|PRODUCTION`
+- To run a test for a property version: `test run [--property-name 'PROPERTY NAME' | --property-id 'ID' --property-version 'PROPERTY VERSION'] --env STAGING|PRODUCTION`
+- To run a test for a simple test case: `test run [-url URL -condition CONDITION STATEMENT --ip-version v4|v6 [--client CURL| CHROME] [--request-method GET|HEAD|POST] [--request-body REQUEST_BODY] [--encode-request-body] [--add-header 'name: value' ...] [--modify-header 'name: value' ...] [--filter-header name ...]] --env STAGING|PRODUCTION`, where:
+
+ - `ID` and `NAME` specify the test suite you want to run the test for. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--test-suite-id` or `--test-suite-name`.
+ - `PROPERTY NAME` or `ID` and `PROPERTY VERSION` specify the property in Property Manager you want to run the test for. To get these values you can use the [Property Manager CLI](https://github.com/akamai/cli-property-manager) and the `list-properties|lpr` operation. Provide either the `--property-name` or `--property-id` flag.
+ - `URL` is the fully qualified URL of the resource to test. It needs to contain the protocol, hostname, path, and any applicable string parameters — for example, *https://www.example.com*. This flag needs to be combined with `--ip-version` and `--condition` flags.
+ - `CONDITION STATEMENT` is a condition statement you want to run the test for. To get the list of created conditions to reuse, run the [List created conditions](#list-created-conditions) operation and to create a new condition, run the [List supported conditions](#list-supported-conditions) operation. Make sure to replace default values in `" "` with your own. The `--condition` flag needs to be combined with `--url` and `--ip-version` flags.
+ - the `--ip-version` flag specifies the IP version to execute the test case over, either `v4` or `v6`. This flag is optional, set to `v4` by default. This flag needs to be combined with `--url` and `--condition` flags.
+ - the `--client` flag specifies the client profile to execute the test case over, either `CURL` or `CHROME`. It's set to `CURL` by default. This flag is optional.
+ - the `--request-method` flag specifies the request method for the test case, either `GET`, `HEAD` or `POST`. It's set to `GET` by default. This flag is optional.
+ - the `--request-body` flag adds `REQUEST_BODY` to the request. This flag is optional and applicable only if `--client` is set to `CURL` and `--request-method` to `POST`.
+ - the `--encode-request-body` flag encodes `REQUEST BODY`. This flag is optional and applicable only if `--client` is set to `CURL` and `--request-method` to `POST`.
+ - the `--add-header` and `--modify-header` flags specify the request headers to respectively added or modify by the request. Headers should follow the format `name: value`. These flags are optional and accept multiple values. You can also use these flags to provide Pragma headers. See [Pragma headers](https://techdocs.akamai.com/edge-diagnostics/docs/pragma-headers) for the list of supported values. These flag needs to be combined with `--url`, `--ip-version`, and `--condition` flags.
+ - the `--filter-header` flag filters the header from the request. Provide only the `name` of the header. This flag is optional. This flag needs to be combined with `--url`, `--ip-version`, and `--condition` flags.
+ - the `--env` flag specifies the environment you want to run the test on, either `STAGING` or `PRODUCTION`. This flag is optional, set to `STAGING` by default.
+
+**Examples**:
+- `akamai test-center test run --test-suite-name 'Regression test cases for example.com'`
+- `akamai test-center test run --property-name 'example.com' --property-version '26'`
+- `akamai test-center test run --property-id '438285' --property-version '26' --env PRODUCTION`
+- `akamai test-center test run --url 'https://example.com/' --condition 'Response code is one of "200"' --ip-version 'V6' --modify-header 'Accept: application/json'`
+
+**Expected output**: Once you submit the test run, it may take few minutes for Test Center to execute the test. To learn more about returned test results, check [Functional testing results](https://techdocs.akamai.com/test-ctr/docs/test-run-results#functional-testing-results). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-test-runs) description.
+
+## Run a test using JSON
+The `test` command runs a test for a specific test suite, single test case, or a property version using a JSON file or JSON input. You can use the [API documentation](https://techdocs.akamai.com/test-ctr/reference/post-test-runs) to create the JSON file. Add your values to `BODY PARAMS` fields, copy the body of your request from the CURL code sample, and save it as a JSON file. To get `testCaseId` values run the `test-suite view` command for a specific test suite with the `--json` flag.
+
+**Command**:
+
+To import a specific file from your computer: `test-center test run < {FILE_PATH}/FILE_NAME.json`, where `FILE_PATH` and `FILE_NAME` are respectively location and name of the file to import.
+
+JSON example to run a test for a property version:
+```
+{
+ "functional":{
+ "configVersionExecutions":[
+ {
+ "testSuiteExecutions":[
+ {
+ "testSuiteId":31306
+ },
+ {
+ "testCaseExecutions":[
+ {
+ "testCaseId":41
+ }
+ ],
+ "testSuiteId":87
+ }
+ ],
+ "configVersionId":22556
+ }
+ ]
+ },
+ "targetEnvironment": "STAGING"
+}
+```
+
+JSON example to run a test for a test suite:
+```
+{
+ "functional":{
+ "testSuiteExecutions":[
+ {
+ "testCaseExecutions":[
+ {
+ "testCaseId":65
+ },
+ {
+ "testCaseId":71
+ },
+ {
+ "testCaseId":98
+ }
+ ],
+ "testSuiteId":281
+ }
+ ]
+ },
+ "targetEnvironment": "STAGING"
+}
+```
+JSON example to run a test for a single test case:
+```
+{
+ "functional":{
+ "testCaseExecution":{
+ "testRequest":{
+ "testRequestUrl":"https://www.example.com"
+ },
+ "condition":{
+ "conditionExpression":"Log request details - Referrer header is not logged"
+ },
+ "clientProfile":{
+ "ipVersion":"IPV4"
+ }
+ }
+ },
+ "targetEnvironment":"STAGING"
+}
+```
+
+**Expected output**: Once you submit the test run, it may take a few minutes for Test Center to execute the test. To learn more about returned test results, check [Functional testing results](https://techdocs.akamai.com/test-ctr/docs/test-run-results#functional-testing-results). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-test-runs) description.
+
+## List test runs
+The `test list` command returns test runs created by users of your account.
+
+**Command**: `test list`
+
+**Expected output**: List of created test runs. You can use a returned `testRunId` to [get a specific test run results](#get-a-test-run). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-runs) description.
+
+## Get a test run
+The `test get` command returns details and results of a specific test run.
+
+**Command**: `test get --test-run-id ID`, where `ID` is the `testRunId` of the test run you want to get the details of. You can get this value with the [List test runs](#list-test-runs) operation.
+
+**Example**: `test get --test-run-id 2500`
+
+**Expected output**: Returns the results of a test run. To learn more about returned test results, check [Functional testing results](https://techdocs.akamai.com/test-ctr/docs/test-run-results#functional-testing-results). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-run) description.
+
## List test suites
The `test-suite list` command lists all test suites. You can filter the results for test suites created by a user, a property the test suite is associated with, or a string from the test suite's name or description.
The list also includes the recently deleted test suites that you can [restore](#restore-a-test-suite).
-**Command**: `test-suite list [--property 'PROPERTY NAME'] [--propver 'PROPERTY VERSION'] [-user 'USERNAME'] [--search STRING]`, where:
+**Command**: `test-suite list [--property-name 'PROPERTY NAME'| --property-id 'ID'] [--property-version 'PROPERTY VERSION'] [-user 'USERNAME'] [--search STRING]`, where:
-- the `--property` flag filters the results for a specific `PROPERTY NAME` which the test suite is associated with. The `--propver` flag filters the results further for a specific `PROPERTY VERSION`.
+- the `--property-name` or `--property-id` flags filter the results for a specific `PROPERTY NAME` or `ID` which the test suite is associated with. The `--property-version` flag filters the results further for a specific `PROPERTY VERSION`. If applicable, provide either the `--property-name` or `--property-id` flag.
- the `--user` flag filters the results for a `USERNAME` who created, edited, or deleted the test suite.
- the `--search` flag filters the results for a specific `STRING` in the test suite's name or description.
@@ -128,104 +289,110 @@ You can combine multiple flags to narrow the list.
**Examples**
- `akamai test-center test-suite list`
-- `akamai test-center test-suite list --property 'example.com' --propver '4'`
-- `akamai test-center test-suite list -u 'johndoe' -s 'regression'`
+- `akamai test-center test-suite list --property-name 'example.com' --property-version '4'`
+- `akamai test-center test-suite list -u 'johndoe' --search 'regression'`
+
+**Expected output**: The response lists all test suites matching the requested filters. You can use the returned test suite ID to [get a test suite's overview](#get-a-test-suites-overview) or [get a test suite with child objects](#get-a-test-suite-with-child-objects). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-suites) description.
+
+## Get raw request and response for a test run or test case execution
+The `raw-request-response` command returns a raw request and response for a test run or a test case execution.
+
+**Command**: `raw-request-response [--test-run-id TEST_RUN_ID | --tcx-id TEST_CASE_EXECUTION_ID]`, where:
+
+- `TEST_RUN_ID` specifies the test run ID you want to get the transaction details of. To get this value, run the [List test runs](#list-test-runs) operation.
+- `TEST_CASE_EXECUTION_ID` specifies the test case execution you want to get the details of. To get this value, run the [Get a test run](#get-a-test-run) operation.
+
+Provide either the `--tcx-id` or `--test-run-id` flag.
+
+**Example**: `akamai test-center raw-request-response --test-run-id 2009`
+
+**Expected output**: The response provides the raw request and response.
-**Expected output**: The response lists all test suites matching the requested filters. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/get-test-suites) description. You can use the returned test suite ID to run the [Get a test suite's details](#get-a-test-suites-details) operation.
+## Get log lines for a test case execution
+The `log-lines` command returns log lines for a specific test case execution.
+
+**Command**: `log-lines --tcx-id TEST_CASE_EXECUTION_ID`, where the `TEST_CASE_EXECUTION_ID` specifies the execution you want to get the logs for. To get this value, run the [Get a test run](#get-a-test-run) operation.
+
+**Example**: `akamai test-center test log-lines --tcx-id 1`
+
+**Expected output**: The response provides log lines for the execution.
## Create a test suite
-The `test-suite add` command creates a new test suite.
+The `test-suite create` command creates a new test suite.
-**Command**: `test-suite add --name 'NAME' [--description 'DESCRIPTION'] [--unlocked] [--stateful] [--property 'PROPERTY NAME' --propver 'PROPERTY VERSION']`, where:
+**Command**: `test-suite create --name 'NAME' [--description 'DESCRIPTION'] [--unlocked] [--stateful] [--property-name 'PROPERTY NAME' | --property-id 'ID' --property-version 'PROPERTY VERSION']`, where:
- `NAME` is the name of the test suite.
- `DESCRIPTION` is the description for the test suite. The `--description` flag is optional.
- the `--unlocked` flag unlocks the test suite. This flag is optional. By default, all test suites are [locked](#concepts).
- the `--stateful` flag makes the test suite stateful. This flag is optional. By default, all test suites are [stateless](#concepts).
-- the `--property` and `--propver` flags associate the test suite with a specific property version. `PROPERTY NAME` is the name of the property in Property Manager and `PROPERTY VERSION`, its appropriate version. You can use [Property Manager CLI](https://github.com/akamai/cli-property-manager) and the `list-properties|lpr` operation to get these values. These flags are optional, but they need to be used together.
+- the `--property-name` or `--property-id` and `--property-version` flags associate the test suite with a specific property version. `PROPERTY NAME` is the name of the property in Property Manager, ID its unique identifier, and `PROPERTY VERSION`, its appropriate version. You can use [Property Manager CLI](https://github.com/akamai/cli-property-manager) and the `list-properties|lpr` operation to get these values. These flags are optional. If appropriate, provide either `--property-name` or `--property-id` and combine it with `--property-version`.
**Examples**:
-- `akamai test-center test-suite add --name 'new test suite'`
-- `akamai test-center test-suite add --name 'new test suite' --description 'TS for example.com' --unlocked --stateful --property 'example.com' --propver '4'`
+- `akamai test-center test-suite create --name 'new test suite'`
+- `akamai test-center test-suite create --name 'new test suite' --description 'TS for example.com' --unlocked --stateful --property-name 'example.com' --property-version '4'`
-**Expected output**: The response includes details about the created test suite. It also includes the ID of the test suite that you can use in other operations — for example, to [add a test case to a test suite](#add-a-test-case-to-a-test-suite). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/post-test-suites) description.
+**Expected output**: The response includes details about the created test suite. It also includes the ID of the test suite that you can use in other operations — for example, to [add a test case to a test suite](#add-a-test-case-to-a-test-suite). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-test-suites) description.
## Import a test suite
-The `test-suite import` command imports a test suite from a JSON file or standard JSON input. You can use the [API documentation](https://techdocs.akamai.com/test-ctr/v3/reference/post-test-suites-with-child-objects) to create the JSON file. Add your values to `BODY PARAMS` fields, copy the body of your request from the CURL code sample, and save it as a JSON file.
+The `test-suite create-with-child-objects` command imports a test suite from a JSON file or standard JSON input. You can use the [Generate a default test suite for a property](#generate-a-default-test-suite-for-a-property) operation or the [API documentation](https://techdocs.akamai.com/test-ctr/reference/post-test-suites-with-child-objects) to create the JSON file. Add your values to `BODY PARAMS` fields, copy the body of your request from the CURL code sample, and save it as a JSON file.
**Command**:
-- To import a specific file from your computer: `test-center test-suite import < {FILE_PATH}/FILE_NAME.json`, where `FILE_PATH` and `FILE_NAME` are respectively location and name of the file to import.
-- To import an outputted string: `echo '{"testSuiteName":"TEST_SUITE_NAME","testSuiteDescription":"TEST_SUITE_DESCRIPTION","isLocked":true|false,"isStateful":true|false,"variables":[{"variableName":"VARIABLE_NAME","variableValue":"VARIABLE_VALUE"}],"testCases":[]}' | akamai test-center test-suite import`, where `TEST_SUITE_NAME`,`TEST_SUITE_DESCRIPTION`, `VARIABLE_NAME`, and `VARIABLE_VALUE` are your values for the test suite.
+- To import a specific file from your computer: `test-center test-suite create-with-child-objects < {FILE_PATH}/FILE_NAME.json`, where `FILE_PATH` and `FILE_NAME` are respectively location and name of the file to import.
+- To import an outputted string: `echo '{"testSuiteName":"TEST_SUITE_NAME","testSuiteDescription":"TEST_SUITE_DESCRIPTION","isLocked":true|false,"isStateful":true|false,"variables":[{"variableName":"VARIABLE_NAME","variableValue":"VARIABLE_VALUE"}],"testCases":[]}' | akamai test-center test-suite create-with-child-objects`, where `TEST_SUITE_NAME`,`TEST_SUITE_DESCRIPTION`, `VARIABLE_NAME`, and `VARIABLE_VALUE` are your values for the test suite.
**Examples**:
-- `akamai test-center test-suite import < ./users/johndoe/documents/test_suite_prop19.json`
-- `echo '{"testSuiteName":"test_suite_prop19","testSuiteDescription":"test suite for property version 19","isLocked":true,"isStateful":false,"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite import`
-
-**Expected output**: The response includes details about the imported test suite. It also includes the ID of the test suite that you can use in other operations — for example, to [edit the test suite using JSON](#edit-a-test-suite-using-json). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/post-test-suites-with-child-objects) description.
-
-## Add a test case to a test suite
-The `test-suite add-test-case` command adds a functional test case to a specific test suite.
-
-**Command**: `test-suite add-test-case [--test-suite-id ID | --test-suite-name NAME] --url URL --condition CONDITION_STATEMENT [--ip-version v4|v6] [-a header ...] [-m header ...] [-f header ...]`, where:
-
-- `ID` or `NAME` specify the test suite you want to add the test case to. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--test-suite-id` or `--test-suite-name`.
-- `URL` is the fully qualified URL of the resource to test. It needs to contain the protocol, hostname, path, and any applicable string parameters. For example *https://www.example.com*.
-- `CONDITION_STATEMENT` is one of the condition statements from the list of supported conditions with entered required values. To get the available condition statements, run the [List supported conditions](#list-supported-conditions) operation. Make sure to substitute default values in `" "` with your own.
-- the `--ip-version` flag specifies the IP version to execute the test suite over, either `v4` or `v6`. It's set to `v4` by default. This flag is optional.
-- the `--add-header` and `--modify-header` flags specify the request headers to respectively add or modify by the request. Headers should follow the format `name: value`. These flags are optional. You can also use these flags to provide Pragma headers. See [Pragma headers](https://techdocs.akamai.com/edge-diagnostics/docs/pragma-headers) for the list of supported values.
-- the `--filter-header` flag filters the header from the request. Provide only the `name` of the header. This flag is optional.
+- `akamai test-center test-suite create-with-child-objects < ./users/johndoe/documents/test_suite_prop19.json`
+- `echo '{"testSuiteName":"test_suite_prop19","testSuiteDescription":"test suite for property version 19","isLocked":true,"isStateful":false,"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite create-with-child-objects`
-**Examples**:
-- `akamai test-center test-suite add-test-case --test-suite-id 1001 --url 'https://example.com/' --condition 'Response code is one of "200,201"'`
-- `akamai test-center test-suite add-test-case --test-suite-name 'Example TS' --u 'https://example.com/' -c 'Response code is one of "200"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language'`
+**Expected output**: The response includes details about the imported test suite. It also includes the ID of the test suite that you can use in other operations — for example, to [edit the test suite using JSON](#edit-a-test-suite-using-json). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-test-suites-with-child-objects) description.
-**Expected output**: The response includes details of the test case created for the test suite. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/post-test-cases) description.
## Generate a default test suite for a property
The `test-suite generate-default` command generates a default test suite with test cases for a specific property. Based on property settings and its behaviors and the `--url` flag value, Test Center generates a test suite object with test cases and variables for you to modify and add to Test Center using the [Import a test suite](#import-a-test-suite) operation.
-**Command**: `test-suite generate-default --property 'PROPERTY NAME' --propver 'PROPERTY VERSION' --url URL ...`, where:
+**Command**: `test-suite generate-default --property-name 'PROPERTY NAME'| --property-id 'ID' --property-version 'PROPERTY VERSION' --url URL ...`, where:
-- `PROPERTY NAME` and `PROPERTY VERSION` specify the property in Property Manager you want to generate a test suite for. To get these values you can use the [Property Manager CLI](https://github.com/akamai/cli-property-manager) and the `list-properties|lpr` operation.
-- `URL` is the fully qualified URL of the property hostname. The `--URL` flag can be used multiple times.
+- `PROPERTY NAME` or `ID` and `PROPERTY VERSION` specify the property in Property Manager you want to generate a test suite for. To get these values you can use the [Property Manager CLI](https://github.com/akamai/cli-property-manager) and the `list-properties|lpr` operation. Provide either the `--property-name` or `--property-id` flag.
+- `URL` is the fully qualified URL of the property hostname. The `--url` flag can be used multiple times.
**Examples**:
-- `akamai test-center test-suite generate-default --property 'example.com' --propver '4' --url "https://www.example.com/" -u "https://www.example.com/index/"`
+- `akamai test-center test-suite generate-default --property-name 'example.com' --property-version '4' --url "https://www.example.com/" -u "https://www.example.com/index/"`
-**Expected output**: The response includes details about the generated response and included test cases. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/auto-generate-test-suite) description.
+**Expected output**: The response includes details about the generated response and included test cases. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-auto-generate-test-suite) description.
## Edit a test suite
-The `test-suite edit` command edits basic data of a specific test suite. Provide only data you want to edit in the original test suite.
+The `test-suite update` command edits basic data of a specific test suite. Provide only data you want to edit in the original test suite.
-**Command**: `test-suite edit --id ID [--name NAME] [--description DESCRIPTION] [--unlocked | --locked] [--stateful | --stateless] [--property 'PROPERTY NAME' --propver 'PROPERTY VERSION' | --remove-property ]`, where:
+**Command**: `test-suite update --id ID [--name NAME] [--description DESCRIPTION] [--unlocked | --locked] [--stateful | --stateless] [--property-name 'PROPERTY NAME' | --property-id 'ID' --property-version 'PROPERTY VERSION' | --remove-property ]`, where:
- `ID` is the identifier of the test suite you want to edit. To get this value, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--id` or `--name`.
- `NAME` is the new test suite's name.
- `DESCRIPTION` is the new description for the test suite.
- `unlocked`, `locked`, `stateful`, `stateless` flags update the status of the test suite.
-- `--property` and `--propver` update the test suite's association to the property with a specific `PROPERTY NAME` and `PROPERTY VERSION`. If applicable, provide either these flags or `--remove-property`.
-- the `--remove-property` removes the association to a property version. If applicable, provide either this flag or `--property` and `--propver`.
+- `--property-name` or `--property-id` and `--property-version` update the test suite's association to the property with a specific `PROPERTY NAME` or `ID` and `PROPERTY VERSION`. If applicable, provide either `--property-name` or `--property-id` or `--remove-property`.
+- the `--remove-property` removes the association to a property version. If applicable, provide either this flag or `--property-name` or `--property-id` with `--property-version`.
**Examples**:
-- `akamai test-center test-suite edit --id 1001 --name 'Updated test suite'`
-- `akamai test-center test-suite edit --id 1001 --name 'Updated test suite' --description 'Test suite for example.com' --property 'example.com' --propver '4' --unlocked`
-- `akamai test-center test-suite edit --id 1001 --stateful --remove-property`
+- `akamai test-center test-suite update --id 1001 --name 'Updated test suite'`
+- `akamai test-center test-suite update --id 1001 --name 'Updated test suite' --description 'Test suite for example.com' --property-name 'example.com' --property-version '4' --unlocked`
+- `akamai test-center test-suite update --id 1001 --stateful --remove-property`
-**Expected output**: The response returns the updated test suite. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/put-test-suite) description.
+**Expected output**: The response returns the updated test suite. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/put-test-suite) description.
## Edit a test suite using JSON
-The `test-suite manage` command uses the JSON input to edit a specific test suite. Provide the whole test suite object, together with test cases and variables, to include in Test Center. Only data provided in the latest JSON input will be saved. You can use the [API documentation](https://techdocs.akamai.com/test-ctr/v3/reference/put-test-suites-with-child-objects) to create the JSON file. Add your values to `BODY PARAMS` fields, copy the body of your request from the CURL code sample, and save it as a JSON file.
+The `test-suite update-with-child-objects` command uses the JSON input to edit a specific test suite. Provide the whole test suite object, together with test cases and variables, to include in Test Center. Only data provided in the latest JSON input will be saved. You can use the [API documentation](https://techdocs.akamai.com/test-ctr/reference/put-test-suites-with-child-objects) to create the JSON file. Add your values to `BODY PARAMS` fields, copy the body of your request from the CURL code sample, and save it as a JSON file.
**Command**:
-- To edit the test suite with a specific file from your computer: `test-center test-suite manage < {FILE_PATH}/FILE_NAME.json`, where `FILE_PATH` and `FILE_NAME` are respectively location and name of the file to import.
-- To edit the test suite with outputted string: `echo '{"testSuiteId":ID,"testSuiteName":"TEST_SUITE_NAME","testSuiteDescription":"TEST_SUITE_DESCRIPTION","isLocked":true|false,"isStateful":true|false,"variables":[{"variableName":"VARIABLE_NAME","variableValue":"VARIABLE_VALUE"}],"testCases":[]}' | akamai test-center test-suite manage`, where:
+- To edit the test suite with a specific file from your computer: `test-center test-suite update-with-child-objects < {FILE_PATH}/FILE_NAME.json`, where `FILE_PATH` and `FILE_NAME` are respectively location and name of the file to import.
+- To edit the test suite with outputted string: `echo '{"testSuiteId":ID,"testSuiteName":"TEST_SUITE_NAME","testSuiteDescription":"TEST_SUITE_DESCRIPTION","isLocked":true|false,"isStateful":true|false,"variables":[{"variableName":"VARIABLE_NAME","variableValue":"VARIABLE_VALUE"}],"testCases":[]}' | akamai test-center test-suite update-with-child-objects`, where:
- `ID` is the unique identifier of the test suite you want to edit.
- `TEST_SUITE_NAME`,`TEST_SUITE_DESCRIPTION`, `VARIABLE_NAME`, and `VARIABLE_VALUE` are your values for the edited test suite.
**Examples**:
-- `akamai test-center test-suite manage < ./users/johndoe/documents/test_suite_prop19.json`
-- `echo '{"testSuiteName":"test_suite_prop19","testSuiteDescription":"test suite for property version 19","isLocked":true,"isStateful":false,"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite manage`
+- `akamai test-center test-suite update-with-child-objects < ./users/johndoe/documents/test_suite_prop19.json`
+- `echo '{"testSuiteName":"test_suite_prop19","testSuiteDescription":"test suite for property version 19","isLocked":true,"isStateful":false,"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite update-with-child-objects`
**Expected output**: Successful operation confirmed.
@@ -240,148 +407,225 @@ The `test-suite remove` command removes a specific test suite from Test Center.
**Expected output**: Successful operation confirmed.
+## Restore a test suite
+The `test-suite restore` command restores a removed test suites and included test cases. Test suites can be restored for 30 days since their removal.
+
+**Command**: `test-suite restore [--id ID | --name "NAME"]`, where `ID` and `NAME` specify the test suite you want to restore. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--id` or `--name`.
+
+**Example**:
+- `akamai test-center test-suite restore --name "test_suite_prop19"`
+- `akamai test-center test-suite restore --id 12345`
+
+**Expected output**: Successful operation confirmed.
+
+## Get a test suite's overview
+The `test-suites get` command returns basic data about a test suite. You can group the included test cases by a test request, condition, or IP version.
+
+**Command**: `test-suite get [--test-suite-id ID | --test-suite-name 'NAME']`, where the `ID` and `NAME` specify the test suite you want to get the details of. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--id` or `--name`.
+
+**Example**: `akamai test-center test-suite get --test-suite-id 1001`
+
+**Expected output**: The response includes overview of the test suite. To get the test suite with included objects, test cases and variables, run the [Get a test suite with child objects](#get-a-test-suite-with-child-objects) operation. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-suite) description.
+
+## Get a test suite with child objects
+The `test-suites get-with-child-objects` command returns details of a test suite and all included objects, test cases and variables. You can group the included test cases by a test request, condition, or IP version.
+
+**Command**: `test-suite get-with-child-objects [--test-suite-id ID | --test-suite-name 'NAME'] [--group-by test-request | condition | client-profile]`, where:
+
+- `ID` and `NAME` specify the test suite you want to get the details of. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--id` or `--name`
+- the `--group-by` flag specifies grouping of the included test cases, by `test-request`, `condition`, or `client-profile`. This flag is optional.
+
+**Examples**:
+- `akamai test-center test-suite get-with-child-objects --test-suite-id 1001`
+- `akamai test-center test-suite get-with-child-objects --test-suite-name 'test_suite_prop19' --group-by test-request`
+
+**Expected output**: The response includes details of the test suite. Run this operation with the `--json` flag so that you can save the returned object and [import it](#import-a-test-suite) on a different account or [edit it](#edit-a-test-suite-using-json). You can also use the response to clone test suites within your account. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-suites-with-child-objects) description.
+
+## Add a test case to a test suite
+The `test-case create` command adds a functional test case to a specific test suite.
+
+**Command**: `test-case create [--test-suite-id ID | --test-suite-name 'NAME'] --url URL --condition CONDITION_STATEMENT [--ip-version v4|v6] [--client CURL| CHROME] [--request-method GET|HEAD|POST] [--request-body REQUEST_BODY] [--encode-request-body] [--set-variable VARIABLE_NAME:VARIABLE_VALUE ...] [--add-header header ...] [--modify-header header ...] [--filter-header header ...]`, where:
+
+- `ID` or `NAME` specify the test suite you want to add the test case to. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--test-suite-id` or `--test-suite-name`.
+- `URL` is the fully qualified URL of the resource to test. It needs to contain the protocol, hostname, path, and any applicable string parameters. For example *https://www.example.com*.
+- `CONDITION_STATEMENT` is one of the condition statements from the list of supported conditions with entered required values. To get the available condition statements, run the [List created conditions](#list-created-conditions) operation and to create a new condition, run the [List supported conditions](#list-supported-conditions) operation. Make sure to substitute default values in `" "` with your own.
+- the `--ip-version` flag specifies the IP version to execute the test suite over, either `v4` or `v6`. It's set to `v4` by default. This flag is optional.
+- the `--client` flag specifies the client profile to execute the test suite over, either `CURL` or `CHROME`. It's set to `CURL` by default. This flag is optional.
+- the `--request-method` flag specifies the request method for the test case, either `GET`, `HEAD` or `POST`. It's set to `GET` by default. This flag is optional.
+- the `--request-body` flag adds `REQUEST_BODY` to the request. This flag is optional and applicable only if `--client` is set to `CURL` and `--request-method` to `POST`.
+- the `--encode-request-body` flag encodes `REQUEST BODY`. This flag is optional and applicable only if `--client` is set to `CURL` and `--request-method` to `POST`.
+- the `--set-variable` flag defines variables for the test case, provide in the format: `VARIABLE_NAME:VARIABLE_VALUE`. This flag is optional. To learn more about variables, see [Variables](https://techdocs.akamai.com/test-ctr/reference/variables-overview).
+- the `--add-header` and `--modify-header` flags specify the request headers to respectively add or modify by the request. Headers should follow the format `name: value`. These flags are optional. You can also use these flags to provide Pragma headers. See [Pragma headers](https://techdocs.akamai.com/edge-diagnostics/docs/pragma-headers) for the list of supported values.
+- the `--filter-header` flag filters the header from the request. Provide only the `name` of the header. This flag is optional.
+
+**Examples**:
+- `akamai test-center test-case create --test-suite-id 1001 --url 'https://example.com/' --condition 'Response code is one of "200,201"'`
+- `akamai test-center test-case create --test-suite-name 'Example TS' --u 'https://example.com/' -c 'Response code is one of "200"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language'`
+
+**Expected output**: The response includes details of the test case created for the test suite. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-test-cases) description.
+
## Remove a test case from a test suite
-The `test suite remove-test-case` command removes a test case with a specific order number from a test suite. Removed test cases can't be restored.
+The `test case remove` command removes a test case from a test suite. Removed test cases can't be restored.
-**Command**: `test-suite remove-test-case --test-suite-id ID --order-num ORDER_NUMBER`, where:
+**Command**: `test-case remove --test-suite-id ID [--order-num ORDER_NUMBER | --test-case-id TEST_CASE_ID] `, where:
- `ID` is the unique identifier of the test suite you want to remove the test case from. To get this values, run the [List test suites](#list-test-suites) operation.
-- `ORDER_NUMBER` is the order number of the test case you want to remove. To get this value, run the [Get a test suite's details](#get-a-test-suites-details) operation.
+- `ORDER_NUMBER` is the order number of the test case you want to remove. To get this value, run the [Get a test suite's overview](#get-a-test-suites-overview) operation.
+- `TEST_CASE_ID` specifies the test case to be removed. To get this value, run the [Get a test suite's overview](#get-a-test-suites-overview) operation. Provide either the `--test-case-id` or `--order-num` flag.
-**Examples**: `akamai test-center test-suite remove-test-case --test-suite-id 1001 --order-num 6`
+**Examples**: `akamai test-center test-suite remove --test-suite-id 1001 --order-num 6`
**Expected output**: Successful operation confirmed.
-## Restore a test suite
-The `test-suite restore` command restores a removed test suites and included test cases. Test suites can be restored for 30 days since their removal.
+## Edit a test case in a test suite
+The `test case update` command edits a test case with a specific test case in a test suite. Provide only data you want to edit in the original test case.
-**Command**: `test-suite restore [--id ID | --name "NAME"]`, where `ID` and `NAME` specify the test suite you want to restore. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--id` or `--name`.
+**Command**: `test-case update [--test-suite-id ID | --test-suite-name 'NAME'] --url URL --condition CONDITION_STATEMENT [--ip-version v4|v6] [--client CURL| CHROME] [--request-method GET|HEAD|POST] [--request-body REQUEST_BODY] [--encode-request-body] [--set-variable VARIABLE_NAME:VARIABLE_VALUE ...] [--add-header header ...] [--modify-header header ...] [--filter-header header ...]`, where:
-**Example**:
-- `akamai test-center test-suite restore --name "test_suite_prop19"`
-- `akamai test-center test-suite restore --id 12345`
+- `ID` or `NAME` specify the test suite you want to add the test case to. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--test-suite-id` or `--test-suite-name`.
+- `URL` is the fully qualified URL of the resource to test. It needs to contain the protocol, hostname, path, and any applicable string parameters. For example *https://www.example.com*.
+- `CONDITION_STATEMENT` is one of the condition statements from the list of supported conditions with entered required values. To get the list of created conditions to reuse, run the [List created conditions](#list-created-conditions) operation and to create a new condition, run the [List supported conditions](#list-supported-conditions) operation. Make sure to substitute default values in `" "` with your own.
+- the `--ip-version` flag specifies the IP version to execute the test suite over, either `v4` or `v6`. It's set to `v4` by default. This flag is optional.
+- the `--client` flag specifies the client profile to execute the test suite over, either `CURL` or `CHROME`. It's set to `CURL` by default. This flag is optional.
+- the `--request-method` flag specifies the request method for the test case, either `GET`, `HEAD` or `POST`. It's set to `GET` by default. This flag is optional.
+- the `--request-body` flag adds `REQUEST_BODY` to the request. This flag is optional and applicable only if `--client` is set to `CURL` and `--request-method` to `POST`.
+- the `--encode-request-body` flag encodes `REQUEST BODY`. This flag is optional and applicable only if `--client` is set to `CURL` and `--request-method` to `POST`.
+- the `--set-variable` flag defines variables for the test case, provide in the format: `VARIABLE_NAME:VARIABLE_VALUE`. This flag is optional. To learn more about variables, see [Variables](https://techdocs.akamai.com/test-ctr/reference/variables-overview).
+- the `--add-header` and `--modify-header` flags specify the request headers to respectively add or modify by the request. Headers should follow the format `name: value`. These flags are optional. You can also use these flags to provide Pragma headers. See [Pragma headers](https://techdocs.akamai.com/edge-diagnostics/docs/pragma-headers) for the list of supported values.
+- the `--filter-header` flag filters the header from the request. Provide only the `name` of the header. This flag is optional.
+
+**Examples**:
+- `akamai test-center test-case update --test-suite-id 1001 --test-case-id 101 --url 'https://example.com/' --condition 'Response code is one of "200,201"`
+- `akamai test-center test-case update --test-suite-id 1001 --test-case-id 101 -u 'https://example.com/' -c 'Response code is one of "200"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language' -C curl -M POST --set-variable 'varName: varValue'`
**Expected output**: Successful operation confirmed.
-## Get a test suite's details
-The `test-suites view` command exports details of a specific test suite, including its test cases. You can group the included test cases by a test request, condition, or IP version.
+## List test cases
+The `test-case list` command lists all test cases.
+
+**Command**: `test-case list [--test-suite-name 'NAME'| --test-suite-id 'ID'] [--group-by test-request | condition | client-profile]`, where:
+
+- the `--test-suite-name` or `--test-suite-id` flags filter the results for a specific test suite. Provide either the `--test-suite-name` or `--test-suite-id` flag.
+- the `--group-by` flag specifies grouping of the included test cases, by `test-request`, `condition`, or `client-profile`. This flag is optional.
+
+**Example**: `akamai test-center test-case list --test-suite-name 'Test suite for example.com' --group-by test-request`
+
+**Expected output**: The response lists all test cases. You can use the returned test case ID to run the [Get a specific test case](#get-a-specific-test-case) operation. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-cases) description.
-**Command**: `test-suite view [--id ID | --name NAME] [--group-by test-request | condition | ipversion]`, where:
+## Get a specific test case
+The `test-case get` command returns details a specific test case.
+
+**Command**: `test-case get [--test-suite-id ID | --test-suite-name 'NAME'] --test-case-id TEST_CASE_ID`, where:
- `ID` and `NAME` specify the test suite you want to get the details of. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--id` or `--name`
-- the `--group-by` flag specifies grouping of the included test cases, by `test-request`, `condition`, or `ipversion`. This flag is optional.
+- `TEST_CASE_ID` specifies the test case you want to get the details of. To get these values, run the [Get a test suite's overview](#get-a-test-suites-overview) operation.
+
+**Examples**: `akamai test-center test-suite get --test-suite-id 1001 --test-case-id 3`
+
+**Expected output**: The response includes details of the test case. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-case) description.
+
+## Create variables
+The `variable create` command creates variables for a test suite. You can use variables in a test request's URL or request headers and in condition expression, as a substitute of placeholders. To learn more, see [Variables](https://techdocs.akamai.com/test-ctr/reference/variables-overview).
+
+**Command**: `variable create --test-suite-id ID --name VARIABLE_NAME [--value VALUE | --group-value H1: value1, value2 --group-value H2: value3, value4]`, where:
+
+- `ID` specifies the test suite you want to create the variable for. To get this value, run the [List test suites](#list-test-suites) operation.
+- `VARIABLE_NAME` is the name of the variable.
+- For the value, you can either use the `--value` flag and provide a single `VALUE` or the `--group-value` flag to create variable groups. To learn more, see [Variable groups](https://techdocs.akamai.com/test-ctr/reference/variables-overview#variable-groups).
**Examples**:
-- `akamai test-center test-suite view --id 1001`
-- `akamai test-center test-suite view --name 'test_suite_prop19' --group-by test-request`
+- `akamai test-center variable create --test-suite-id 1001 --name url --value 'https://example.com/`
+- `akamai test-center variable create --test-suite-id 1001 --name url --group-value hostName: https://example.com/,https://example.com/123 --group-value ResponseCodes: 200,300`
-**Expected output**: The response includes details about the test suite. Run this operation with the `--json` flag so that you can save the returned object and [import it](#import-a-test-suite) on a different account or [edit](#edit-a-test-suite-using-json) it. You can also use the response to clone test suites within your account. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/get-test-suites-with-child-objects) description.
+**Expected output**: The response includes details about the created variable. You can now reuse the variable by entering it in *{{ }}*. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-variables) description.
-## List supported conditions
-The `conditions` command returns the list of all conditions you can use when creating a test case for a test suite. Note that the statements contain default values in `" "`. You need to replace them with your own values before creating the test case.
+## Edit a variable
+The `variable update` command edits a specific variable. Provide only data you want to edit in the original variable.
-**Command**: `conditions`
+**Command**: `update --test-suite-id ID --variable-id VARIABLE_ID --name NAME [--value VALUE | --group-value H1: value1, value2 --group-value H2: value3, value4]`, where:
-**Expected output**: List of supported condition statements. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/get-test-catalog-template) description.
+- `ID` specifies the test suite you want to edit the variable for. To get this value, run the [List test suites](#list-test-suites) operation.
+- `VARIABLE_ID` specifies the variable to edit. To get this value, run the [List variables](#list-variables) operation.
+- `VARIABLE_NAME` is the name of the variable.
+- For the value, you can either use the `--value` flag and provide a single `VALUE` or the `--group-value` flag to create variable groups. To learn more, see [Variable groups](https://techdocs.akamai.com/test-ctr/reference/variables-overview#variable-groups).
-## Run a test
-The `test` command runs a test for a specific test suite, single test case, or a property version.
+**Examples**:
+- `akamai test-center variable update --test-suite-id 1001 --variable-id 1 --name url --value 'https://example.com/`
+- `akamai test-center variable update --test-suite-id 1001 --name url --variable-id 1 --group-value hostName: https://example.com/,https://example.com/123 --group-value ResponseCodes: 200,300`
-**Command**:
-- To run a test for a test suite: `test [--test-suite-id ID | --test-suite-name 'NAME'] -e STAGING|PRODUCTION`
-- To run a test for a property version: `test [--property 'PROPERTY NAME' --propver 'PROPERTY VERSION'] -e STAGING|PRODUCTION`
-- To run a test for a single test case: `test [-u URL -c CONDITION STATEMENT -i v4|v6 [--add-header 'name: value' ...] [--modify-header 'name: value' ...] [--filter-header name ...]] -e STAGING|PRODUCTION`, where:
-
- - `ID` and `NAME` specify the test suite you want to run the test for. To get these values, run the [List test suites](#list-test-suites) operation. You need to provide either of these flags: `--id` or `--name`
- - `PROPERTY NAME` and `PROPERTY VERSION` specify the property in Property Manager you want to run the test for. To get these values you can use the [Property Manager CLI](https://github.com/akamai/cli-property-manager) and the `list-properties|lpr` operation.
- - `URL` is the fully qualified URL of the resource to test. It needs to contain the protocol, hostname, path, and any applicable string parameters — for example, *https://www.example.com*. This flag needs to be combined with '--ip-version' and '--condition' flags.
- - `CONDITION STATEMENT` is one of the condition statements from the list of supported conditions with entered required values. To get the list of supported conditions, run the [List supported conditions](#list-supported-conditions) operation. Make sure to replace default values in `" "` with your own. This flag needs to be combined with '--url' and '--ip-version' flags.
- - the `ip-version` flag specifies the IP version to execute the test case over, either `v4` or `v6`. This flag is optional, set to `v4` by default. This flag needs to be combined with '--url' and '--condition' flags.
- - the `--add-header` and `--modify-header` flags specify the request headers to respectively added or modify by the request. Headers should follow the format `name: value`. These flags are optional and accept multiple values. You can also use these flags to provide Pragma headers. See [Pragma headers](https://techdocs.akamai.com/edge-diagnostics/docs/pragma-headers) for the list of supported values. These flag needs to be combined with '--url', '--ip-version', and '--condition' flags.
- - the `--filter-header` flag filters the header from the request. Provide only the `name` of the header. This flag is optional. This flag needs to be combined with '--url', '--ip-version', and '--condition' flags.
- - the `--env` flag specifies the environment you want to run the test on, either `STAGING` or `PRODUCTION`. This flag is optional, set to `STAGING` by default.
+**Expected output**: The response returns the updated variable. You can now reuse the variable by entering it in *{{ }}*. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/put-variables) description.
-**Expected output**: Once you submit the test run, it may take few minutes for Test Center to execute the test. To learn more about returned test results, check [How to read test run results - Functional testing](https://techdocs.akamai.com/test-ctr/docs/view-results#functional-testing). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/post-test-runs) description.
+## List variables
+The `variable list` command list all variables created for a test suite that you can further reuse.
-## Run a test using JSON
-The `test` command runs a test for a specific test suite, single test case, or a property version using a JSON file or JSON input. You can use the [API documentation](https://techdocs.akamai.com/test-ctr/v3/reference/post-test-runs) to create the JSON file. Add your values to `BODY PARAMS` fields, copy the body of your request from the CURL code sample, and save it as a JSON file. To get `testCaseId` values run the `test-suite view` command for a specific test suite with the `--json` flag.
+**Command**: `variable list --test-suite-id ID`, where `ID` specifies the test suite you want to get the variables for. To get this value, run the [List test suites](#list-test-suites) operation.
-**Command**:
+**Example**: `akamai test-center --test-suite-id 2005`
-To import a specific file from your computer: `test-center test < {FILE_PATH}/FILE_NAME.json`, where `FILE_PATH` and `FILE_NAME` are respectively location and name of the file to import.
+**Expected output**: The response lists test suite's variables. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-variables) description.
-JSON example to run a test for a property version:
-```
-{
- "functional":{
- "configVersionExecutions":[
- {
- "testSuiteExecutions":[
- {
- "testSuiteId":31306
- },
- {
- "testCaseExecutions":[
- {
- "testCaseId":41
- }
- ],
- "testSuiteId":87
- }
- ],
- "configVersionId":22556
- }
- ]
- },
- "targetEnvironment": "STAGING"
-}
-```
+## Get a specific variable
+The `variable get` command returns details for a specific variable.
+
+**Command**: `variable get --test-suite-id ID --variable-id VARIABLE_ID`, where:
+
+- `ID` specifies the test suite you want to get the variable for. To get this value, run the [List test suites](#list-test-suites) operation.
+- `VARIABLE_ID` specifies the variable you want to get the details of. To get this value, run the [List variables](#list-variables) operation.
+
+**Examples**: `akamai test-center variable get --test-suite-id 1001 --variable-id 3`
+
+**Expected output**: The response includes details of the variable. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-variable) description.
+
+## Remove a specific variable
+The `variable remove` command removes a variable from a test suite.
+
+**Command**: `variable remove --test-suite-id ID --variable-id VARIABLE_ID`, where:
+
+- `ID` specifies the test suite you want to remove the variable from. To get this value, run the [List test suites](#list-test-suites) operation.
+- `VARIABLE_ID` specifies the variable you want to remove. To get this value, run the [List variables](#list-variables) operation.
+
+**Examples**: `akamai test-center variable remove --test-suite-id 1001 --variable-id 4`
+
+**Expected output**: Successful operation confirmed.
+
+## Check how functions work using JSON
+The `function try-it` command uses the JSON input to run a created function on sample data to check whether it returns the expected value. A function is valid for use in a test case if the response's `results` value returns only one value. To learn more about functions and variables, see [Variables](https://techdocs.akamai.com/test-ctr/reference/variables-overview).
+
+**Command**:
+- To check a function with a specific file from your computer: `function try-it < {FILE_PATH}/FILE_NAME.json`, where `FILE_PATH` and `FILE_NAME` are respectively location and name of the file to import.
+- To check a function with outputted string: `echo '"functionExpression": "FUNCTION_EXPRESSION","responseData": {SAMPLE_RESPONSE_DATA}' | akamai test-center function try-it`, where:
+ - `FUNCTION_EXPRESSION` is the function you want to test.
+ - `SAMPLE_RESPONSE_DATA` is the sample response for Test Center to run the function evaluation on.
+
+**Examples**:
+- `akamai test-center function try-it < ./users/johndoe/documents/function.json`
+- `echo '{"functionExpression": "fn_getResponseHeaderValue(headerName, regex)","responseData": {"response": {"status": 200,"statusText": "OK","httpVersion": "HTTP/1.1","headers": [{"name": "server", "value":"Apache/2.2.15 (CentOS)"}]}}}' | akamai test-center function try-it`
+
+**Expected output**: The response is the matching result for the input function expression. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/post-try-it) description.
+
+
+## List created test requests
+The `test-request list` command returns all test requests created by users of your account while creating test cases. You can further reuse these test requests in test cases.
+
+**Command**: `test-request list`
+
+**Expected output**: The response lists created test requests. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-requests) description.
+
+## List supported conditions
+The `condition template` command returns the supported condition expressions you can use when creating test cases. Note that the statements contain default values in `" "`. You need to replace them with your own values before creating the test case.
+
+**Command**: `condition template`
+
+**Expected output**: The response lists supported condition statements. For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/reference/get-test-catalog-template) description.
+
+## List created conditions
+The `condition list` command returns all conditions created by users of your account while creating test cases. You can further reuse these conditions in test suites or test cases.
+
+**Command**: `condition list`
+
+**Expected output**: The response lists created condition statements.
-JSON example to run a test for a test suite:
-```
-{
- "functional":{
- "testSuiteExecutions":[
- {
- "testCaseExecutions":[
- {
- "testCaseId":65
- },
- {
- "testCaseId":71
- },
- {
- "testCaseId":98
- }
- ],
- "testSuiteId":281
- }
- ]
- },
- "targetEnvironment": "STAGING"
-}
-```
-JSON example to run a test for a single test case:
-```
-{
- "functional":{
- "testCaseExecution":{
- "testRequest":{
- "testRequestUrl":"https://www.example.com"
- },
- "condition":{
- "conditionExpression":"Log request details - Referrer header is not logged"
- },
- "clientProfile":{
- "ipVersion":"IPV4"
- }
- }
- },
- "targetEnvironment":"STAGING"
-}
-```
-**Expected output**: Once you submit the test run, it may take a few minutes for Test Center to execute the test. To learn more about returned test results, check [How to read test run results - Functional testing](https://techdocs.akamai.com/test-ctr/docs/view-results#functional-testing). For more details, you can check the [API response](https://techdocs.akamai.com/test-ctr/v3/reference/post-test-runs) description.
# Available flags
@@ -396,7 +640,7 @@ Without this flag, the user's home directory is used by default.
**Example**: `$akamai test-center --edgerc C:/users/johndoe/.edgerc test-suite list`
## section
-The `--section` flag changes the default section name. The section name specifies which section of API credentials to read from the .edgerc file. Without this flag, the default `test-center` section name is used by default.
+The `--section` flag changes the default section name. The section name specifies which section of API credentials to read from the .edgerc file. Without this flag, the `default` section name is used by default.
**Command**: `$akamai test-center --section SECTION_NAME [command]`
diff --git a/cli.json b/cli.json
index 852ff43..b8fcefe 100644
--- a/cli.json
+++ b/cli.json
@@ -1,11 +1,13 @@
{
- "requirements": {
- "go": "1.15"
- },
- "commands": [{
- "name": "test-center",
- "version": "0.2.0",
- "description": "Test Center is a testing tool that checks the effect of configuration changes on your web property. Use this tool as part of your testing protocol to increase your confidence in the safety and accuracy of your configuration changes.",
- "bin": "https://github.com/akamai/cli-test-center/releases/download/{{.Version}}/akamai-{{.Name}}-{{.Version}}-{{.OS}}{{.Arch}}{{.BinSuffix}}"
- }]
+ "requirements": {
+ "go": ">=1.15"
+ },
+ "commands": [
+ {
+ "name": "test-center",
+ "version": "1.0.0",
+ "description": "Test Center is a testing tool that checks the effect of configuration changes on your web property. Use this tool as part of your testing protocol to increase your confidence in the safety and accuracy of your configuration changes.",
+ "bin": "https://github.com/akamai/cli-test-center/releases/download/{{.Version}}/akamai-{{.Name}}-{{.Version}}-{{.OS}}{{.Arch}}{{.BinSuffix}}"
+ }
+ ]
}
\ No newline at end of file
diff --git a/cmd/command_usage_and_example_constants.go b/cmd/command_usage_and_example_constants.go
deleted file mode 100644
index feeea01..0000000
--- a/cmd/command_usage_and_example_constants.go
+++ /dev/null
@@ -1,129 +0,0 @@
-package cmd
-
-// command usage and example
-const (
- RootCommandUse = "test-center"
-
- TestUse = "test [--test-suite-id ID | --test-suite-name 'NAME'] | [--property 'PROPERTY NAME' --propver 'PROPERTY VERSION'] |\n\t\t [-u URL -c CONDITION -i V4|V6 [--add-header 'name: value' ...] [--modify-header 'name: value' ...] [--filter-header name ...]] \n\t\t -e STAGING|PRODUCTION"
- TestExample = ` $ akamai test-center test --test-suite-id 2500
- $ akamai test-center test --test-suite-name 'Regression test cases for example.com'
- $ akamai test-center test --property 'example.com' --propver '26'
- $ akamai test-center test --url 'https://example.com/' --condition 'Response code is one of "200"' --ip-version 'V6' --modify-header 'Accept: application/json'
- $ akamai test-center test < {FILE_PATH}/FILE_NAME.json`
- TestCommandAlias = "t"
-
- TestSuiteUse = "test-suite"
- TestSuiteCommandAlias = "ts"
-
- TestSuiteAddUse = "add --name NAME [--description DESCRIPTION] [--unlocked] [--stateful] [--property 'PROPERTY NAME' --propver 'PROPERTY VERSION'] "
- TestSuiteAddExample = ` $ akamai test-center test-suite add --name 'Example TS'
- $ akamai test-center test-suite add --name 'Example TS' --description 'TS for example.com' --unlocked --stateful --property 'example.com' --propver '4'`
-
- TestSuiteAddTestCaseUse = "add-test-case [--test-suite-id ID | --test-suite-name NAME] -u URL -c CONDITION [-i V4|V6] [-a header ...] [-m header ...] [-f header ...]"
- TestSuiteAddTestCaseExample = ` $ akamai test-center test-suite add-test-case --test-suite-id 1001 --url 'https://example.com/' --condition 'Response code is one of "200,201"'
- $ akamai test-center test-suite add-test-case --test-suite-name 'Example TS' -u 'https://example.com/' -c 'Response code is one of "200"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language'`
-
- TestSuiteAutoGenerationUse = "generate-default --property 'PROPERTY NAME' --propver 'PROPERTY VERSION' --url URL ... "
- TestSuiteAutoGenerationExample = ` $ akamai test-center test-suite generate-default --property 'example.com' --propver '4' --url "https://www.example.com/" -u "https://www.example.com/index/"
- $ akamai test-center test-suite generate-default < {filepath}/filename.json`
-
- TestSuiteEditUse = "edit --id ID [--name NAME] [--description DESCRIPTION] [--unlocked | --locked] [--stateful | --stateless] [--property 'PROPERTY NAME' --propver 'PROPERTY VERSION' | --remove-property]"
- TestSuiteEditExample = ` $ akamai test-center test-suite edit --id 1001 --name 'Updated Example TS'
- $ akamai test-center test-suite edit --id 1001 --name 'Updated Example TS' --description 'TS for example.com' --property 'example.com' --propver '4' --unlocked
- $ akamai test-center test-suite edit --id 1001 --stateful --remove-property`
-
- TestSuiteImportUse = "import"
- TestSuiteImportExample = ` $ akamai test-center test-suite import < {FILE_PATH}/FILE_NAME.json
- $ echo '{"testSuiteName":"ts1","testSuiteDescription":"ts1 description.","isLocked":true,"isStateful":false,"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite import`
-
- TestSuiteListUse = "list [--property 'PROPERTY NAME'] [--propver 'PROPERTY VERSION'] [-u 'USERNAME'] [-s 'SEARCH STRING']"
- TestSuiteListExample = ` $ akamai test-center test-suite list
- $ akamai test-center test-suite list --property 'example.com' --propver '4'
- $ akamai test-center test-suite list -u 'johndoe' -s 'regression'`
- TestSuiteListCommandAlias = "ls"
-
- TestSuiteManageUse = "manage"
- TestSuiteManageExample = ` $ akamai test-center test-suite manage < {FILE_PATH}/FILE_NAME.json
- $ echo '{"testSuiteId":1,"testSuiteName":"ts1","testSuiteDescription":"ts1 description.","isLocked":true,"isStateful":false,"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite manage`
-
- TestSuiteRemoveUse = "remove [--id ID | --name NAME]"
- TestSuiteRemoveExample = ` $ akamai test-center test-suite remove --name "Test suite name"
- $ akamai test-center test-suite remove --id 12345`
-
- TestSuiteRemoveTestCaseUse = "remove-test-case --test-suite-id ID --order-num ORDER_NUMBER"
- TestSuiteRemoveTestCaseExample = ` $ akamai test-center test-suite remove-test-case --test-suite-id 1001 --order-num 6`
-
- TestSuiteRestoreUse = "restore [--id ID | --name NAME]"
- TestSuiteRestoreExample = ` $ akamai test-center test-suite restore --name "Test suite name"
- $ akamai test-center test-suite restore --id 12345`
-
- TestSuiteViewUse = "view [--id ID | --name NAME] [--group-by test-request | condition | ip-version]"
- TestSuiteViewExample = ` $ akamai test-center test-suite view --id 1001
- $ akamai test-center test-suite view --name 'Example TS' --group-by test-request`
- TestSuiteViewCommandAliases = "export"
-
- ConditionTemplateUse = "conditions"
- ConditionTemplateExample = ` $ akamai test-center conditions`
-)
-
-// Flag Names
-const (
- FlagEdgerc = "edgerc"
- FlagSection = "section"
- FlagAccountKey = "account-key"
- FlagJson = "json"
- FlagForceColor = "force-color"
- FlagProperty = "property"
- FlagPropver = "propver"
- FlagUrl = "url"
- FlagEnv = "env"
- FlagAddHeader = "add-header"
- FlagModifyHeader = "modify-header"
- FlagFilterHeader = "filter-header"
- FlagTestSuiteId = "test-suite-id"
- FlagTestSuiteName = "test-suite-name"
- FlagIpVersion = "ip-version"
- FlagCondition = "condition"
- FlagId = "id"
- FlagName = "name"
- FlagDescription = "description"
- FlagStateFul = "stateful"
- FlagUnlocked = "unlocked"
- FlagStateless = "stateless"
- FlagLocked = "locked"
- FlagRemoveProperty = "remove-property"
- FlagUser = "user"
- FlagSearch = "search"
- FlagOrderNumber = "order-num"
- FlagGroupBy = "group-by"
- FlagHelp = "help"
- FlagVersion = "version"
-)
-
-const (
- FlagUrlShortHand = "u"
- FlagUserShortHand = "u"
- FlagSearchShortHand = "s"
- FlagEnvShortHand = "e"
- FlagAddHeaderShortHand = "a"
- FlagModifyHeaderShortHand = "m"
- FlagFilterHeaderShortHand = "f"
- FlagIpVersionShortHand = "i"
- FlagConditionShortHand = "c"
- FlagHelpShortHand = "h"
- FlagVersionShortHand = "v"
-)
-
-// Flag Values
-const (
- FlagEdgercDefaultValue = "~/.edgerc"
- FlagSectionDefaultValue = "test-center"
- FlagIpVersionDefaultValue = "V4"
-)
-
-// Environment variable Constants
-const (
- DefaultEdgercPathKey = "AKAMAI_EDGERC"
- DefaultEdgercSectionKey = "AKAMAI_EDGERC_SECTION"
- DefaultJsonOutputKey = "AKAMAI_OUTPUT_JSON"
-)
diff --git a/cmd/condition.go b/cmd/condition.go
new file mode 100644
index 0000000..3b49b40
--- /dev/null
+++ b/cmd/condition.go
@@ -0,0 +1,26 @@
+package cmd
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var condCmd = &cobra.Command{
+ Use: externalconstant.ConditionUse,
+ Aliases: []string{externalconstant.ConditionCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateParentSubCommands(cmd, args, false)
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(condCmd)
+
+ condCmd.Short = util.GetMessageForKey(condCmd, internalconstant.Short)
+ condCmd.Long = util.GetMessageForKey(condCmd, internalconstant.Long)
+}
diff --git a/cmd/condition_list.go b/cmd/condition_list.go
new file mode 100644
index 0000000..95b2733
--- /dev/null
+++ b/cmd/condition_list.go
@@ -0,0 +1,34 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var condListCmd = &cobra.Command{
+ Use: externalconstant.ConditionListUse,
+ Example: externalconstant.ConditionListExample,
+ Aliases: []string{externalconstant.ConditionListCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ svc.GetConditionListAndPrintResult(cmd)
+ },
+}
+
+func init() {
+ condCmd.AddCommand(condListCmd)
+
+ condListCmd.Short = util.GetMessageForKey(condListCmd, internalconstant.Short)
+ condListCmd.Long = util.GetMessageForKey(condListCmd, internalconstant.Long)
+}
diff --git a/cmd/condition_template.go b/cmd/condition_template.go
new file mode 100644
index 0000000..9438219
--- /dev/null
+++ b/cmd/condition_template.go
@@ -0,0 +1,33 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var condTemplateCmd = &cobra.Command{
+ Use: externalconstant.ConditionTemplateUse,
+ Example: externalconstant.ConditionTemplateExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ svc.GetConditionTemplateAndPrintResult(cmd)
+ },
+}
+
+func init() {
+ condCmd.AddCommand(condTemplateCmd)
+
+ condTemplateCmd.Short = util.GetMessageForKey(condTemplateCmd, internalconstant.Short)
+ condTemplateCmd.Long = util.GetMessageForKey(condTemplateCmd, internalconstant.Long)
+}
diff --git a/cmd/conditions_template.go b/cmd/conditions_template.go
deleted file mode 100644
index d27b647..0000000
--- a/cmd/conditions_template.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var condTemplateCmd = &cobra.Command{
- Use: ConditionTemplateUse,
- Example: ConditionTemplateExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
- condTemplate := svc.GetConditionTemplate()
- internal.PrintConditions(cmd, *condTemplate)
- },
-}
-
-func init() {
- rootCmd.AddCommand(condTemplateCmd)
-
- condTemplateCmd.Short = internal.GetMessageForKey(condTemplateCmd, internal.Short)
- condTemplateCmd.Long = internal.GetMessageForKey(condTemplateCmd, internal.Long)
-}
diff --git a/cmd/function.go b/cmd/function.go
new file mode 100644
index 0000000..4a94e06
--- /dev/null
+++ b/cmd/function.go
@@ -0,0 +1,30 @@
+package cmd
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var tryFunction model.TryFunction
+
+var functionCmd = &cobra.Command{
+ Use: externalconstant.FunctionUse,
+ Aliases: []string{externalconstant.FunctionAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ globalValidator.ValidateParentSubCommands(cmd, args, false)
+ },
+}
+
+func init() {
+
+ rootCmd.AddCommand(functionCmd)
+ createTestCaseCmd.Flags().SortFlags = false
+
+ functionCmd.Short = util.GetMessageForKey(functionCmd, internalconstant.Short)
+ functionCmd.Long = util.GetMessageForKey(functionCmd, internalconstant.Long)
+}
diff --git a/cmd/root.go b/cmd/root.go
index f5e61df..fe455b6 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -3,7 +3,9 @@ package cmd
import (
"errors"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
- "github.com/akamai/cli-test-center/internal"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
"github.com/fatih/color"
"github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
@@ -25,7 +27,7 @@ var (
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
- Use: RootCommandUse,
+ Use: externalconstant.RootCommandUse,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if forceColor {
color.NoColor = false
@@ -34,7 +36,7 @@ var rootCmd = &cobra.Command{
var err error
config, err = edgegrid.InitEdgeRc(edgeRcPath, edgeRcSection)
if err != nil {
- internal.AbortWithExitCode(internal.GetGlobalErrorMessage("initEdgeRc"), internal.ExitStatusCode1)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.InitEdgeRc), internalconstant.ExitStatusCode1)
}
},
}
@@ -43,18 +45,18 @@ var rootCmd = &cobra.Command{
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(Version string) {
rootCmd.Version = Version
- code := internal.ExitStatusCode0
+ code := internalconstant.ExitStatusCode0
if err := rootCmd.Execute(); err != nil {
switch err.Error() {
case "2":
// For rootCmd and Subcommand invalid flags
- code = internal.ExitStatusCode2
+ code = internalconstant.ExitStatusCode2
break
default:
- internal.PrintError(err.Error() + "\n")
+ util.PrintError(err.Error() + "\n")
rootCmd.Println("\n" + rootCmd.UsageString())
// For rootCmd wrong arguments
- code = internal.ExitStatusCode2
+ code = internalconstant.ExitStatusCode2
break
}
}
@@ -63,7 +65,7 @@ func Execute(Version string) {
func init() {
rootCmd.CompletionOptions.DisableDefaultCmd = true // Remove this if we choose to offer a completion command
- isStandardInputAvailable, jsonData = internal.ReadStdin(rootCmd)
+ isStandardInputAvailable, jsonData = util.ReadStdin(rootCmd)
rootCmd.Flags().SortFlags = false
rootCmd.PersistentFlags().SortFlags = false
@@ -73,34 +75,34 @@ func init() {
rootCmd.SilenceUsage = true
// Setting the default values for the global flags from environment variable.
- defaultEdgercPath := os.Getenv(DefaultEdgercPathKey)
- defaultEdgercSection := os.Getenv(DefaultEdgercSectionKey)
- globalJsonFlag, _ := strconv.ParseBool(os.Getenv(DefaultJsonOutputKey))
+ defaultEdgercPath := os.Getenv(internalconstant.DefaultEdgercPathKey)
+ defaultEdgercSection := os.Getenv(internalconstant.DefaultEdgercSectionKey)
+ globalJsonFlag, _ := strconv.ParseBool(os.Getenv(internalconstant.DefaultJsonOutputKey))
- if defaultEdgercPath == internal.Empty {
+ if defaultEdgercPath == internalconstant.Empty {
if home, err := homedir.Dir(); err == nil {
- defaultEdgercPath = filepath.Join(home, FlagEdgercDefaultValue)
+ defaultEdgercPath = filepath.Join(home, internalconstant.EdgercFileNameDefaultValue)
}
}
- if defaultEdgercSection == internal.Empty {
- defaultEdgercSection = FlagSectionDefaultValue
+ if defaultEdgercSection == internalconstant.Empty {
+ defaultEdgercSection = internalconstant.SectionDefaultValue
}
rootCmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
- internal.PrintError(err.Error() + "\n\n")
+ util.PrintError(err.Error() + "\n\n")
cmd.Println(cmd.UsageString())
- return errors.New(strconv.Itoa(internal.ExitStatusCode2))
+ return errors.New(strconv.Itoa(internalconstant.ExitStatusCode2))
})
- rootCmd.Short = internal.GetMessageForKey(rootCmd, internal.Short)
- rootCmd.Long = internal.GetMessageForKey(rootCmd, internal.Long)
+ rootCmd.Short = util.GetMessageForKey(rootCmd, internalconstant.Short)
+ rootCmd.Long = util.GetMessageForKey(rootCmd, internalconstant.Long)
- rootCmd.PersistentFlags().StringVar(&edgeRcPath, FlagEdgerc, defaultEdgercPath, internal.GetMessageForKey(rootCmd, FlagEdgerc))
- rootCmd.PersistentFlags().StringVar(&edgeRcSection, FlagSection, defaultEdgercSection, internal.GetMessageForKey(rootCmd, FlagSection))
- rootCmd.PersistentFlags().StringVar(&accountSwitchKey, FlagAccountKey, internal.Empty, internal.GetMessageForKey(rootCmd, FlagAccountKey))
- rootCmd.PersistentFlags().BoolVar(&jsonOutput, FlagJson, globalJsonFlag, internal.GetMessageForKey(rootCmd, FlagJson))
- rootCmd.PersistentFlags().BoolVar(&forceColor, FlagForceColor, false, internal.GetMessageForKey(rootCmd, FlagForceColor))
- rootCmd.Flags().BoolP(FlagHelp, FlagHelpShortHand, false, internal.GetMessageForKey(rootCmd, FlagHelp))
- rootCmd.Flags().BoolP(FlagVersion, FlagVersionShortHand, false, internal.GetMessageForKey(rootCmd, FlagVersion))
+ rootCmd.PersistentFlags().StringVarP(&edgeRcPath, externalconstant.FlagEdgerc, externalconstant.FlagEdgercShortHand, defaultEdgercPath, util.GetMessageForKey(rootCmd, externalconstant.FlagEdgerc))
+ rootCmd.PersistentFlags().StringVarP(&edgeRcSection, externalconstant.FlagSection, externalconstant.FlagSectionShortHand, defaultEdgercSection, util.GetMessageForKey(rootCmd, externalconstant.FlagSection))
+ rootCmd.PersistentFlags().StringVar(&accountSwitchKey, externalconstant.FlagAccountKey, internalconstant.Empty, util.GetMessageForKey(rootCmd, externalconstant.FlagAccountKey))
+ rootCmd.PersistentFlags().BoolVar(&jsonOutput, externalconstant.FlagJson, globalJsonFlag, util.GetMessageForKey(rootCmd, externalconstant.FlagJson))
+ rootCmd.PersistentFlags().BoolVar(&forceColor, externalconstant.FlagForceColor, false, util.GetMessageForKey(rootCmd, externalconstant.FlagForceColor))
+ rootCmd.Flags().BoolP(externalconstant.FlagHelp, externalconstant.FlagHelpShortHand, false, util.GetMessageForKey(rootCmd, externalconstant.FlagHelp))
+ rootCmd.Flags().Bool(externalconstant.FlagVersion, false, util.GetMessageForKey(rootCmd, externalconstant.FlagVersion))
}
diff --git a/cmd/test.go b/cmd/test.go
index 7e9d821..bbce902 100644
--- a/cmd/test.go
+++ b/cmd/test.go
@@ -1,66 +1,28 @@
package cmd
import (
- "github.com/akamai/cli-test-center/internal"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
"github.com/spf13/cobra"
)
-var (
- url string
- addHeader []string
- modifyHeader []string
- filterHeader []string
- condition string
- ipVersion string
- testSuiteName string
- testSuiteIdStr string
- propertyStr string
- propverStr string
- targetEnvironment string
-)
-
-var testRunRequest internal.TestRun
+var testCaseExecutionId string
var testCmd = &cobra.Command{
- Use: TestUse,
- Aliases: []string{TestCommandAlias},
- Example: TestExample,
+ Use: externalconstant.TestUse,
+ Aliases: []string{externalconstant.TestCommandAlias},
Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, jsonData)
-
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
// validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- // validate different flags and combination to run test
- runTestUsing := validator.ValidateTestRunFlagsAndGetRunEnum(testSuiteIdStr, testSuiteName, propertyStr, propverStr,
- url, condition, ipVersion, targetEnvironment, addHeader, modifyHeader, jsonData, &testRunRequest,
- isStandardInputAvailable)
-
- //Run test
- svc.RunTest(runTestUsing, testSuiteIdStr, testSuiteName, propertyStr, propverStr,
- url, condition, ipVersion, targetEnvironment, addHeader, modifyHeader, filterHeader, testRunRequest)
+ globalValidator.ValidateParentSubCommands(cmd, args, false)
},
}
func init() {
rootCmd.AddCommand(testCmd)
- testCmd.Flags().SortFlags = false
-
- testCmd.Short = internal.GetMessageForKey(testCmd, internal.Short)
- testCmd.Long = internal.GetMessageForKey(testCmd, internal.Long)
- testCmd.Flags().StringVarP(&url, FlagUrl, FlagUrlShortHand, "", internal.GetMessageForKey(testCmd, FlagUrl))
- testCmd.Flags().StringArrayVarP(&addHeader, FlagAddHeader, FlagAddHeaderShortHand, []string{}, internal.GetMessageForKey(testCmd, FlagAddHeader))
- testCmd.Flags().StringArrayVarP(&modifyHeader, FlagModifyHeader, FlagModifyHeaderShortHand, []string{}, internal.GetMessageForKey(testCmd, FlagModifyHeader))
- testCmd.Flags().StringArrayVarP(&filterHeader, FlagFilterHeader, FlagFilterHeaderShortHand, []string{}, internal.GetMessageForKey(testCmd, FlagFilterHeader))
- testCmd.Flags().StringVarP(&condition, FlagCondition, FlagConditionShortHand, "", internal.GetMessageForKey(testCmd, FlagCondition))
- testCmd.Flags().StringVarP(&ipVersion, FlagIpVersion, FlagIpVersionShortHand, FlagIpVersionDefaultValue, internal.GetMessageForKey(testCmd, FlagIpVersion))
- testCmd.Flags().StringVar(&testSuiteName, FlagTestSuiteName, "", internal.GetMessageForKey(testCmd, FlagTestSuiteName))
- testCmd.Flags().StringVar(&testSuiteIdStr, FlagTestSuiteId, "", internal.GetMessageForKey(testCmd, FlagTestSuiteId))
- testCmd.Flags().StringVar(&propertyStr, FlagProperty, "", internal.GetMessageForKey(testCmd, FlagProperty))
- testCmd.Flags().StringVar(&propverStr, FlagPropver, "", internal.GetMessageForKey(testCmd, FlagPropver))
- testCmd.Flags().StringVarP(&targetEnvironment, FlagEnv, FlagEnvShortHand, internal.Staging, internal.GetMessageForKey(testCmd, FlagEnv))
+ testCmd.Short = util.GetMessageForKey(testCmd, internalconstant.Short)
+ testCmd.Long = util.GetMessageForKey(testCmd, internalconstant.Long)
}
diff --git a/cmd/test_cases.go b/cmd/test_cases.go
new file mode 100644
index 0000000..e9115dc
--- /dev/null
+++ b/cmd/test_cases.go
@@ -0,0 +1,35 @@
+package cmd
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var (
+ testCaseIdStr string
+ resolveVariables bool
+ setVariables []string
+)
+
+var testCaseCmd = &cobra.Command{
+ Use: externalconstant.TestCaseUse,
+ Aliases: []string{externalconstant.TestCaseCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+
+ globalValidator.ValidateParentSubCommands(cmd, args, false)
+ },
+}
+
+func init() {
+
+ rootCmd.AddCommand(testCaseCmd)
+ testCaseCmd.Flags().SortFlags = false
+
+ testCaseCmd.Short = util.GetMessageForKey(testCaseCmd, internalconstant.Short)
+ testCaseCmd.Long = util.GetMessageForKey(testCaseCmd, internalconstant.Long)
+
+}
diff --git a/cmd/test_cases_create.go b/cmd/test_cases_create.go
new file mode 100644
index 0000000..939a8bf
--- /dev/null
+++ b/cmd/test_cases_create.go
@@ -0,0 +1,56 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+ "strings"
+)
+
+var createTestCaseCmd = &cobra.Command{
+ Use: externalconstant.CreateTestCaseUse,
+ Example: externalconstant.CreateTestCaseExample,
+ Aliases: []string{externalconstant.CreateTestCaseCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testCaseService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ //Check if all required flag are present.
+ validator.AddTestCaseToTestSuiteFlagCheck(testSuiteIdStr, testSuiteName, url, condition, ipVersion, addHeader, modifyHeader, client, requestMethod, requestBody, encodeRequestBody, setVariables)
+
+ // common method for create and update test case under TS. As part of create, testCaseId will be always empty.
+ testCaseService.AddTestCaseWithTestSuite(cmd, testSuiteIdStr, testSuiteName, url, condition, ipVersion, addHeader, modifyHeader, filterHeader, internalconstant.Empty, strings.ToUpper(client), strings.ToUpper(requestMethod), requestBody, encodeRequestBody, setVariables)
+ },
+}
+
+func init() {
+
+ testCaseCmd.AddCommand(createTestCaseCmd)
+ createTestCaseCmd.Flags().SortFlags = false
+
+ createTestCaseCmd.Short = util.GetMessageForKey(createTestCaseCmd, internalconstant.Short)
+ createTestCaseCmd.Long = util.GetMessageForKey(createTestCaseCmd, internalconstant.Long)
+
+ createTestCaseCmd.Flags().StringVarP(&testSuiteIdStr, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagTestSuiteId))
+ createTestCaseCmd.Flags().StringVarP(&testSuiteName, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagTestSuiteName))
+ createTestCaseCmd.Flags().StringVarP(&url, externalconstant.FlagUrl, externalconstant.FlagUrlShortHand, internalconstant.Empty, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagUrl))
+ createTestCaseCmd.Flags().StringArrayVarP(&addHeader, externalconstant.FlagAddHeader, externalconstant.FlagAddHeaderShortHand, []string{}, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagAddHeader))
+ createTestCaseCmd.Flags().StringArrayVarP(&modifyHeader, externalconstant.FlagModifyHeader, externalconstant.FlagModifyHeaderShortHand, []string{}, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagModifyHeader))
+ createTestCaseCmd.Flags().StringArrayVarP(&filterHeader, externalconstant.FlagFilterHeader, externalconstant.FlagFilterHeaderShortHand, []string{}, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagFilterHeader))
+ createTestCaseCmd.Flags().StringVarP(&condition, externalconstant.FlagCondition, externalconstant.FlagConditionShortHand, internalconstant.Empty, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagCondition))
+ createTestCaseCmd.Flags().StringVar(&ipVersion, externalconstant.FlagIpVersion, internalconstant.IpVersionDefaultValue, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagIpVersion))
+ createTestCaseCmd.Flags().StringVarP(&client, externalconstant.FlagClient, externalconstant.FlagClientShortHand, internalconstant.Curl, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagClient))
+ createTestCaseCmd.Flags().StringVarP(&requestMethod, externalconstant.FlagRequestMethod, externalconstant.FlagRequestMethodShortHand, internalconstant.GetRequestMethod, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagRequestMethod))
+ createTestCaseCmd.Flags().StringVarP(&requestBody, externalconstant.FlagRequestBody, externalconstant.FlagRequestBodyShortHand, internalconstant.Empty, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagRequestBody))
+ createTestCaseCmd.Flags().BoolVarP(&encodeRequestBody, externalconstant.FlagEncodeRequestBody, externalconstant.FlagEncodeRequestBodyShortHand, false, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagEncodeRequestBody))
+ createTestCaseCmd.Flags().StringArrayVarP(&setVariables, externalconstant.FlagSetVariables, externalconstant.FlagSetVariablesShortHand, []string{}, util.GetMessageForKey(createTestCaseCmd, externalconstant.FlagSetVariables))
+}
diff --git a/cmd/test_cases_get.go b/cmd/test_cases_get.go
new file mode 100644
index 0000000..10aa829
--- /dev/null
+++ b/cmd/test_cases_get.go
@@ -0,0 +1,49 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var getTestCaseCmd = &cobra.Command{
+ Use: externalconstant.GetTestCaseUse,
+ Example: externalconstant.GetTestCaseExample,
+ Aliases: []string{externalconstant.GetTestCaseCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testCaseService := service.NewService(*api, cmd, jsonOutput)
+
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ //Check if required test suite flag is present.
+ validator.TestSuiteIdAndNameFlagCheck(testSuiteIdStr, testSuiteName)
+
+ //Check if required test case flag is present.
+ validator.ValidateTestCaseFlagCheck(testCaseIdStr)
+
+ testCaseService.GetTestCaseByIdToTestSuite(cmd, testSuiteIdStr, testSuiteName, testCaseIdStr, resolveVariables)
+ },
+}
+
+func init() {
+
+ testCaseCmd.AddCommand(getTestCaseCmd)
+ getTestCaseCmd.Flags().SortFlags = false
+
+ getTestCaseCmd.Short = util.GetMessageForKey(getTestCaseCmd, internalconstant.Short)
+ getTestCaseCmd.Long = util.GetMessageForKey(getTestCaseCmd, internalconstant.Long)
+
+ getTestCaseCmd.Flags().StringVarP(&testSuiteIdStr, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(getTestCaseCmd, externalconstant.FlagTestSuiteId))
+ getTestCaseCmd.Flags().StringVarP(&testCaseIdStr, externalconstant.FlagTestCaseId, externalconstant.FlagTestCaseIdShortHand, internalconstant.Empty, util.GetMessageForKey(getTestCaseCmd, externalconstant.FlagTestCaseId))
+ getTestCaseCmd.Flags().BoolVar(&resolveVariables, externalconstant.FlagResolveVariables, false, util.GetMessageForKey(getTestCaseCmd, externalconstant.FlagResolveVariables))
+}
diff --git a/cmd/test_cases_list.go b/cmd/test_cases_list.go
new file mode 100644
index 0000000..ae6249d
--- /dev/null
+++ b/cmd/test_cases_list.go
@@ -0,0 +1,46 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var getAllTestCaseCmd = &cobra.Command{
+ Use: externalconstant.ListTestCasesUse,
+ Example: externalconstant.ListTestCasesExample,
+ Aliases: []string{externalconstant.ListTestCasesCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testCaseService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ // validate testSuiteId, testSuiteName and groupBy flags.
+ validator.ValidateGetTestSuiteWithChildObjectsFlags(testSuiteIdStr, testSuiteName, groupBy)
+
+ testCaseService.GetTestCasesWithTestSuite(testSuiteIdStr, testSuiteName, groupBy, resolveVariables)
+ },
+}
+
+func init() {
+
+ testCaseCmd.AddCommand(getAllTestCaseCmd)
+ getAllTestCaseCmd.Flags().SortFlags = false
+
+ getAllTestCaseCmd.Short = util.GetMessageForKey(getAllTestCaseCmd, internalconstant.Short)
+ getAllTestCaseCmd.Long = util.GetMessageForKey(getAllTestCaseCmd, internalconstant.Long)
+
+ getAllTestCaseCmd.Flags().StringVarP(&testSuiteIdStr, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(getAllTestCaseCmd, externalconstant.FlagTestSuiteId))
+ getAllTestCaseCmd.Flags().StringVarP(&testSuiteName, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(getAllTestCaseCmd, externalconstant.FlagTestSuiteName))
+ getAllTestCaseCmd.Flags().BoolVar(&resolveVariables, externalconstant.FlagResolveVariables, false, util.GetMessageForKey(getAllTestCaseCmd, externalconstant.FlagResolveVariables))
+ getAllTestCaseCmd.Flags().StringVarP(&groupBy, externalconstant.FlagGroupBy, externalconstant.FlagGroupShortHand, internalconstant.Empty, util.GetMessageForKey(getAllTestCaseCmd, externalconstant.FlagGroupBy))
+}
diff --git a/cmd/test_cases_remove.go b/cmd/test_cases_remove.go
new file mode 100644
index 0000000..424b211
--- /dev/null
+++ b/cmd/test_cases_remove.go
@@ -0,0 +1,45 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var removeTestCaseCmd = &cobra.Command{
+ Use: externalconstant.RemoveTestCaseUse,
+ Example: externalconstant.RemoveTestCaseExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testCaseService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ //Check if all required flag are present.
+ validator.RemoveTestCaseFromTestSuiteFlagCheck(testSuiteIdStr, orderNumber, testCaseIdStr)
+
+ testCaseService.RemoveTestCaseFromTestSuiteUsingOrderNumberOrTestCaseId(testSuiteIdStr, orderNumber, testCaseIdStr)
+ },
+}
+
+func init() {
+
+ testCaseCmd.AddCommand(removeTestCaseCmd)
+ removeTestCaseCmd.Flags().SortFlags = false
+
+ removeTestCaseCmd.Short = util.GetMessageForKey(removeTestCaseCmd, internalconstant.Short)
+ removeTestCaseCmd.Long = util.GetMessageForKey(removeTestCaseCmd, internalconstant.Long)
+
+ removeTestCaseCmd.Flags().StringVarP(&testSuiteIdStr, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(removeTestCaseCmd, externalconstant.FlagTestSuiteId))
+ removeTestCaseCmd.Flags().StringVarP(&orderNumber, externalconstant.FlagOrderNumber, externalconstant.FlagOrderNumberShortHand, internalconstant.Empty, util.GetMessageForKey(removeTestCaseCmd, externalconstant.FlagOrderNumber))
+ removeTestCaseCmd.Flags().StringVarP(&testCaseIdStr, externalconstant.FlagTestCaseId, externalconstant.FlagTestCaseIdShortHand, internalconstant.Empty, util.GetMessageForKey(removeTestCaseCmd, externalconstant.FlagTestCaseId))
+
+}
diff --git a/cmd/test_cases_update.go b/cmd/test_cases_update.go
new file mode 100644
index 0000000..b065231
--- /dev/null
+++ b/cmd/test_cases_update.go
@@ -0,0 +1,61 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+ "strings"
+)
+
+var updateTestCaseCmd = &cobra.Command{
+ Use: externalconstant.UpdateTestCaseUse,
+ Example: externalconstant.UpdateTestCaseExample,
+ Aliases: []string{externalconstant.UpdateTestCaseCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testCaseService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ //Check if all required flag are present.
+ validator.AddTestCaseToTestSuiteFlagCheck(testSuiteIdStr, testSuiteName, url, condition, ipVersion, addHeader, modifyHeader, client, requestMethod, requestBody, encodeRequestBody, setVariables)
+
+ //Check if required test case flag is present.
+ validator.ValidateTestCaseFlagCheck(testCaseIdStr)
+
+ // common method for create and update test case under TS. As part of update, testCaseId should be valid.
+ testCaseService.EditTestCaseWithTestSuite(cmd, testSuiteIdStr, testSuiteName, url, condition, ipVersion, addHeader, modifyHeader, filterHeader, testCaseIdStr, strings.ToUpper(client), strings.ToUpper(requestMethod), requestBody, encodeRequestBody, setVariables)
+ },
+}
+
+func init() {
+
+ testCaseCmd.AddCommand(updateTestCaseCmd)
+ updateTestCaseCmd.Flags().SortFlags = false
+
+ updateTestCaseCmd.Short = util.GetMessageForKey(updateTestCaseCmd, internalconstant.Short)
+ updateTestCaseCmd.Long = util.GetMessageForKey(updateTestCaseCmd, internalconstant.Long)
+
+ updateTestCaseCmd.Flags().StringVarP(&testSuiteIdStr, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagTestSuiteId))
+ updateTestCaseCmd.Flags().StringVarP(&testSuiteName, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagTestSuiteName))
+ updateTestCaseCmd.Flags().StringVarP(&testCaseIdStr, externalconstant.FlagTestCaseId, externalconstant.FlagTestCaseIdShortHand, internalconstant.Empty, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagTestCaseId))
+ updateTestCaseCmd.Flags().StringVarP(&url, externalconstant.FlagUrl, externalconstant.FlagUrlShortHand, internalconstant.Empty, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagUrl))
+ updateTestCaseCmd.Flags().StringArrayVarP(&addHeader, externalconstant.FlagAddHeader, externalconstant.FlagAddHeaderShortHand, []string{}, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagAddHeader))
+ updateTestCaseCmd.Flags().StringArrayVarP(&modifyHeader, externalconstant.FlagModifyHeader, externalconstant.FlagModifyHeaderShortHand, []string{}, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagModifyHeader))
+ updateTestCaseCmd.Flags().StringArrayVarP(&filterHeader, externalconstant.FlagFilterHeader, externalconstant.FlagFilterHeaderShortHand, []string{}, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagFilterHeader))
+ updateTestCaseCmd.Flags().StringVarP(&condition, externalconstant.FlagCondition, externalconstant.FlagConditionShortHand, internalconstant.Empty, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagCondition))
+ updateTestCaseCmd.Flags().StringVar(&ipVersion, externalconstant.FlagIpVersion, internalconstant.IpVersionDefaultValue, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagIpVersion))
+ updateTestCaseCmd.Flags().StringVarP(&client, externalconstant.FlagClient, externalconstant.FlagClientShortHand, internalconstant.Curl, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagClient))
+ updateTestCaseCmd.Flags().StringVarP(&requestMethod, externalconstant.FlagRequestMethod, externalconstant.FlagRequestMethodShortHand, internalconstant.GetRequestMethod, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagRequestMethod))
+ updateTestCaseCmd.Flags().StringVarP(&requestBody, externalconstant.FlagRequestBody, externalconstant.FlagRequestBodyShortHand, internalconstant.Empty, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagRequestBody))
+ updateTestCaseCmd.Flags().BoolVarP(&encodeRequestBody, externalconstant.FlagEncodeRequestBody, externalconstant.FlagEncodeRequestBodyShortHand, false, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagEncodeRequestBody))
+ updateTestCaseCmd.Flags().StringArrayVarP(&setVariables, externalconstant.FlagSetVariables, externalconstant.FlagSetVariablesShortHand, []string{}, util.GetMessageForKey(updateTestCaseCmd, externalconstant.FlagSetVariables))
+}
diff --git a/cmd/test_get.go b/cmd/test_get.go
new file mode 100644
index 0000000..a442651
--- /dev/null
+++ b/cmd/test_get.go
@@ -0,0 +1,44 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testRunId string
+
+var testGetCmd = &cobra.Command{
+ Use: externalconstant.TestGetUse,
+ Aliases: []string{externalconstant.TestGetAlias},
+ Example: externalconstant.TestGetExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testRunService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate id flag.
+ validator.ValidateGetTestRunFlag(testRunId)
+
+ testRunService.GetTestRunAndPrintResult(testRunId)
+
+ },
+}
+
+func init() {
+ testCmd.AddCommand(testGetCmd)
+ testGetCmd.Flags().SortFlags = false
+
+ testGetCmd.Short = util.GetMessageForKey(testGetCmd, internalconstant.Short)
+ testGetCmd.Long = util.GetMessageForKey(testGetCmd, internalconstant.Long)
+
+ testGetCmd.Flags().StringVarP(&testRunId, externalconstant.FlagTestRunId, externalconstant.FlagTestRunIdShortHand, internalconstant.Empty, util.GetMessageForKey(testGetCmd, externalconstant.FlagTestRunId))
+}
diff --git a/cmd/test_list.go b/cmd/test_list.go
new file mode 100644
index 0000000..c92ee22
--- /dev/null
+++ b/cmd/test_list.go
@@ -0,0 +1,36 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testListCmd = &cobra.Command{
+ Use: externalconstant.TestListUse,
+ Aliases: []string{externalconstant.TestListAlias},
+ Example: externalconstant.TestListExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testRunService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ testRunService.GetTestRunsAndPrint()
+
+ },
+}
+
+func init() {
+ testCmd.AddCommand(testListCmd)
+ testListCmd.Flags().SortFlags = false
+
+ testListCmd.Short = util.GetMessageForKey(testListCmd, internalconstant.Short)
+ testListCmd.Long = util.GetMessageForKey(testListCmd, internalconstant.Long)
+}
diff --git a/cmd/test_log_lines.go b/cmd/test_log_lines.go
new file mode 100644
index 0000000..82033c6
--- /dev/null
+++ b/cmd/test_log_lines.go
@@ -0,0 +1,43 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testLogLinesCmd = &cobra.Command{
+ Use: externalconstant.TestLogLinesUse,
+ Aliases: []string{externalconstant.TestLogLinesCommandAliases},
+ Example: externalconstant.TestLogLinesExampleUse,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testRunService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate tcx-id flag.
+ validator.ValidateGetLogLinesFlag(testCaseExecutionId)
+
+ testRunService.GetTestLogLinesAndPrintJson(testCaseExecutionId)
+
+ },
+}
+
+func init() {
+ testCmd.AddCommand(testLogLinesCmd)
+ testLogLinesCmd.Flags().SortFlags = false
+
+ testLogLinesCmd.Short = util.GetMessageForKey(testLogLinesCmd, internalconstant.Short)
+ testLogLinesCmd.Long = util.GetMessageForKey(testLogLinesCmd, internalconstant.Long)
+
+ testLogLinesCmd.Flags().StringVarP(&testCaseExecutionId, externalconstant.FlagTestCaseExecId, externalconstant.FlagTestCaseExecShortHand, internalconstant.Empty, util.GetMessageForKey(testLogLinesCmd, externalconstant.FlagTestCaseExecId))
+
+}
diff --git a/cmd/test_raw_request_response.go b/cmd/test_raw_request_response.go
new file mode 100644
index 0000000..3550753
--- /dev/null
+++ b/cmd/test_raw_request_response.go
@@ -0,0 +1,44 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testRawReqResCmd = &cobra.Command{
+ Use: externalconstant.TestRawReqResUse,
+ Aliases: []string{externalconstant.TestRawReqResCommandAliases},
+ Example: externalconstant.TestRawReqResExampleUse,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testRunService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate ids flag.
+ validator.ValidateGetRawRequestResponseFlag(testRunId, testCaseExecutionId)
+
+ testRunService.GetRawRequestResponseAndPrintResult(testRunId, testCaseExecutionId)
+
+ },
+}
+
+func init() {
+ testCmd.AddCommand(testRawReqResCmd)
+ testRawReqResCmd.Flags().SortFlags = false
+
+ testRawReqResCmd.Short = util.GetMessageForKey(testRawReqResCmd, internalconstant.Short)
+ testRawReqResCmd.Long = util.GetMessageForKey(testRawReqResCmd, internalconstant.Long)
+
+ testRawReqResCmd.Flags().StringVarP(&testRunId, externalconstant.FlagTestRunId, externalconstant.FlagTestRunIdShortHand, internalconstant.Empty, util.GetMessageForKey(testRawReqResCmd, externalconstant.FlagTestRunId))
+ testRawReqResCmd.Flags().StringVarP(&testCaseExecutionId, externalconstant.FlagTestCaseExecId, externalconstant.FlagTestCaseExecShortHand, internalconstant.Empty, util.GetMessageForKey(testRawReqResCmd, externalconstant.FlagTestCaseExecId))
+
+}
diff --git a/cmd/test_requests.go b/cmd/test_requests.go
new file mode 100644
index 0000000..58a5aa8
--- /dev/null
+++ b/cmd/test_requests.go
@@ -0,0 +1,26 @@
+package cmd
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testReqCmd = &cobra.Command{
+ Use: externalconstant.TestRequestUse,
+ Aliases: []string{externalconstant.TestRequestCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateParentSubCommands(cmd, args, false)
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(testReqCmd)
+
+ testReqCmd.Short = util.GetMessageForKey(testReqCmd, internalconstant.Short)
+ testReqCmd.Long = util.GetMessageForKey(testReqCmd, internalconstant.Long)
+}
diff --git a/cmd/test_requests_list.go b/cmd/test_requests_list.go
new file mode 100644
index 0000000..4b4950c
--- /dev/null
+++ b/cmd/test_requests_list.go
@@ -0,0 +1,34 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testReqListCmd = &cobra.Command{
+ Use: externalconstant.TestRequestListUse,
+ Example: externalconstant.TestRequestListExample,
+ Aliases: []string{externalconstant.TestRequestListCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ svc.GetTestRequestAndPrintResult(cmd)
+ },
+}
+
+func init() {
+ testReqCmd.AddCommand(testReqListCmd)
+
+ testReqListCmd.Short = util.GetMessageForKey(testReqListCmd, internalconstant.Short)
+ testReqListCmd.Long = util.GetMessageForKey(testReqListCmd, internalconstant.Long)
+}
diff --git a/cmd/test_run.go b/cmd/test_run.go
new file mode 100644
index 0000000..8ef9df7
--- /dev/null
+++ b/cmd/test_run.go
@@ -0,0 +1,92 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var (
+ url string
+ addHeader []string
+ modifyHeader []string
+ filterHeader []string
+ condition string
+ ipVersion string
+ testSuiteName string
+ testSuiteIdStr string
+ propertyIdStr string
+ propertyNameStr string
+ propertyVersionStr string
+ targetEnvironment string
+
+ // new flag variables
+ client string
+ location string
+ requestMethod string
+ encodeRequestBody bool
+ requestBody string
+)
+
+var testRunRequest model.TestRun
+
+var runCmd = &cobra.Command{
+ Use: externalconstant.TestRunUse,
+ Example: externalconstant.TestRunExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ testRunService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, true)
+
+ validator := validator.NewValidator(cmd, jsonData)
+
+ // validate different flags and combination to run test
+ runTestUsing := validator.ValidateTestRunFlagsAndGetRunEnum(testSuiteIdStr, testSuiteName, propertyIdStr, propertyNameStr, propertyVersionStr,
+ url, condition, ipVersion, targetEnvironment, client, location, requestMethod, requestBody, addHeader, modifyHeader,
+ jsonData, &testRunRequest, isStandardInputAvailable, encodeRequestBody)
+
+ //Run test
+ testRunService.RunTest(runTestUsing, testSuiteIdStr, testSuiteName, propertyIdStr, propertyNameStr, propertyVersionStr,
+ url, condition, ipVersion, targetEnvironment, client, location, requestMethod, requestBody, addHeader, modifyHeader,
+ filterHeader, testRunRequest, encodeRequestBody)
+ },
+}
+
+func init() {
+ testCmd.AddCommand(runCmd)
+ runCmd.Flags().SortFlags = false
+
+ runCmd.Short = util.GetMessageForKey(runCmd, internalconstant.Short)
+ runCmd.Long = util.GetMessageForKey(runCmd, internalconstant.Long)
+
+ runCmd.Flags().StringVarP(&url, externalconstant.FlagUrl, externalconstant.FlagUrlShortHand, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagUrl))
+ runCmd.Flags().StringVarP(&testSuiteIdStr, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagTestSuiteId))
+ runCmd.Flags().StringVarP(&testSuiteName, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagTestSuiteName))
+ runCmd.Flags().StringVarP(&propertyIdStr, externalconstant.FlagPropertyId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagPropertyId))
+ runCmd.Flags().StringVarP(&propertyNameStr, externalconstant.FlagPropertyName, externalconstant.FlagPropertyShortHand, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagPropertyName))
+ runCmd.Flags().StringVarP(&propertyVersionStr, externalconstant.FlagPropertyVersion, externalconstant.FlagPropertyVersionShortHand, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagPropertyVersion))
+ runCmd.Flags().StringVar(&ipVersion, externalconstant.FlagIpVersion, internalconstant.IpVersionDefaultValue, util.GetMessageForKey(runCmd, externalconstant.FlagIpVersion))
+ runCmd.Flags().StringArrayVarP(&addHeader, externalconstant.FlagAddHeader, externalconstant.FlagAddHeaderShortHand, []string{}, util.GetMessageForKey(runCmd, externalconstant.FlagAddHeader))
+ runCmd.Flags().StringArrayVarP(&modifyHeader, externalconstant.FlagModifyHeader, externalconstant.FlagModifyHeaderShortHand, []string{}, util.GetMessageForKey(runCmd, externalconstant.FlagModifyHeader))
+ runCmd.Flags().StringArrayVarP(&filterHeader, externalconstant.FlagFilterHeader, externalconstant.FlagFilterHeaderShortHand, []string{}, util.GetMessageForKey(runCmd, externalconstant.FlagFilterHeader))
+ runCmd.Flags().StringVarP(&condition, externalconstant.FlagCondition, externalconstant.FlagConditionShortHand, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagCondition))
+ runCmd.Flags().StringVar(&targetEnvironment, externalconstant.FlagEnv, internalconstant.Staging, util.GetMessageForKey(runCmd, externalconstant.FlagEnv))
+
+ // new Flags
+ runCmd.Flags().StringVarP(&client, externalconstant.FlagClient, externalconstant.FlagClientShortHand, internalconstant.Curl, util.GetMessageForKey(runCmd, externalconstant.FlagClient))
+
+ // we are disabling this flag for now as we support only one location, we may enable it in future.
+ //runCmd.Flags().StringVarP(&location, externalconstant.FlagLocation, externalconstant.FlagLocationShortHand, internalconstant.DefaultLocation, util.GetMessageForKey(runCmd, externalconstant.FlagLocation))
+
+ runCmd.Flags().StringVarP(&requestMethod, externalconstant.FlagRequestMethod, externalconstant.FlagRequestMethodShortHand, internalconstant.GetRequestMethod, util.GetMessageForKey(runCmd, externalconstant.FlagRequestMethod))
+ runCmd.Flags().BoolVarP(&encodeRequestBody, externalconstant.FlagEncodeRequestBody, externalconstant.FlagEncodeRequestBodyShortHand, false, util.GetMessageForKey(runCmd, externalconstant.FlagEncodeRequestBody))
+ runCmd.Flags().StringVarP(&requestBody, externalconstant.FlagRequestBody, externalconstant.FlagRequestBodyShortHand, internalconstant.Empty, util.GetMessageForKey(runCmd, externalconstant.FlagRequestBody))
+}
diff --git a/cmd/test_suite.go b/cmd/test_suite.go
new file mode 100644
index 0000000..3b9b4bb
--- /dev/null
+++ b/cmd/test_suite.go
@@ -0,0 +1,45 @@
+package cmd
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var (
+ id string
+ name string
+ description string
+ unlocked bool
+ locked bool
+ stateful bool
+ stateless bool
+ propertyId string
+ propertyName string
+ propertyVersion string
+ removeProperty bool
+ search string
+ user string
+ orderNumber string
+ groupBy string
+)
+
+var testSuiteCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteUse,
+ Aliases: []string{externalconstant.TestSuiteCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateParentSubCommands(cmd, args, false)
+
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(testSuiteCmd)
+
+ testSuiteCmd.Short = util.GetMessageForKey(testSuiteCmd, internalconstant.Short)
+ testSuiteCmd.Long = util.GetMessageForKey(testSuiteCmd, internalconstant.Long)
+}
diff --git a/cmd/test_suite_create.go b/cmd/test_suite_create.go
new file mode 100644
index 0000000..93e463e
--- /dev/null
+++ b/cmd/test_suite_create.go
@@ -0,0 +1,53 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuite model.TestSuite
+
+var testSuiteAddCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteAddUse,
+ Example: externalconstant.TestSuiteAddExample,
+ Aliases: []string{externalconstant.TestSuiteAddCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, true)
+
+ validator := validator.NewValidator(cmd, jsonData)
+
+ // validate json input or flags provided by user and assign json to test suite if provided
+ validator.ValidateCreateTestSuiteFields(&testSuite, isStandardInputAvailable, name, propertyId, propertyName, propertyVersion)
+
+ svc.AddTestSuiteAndPrint(cmd, name, description, propertyId, propertyName, propertyVersion, unlocked, stateful, isStandardInputAvailable, testSuite)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteAddCmd)
+ testSuiteAddCmd.Flags().SortFlags = false
+
+ testSuiteAddCmd.Short = util.GetMessageForKey(testSuiteAddCmd, internalconstant.Short)
+ testSuiteAddCmd.Long = util.GetMessageForKey(testSuiteAddCmd, internalconstant.Long)
+
+ testSuiteAddCmd.Flags().StringVarP(&name, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteAddCmd, externalconstant.FlagTestSuiteName))
+ testSuiteAddCmd.Flags().StringVarP(&description, externalconstant.FlagDescription, externalconstant.FlagDescriptionShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteAddCmd, externalconstant.FlagDescription))
+ testSuiteAddCmd.Flags().BoolVar(&unlocked, externalconstant.FlagUnlocked, false, util.GetMessageForKey(testSuiteAddCmd, externalconstant.FlagUnlocked))
+ testSuiteAddCmd.Flags().BoolVar(&stateful, externalconstant.FlagStateFul, false, util.GetMessageForKey(testSuiteAddCmd, externalconstant.FlagStateFul))
+ testSuiteAddCmd.Flags().StringVarP(&propertyId, externalconstant.FlagPropertyId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(testSuiteAddCmd, externalconstant.FlagPropertyId))
+ testSuiteAddCmd.Flags().StringVarP(&propertyName, externalconstant.FlagPropertyName, externalconstant.FlagPropertyShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteAddCmd, externalconstant.FlagPropertyName))
+ testSuiteAddCmd.Flags().StringVarP(&propertyVersion, externalconstant.FlagPropertyVersion, externalconstant.FlagPropertyVersionShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteAddCmd, externalconstant.FlagPropertyVersion))
+
+}
diff --git a/cmd/test_suite_create_with_child_objects.go b/cmd/test_suite_create_with_child_objects.go
new file mode 100644
index 0000000..943e46a
--- /dev/null
+++ b/cmd/test_suite_create_with_child_objects.go
@@ -0,0 +1,43 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteImport model.TestSuite
+
+var testSuiteImportCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteCreateWithChildObjects,
+ Example: externalconstant.TestSuiteCreateWithChildObjectsExample,
+ Aliases: []string{externalconstant.TestSuiteCreateWithChildObjectsCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, true)
+
+ validator := validator.NewValidator(cmd, jsonData)
+
+ validator.ValidateImportFields(&testSuiteImport)
+ svc.ImportTestSuites(testSuiteImport)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteImportCmd)
+ testSuiteImportCmd.Flags().SortFlags = false
+
+ testSuiteImportCmd.Short = util.GetMessageForKey(testSuiteImportCmd, internalconstant.Short)
+ testSuiteImportCmd.Long = util.GetMessageForKey(testSuiteImportCmd, internalconstant.Long)
+
+}
diff --git a/cmd/test_suite_generate-default.go b/cmd/test_suite_generate-default.go
new file mode 100644
index 0000000..a19abe2
--- /dev/null
+++ b/cmd/test_suite_generate-default.go
@@ -0,0 +1,52 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var (
+ urls []string
+ defaultTestSuite model.DefaultTestSuiteRequest
+)
+
+var testSuiteDefaultCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteGenerateDefaultUse,
+ Example: externalconstant.TestSuiteGenerateDefaultExample,
+ Aliases: []string{externalconstant.TestSuiteGenerateDefaultCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, true)
+
+ validator := validator.NewValidator(cmd, jsonData)
+
+ // validate configVersion and urls for flag usage OR construct payload json from input file
+ validator.ValidateDefaultTestSuiteFields(propertyId, propertyName, propertyVersion, urls, jsonData, &defaultTestSuite,
+ isStandardInputAvailable)
+
+ // generate default ts
+ svc.GenerateTestSuite(propertyId, propertyName, propertyVersion, urls, defaultTestSuite, isStandardInputAvailable)
+ },
+}
+
+func init() {
+ testSuiteCmd.AddCommand(testSuiteDefaultCmd)
+ testSuiteDefaultCmd.Flags().SortFlags = false
+
+ testSuiteDefaultCmd.Short = util.GetMessageForKey(testSuiteDefaultCmd, internalconstant.Short)
+ testSuiteDefaultCmd.Long = util.GetMessageForKey(testSuiteDefaultCmd, internalconstant.Long)
+ testSuiteDefaultCmd.Flags().StringVarP(&propertyId, externalconstant.FlagPropertyId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(testSuiteDefaultCmd, externalconstant.FlagPropertyId))
+ testSuiteDefaultCmd.Flags().StringVarP(&propertyName, externalconstant.FlagPropertyName, externalconstant.FlagPropertyShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteDefaultCmd, externalconstant.FlagPropertyName))
+ testSuiteDefaultCmd.Flags().StringVarP(&propertyVersion, externalconstant.FlagPropertyVersion, externalconstant.FlagPropertyVersionShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteDefaultCmd, externalconstant.FlagPropertyVersion))
+ testSuiteDefaultCmd.Flags().StringArrayVarP(&urls, externalconstant.FlagUrl, externalconstant.FlagUrlShortHand, []string{}, util.GetMessageForKey(testSuiteDefaultCmd, externalconstant.FlagUrl))
+}
diff --git a/cmd/test_suite_get.go b/cmd/test_suite_get.go
new file mode 100644
index 0000000..2a7d74d
--- /dev/null
+++ b/cmd/test_suite_get.go
@@ -0,0 +1,46 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteGetCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteGetUse,
+ Example: externalconstant.TestSuiteGetExample,
+ Aliases: []string{externalconstant.TestSuiteGetCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ // validate id, name flags.
+ validator.TestSuiteIdAndNameFlagCheck(id, name)
+
+ //Get and print test suite, test cases
+ svc.GetTestSuiteAndPrint(id, name)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteGetCmd)
+ testSuiteGetCmd.Flags().SortFlags = false
+
+ testSuiteGetCmd.Short = util.GetMessageForKey(testSuiteGetCmd, internalconstant.Short)
+ testSuiteGetCmd.Long = util.GetMessageForKey(testSuiteGetCmd, internalconstant.Long)
+
+ testSuiteGetCmd.Flags().StringVarP(&id, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteGetCmd, externalconstant.FlagTestSuiteId))
+ testSuiteGetCmd.Flags().StringVarP(&name, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteGetCmd, externalconstant.FlagTestSuiteName))
+
+}
diff --git a/cmd/test_suite_get_with_child_objects.go b/cmd/test_suite_get_with_child_objects.go
new file mode 100644
index 0000000..285e4d4
--- /dev/null
+++ b/cmd/test_suite_get_with_child_objects.go
@@ -0,0 +1,48 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteExportCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteGetWithChildObjectsUse,
+ Example: externalconstant.TestSuiteGetWithChildObjectsExample,
+ Aliases: []string{externalconstant.TestSuiteGetWithChildObjectsCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ // validate id, name and groupBy flags.
+ validator.ValidateGetTestSuiteWithChildObjectsFlags(id, name, groupBy)
+
+ //Get and print test suite, test cases
+ svc.GetTestSuiteWithChildObjectsAndPrint(id, name, groupBy, resolveVariables)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteExportCmd)
+ testSuiteExportCmd.Flags().SortFlags = false
+
+ testSuiteExportCmd.Short = util.GetMessageForKey(testSuiteExportCmd, internalconstant.Short)
+ testSuiteExportCmd.Long = util.GetMessageForKey(testSuiteExportCmd, internalconstant.Long)
+
+ testSuiteExportCmd.Flags().StringVarP(&id, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteExportCmd, externalconstant.FlagTestSuiteId))
+ testSuiteExportCmd.Flags().StringVarP(&name, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteExportCmd, externalconstant.FlagTestSuiteName))
+ testSuiteExportCmd.Flags().StringVarP(&groupBy, externalconstant.FlagGroupBy, externalconstant.FlagGroupShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteExportCmd, externalconstant.FlagGroupBy))
+ testSuiteExportCmd.Flags().BoolVar(&resolveVariables, externalconstant.FlagResolveVariables, false, util.GetMessageForKey(testSuiteExportCmd, externalconstant.FlagResolveVariables))
+
+}
diff --git a/cmd/test_suite_list.go b/cmd/test_suite_list.go
new file mode 100644
index 0000000..ad9b153
--- /dev/null
+++ b/cmd/test_suite_list.go
@@ -0,0 +1,47 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteListCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteListUse,
+ Example: externalconstant.TestSuiteListExample,
+ Aliases: []string{externalconstant.TestSuiteListCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ validator.PropertyAndVersionFlagCheck(propertyId, propertyName, propertyVersion, true)
+
+ svc.GetTestSuitesAndPrint(cmd, propertyId, propertyName, propertyVersion, user, search)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteListCmd)
+ testSuiteListCmd.Flags().SortFlags = false
+
+ testSuiteListCmd.Short = util.GetMessageForKey(testSuiteListCmd, internalconstant.Short)
+ testSuiteListCmd.Long = util.GetMessageForKey(testSuiteListCmd, internalconstant.Long)
+
+ testSuiteListCmd.Flags().StringVarP(&propertyId, externalconstant.FlagPropertyId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(testSuiteListCmd, externalconstant.FlagPropertyId))
+ testSuiteListCmd.Flags().StringVarP(&propertyName, externalconstant.FlagPropertyName, externalconstant.FlagPropertyShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteListCmd, externalconstant.FlagPropertyName))
+ testSuiteListCmd.Flags().StringVarP(&propertyVersion, externalconstant.FlagPropertyVersion, externalconstant.FlagPropertyVersionShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteListCmd, externalconstant.FlagPropertyVersion))
+ testSuiteListCmd.Flags().StringVarP(&user, externalconstant.FlagUser, externalconstant.FlagUserShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteListCmd, externalconstant.FlagUser))
+ testSuiteListCmd.Flags().StringVar(&search, externalconstant.FlagSearch, internalconstant.Empty, util.GetMessageForKey(testSuiteListCmd, externalconstant.FlagSearch))
+
+}
diff --git a/cmd/test_suite_remove.go b/cmd/test_suite_remove.go
new file mode 100644
index 0000000..e2069dc
--- /dev/null
+++ b/cmd/test_suite_remove.go
@@ -0,0 +1,43 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteRemoveCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteRemoveUse,
+ Example: externalconstant.TestSuiteRemoveExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ //Check if all required flag are present.
+ validator.TestSuiteIdAndNameFlagCheck(id, name)
+
+ svc.RemoveTestSuiteByIdOrName(id, name)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteRemoveCmd)
+ testSuiteRemoveCmd.Flags().SortFlags = false
+
+ testSuiteRemoveCmd.Short = util.GetMessageForKey(testSuiteRemoveCmd, internalconstant.Short)
+ testSuiteRemoveCmd.Long = util.GetMessageForKey(testSuiteRemoveCmd, internalconstant.Long)
+
+ testSuiteRemoveCmd.Flags().StringVarP(&id, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteRemoveCmd, externalconstant.FlagTestSuiteId))
+ testSuiteRemoveCmd.Flags().StringVarP(&name, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteRemoveCmd, externalconstant.FlagTestSuiteName))
+}
diff --git a/cmd/test_suite_restore.go b/cmd/test_suite_restore.go
new file mode 100644
index 0000000..4b9819a
--- /dev/null
+++ b/cmd/test_suite_restore.go
@@ -0,0 +1,43 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteRestoreCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteRestoreUse,
+ Example: externalconstant.TestSuiteRestoreExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+
+ //Check if all required flag are present.
+ validator.TestSuiteIdAndNameFlagCheck(id, name)
+
+ svc.RestoreTestSuiteByIdOrName(id, name)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteRestoreCmd)
+ testSuiteRestoreCmd.Flags().SortFlags = false
+
+ testSuiteRestoreCmd.Short = util.GetMessageForKey(testSuiteRestoreCmd, internalconstant.Short)
+ testSuiteRestoreCmd.Long = util.GetMessageForKey(testSuiteRestoreCmd, internalconstant.Long)
+
+ testSuiteRestoreCmd.Flags().StringVarP(&id, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteRestoreCmd, externalconstant.FlagTestSuiteId))
+ testSuiteRestoreCmd.Flags().StringVarP(&name, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteRestoreCmd, externalconstant.FlagTestSuiteName))
+}
diff --git a/cmd/test_suite_update.go b/cmd/test_suite_update.go
new file mode 100644
index 0000000..618fde9
--- /dev/null
+++ b/cmd/test_suite_update.go
@@ -0,0 +1,56 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteEditCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteEditUse,
+ Example: externalconstant.TestSuiteEditExample,
+ Aliases: []string{externalconstant.TestSuiteEditCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, true)
+
+ validator := validator.NewValidator(cmd, jsonData)
+
+ // validate json input or flags provided by user and assign json to test suite if provided
+ validator.ValidateUpdateTestSuiteFields(&testSuite, isStandardInputAvailable, id, propertyId, propertyName, propertyVersion,
+ locked, unlocked, stateful, stateless, removeProperty)
+
+ svc.EditTestSuiteAndPrint(cmd, id, name, description, propertyId, propertyName, propertyVersion, unlocked, stateful,
+ removeProperty, locked, stateless, isStandardInputAvailable, testSuite)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteEditCmd)
+ testSuiteEditCmd.Flags().SortFlags = false
+
+ testSuiteEditCmd.Short = util.GetMessageForKey(testSuiteEditCmd, internalconstant.Short)
+ testSuiteEditCmd.Long = util.GetMessageForKey(testSuiteEditCmd, internalconstant.Long)
+
+ testSuiteEditCmd.Flags().StringVarP(&id, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagTestSuiteId))
+ testSuiteEditCmd.Flags().StringVarP(&name, externalconstant.FlagTestSuiteName, externalconstant.FlagTestSuiteNameShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagTestSuiteName))
+ testSuiteEditCmd.Flags().StringVarP(&description, externalconstant.FlagDescription, externalconstant.FlagDescriptionShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagDescription))
+ testSuiteEditCmd.Flags().BoolVar(&unlocked, externalconstant.FlagUnlocked, false, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagUnlocked))
+ testSuiteEditCmd.Flags().BoolVar(&stateful, externalconstant.FlagStateFul, false, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagStateFul))
+ testSuiteEditCmd.Flags().BoolVar(&locked, externalconstant.FlagLocked, false, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagLocked))
+ testSuiteEditCmd.Flags().BoolVar(&stateless, externalconstant.FlagStateless, false, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagStateless))
+ testSuiteEditCmd.Flags().StringVarP(&propertyId, externalconstant.FlagPropertyId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagPropertyId))
+ testSuiteEditCmd.Flags().StringVarP(&propertyName, externalconstant.FlagPropertyName, externalconstant.FlagPropertyShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagPropertyName))
+ testSuiteEditCmd.Flags().StringVarP(&propertyVersion, externalconstant.FlagPropertyVersion, externalconstant.FlagPropertyVersionShortHand, internalconstant.Empty, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagPropertyVersion))
+ testSuiteEditCmd.Flags().BoolVar(&removeProperty, externalconstant.FlagRemoveProperty, false, util.GetMessageForKey(testSuiteEditCmd, externalconstant.FlagRemoveProperty))
+
+}
diff --git a/cmd/test_suite_update_with_child_objects.go b/cmd/test_suite_update_with_child_objects.go
new file mode 100644
index 0000000..93d3d85
--- /dev/null
+++ b/cmd/test_suite_update_with_child_objects.go
@@ -0,0 +1,43 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var testSuiteManage model.TestSuite
+
+var testSuiteManageCmd = &cobra.Command{
+ Use: externalconstant.TestSuiteUpdateWithChildObjectsUse,
+ Example: externalconstant.TestSuiteUpdateWithChildObjectsExample,
+ Aliases: []string{externalconstant.TestSuiteUpdateWithChildObjectsCommandAlias},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, true)
+
+ validator := validator.NewValidator(cmd, jsonData)
+
+ validator.ValidateManageFields(&testSuiteManage)
+ svc.ManageTestSuites(testSuiteManage)
+ },
+}
+
+func init() {
+
+ testSuiteCmd.AddCommand(testSuiteManageCmd)
+ testSuiteManageCmd.Flags().SortFlags = false
+
+ testSuiteManageCmd.Short = util.GetMessageForKey(testSuiteManageCmd, internalconstant.Short)
+ testSuiteManageCmd.Long = util.GetMessageForKey(testSuiteManageCmd, internalconstant.Long)
+
+}
diff --git a/cmd/test_suites.go b/cmd/test_suites.go
deleted file mode 100644
index b51a8e6..0000000
--- a/cmd/test_suites.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var (
- id string
- name string
- description string
- unlocked bool
- locked bool
- stateful bool
- stateless bool
- propertyName string
- propertyVersion string
- removeProperty bool
- search string
- user string
- orderNumber string
- groupBy string
-)
-
-var testSuitesCmd = &cobra.Command{
- Use: TestSuiteUse,
- Aliases: []string{TestSuiteCommandAlias},
- Run: func(cmd *cobra.Command, args []string) {
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand for no arguments
- validator.NotValidSubcommandCheck(cmd, args)
-
- // validate subcommand
- validator.ValidSubcommandLegacyArgsCheck(cmd, args)
- },
-}
-
-func init() {
- rootCmd.AddCommand(testSuitesCmd)
-
- testSuitesCmd.Short = internal.GetMessageForKey(testSuitesCmd, internal.Short)
- testSuitesCmd.Long = internal.GetMessageForKey(testSuitesCmd, internal.Long)
-}
diff --git a/cmd/test_suites_add.go b/cmd/test_suites_add.go
deleted file mode 100644
index 6df02fe..0000000
--- a/cmd/test_suites_add.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesAddCmd = &cobra.Command{
- Use: TestSuiteAddUse,
- Example: TestSuiteAddExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- // validate name flag check.
- validator.AddTestSuiteNameFlagCheck(name)
-
- // validate propertyVersion usage.
- propName, propVersion := validator.PropertyAndVersionFlagCheck(propertyName, propertyVersion, true)
-
- testSuite := svc.AddTestSuite(name, description, propName, propVersion, unlocked, stateful)
- internal.PrintSuccess(internal.GetServiceMessage(cmd, internal.MessageTypeDisplay, "", "addTestSuiteSuccess") + "\n")
- internal.PrintTestSuite(*testSuite)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesAddCmd)
- testSuitesAddCmd.Flags().SortFlags = false
-
- testSuitesAddCmd.Short = internal.GetMessageForKey(testSuitesAddCmd, internal.Short)
- testSuitesAddCmd.Long = internal.GetMessageForKey(testSuitesAddCmd, internal.Long)
-
- testSuitesAddCmd.Flags().StringVar(&name, FlagName, "", internal.GetMessageForKey(testSuitesAddCmd, FlagName))
- testSuitesAddCmd.Flags().StringVar(&description, FlagDescription, "", internal.GetMessageForKey(testSuitesAddCmd, FlagDescription))
- testSuitesAddCmd.Flags().BoolVar(&unlocked, FlagUnlocked, false, internal.GetMessageForKey(testSuitesAddCmd, FlagUnlocked))
- testSuitesAddCmd.Flags().BoolVar(&stateful, FlagStateFul, false, internal.GetMessageForKey(testSuitesAddCmd, FlagStateFul))
- testSuitesAddCmd.Flags().StringVar(&propertyName, FlagProperty, "", internal.GetMessageForKey(testSuitesAddCmd, FlagProperty))
- testSuitesAddCmd.Flags().StringVar(&propertyVersion, FlagPropver, "", internal.GetMessageForKey(testSuitesAddCmd, FlagPropver))
-
-}
diff --git a/cmd/test_suites_add_test_case.go b/cmd/test_suites_add_test_case.go
deleted file mode 100644
index 54e5237..0000000
--- a/cmd/test_suites_add_test_case.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesAddTestCaseCmd = &cobra.Command{
- Use: TestSuiteAddTestCaseUse,
- Example: TestSuiteAddTestCaseExample,
-
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- //Check if all required flag are present.
- validator.AddTestCaseToTestSuiteFlagCheck(testSuiteIdStr, testSuiteName, url, condition, ipVersion, addHeader, modifyHeader)
-
- testSuites := svc.GetTestSuitesByIdOrName(testSuiteIdStr, testSuiteName, internal.Empty, true, false, true)
- svc.AddTestCaseWithTestSuite(testSuites, testSuiteName, url, condition, ipVersion, addHeader, modifyHeader, filterHeader)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesAddTestCaseCmd)
- testSuitesAddTestCaseCmd.Flags().SortFlags = false
-
- testSuitesAddTestCaseCmd.Short = internal.GetMessageForKey(testSuitesAddTestCaseCmd, internal.Short)
- testSuitesAddTestCaseCmd.Long = internal.GetMessageForKey(testSuitesAddTestCaseCmd, internal.Long)
-
- testSuitesAddTestCaseCmd.Flags().StringVar(&testSuiteIdStr, FlagTestSuiteId, "", internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagTestSuiteId))
- testSuitesAddTestCaseCmd.Flags().StringVar(&testSuiteName, FlagTestSuiteName, "", internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagTestSuiteName))
- testSuitesAddTestCaseCmd.Flags().StringVarP(&url, FlagUrl, FlagUrlShortHand, "", internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagUrl))
- testSuitesAddTestCaseCmd.Flags().StringArrayVarP(&addHeader, FlagAddHeader, FlagAddHeaderShortHand, []string{}, internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagAddHeader))
- testSuitesAddTestCaseCmd.Flags().StringArrayVarP(&modifyHeader, FlagModifyHeader, FlagModifyHeaderShortHand, []string{}, internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagModifyHeader))
- testSuitesAddTestCaseCmd.Flags().StringArrayVarP(&filterHeader, FlagFilterHeader, FlagFilterHeaderShortHand, []string{}, internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagFilterHeader))
- testSuitesAddTestCaseCmd.Flags().StringVarP(&condition, FlagCondition, FlagConditionShortHand, "", internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagCondition))
- testSuitesAddTestCaseCmd.Flags().StringVarP(&ipVersion, FlagIpVersion, FlagIpVersionShortHand, FlagIpVersionDefaultValue, internal.GetMessageForKey(testSuitesAddTestCaseCmd, FlagIpVersion))
-
-}
diff --git a/cmd/test_suites_auto_gen.go b/cmd/test_suites_auto_gen.go
deleted file mode 100644
index 04e9f6f..0000000
--- a/cmd/test_suites_auto_gen.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var (
- urls []string
- defaultTestSuite internal.DefaultTestSuiteRequest
-)
-
-var testSuitesDefaultCmd = &cobra.Command{
- Use: TestSuiteAutoGenerationUse,
- Example: TestSuiteAutoGenerationExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, jsonData)
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- // validate configVersion and urls for flag usage OR construct payload json from input file
- propName, propVersion := validator.ValidateDefaultTestSuiteFields(propertyName, propertyVersion, urls, jsonData, &defaultTestSuite,
- isStandardInputAvailable)
-
- // generate default ts
- svc.GenerateTestSuite(propName, propVersion, urls, defaultTestSuite, isStandardInputAvailable)
- },
-}
-
-func init() {
- testSuitesCmd.AddCommand(testSuitesDefaultCmd)
- testSuitesDefaultCmd.Flags().SortFlags = false
-
- testSuitesDefaultCmd.Short = internal.GetMessageForKey(testSuitesDefaultCmd, internal.Short)
- testSuitesDefaultCmd.Long = internal.GetMessageForKey(testSuitesDefaultCmd, internal.Long)
- testSuitesDefaultCmd.Flags().StringVar(&propertyName, FlagProperty, "", internal.GetMessageForKey(testSuitesDefaultCmd, FlagProperty))
- testSuitesDefaultCmd.Flags().StringVar(&propertyVersion, FlagPropver, "", internal.GetMessageForKey(testSuitesDefaultCmd, FlagPropver))
- testSuitesDefaultCmd.Flags().StringArrayVarP(&urls, FlagUrl, FlagUrlShortHand, []string{}, internal.GetMessageForKey(testSuitesDefaultCmd, FlagUrl))
-}
diff --git a/cmd/test_suites_edit.go b/cmd/test_suites_edit.go
deleted file mode 100644
index 04c2f95..0000000
--- a/cmd/test_suites_edit.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesEditCmd = &cobra.Command{
- Use: TestSuiteEditUse,
- Example: TestSuiteEditExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- // validate id flag check.
- validator.EditTestSuiteIdFlagCheck(id)
-
- // validate propertyVersion usage.
- propName, propVersion := validator.PropertyAndVersionFlagCheck(propertyName, propertyVersion, true)
-
- //Remove config flag check
- validator.RemoveConfigFlagCheck(propName, removeProperty)
- validator.LockedAndStatefulFlagCheck(locked, unlocked, stateful, stateless)
-
- testSuite := svc.EditTestSuite(id, name, description, propName, propVersion, unlocked, stateful, removeProperty, locked, stateless)
- internal.PrintSuccess(internal.GetServiceMessage(cmd, internal.MessageTypeDisplay, "", "editTSSuccess") + "\n")
- internal.PrintTestSuite(*testSuite)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesEditCmd)
- testSuitesEditCmd.Flags().SortFlags = false
-
- testSuitesEditCmd.Short = internal.GetMessageForKey(testSuitesEditCmd, internal.Short)
- testSuitesEditCmd.Long = internal.GetMessageForKey(testSuitesEditCmd, internal.Long)
-
- testSuitesEditCmd.Flags().StringVar(&id, FlagId, "", internal.GetMessageForKey(testSuitesEditCmd, FlagId))
- testSuitesEditCmd.Flags().StringVar(&name, FlagName, "", internal.GetMessageForKey(testSuitesEditCmd, FlagName))
- testSuitesEditCmd.Flags().StringVar(&description, FlagDescription, "", internal.GetMessageForKey(testSuitesEditCmd, FlagDescription))
- testSuitesEditCmd.Flags().BoolVar(&unlocked, FlagUnlocked, false, internal.GetMessageForKey(testSuitesEditCmd, FlagUnlocked))
- testSuitesEditCmd.Flags().BoolVar(&stateful, FlagStateFul, false, internal.GetMessageForKey(testSuitesEditCmd, FlagStateFul))
- testSuitesEditCmd.Flags().BoolVar(&locked, FlagLocked, false, internal.GetMessageForKey(testSuitesEditCmd, FlagLocked))
- testSuitesEditCmd.Flags().BoolVar(&stateless, FlagStateless, false, internal.GetMessageForKey(testSuitesEditCmd, FlagStateless))
- testSuitesEditCmd.Flags().StringVar(&propertyName, FlagProperty, "", internal.GetMessageForKey(testSuitesEditCmd, FlagProperty))
- testSuitesEditCmd.Flags().StringVar(&propertyVersion, FlagPropver, "", internal.GetMessageForKey(testSuitesEditCmd, FlagPropver))
- testSuitesEditCmd.Flags().BoolVar(&removeProperty, FlagRemoveProperty, false, internal.GetMessageForKey(testSuitesEditCmd, FlagRemoveProperty))
-
-}
diff --git a/cmd/test_suites_import.go b/cmd/test_suites_import.go
deleted file mode 100644
index da8baf2..0000000
--- a/cmd/test_suites_import.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuiteImport internal.TestSuiteV3
-
-var testSuitesImportCmd = &cobra.Command{
- Use: TestSuiteImportUse,
- Example: TestSuiteImportExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, jsonData)
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- validator.ValidateImportFields(&testSuiteImport)
- svc.ImportTestSuites(testSuiteImport)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesImportCmd)
- testSuitesImportCmd.Flags().SortFlags = false
-
- testSuitesImportCmd.Short = internal.GetMessageForKey(testSuitesImportCmd, internal.Short)
- testSuitesImportCmd.Long = internal.GetMessageForKey(testSuitesImportCmd, internal.Long)
-
-}
diff --git a/cmd/test_suites_list.go b/cmd/test_suites_list.go
deleted file mode 100644
index 2794765..0000000
--- a/cmd/test_suites_list.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesListCmd = &cobra.Command{
- Use: TestSuiteListUse,
- Example: TestSuiteListExample,
- Aliases: []string{TestSuiteListCommandAlias},
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- validator.ConfigFlagCheckForListTestSuites(propertyVersion, propertyName)
-
- testSuites := svc.GetTestSuites(propertyName, propertyVersion, user, search)
- internal.PrintTestSuitesTable(cmd, testSuites)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesListCmd)
- testSuitesListCmd.Flags().SortFlags = false
-
- testSuitesListCmd.Short = internal.GetMessageForKey(testSuitesListCmd, internal.Short)
- testSuitesListCmd.Long = internal.GetMessageForKey(testSuitesListCmd, internal.Long)
-
- testSuitesListCmd.Flags().StringVar(&propertyName, FlagProperty, "", internal.GetMessageForKey(testSuitesListCmd, FlagProperty))
- testSuitesListCmd.Flags().StringVar(&propertyVersion, FlagPropver, "", internal.GetMessageForKey(testSuitesListCmd, FlagPropver))
- testSuitesListCmd.Flags().StringVarP(&user, FlagUser, FlagUserShortHand, "", internal.GetMessageForKey(testSuitesListCmd, FlagUser))
- testSuitesListCmd.Flags().StringVarP(&search, FlagSearch, FlagSearchShortHand, "", internal.GetMessageForKey(testSuitesListCmd, FlagSearch))
-
-}
diff --git a/cmd/test_suites_manage.go b/cmd/test_suites_manage.go
deleted file mode 100644
index c37337d..0000000
--- a/cmd/test_suites_manage.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuiteManage internal.TestSuiteV3
-
-var testSuitesManageCmd = &cobra.Command{
- Use: TestSuiteManageUse,
- Example: TestSuiteManageExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, jsonData)
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- validator.ValidateManageFields(&testSuiteManage)
- svc.ManageTestSuites(testSuiteManage)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesManageCmd)
- testSuitesManageCmd.Flags().SortFlags = false
-
- testSuitesManageCmd.Short = internal.GetMessageForKey(testSuitesManageCmd, internal.Short)
- testSuitesManageCmd.Long = internal.GetMessageForKey(testSuitesManageCmd, internal.Long)
-
-}
diff --git a/cmd/test_suites_remove.go b/cmd/test_suites_remove.go
deleted file mode 100644
index 259802e..0000000
--- a/cmd/test_suites_remove.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesRemoveCmd = &cobra.Command{
- Use: TestSuiteRemoveUse,
- Example: TestSuiteRemoveExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- //Check if all required flag are present.
- validator.TestSuiteIdAndNameFlagCheck(id, name)
-
- svc.RemoveTestSuiteByIdOrName(id, name)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesRemoveCmd)
- testSuitesRemoveCmd.Flags().SortFlags = false
-
- testSuitesRemoveCmd.Short = internal.GetMessageForKey(testSuitesRemoveCmd, internal.Short)
- testSuitesRemoveCmd.Long = internal.GetMessageForKey(testSuitesRemoveCmd, internal.Long)
-
- testSuitesRemoveCmd.Flags().StringVar(&id, FlagId, "", internal.GetMessageForKey(testSuitesRemoveCmd, FlagId))
- testSuitesRemoveCmd.Flags().StringVar(&name, FlagName, "", internal.GetMessageForKey(testSuitesRemoveCmd, FlagName))
-}
diff --git a/cmd/test_suites_remove_test_case.go b/cmd/test_suites_remove_test_case.go
deleted file mode 100644
index 627c8d9..0000000
--- a/cmd/test_suites_remove_test_case.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package cmd
-
-import (
- "strconv"
-
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesRemoveTestCaseCmd = &cobra.Command{
- Use: TestSuiteRemoveTestCaseUse,
- Example: TestSuiteRemoveTestCaseExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- //Check if all required flag are present.
- validator.RemoveTestCaseFromTestSuiteFlagCheck(testSuiteIdStr, orderNumber)
-
- testSuiteId, _ := strconv.Atoi(testSuiteIdStr)
- testSuite := svc.GetSingleTestSuiteByIdOrName(testSuiteIdStr, "", internal.Empty, true)
- testCases, _ := svc.GetV3AssociatedTestCasesForTestSuite(testSuiteId)
- svc.RemoveTestCaseFromTestSuiteUsingOrderNumber(testSuite, testCases, orderNumber)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesRemoveTestCaseCmd)
- testSuitesRemoveTestCaseCmd.Flags().SortFlags = false
-
- testSuitesRemoveTestCaseCmd.Short = internal.GetMessageForKey(testSuitesRemoveTestCaseCmd, internal.Short)
- testSuitesRemoveTestCaseCmd.Long = internal.GetMessageForKey(testSuitesRemoveTestCaseCmd, internal.Long)
-
- testSuitesRemoveTestCaseCmd.Flags().StringVar(&testSuiteIdStr, FlagTestSuiteId, "", internal.GetMessageForKey(testSuitesRemoveTestCaseCmd, FlagTestSuiteId))
- testSuitesRemoveTestCaseCmd.Flags().StringVar(&orderNumber, FlagOrderNumber, "", internal.GetMessageForKey(testSuitesRemoveTestCaseCmd, FlagOrderNumber))
-
-}
diff --git a/cmd/test_suites_restore.go b/cmd/test_suites_restore.go
deleted file mode 100644
index 9ed9d20..0000000
--- a/cmd/test_suites_restore.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesRestoreCmd = &cobra.Command{
- Use: TestSuiteRestoreUse,
- Example: TestSuiteRestoreExample,
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- //Check if all required flag are present.
- validator.TestSuiteIdAndNameFlagCheck(id, name)
-
- svc.RestoreTestSuiteByIdOrName(id, name)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesRestoreCmd)
- testSuitesRestoreCmd.Flags().SortFlags = false
-
- testSuitesRestoreCmd.Short = internal.GetMessageForKey(testSuitesRestoreCmd, internal.Short)
- testSuitesRestoreCmd.Long = internal.GetMessageForKey(testSuitesRestoreCmd, internal.Long)
-
- testSuitesRestoreCmd.Flags().StringVar(&id, FlagId, "", internal.GetMessageForKey(testSuitesRestoreCmd, FlagId))
- testSuitesRestoreCmd.Flags().StringVar(&name, FlagName, "", internal.GetMessageForKey(testSuitesRestoreCmd, FlagName))
-}
diff --git a/cmd/test_suites_view.go b/cmd/test_suites_view.go
deleted file mode 100644
index 6390b75..0000000
--- a/cmd/test_suites_view.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package cmd
-
-import (
- "github.com/akamai/cli-test-center/internal"
- "github.com/spf13/cobra"
-)
-
-var testSuitesViewCmd = &cobra.Command{
- Use: TestSuiteViewUse,
- Example: TestSuiteViewExample,
- Aliases: []string{TestSuiteViewCommandAliases},
- Run: func(cmd *cobra.Command, args []string) {
- eghc := internal.NewEdgeGridHttpClient(config, accountSwitchKey)
- api := internal.NewApiClient(*eghc)
- svc := internal.NewService(*api, cmd, jsonOutput)
- validator := internal.NewValidator(cmd, []byte{})
-
- // validate subcommand
- validator.ValidateSubcommandsNoArgCheck(cmd, args)
-
- // validate id, name and groupBy flags.
- validator.ValidateViewTestSuiteFlags(id, name, groupBy)
-
- //Get and print test suite, test cases
- svc.ViewTestSuite(id, name, groupBy)
- },
-}
-
-func init() {
-
- testSuitesCmd.AddCommand(testSuitesViewCmd)
- testSuitesViewCmd.Flags().SortFlags = false
-
- testSuitesViewCmd.Short = internal.GetMessageForKey(testSuitesViewCmd, internal.Short)
- testSuitesViewCmd.Long = internal.GetMessageForKey(testSuitesViewCmd, internal.Long)
-
- testSuitesViewCmd.Flags().StringVar(&id, FlagId, "", internal.GetMessageForKey(testSuitesViewCmd, FlagId))
- testSuitesViewCmd.Flags().StringVar(&name, FlagName, "", internal.GetMessageForKey(testSuitesViewCmd, FlagName))
- testSuitesViewCmd.Flags().StringVar(&groupBy, FlagGroupBy, "", internal.GetMessageForKey(testSuitesViewCmd, FlagGroupBy))
-
-}
diff --git a/cmd/try_it_function.go b/cmd/try_it_function.go
new file mode 100644
index 0000000..d06f346
--- /dev/null
+++ b/cmd/try_it_function.go
@@ -0,0 +1,42 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var tryItCmd = &cobra.Command{
+ Use: externalconstant.TryItFunctionUse,
+ Example: externalconstant.TryItFunctionExample,
+ Aliases: []string{externalconstant.TryItFunctionAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ functionService := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, true)
+
+ validator := validator.NewValidator(cmd, jsonData)
+
+ validator.ValidateTryItFunctionInputFields(&tryFunction)
+
+ functionService.EvaluateFunction(&tryFunction)
+
+ },
+}
+
+func init() {
+
+ functionCmd.AddCommand(tryItCmd)
+ tryItCmd.Flags().SortFlags = false
+
+ tryItCmd.Short = util.GetMessageForKey(tryItCmd, internalconstant.Short)
+ tryItCmd.Long = util.GetMessageForKey(tryItCmd, internalconstant.Long)
+
+}
diff --git a/cmd/variable.go b/cmd/variable.go
new file mode 100644
index 0000000..6a666d5
--- /dev/null
+++ b/cmd/variable.go
@@ -0,0 +1,35 @@
+package cmd
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var (
+ testSuiteId string
+ variableName string
+ variableValue string
+ variableGroupValues []string
+ variableId string
+)
+
+var variableCmd = &cobra.Command{
+ Use: externalconstant.VariableUse,
+ Aliases: []string{externalconstant.VariableCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateParentSubCommands(cmd, args, false)
+
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(variableCmd)
+
+ variableCmd.Short = util.GetMessageForKey(variableCmd, internalconstant.Short)
+ variableCmd.Long = util.GetMessageForKey(variableCmd, internalconstant.Long)
+}
diff --git a/cmd/variable_create.go b/cmd/variable_create.go
new file mode 100644
index 0000000..ca3e5f3
--- /dev/null
+++ b/cmd/variable_create.go
@@ -0,0 +1,45 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var variableCreateCmd = &cobra.Command{
+ Use: externalconstant.VariableCreateUse,
+ Example: externalconstant.VariableCreateExample,
+ Aliases: []string{externalconstant.VariableCreateCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate flag checks.
+ validator.ValidateVariableCreateFlagCheck(testSuiteId, variableName, variableValue, variableGroupValues)
+
+ svc.CreateVariablesAndPrintResult(cmd, variableName, variableValue, testSuiteId, variableGroupValues)
+ },
+}
+
+func init() {
+ variableCmd.AddCommand(variableCreateCmd)
+ variableCreateCmd.Flags().SortFlags = false
+
+ variableCreateCmd.Short = util.GetMessageForKey(variableCreateCmd, internalconstant.Short)
+ variableCreateCmd.Long = util.GetMessageForKey(variableCreateCmd, internalconstant.Long)
+
+ variableCreateCmd.Flags().StringVarP(&variableName, externalconstant.FlagVariableName, externalconstant.FlagVariableNameShortHand, internalconstant.Empty, util.GetMessageForKey(variableCreateCmd, externalconstant.FlagVariableName))
+ variableCreateCmd.Flags().StringVarP(&variableValue, externalconstant.FlagVariableValue, externalconstant.FlagVariableValueShortHand, internalconstant.Empty, util.GetMessageForKey(variableCreateCmd, externalconstant.FlagVariableValue))
+ variableCreateCmd.Flags().StringVarP(&testSuiteId, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(variableCreateCmd, externalconstant.FlagTestSuiteId))
+ variableCreateCmd.Flags().StringArrayVarP(&variableGroupValues, externalconstant.FlagVarGroupValue, externalconstant.FlagVariableGroupShortHand, []string{}, util.GetMessageForKey(variableCreateCmd, externalconstant.FlagVarGroupValue))
+
+}
diff --git a/cmd/variable_get.go b/cmd/variable_get.go
new file mode 100644
index 0000000..8163231
--- /dev/null
+++ b/cmd/variable_get.go
@@ -0,0 +1,42 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var variableGetCmd = &cobra.Command{
+ Use: externalconstant.VariableGetUse,
+ Example: externalconstant.VariableGetExample,
+ Aliases: []string{externalconstant.VariableGetCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate flag checks.
+ validator.ValidateVariableFlagCheck(testSuiteId, variableId)
+
+ svc.GetVariableAndPrintResult(cmd, testSuiteId, variableId)
+ },
+}
+
+func init() {
+ variableCmd.AddCommand(variableGetCmd)
+ variableGetCmd.Flags().SortFlags = false
+
+ variableGetCmd.Short = util.GetMessageForKey(variableGetCmd, internalconstant.Short)
+ variableGetCmd.Long = util.GetMessageForKey(variableGetCmd, internalconstant.Long)
+
+ variableGetCmd.Flags().StringVarP(&testSuiteId, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(variableGetCmd, externalconstant.FlagTestSuiteId))
+ variableGetCmd.Flags().StringVarP(&variableId, externalconstant.FlagVariableId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(variableGetCmd, externalconstant.FlagVariableId))
+}
diff --git a/cmd/variable_remove.go b/cmd/variable_remove.go
new file mode 100644
index 0000000..9d015ec
--- /dev/null
+++ b/cmd/variable_remove.go
@@ -0,0 +1,42 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var variableRemoveCmd = &cobra.Command{
+ Use: externalconstant.VariableRemoveUse,
+ Example: externalconstant.VariableRemoveExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate flag checks
+ validator.ValidateVariableFlagCheck(testSuiteId, variableId)
+
+ svc.RemoveVariablesAndPrintResult(cmd, testSuiteId, variableId)
+ },
+}
+
+func init() {
+ variableCmd.AddCommand(variableRemoveCmd)
+ variableRemoveCmd.Flags().SortFlags = false
+
+ variableRemoveCmd.Short = util.GetMessageForKey(variableRemoveCmd, internalconstant.Short)
+ variableRemoveCmd.Long = util.GetMessageForKey(variableRemoveCmd, internalconstant.Long)
+
+ variableRemoveCmd.Flags().StringVarP(&testSuiteId, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(variableRemoveCmd, externalconstant.FlagTestSuiteId))
+ variableRemoveCmd.Flags().StringVarP(&variableId, externalconstant.FlagVariableId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(variableRemoveCmd, externalconstant.FlagVariableId))
+
+}
diff --git a/cmd/variable_update.go b/cmd/variable_update.go
new file mode 100644
index 0000000..c8cf8fc
--- /dev/null
+++ b/cmd/variable_update.go
@@ -0,0 +1,46 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var variableUpdateCmd = &cobra.Command{
+ Use: externalconstant.VariableUpdateUse,
+ Example: externalconstant.VariableUpdateExample,
+ Aliases: []string{externalconstant.VariableUpdateCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate flag checks
+ validator.ValidateVariableEditFlagCheck(testSuiteId, variableName, variableValue, variableId, variableGroupValues)
+
+ svc.UpdateVariablesAndPrintResult(cmd, testSuiteId, variableId, variableName, variableValue, variableGroupValues)
+ },
+}
+
+func init() {
+ variableCmd.AddCommand(variableUpdateCmd)
+ variableUpdateCmd.Flags().SortFlags = false
+
+ variableUpdateCmd.Short = util.GetMessageForKey(variableUpdateCmd, internalconstant.Short)
+ variableUpdateCmd.Long = util.GetMessageForKey(variableUpdateCmd, internalconstant.Long)
+
+ variableUpdateCmd.Flags().StringVarP(&testSuiteId, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(variableUpdateCmd, externalconstant.FlagTestSuiteId))
+ variableUpdateCmd.Flags().StringVarP(&variableId, externalconstant.FlagVariableId, internalconstant.Empty, internalconstant.Empty, util.GetMessageForKey(variableUpdateCmd, externalconstant.FlagVariableId))
+ variableUpdateCmd.Flags().StringVarP(&variableName, externalconstant.FlagVariableName, externalconstant.FlagVariableNameShortHand, internalconstant.Empty, util.GetMessageForKey(variableUpdateCmd, externalconstant.FlagVariableName))
+ variableUpdateCmd.Flags().StringVarP(&variableValue, externalconstant.FlagVariableValue, externalconstant.FlagVariableValueShortHand, internalconstant.Empty, util.GetMessageForKey(variableUpdateCmd, externalconstant.FlagVariableValue))
+ variableUpdateCmd.Flags().StringArrayVarP(&variableGroupValues, externalconstant.FlagVarGroupValue, externalconstant.FlagVariableGroupShortHand, []string{}, util.GetMessageForKey(variableUpdateCmd, externalconstant.FlagVarGroupValue))
+
+}
diff --git a/cmd/variables_list.go b/cmd/variables_list.go
new file mode 100644
index 0000000..25b8568
--- /dev/null
+++ b/cmd/variables_list.go
@@ -0,0 +1,41 @@
+package cmd
+
+import (
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/service"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+)
+
+var variablesListCmd = &cobra.Command{
+ Use: externalconstant.VariablesListUse,
+ Example: externalconstant.VariablesListExample,
+ Aliases: []string{externalconstant.VariablesListCommandAliases},
+ Run: func(cmd *cobra.Command, args []string) {
+ eghc := api.NewEdgeGridHttpClient(config, accountSwitchKey)
+ api := api.NewApiClient(*eghc)
+ svc := service.NewService(*api, cmd, jsonOutput)
+ globalValidator := validator.NewGlobalValidator(cmd, jsonData)
+ // validate subcommand
+ globalValidator.ValidateSubCommandsNotAllowed(cmd, args, false)
+
+ validator := validator.NewValidator(cmd, []byte{})
+ // validate flag checks.
+ validator.ValidateVariablesListFlagCheck(testSuiteId)
+
+ svc.GetVariablesAndPrintResult(cmd, testSuiteId)
+ },
+}
+
+func init() {
+ variableCmd.AddCommand(variablesListCmd)
+
+ variablesListCmd.Short = util.GetMessageForKey(variablesListCmd, internalconstant.Short)
+ variablesListCmd.Long = util.GetMessageForKey(variablesListCmd, internalconstant.Long)
+
+ variablesListCmd.Flags().StringVarP(&testSuiteId, externalconstant.FlagTestSuiteId, externalconstant.FlagTestSuiteIdShortHand, internalconstant.Empty, util.GetMessageForKey(variablesListCmd, externalconstant.FlagTestSuiteId))
+
+}
diff --git a/go.mod b/go.mod
index 54c7548..a6b2790 100644
--- a/go.mod
+++ b/go.mod
@@ -3,18 +3,17 @@ module github.com/akamai/cli-test-center
go 1.16
require (
- github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.1
- github.com/briandowns/spinner v1.15.0
- github.com/clarketm/json v1.15.7
+ github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2
+ github.com/briandowns/spinner v1.23.0
+ github.com/clarketm/json v1.17.1
github.com/fatih/camelcase v1.0.0
- github.com/fatih/color v1.12.0
- github.com/google/uuid v1.3.0 // indirect
- github.com/jinzhu/copier v0.3.2
- github.com/mitchellh/go-homedir v1.1.0 // indirect
+ github.com/fatih/color v1.15.0
+ github.com/google/uuid v1.3.1 // indirect
+ github.com/mitchellh/go-homedir v1.1.0
github.com/oleiade/reflections v1.0.1
github.com/olekukonko/tablewriter v0.0.5
- github.com/sirupsen/logrus v1.8.1
- github.com/spf13/cobra v1.2.1
+ github.com/sirupsen/logrus v1.9.3
+ github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
- github.com/tidwall/gjson v1.9.3
+ github.com/tidwall/gjson v1.16.0
)
diff --git a/go.sum b/go.sum
index 660b760..c7bdf56 100644
--- a/go.sum
+++ b/go.sum
@@ -1,273 +1,74 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
-cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
-cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
-cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
-cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
-cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
-cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
-cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
-cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
-cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
-cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
-cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
-cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
-cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
-cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
-cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
-cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
-cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
-cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
-cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
-cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
-cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
-cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
-cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
-cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
-cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
-cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.1 h1:bLzehmpyCwQiqCE1Qe9Ny6fbFqs7hPlmo9vKv2orUxs=
-github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.1/go.mod h1:kX6YddBkXqqywAe8c9LyvgTCyFuZCTMF4cRPQhc3Fy8=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
-github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
-github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
-github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
-github.com/briandowns/spinner v1.15.0 h1:L0jR0MYN7OAeMwpTzDZWIeqyDLXtTeJFxqoq+sL0VQM=
-github.com/briandowns/spinner v1.15.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/clarketm/json v1.15.7 h1:zWsOtfj736/nP76KiS0HpcyO6W50ojEodx7T4LW4NMc=
-github.com/clarketm/json v1.15.7/go.mod h1:ynr2LRfb0fQU34l07csRNBTcivjySLLiY1YzQqKVfdo=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 h1:F1j7z+/DKEsYqZNoxC6wvfmaiDneLsQOFQmuq9NADSY=
+github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2/go.mod h1:QlXr/TrICfQ/ANa76sLeQyhAJyNR9sEcfNuZBkY9jgY=
+github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A=
+github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE=
+github.com/clarketm/json v1.17.1 h1:U1IxjqJkJ7bRK4L6dyphmoO840P6bdhPdbbLySourqI=
+github.com/clarketm/json v1.17.1/go.mod h1:ynr2LRfb0fQU34l07csRNBTcivjySLLiY1YzQqKVfdo=
+github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
-github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
-github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
-github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
+github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
-github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
+github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
-github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
-github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
-github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
-github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
-github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
-github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
-github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
-github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
-github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
-github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
-github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
-github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/jinzhu/copier v0.3.2 h1:QdBOCbaouLDYaIPFfi1bKv5F5tPpeTwXe4sD0jqtz5w=
-github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
-github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
-github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
-github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
-github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
-github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
-github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM=
github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
-github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
-github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
-github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
-github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
+github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/tidwall/gjson v1.9.1 h1:wrrRk7TyL7MmKanNRck/Mcr3VU1sdMvJHvJXzqBIUNo=
-github.com/tidwall/gjson v1.9.1/go.mod h1:jydLKE7s8J0+1/5jC4eXcuFlzKizGrCKvLmBVX/5oXc=
-github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E=
-github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
-github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
-github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
+github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
@@ -275,360 +76,25 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
-go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
-go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
-go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
-go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
-go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
-golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
-golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
-golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
-golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
-golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
-golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
-golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
-golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
-google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
-google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
-google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
-google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
-google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
-google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
-google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
-google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
-google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
+gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
-gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
-honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
-rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/api/api_client.go b/internal/api/api_client.go
new file mode 100644
index 0000000..74c43c8
--- /dev/null
+++ b/internal/api/api_client.go
@@ -0,0 +1,756 @@
+package api
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "net/http"
+ "net/url"
+ "strconv"
+
+ "github.com/clarketm/json"
+ log "github.com/sirupsen/logrus"
+)
+
+type ApiClient struct {
+ client EdgeGridHttpClient
+}
+
+func NewApiClient(client EdgeGridHttpClient) *ApiClient {
+ return &ApiClient{client}
+}
+
+// Adds query parameters to url.
+// QueryMap entries with empty values are ignored
+func addQueryParams(url *url.URL, queryMap map[string]string) {
+ queryParams := url.Query()
+
+ log.Debug("Adding query parameters to url %s", url)
+ for k, v := range queryMap {
+ log.Tracef("Processing query parameter - [%s]:[%s]", k, v)
+
+ if v != "" {
+ queryParams.Set(k, v)
+ }
+ }
+
+ url.RawQuery = queryParams.Encode()
+ log.Tracef("Url with query parameters: %s", url.String())
+}
+
+func (api ApiClient) SubmitTestRun(testRun model.TestRun) (*model.TestRun, *model.CliError) {
+ testRunBytes, err := json.Marshal(testRun)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Post, "/test-management/v3/test-runs", &testRunBytes, requestHeaders)
+ if resp.StatusCode == 202 {
+ var testRunResponse model.TestRun
+ err := json.Unmarshal(*byt, &testRunResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &testRunResponse, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorSubmitTestRunPostCall)
+}
+
+func (api ApiClient) GetTestRun(testRunId int) (*model.TestRun, *model.CliError) {
+ resp, byt := api.client.request(http.MethodGet, fmt.Sprintf("/test-management/v3/test-runs/%d", testRunId), nil, nil)
+ if resp.StatusCode == 200 {
+ var testRun model.TestRun
+ err := json.Unmarshal(*byt, &testRun)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &testRun, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestRunGetCall)
+}
+
+func (api ApiClient) GetTestRunContext(testRunId int) (*model.TestRunContext, *model.CliError) {
+ resp, byt := api.client.request(http.MethodGet, fmt.Sprintf("/test-management/v3/test-runs/%d/context", testRunId), nil, nil)
+ if resp.StatusCode == 200 {
+ var testRunContext model.TestRunContext
+ err := json.Unmarshal(*byt, &testRunContext)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &testRunContext, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestRunContextGetCall)
+}
+
+func (api ApiClient) GetTestSuites(propertyId, propertyName, propVersion, user string, includeDeleted bool) ([]model.TestSuite, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-suites?includeRecentlyDeleted=" + strconv.FormatBool(includeDeleted)
+ tsV3Url, _ := url.Parse(v3Path)
+
+ // add optional query parameters
+ queryMap := map[string]string{
+ "propertyId": propertyId,
+ "propertyName": propertyName,
+ "propertyVersion": propVersion,
+ "user": user,
+ }
+ addQueryParams(tsV3Url, queryMap)
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Get, tsV3Url.String(), nil, nil)
+
+ // parse result
+ if resp.StatusCode == 200 {
+ var testSuites model.ListResponse
+ err := json.Unmarshal(*byt, &testSuites)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ log.Infof("GetTestSuites [%s] returned %d items", tsV3Url.String(), len(testSuites.TestSuites))
+ return testSuites.TestSuites, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestSuiteV3GetCall)
+}
+
+func (api ApiClient) GetTestRuns() ([]model.TestRun, *model.CliError) {
+
+ v3Path := "/test-management/v3/test-runs"
+ testRunsV3Url, _ := url.Parse(v3Path)
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Get, testRunsV3Url.String(), nil, nil)
+
+ // parse result
+ if resp.StatusCode == 200 {
+ var listResponse model.ListResponse
+ err := json.Unmarshal(*byt, &listResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ log.Infof("GetTestRuns: [%s] returned %d items", testRunsV3Url.String(), len(listResponse.TestRuns))
+ return listResponse.TestRuns, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestRunsGetCall)
+}
+
+func (api ApiClient) GetTestSuiteV3(id string) (*model.TestSuite, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-suites/" + id
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Get, v3Path, nil, nil)
+
+ // parse result
+ if resp.StatusCode == 200 {
+ var testSuite model.TestSuite
+ err := json.Unmarshal(*byt, &testSuite)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ return &testSuite, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestSuiteV3GetCall)
+}
+
+func (api ApiClient) RemoveTestSuite(id string) *model.CliError {
+
+ v3Path := "/test-management/v3/functional/test-suites/" + id
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Delete, v3Path, nil, nil)
+
+ // parse result
+ if resp.StatusCode == 204 {
+ return nil
+ }
+
+ // if not 204 response
+ return model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorRemoveTestSuiteDeleteCall)
+}
+
+func (api ApiClient) RestoreTestSuite(id string) (*model.TestSuite, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-suites/" + id + "/restore"
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Post, v3Path, nil, nil)
+
+ // parse result
+ if resp.StatusCode == 200 {
+ var testSuite model.TestSuite
+ err := json.Unmarshal(*byt, &testSuite)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ return &testSuite, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorRestoreTestSuitePostCall)
+}
+
+func (api ApiClient) AddTestSuitesV3(testSuiteV3 model.TestSuite) (*model.TestSuite, *model.CliError) {
+ testSuiteBytes, err := json.Marshal(testSuiteV3)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ v3Path := "/test-management/v3/functional/test-suites"
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Post, v3Path, &testSuiteBytes, requestHeaders)
+
+ // parse result
+ if resp.StatusCode == 201 {
+ var testSuite model.TestSuite
+ err := json.Unmarshal(*byt, &testSuite)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ return &testSuite, nil
+ }
+
+ // if not 201 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestSuiteV3PostCall)
+}
+
+func (api ApiClient) EditTestSuitesV3(testSuiteV3 model.TestSuite, id string) (*model.TestSuite, *model.CliError) {
+ testSuiteBytes, err := json.Marshal(testSuiteV3)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ v3Path := "/test-management/v3/functional/test-suites/" + id
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Put, v3Path, &testSuiteBytes, requestHeaders)
+
+ // parse result
+ if resp.StatusCode == 200 {
+ var testSuite model.TestSuite
+ err := json.Unmarshal(*byt, &testSuite)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ return &testSuite, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorEditTestSuiteV3PostCall)
+}
+
+func (api ApiClient) GetTestSuitesWithChildObjects(testSuiteId int, resolveVariables bool) (*model.TestSuite, *model.CliError) {
+
+ v3Path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/with-child-objects?resolveVariables="+strconv.FormatBool(resolveVariables), testSuiteId)
+ resp, byt := api.client.request(internalconstant.Get, v3Path, nil, nil)
+
+ if resp.StatusCode == 200 {
+ var testSuite model.TestSuite
+ err := json.Unmarshal(*byt, &testSuite)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &testSuite, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestSuiteWithChildObjectGetCall)
+}
+
+func (api ApiClient) AddTestCaseToTestSuite(testSuiteId int, testCases []model.TestCase) (*model.TestCaseBulkResponse, *model.CliError) {
+
+ testCasesBytes, err := json.Marshal(testCases)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases", testSuiteId)
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Post, path, &testCasesBytes, requestHeaders)
+ if resp.StatusCode == 207 {
+ var createTestCaseResponse model.TestCaseBulkResponse
+ err := json.Unmarshal(*byt, &createTestCaseResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &createTestCaseResponse, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorAddTestCasesToTestSuitPostCall)
+}
+
+func (api ApiClient) EditTestCaseToTestSuite(testSuiteId int, testCases []model.TestCase) (*model.TestCaseBulkResponse, *model.CliError) {
+
+ testCasesBytes, err := json.Marshal(testCases)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases", testSuiteId)
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Put, path, &testCasesBytes, requestHeaders)
+ if resp.StatusCode == 207 {
+ var createTestCaseResponse model.TestCaseBulkResponse
+ err := json.Unmarshal(*byt, &createTestCaseResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &createTestCaseResponse, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorUpdateTestCasesToTestSuitPutCall)
+}
+
+func (api ApiClient) ImportTestSuite(testSuiteImport model.TestSuite) (*model.TestSuiteImportResponse, *model.CliError) {
+
+ testSuiteImportJson, err := json.Marshal(testSuiteImport)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := "/test-management/v3/functional/test-suites/with-child-objects"
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Post, path, &testSuiteImportJson, requestHeaders)
+ if resp.StatusCode == 207 {
+ var testSuiteImportResponseV3 model.TestSuiteImportResponse
+ err := json.Unmarshal(*byt, &testSuiteImportResponseV3)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &testSuiteImportResponseV3, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorImportTestSuiteV3PostCall)
+}
+
+func (api ApiClient) ManageTestSuite(testSuiteManage model.TestSuite, testSuiteId int) (*model.TestSuite, *model.CliError) {
+
+ testSuiteManageJson, err := json.Marshal(testSuiteManage)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/with-child-objects", testSuiteId)
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Put, path, &testSuiteManageJson, requestHeaders)
+ if resp.StatusCode == 200 {
+ var testSuiteManageResponseV3 model.TestSuite
+ err := json.Unmarshal(*byt, &testSuiteManageResponseV3)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &testSuiteManageResponseV3, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorManageTestSuiteV3PutCall)
+}
+
+func (api ApiClient) RemoveTestCasesFromTestSuite(testSuiteId int, testCaseIds []int) (*model.BulkResponse, *model.CliError) {
+
+ testCasesIdsBytes, err := json.Marshal(testCaseIds)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases/remove", testSuiteId)
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Post, path, &testCasesIdsBytes, requestHeaders)
+ if resp.StatusCode == 207 {
+ var removeTestCaseResponse model.BulkResponse
+ err := json.Unmarshal(*byt, &removeTestCaseResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &removeTestCaseResponse, nil
+ }
+
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorRemoveTestCasesPostCall)
+}
+
+func (api ApiClient) GetConditionTemplate() (*model.ConditionTemplate, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-catalog/template"
+ condV3Url, _ := url.Parse(v3Path)
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Get, condV3Url.String(), nil, nil)
+
+ // parse result
+ if resp.StatusCode == 200 {
+ var condTemplate model.ConditionTemplate
+ err := json.Unmarshal(*byt, &condTemplate)
+ if err != nil {
+ log.Error(err)
+ fmt.Println(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ return &condTemplate, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorConditionTemplateGetCall)
+}
+
+func (api ApiClient) GenerateTestSuite(defaultTsRequest model.DefaultTestSuiteRequest) (*model.TestSuite, *model.CliError) {
+
+ defaultTestSuiteReqJson, err := json.Marshal(defaultTsRequest)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := "/test-management/v3/functional/test-suites/auto-generate"
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Post, path, &defaultTestSuiteReqJson, requestHeaders)
+
+ if resp.StatusCode == 200 {
+ var defaultTsResponse model.TestSuite
+ err := json.Unmarshal(*byt, &defaultTsResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &defaultTsResponse, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorAutoGeneratePostCall)
+}
+
+func (api ApiClient) GetV3AssociatedTestCasesForTestSuite(testSuiteId int, resolveVariables bool) (*model.AssociatedTestCases, *model.CliError) {
+
+ path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases?resolveVariables="+strconv.FormatBool(resolveVariables), testSuiteId)
+
+ resp, byt := api.client.request(internalconstant.Get, path, nil, nil)
+ if resp.StatusCode == 200 {
+ var associatedTestCases model.AssociatedTestCases
+ err := json.Unmarshal(*byt, &associatedTestCases)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &associatedTestCases, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestCasesAssociatedForTestSuitGetCall)
+}
+
+func (api ApiClient) GetTestCaseById(testCaseId int, testSuiteId int, resolveVariables bool) (*model.TestCase, *model.CliError) {
+
+ v3Path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases/%d?resolveVariables="+strconv.FormatBool(resolveVariables), testSuiteId, testCaseId)
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Get, v3Path, nil, nil)
+
+ // parse result
+ if resp.StatusCode == 200 {
+ var testCase model.TestCase
+ err := json.Unmarshal(*byt, &testCase)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ return &testCase, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestCaseForTestCaseGetCall)
+}
+
+func (api ApiClient) GetConditionsV3() ([]model.Condition, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-catalog/conditions"
+ condV3Url, _ := url.Parse(v3Path)
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Get, condV3Url.String(), nil, nil)
+
+ // parse result
+ if resp.StatusCode == 200 {
+
+ var listResponse model.ListResponse
+ err := json.Unmarshal(*byt, &listResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ log.Infof("GetConditions: [%s] returned %d items", condV3Url.String(), len(listResponse.Conditions))
+ return listResponse.Conditions, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorGetConditions)
+}
+
+func (api ApiClient) GetTestRequestsV3() ([]model.TestRequest, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-requests"
+ testReqV3Url, _ := url.Parse(v3Path)
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Get, testReqV3Url.String(), nil, nil)
+
+ if resp.StatusCode == 200 {
+ var listResponse model.ListResponse
+ err := json.Unmarshal(*byt, &listResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ log.Infof("GetTestRequests: [%s] returned %d items", testReqV3Url.String(), len(listResponse.TestRequests))
+ return listResponse.TestRequests, nil
+ }
+
+ // if not 200 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorGetTestRequests)
+}
+
+func (api ApiClient) CreateVariables(variable []model.Variable, testSuiteId string) (*model.VariableBulkResponse, *model.CliError) {
+ variables, err := json.Marshal(variable)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ v3Path := "/test-management/v3/functional/test-suites/" + testSuiteId + "/variables"
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Post, v3Path, &variables, requestHeaders)
+
+ if resp.StatusCode == 207 {
+ var br model.VariableBulkResponse
+ err := json.Unmarshal(*byt, &br)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &br, nil
+ }
+
+ // if not 207 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorVariablePostCall)
+}
+
+func (api ApiClient) GetVariables(testSuiteId string) ([]model.Variable, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-suites/" + testSuiteId + "/variables"
+
+ v3Url, _ := url.Parse(v3Path)
+
+ resp, byt := api.client.request(internalconstant.Get, v3Url.String(), nil, nil)
+ if resp.StatusCode == 200 {
+ //var variables []model.Variable
+ var listResponse model.ListResponse
+ err := json.Unmarshal(*byt, &listResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return listResponse.Variables, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorVariablesGetCall)
+}
+
+func (api ApiClient) GetVariable(testSuiteId, variableId string) (*model.Variable, *model.CliError) {
+
+ v3Path := "/test-management/v3/functional/test-suites/" + testSuiteId + "/variables/" + variableId
+
+ v3Url, _ := url.Parse(v3Path)
+
+ resp, byt := api.client.request(internalconstant.Get, v3Url.String(), nil, nil)
+ if resp.StatusCode == 200 {
+ //var variables []model.Variable
+ var variable model.Variable
+ err := json.Unmarshal(*byt, &variable)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &variable, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorVariableGetCall)
+}
+
+func (api ApiClient) UpdateVariables(variable []model.Variable, testSuiteId string) (*model.VariableBulkResponse, *model.CliError) {
+ variables, err := json.Marshal(variable)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ v3Path := "/test-management/v3/functional/test-suites/" + testSuiteId + "/variables"
+
+ // get response
+ resp, byt := api.client.request(internalconstant.Put, v3Path, &variables, requestHeaders)
+
+ if resp.StatusCode == 207 {
+ var br model.VariableBulkResponse
+ err := json.Unmarshal(*byt, &br)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &br, nil
+ }
+
+ // if not 207 response
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorVariablePutCall)
+}
+
+func (api ApiClient) RemoveVariableFromTestSuite(testSuiteId, variableId string) (*model.BulkResponse, *model.CliError) {
+
+ varId, _ := strconv.Atoi(variableId)
+ variableIdArray := []int{varId}
+
+ variableIdBytes, err := json.Marshal(variableIdArray)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := "/test-management/v3/functional/test-suites/" + testSuiteId + "/variables/remove"
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Post, path, &variableIdBytes, requestHeaders)
+ if resp.StatusCode == 207 {
+ var removeVariablesResponse model.BulkResponse
+ err := json.Unmarshal(*byt, &removeVariablesResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &removeVariablesResponse, nil
+ }
+
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorRemoveVariablePostCall)
+}
+
+func (api ApiClient) GetLogLines(tcxId int) (interface{}, *model.CliError) {
+ resp, byt := api.client.request(http.MethodGet, fmt.Sprintf("/test-management/v3/functional/test-case-executions/%d/log-lines", tcxId), nil, nil)
+ if resp.StatusCode == 200 {
+ var loglines interface{}
+ err := json.Unmarshal(*byt, &loglines)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return loglines, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTestLogLinesGetCall)
+}
+
+func (api ApiClient) GetRawReqResForRunId(testRunId string) ([]model.RawRequestResponse, *model.CliError) {
+ path := "/test-management/v3/test-runs/" + testRunId + "/raw-request-response"
+
+ resp, byt := api.client.request(http.MethodGet, path, nil, nil)
+ if resp.StatusCode == 200 {
+ var listResponse model.ListResponse
+ err := json.Unmarshal(*byt, &listResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return listResponse.RawRequestResponse, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorRawRequestResponseGetCall)
+}
+
+func (api ApiClient) GetRawReqResForTcxId(testCaseExecutionId string) (*model.RawRequestResponse, *model.CliError) {
+ path := "/test-management/v3/functional/test-case-executions/" + testCaseExecutionId + "/raw-request-response"
+
+ resp, byt := api.client.request(http.MethodGet, path, nil, nil)
+ if resp.StatusCode == 200 {
+ var rawRequestResponse model.RawRequestResponse
+ err := json.Unmarshal(*byt, &rawRequestResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &rawRequestResponse, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorRawRequestResponseGetCall)
+}
+
+func (api ApiClient) EvaluateFunction(function *model.TryFunction) (*model.TryFunction, *model.CliError) {
+ tryFunction, err := json.Marshal(function)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.RequestParsingError), internalconstant.ExitStatusCode3)
+ }
+
+ path := "/test-management/v3/functional/functions/try-it"
+ var requestHeaders = make(http.Header)
+ requestHeaders.Add(internalconstant.ContentType, internalconstant.ApplicationJson)
+
+ resp, byt := api.client.request(internalconstant.Post, path, &tryFunction, requestHeaders)
+ if resp.StatusCode == 200 {
+ var tryFunctionResponse model.TryFunction
+ err := json.Unmarshal(*byt, &tryFunctionResponse)
+ if err != nil {
+ log.Error(err)
+ util.AbortWithExitCode(util.GetGlobalErrorMessage(internalconstant.ResponseParsingError), internalconstant.ExitStatusCode3)
+ }
+ return &tryFunctionResponse, nil
+ }
+ return nil, model.CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, externalconstant.ApiErrorTryFunctionPostCall)
+}
diff --git a/internal/edge_grid_http_client.go b/internal/api/edge_grid_http_client.go
similarity index 74%
rename from internal/edge_grid_http_client.go
rename to internal/api/edge_grid_http_client.go
index 61d8b26..5f4fac4 100644
--- a/internal/edge_grid_http_client.go
+++ b/internal/api/edge_grid_http_client.go
@@ -1,7 +1,9 @@
-package internal
+package api
import (
"bytes"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
"io"
"net/http"
"net/url"
@@ -46,12 +48,12 @@ func (h EdgeGridHttpClient) request(method string, path string, payload *[]byte,
if payload != nil {
req, err = http.NewRequest(method, protocol+h.config.Host+parsedPath.String(), bytes.NewBuffer(*payload))
if err != nil {
- AbortWithExitCode(err.Error(), ExitStatusCode1)
+ util.AbortWithExitCode(err.Error(), internalconstant.ExitStatusCode1)
}
} else {
req, err = http.NewRequest(method, protocol+h.config.Host+parsedPath.String(), nil)
if err != nil {
- AbortWithExitCode(err.Error(), ExitStatusCode1)
+ util.AbortWithExitCode(err.Error(), internalconstant.ExitStatusCode1)
}
}
if headers != nil {
@@ -60,19 +62,19 @@ func (h EdgeGridHttpClient) request(method string, path string, payload *[]byte,
req = edgegrid.AddRequestHeader(h.config, req)
// adding this custom header for POST/HEAD data filtering done in TMF, to be removed later once we support POST/HEAD
- req.Header.Add(IsRequestFromCli, RequestIsFromCli)
+ req.Header.Add(internalconstant.IsRequestFromCli, internalconstant.RequestIsFromCli)
resp, er := client.Do(req)
if er != nil {
- PrintError("\n" + GetEdgeGridErrorMessage("invalidHost") + "\n")
- PrintError(GetGlobalErrorMessage("initEdgeRc") + "\n")
- os.Exit(ExitStatusCode1)
+ util.PrintError("\n" + util.GetEdgeGridErrorMessage("invalidHost") + "\n")
+ util.PrintError(util.GetGlobalErrorMessage(internalconstant.InitEdgeRc) + "\n")
+ os.Exit(internalconstant.ExitStatusCode1)
}
defer resp.Body.Close()
byt, err := io.ReadAll(resp.Body)
if err != nil {
- AbortWithExitCode(err.Error(), ExitStatusCode1)
+ util.AbortWithExitCode(err.Error(), internalconstant.ExitStatusCode1)
}
log.Debugf("Received response:: Status: %d\n", resp.StatusCode)
diff --git a/internal/api_client.go b/internal/api_client.go
deleted file mode 100644
index d9f0825..0000000
--- a/internal/api_client.go
+++ /dev/null
@@ -1,445 +0,0 @@
-package internal
-
-import (
- "fmt"
- "net/http"
- "net/url"
- "strconv"
-
- "github.com/clarketm/json"
- log "github.com/sirupsen/logrus"
-)
-
-type ApiClient struct {
- client EdgeGridHttpClient
-}
-
-func NewApiClient(client EdgeGridHttpClient) *ApiClient {
- return &ApiClient{client}
-}
-
-// Adds query parameters to url.
-// QueryMap entries with empty values are ignored
-func addQueryParams(url *url.URL, queryMap map[string]string) {
- queryParams := url.Query()
-
- log.Debug("Adding query parameters to url %s", url)
- for k, v := range queryMap {
- log.Tracef("Processing query parameter - [%s]:[%s]", k, v)
-
- if v != "" {
- queryParams.Set(k, v)
- }
- }
-
- url.RawQuery = queryParams.Encode()
- log.Tracef("Url with query parameters: %s", url.String())
-}
-
-func (api ApiClient) GetConfigVersions() ([]ConfigVersion, *CliError) {
- resp, byt := api.client.request(Get, "/test-management/v2/functional/config-versions", nil, nil)
- if resp.StatusCode == 200 {
- var configVersions []ConfigVersion
- err := json.Unmarshal(*byt, &configVersions)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return configVersions, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorConfigVersionGetCall)
-}
-
-func (api ApiClient) SubmitTestRun(testRun TestRun) (*TestRun, *CliError) {
- testRunBytes, err := json.Marshal(testRun)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- resp, byt := api.client.request(Post, "/test-management/v3/test-runs", &testRunBytes, requestHeaders)
- if resp.StatusCode == 202 {
- var testRunResponse TestRun
- err := json.Unmarshal(*byt, &testRunResponse)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &testRunResponse, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorSubmitTestRunPostCall)
-}
-
-func (api ApiClient) GetTestRun(testRunId int) (*TestRun, *CliError) {
- resp, byt := api.client.request(http.MethodGet, fmt.Sprintf("/test-management/v3/test-runs/%d", testRunId), nil, nil)
- if resp.StatusCode == 200 {
- var testRun TestRun
- err := json.Unmarshal(*byt, &testRun)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &testRun, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorTestRunGetCall)
-}
-
-func (api ApiClient) GetTestRunContext(testRunId int) (*TestRunContext, *CliError) {
- resp, byt := api.client.request(http.MethodGet, fmt.Sprintf("/test-management/v3/test-runs/%d/context", testRunId), nil, nil)
- if resp.StatusCode == 200 {
- var testRunContext TestRunContext
- err := json.Unmarshal(*byt, &testRunContext)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &testRunContext, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorTestRunContextGetCall)
-}
-
-func (api ApiClient) GetTestSuitesV3(propertyName, propVersion, user string, includeDeleted bool) ([]TestSuiteV3, *CliError) {
-
- v3Path := "/test-management/v3/functional/test-suites?includeRecentlyDeleted=" + strconv.FormatBool(includeDeleted)
- tsV3Url, _ := url.Parse(v3Path)
-
- // add optional query parameters
- queryMap := map[string]string{
- "propertyName": propertyName,
- "propertyVersion": propVersion,
- "user": user,
- }
- addQueryParams(tsV3Url, queryMap)
-
- // get response
- resp, byt := api.client.request(Get, tsV3Url.String(), nil, nil)
-
- // parse result
- if resp.StatusCode == 200 {
- var testSuites ListResponse
- err := json.Unmarshal(*byt, &testSuites)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
-
- log.Infof("GetTestSuitesV3 [%s] returned %d items", tsV3Url.String(), len(testSuites.TestSuites))
- return testSuites.TestSuites, nil
- }
-
- // if not 200 response
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorTestSuiteV3GetCall)
-}
-
-func (api ApiClient) GetTestSuiteV3(id string) (*TestSuiteV3, *CliError) {
-
- v3Path := "/test-management/v3/functional/test-suites/" + id
-
- // get response
- resp, byt := api.client.request(Get, v3Path, nil, nil)
-
- // parse result
- if resp.StatusCode == 200 {
- var testSuite TestSuiteV3
- err := json.Unmarshal(*byt, &testSuite)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
-
- return &testSuite, nil
- }
-
- // if not 200 response
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorTestSuiteV3GetCall)
-}
-
-func (api ApiClient) RemoveTestSuite(id string) *CliError {
-
- v3Path := "/test-management/v3/functional/test-suites/" + id
-
- // get response
- resp, byt := api.client.request(Delete, v3Path, nil, nil)
-
- // parse result
- if resp.StatusCode == 204 {
- return nil
- }
-
- // if not 204 response
- return CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorRemoveTestSuiteDeleteCall)
-}
-
-func (api ApiClient) RestoreTestSuite(id string) (*TestSuiteV3, *CliError) {
-
- v3Path := "/test-management/v3/functional/test-suites/" + id + "/restore"
-
- // get response
- resp, byt := api.client.request(Post, v3Path, nil, nil)
-
- // parse result
- if resp.StatusCode == 200 {
- var testSuite TestSuiteV3
- err := json.Unmarshal(*byt, &testSuite)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
-
- return &testSuite, nil
- }
-
- // if not 200 response
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorRestoreTestSuitePostCall)
-}
-
-func (api ApiClient) AddTestSuitesV3(testSuiteV3 TestSuiteV3) (*TestSuiteV3, *CliError) {
- testSuiteBytes, err := json.Marshal(testSuiteV3)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- v3Path := "/test-management/v3/functional/test-suites"
-
- // get response
- resp, byt := api.client.request(Post, v3Path, &testSuiteBytes, requestHeaders)
-
- // parse result
- if resp.StatusCode == 201 {
- var testSuite TestSuiteV3
- err := json.Unmarshal(*byt, &testSuite)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
-
- return &testSuite, nil
- }
-
- // if not 201 response
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorTestSuiteV3PostCall)
-}
-
-func (api ApiClient) EditTestSuitesV3(testSuiteV3 TestSuiteV3, id string) (*TestSuiteV3, *CliError) {
- testSuiteBytes, err := json.Marshal(testSuiteV3)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- v3Path := "/test-management/v3/functional/test-suites/" + id
-
- // get response
- resp, byt := api.client.request(Put, v3Path, &testSuiteBytes, requestHeaders)
-
- // parse result
- if resp.StatusCode == 200 {
- var testSuite TestSuiteV3
- err := json.Unmarshal(*byt, &testSuite)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
-
- return &testSuite, nil
- }
-
- // if not 200 response
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorEditTestSuiteV3PostCall)
-}
-
-func (api ApiClient) GetTestSuitesWithChildObjects(testSuiteId int) (*TestSuiteV3, *CliError) {
-
- v3Path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/with-child-objects", testSuiteId)
- resp, byt := api.client.request(Get, v3Path, nil, nil)
-
- if resp.StatusCode == 200 {
- var testSuite TestSuiteV3
- err := json.Unmarshal(*byt, &testSuite)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &testSuite, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorTestSuiteWithChildObjectGetCall)
-}
-
-func (api ApiClient) GetV3AssociatedTestCasesForTestSuite(testSuiteId int) (*AssociatedTestCases, *CliError) {
-
- v3Path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases", testSuiteId)
- resp, byt := api.client.request(Get, v3Path, nil, nil)
-
- if resp.StatusCode == 200 {
- var testCases AssociatedTestCases
- err := json.Unmarshal(*byt, &testCases)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &testCases, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorTestCasesAssociatedForTestSuitGetCall)
-}
-
-func (api ApiClient) AddTestCaseToTestSuite(testSuiteId int, testCases []TestCase) (*TestCaseBulkResponse, *CliError) {
-
- testCasesBytes, err := json.Marshal(testCases)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases", testSuiteId)
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- resp, byt := api.client.request(Post, path, &testCasesBytes, requestHeaders)
- if resp.StatusCode == 207 {
- var createTestCaseResponse TestCaseBulkResponse
- err := json.Unmarshal(*byt, &createTestCaseResponse)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &createTestCaseResponse, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorAddTestCasesToTestSuitPostCall)
-}
-
-func (api ApiClient) ImportTestSuite(testSuiteImport TestSuiteV3) (*TestSuiteImportResponseV3, *CliError) {
-
- testSuiteImportJson, err := json.Marshal(testSuiteImport)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- path := "/test-management/v3/functional/test-suites/with-child-objects"
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- resp, byt := api.client.request(Post, path, &testSuiteImportJson, requestHeaders)
- if resp.StatusCode == 207 {
- var testSuiteImportResponseV3 TestSuiteImportResponseV3
- err := json.Unmarshal(*byt, &testSuiteImportResponseV3)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &testSuiteImportResponseV3, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorImportTestSuiteV3PostCall)
-}
-
-func (api ApiClient) ManageTestSuite(testSuiteManage TestSuiteV3, testSuiteId int) (*TestSuiteV3, *CliError) {
-
- testSuiteManageJson, err := json.Marshal(testSuiteManage)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/with-child-objects", testSuiteId)
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- resp, byt := api.client.request(Put, path, &testSuiteManageJson, requestHeaders)
- if resp.StatusCode == 200 {
- var testSuiteManageResponseV3 TestSuiteV3
- err := json.Unmarshal(*byt, &testSuiteManageResponseV3)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &testSuiteManageResponseV3, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorManageTestSuiteV3PutCall)
-}
-
-func (api ApiClient) RemoveTestCasesFromTestSuite(testSuiteId int, testCaseIds []int) (*BulkResponse, *CliError) {
-
- testCasesIdsBytes, err := json.Marshal(testCaseIds)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- path := fmt.Sprintf("/test-management/v3/functional/test-suites/%d/test-cases/remove", testSuiteId)
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- resp, byt := api.client.request(Post, path, &testCasesIdsBytes, requestHeaders)
- if resp.StatusCode == 207 {
- var removeTestCaseResponse BulkResponse
- err := json.Unmarshal(*byt, &removeTestCaseResponse)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &removeTestCaseResponse, nil
- }
-
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorRemoveTestCasesPostCall)
-}
-
-func (api ApiClient) GetConditionTemplate() (*ConditionTemplate, *CliError) {
-
- v3Path := "/test-management/v3/functional/test-catalog/template"
- condV3Url, _ := url.Parse(v3Path)
-
- // get response
- resp, byt := api.client.request(Get, condV3Url.String(), nil, nil)
-
- // parse result
- if resp.StatusCode == 200 {
- var condTemplate ConditionTemplate
- err := json.Unmarshal(*byt, &condTemplate)
- if err != nil {
- log.Error(err)
- fmt.Println(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
-
- return &condTemplate, nil
- }
-
- // if not 200 response
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorConditionTemplateGetCall)
-}
-
-func (api ApiClient) GenerateTestSuite(defaultTsRequest DefaultTestSuiteRequest) (*TestSuiteV3, *CliError) {
-
- defaultTestSuiteReqJson, err := json.Marshal(defaultTsRequest)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(RequestParsingError), ExitStatusCode3)
- }
-
- path := "/test-management/v3/functional/test-suites/auto-generate"
- var requestHeaders = make(http.Header)
- requestHeaders.Add(ContentType, ApplicationJson)
-
- resp, byt := api.client.request(Post, path, &defaultTestSuiteReqJson, requestHeaders)
-
- if resp.StatusCode == 200 {
- var defaultTsResponse TestSuiteV3
- err := json.Unmarshal(*byt, &defaultTsResponse)
- if err != nil {
- log.Error(err)
- AbortWithExitCode(GetGlobalErrorMessage(ResponseParsingError), ExitStatusCode3)
- }
- return &defaultTsResponse, nil
- }
- return nil, CliErrorFromPulsarProblemObject(*byt, nil, resp.StatusCode, ApiErrorAutoGeneratePostCall)
-}
diff --git a/internal/constant/constants.go b/internal/constant/constants.go
new file mode 100644
index 0000000..7f54ffa
--- /dev/null
+++ b/internal/constant/constants.go
@@ -0,0 +1,118 @@
+package constant
+
+// HTTP headers
+const (
+ ContentType = "Content-Type"
+ IsRequestFromCli = "X-ATC-IS-CLI-REQUEST"
+)
+
+// HTTP header values
+const (
+ ApplicationJson = "application/json"
+ RequestIsFromCli = "YES"
+)
+
+// HTTP request methods
+const (
+ Get = "GET"
+ Post = "POST"
+ Put = "PUT"
+ Delete = "DELETE"
+)
+
+// Request header actions
+const (
+ Add = "ADD"
+ Modify = "MODIFY"
+ Filter = "FILTER"
+)
+
+// Test Center execution / evaluation status
+const (
+ CompletedEnum = "COMPLETED"
+ CompletedWithUnexpectedResultsEnum = "COMPLETED_WITH_UNEXPECTED_RESULTS"
+ InProgressEnum = "IN_PROGRESS"
+ PassedEnum = "PASSED"
+ Inconclusive = "INCONCLUSIVE"
+ FailedEnum = "FAILED"
+)
+
+// IP versions
+const (
+ Ipv4 = "IPV4"
+ Ipv6 = "IPV6"
+)
+
+// Supported client types
+const (
+ Chrome = "CHROME"
+ Curl = "CURL"
+)
+
+// DefaultLocation Supported locations
+const DefaultLocation = "US"
+
+// Supported request methods
+const (
+ GetRequestMethod = "GET"
+ HeadRequestMethod = "HEAD"
+ PostRequestMethod = "POST"
+)
+
+// Environments
+const (
+ Staging = "STAGING"
+ Production = "PRODUCTION"
+)
+
+// Group by Test cases constants
+const (
+ GroupByTestRequest = "test-request"
+ GroupByCondition = "condition"
+ GroupByClientProfile = "client-profile"
+)
+
+// Run Test Using
+const (
+ RunTestUsingTestSuiteId = "testSuiteId"
+ RunTestUsingTestSuiteName = "testSuiteName"
+ RunTestUsingPropertyVersion = "propertyVersion"
+ RunTestUsingSingleTestCase = "singleTestCase"
+ RunTestUsingJsonInput = "jsonInput"
+)
+
+// Raw Request response using
+const (
+ RawRequestUsingTestRunId = "testRun"
+ RawRequestUsingTestCaseExecutionId = "testCaseExecution"
+)
+
+// Exit Status Codes
+const (
+ ExitStatusCode0 = 0 // Success 1xx 2xx 3xx
+ ExitStatusCode1 = 1 // Generic CLI Exception
+ ExitStatusCode2 = 2 // Command arguments and flag missing/mismatch exception
+ ExitStatusCode3 = 3 // Parsing Error
+ BaseSubtractor = 300 // This number is subtracted from 4xx and 5xx status code API responses to get exit code. e.g. For response code 404, Exit code will be - 404-300 = 104
+)
+
+// Default Values
+const (
+ EdgercFileNameDefaultValue = ".edgerc"
+ SectionDefaultValue = "default"
+ IpVersionDefaultValue = "V4"
+)
+
+// Environment variable Constants
+const (
+ DefaultEdgercPathKey = "AKAMAI_EDGERC"
+ DefaultEdgercSectionKey = "AKAMAI_EDGERC_SECTION"
+ DefaultJsonOutputKey = "AKAMAI_OUTPUT_JSON"
+)
+
+const (
+ Empty = ""
+ Space = " "
+ TabSpace = "\t"
+ EmptyArray = "[]"
+)
diff --git a/internal/constant/message_constants.go b/internal/constant/message_constants.go
new file mode 100644
index 0000000..e057e83
--- /dev/null
+++ b/internal/constant/message_constants.go
@@ -0,0 +1,135 @@
+package constant
+
+// constant message keys
+const (
+ InitEdgeRc = "initEdgeRc"
+ Short = "short"
+ Long = "long"
+ Json = "json"
+ Missing = "missing"
+ Invalid = "invalid"
+ Global = "global"
+ RequestParsingError = "requestParsingError"
+ ResponseParsingError = "responseParsingError"
+ TestSuiteResource = "testSuite"
+ TestRunResource = "testRun"
+ Read = "read"
+ Create = "create"
+ Update = "update"
+ SubCommandWrongArgumentPassed = "wrongArgumentPassed"
+ SubCommandWithArgumentNotAllowed = "argumentNotAllowed"
+ PropertyVersionKey = "propertyVersion"
+ PropertyIdErrorKey = "propertyIdError"
+ PropertyVersionErrorKey = "propertyVersionError"
+ MissingVersionWithId = "missingVersionWithId"
+ MissingVersionWithName = "missingVersionWithName"
+ MissingIdOrNameWithVersion = "missingIdOrNameWithVersion"
+ PropertyCombinationErrorKey = "propertyCombinationError"
+ MessageTypeSpinner = "spinner"
+ MessageTypeTestCmdSpinner = "testCmdSpinner"
+ MessageTypeDisplay = "display"
+ NoTestRunsFoundWarning = "noTestRunsFoundWarning"
+ CompletedKey = "completed"
+ CompletedWithUnexpectedResultsKey = "completedWithUnexpectedResults"
+ InProgressKey = "inProgress"
+ FailedKey = "failed"
+ TestRunHeader = "testRunHeader"
+ TestSuiteText = "testSuiteText"
+ TestCasesText = "testCasesText"
+ InProgressText = "inProgressText"
+ PassedText = "passedText"
+ FailedText = "failedText"
+ SystemErrorText = "systemErrorText"
+ GetTestRuns = "getTestRuns"
+ GetTestRun = "getTestRun"
+ TestSuiteNameNotFound = "testSuiteNameNotFound"
+ StartTestRun = "startTestRun"
+ TestRunStart = "testRunStart"
+ RunTests = "runTests"
+ AddTestSuiteSuccess = "addTestSuiteSuccess"
+ EditTSSuccess = "editTSSuccess"
+ RequestMethodWithClient = "requestMethodWithClient"
+ JsonInputNotAllowed = "jsonInputNotAllowed"
+ PurgeOperation = "purgeOperation"
+ EvaluationErrors = "evaluationErrors"
+ GetTestRequests = "getTestRequests"
+ GetConditions = "getConditions"
+ GetConditionTemplate = "getConditionTemplate"
+ ConditionsTemplatesText = "conditionsTemplatesText"
+ TestRequestNotFoundError = "noTestRequestFoundWarning"
+ ConditionNotFoundError = "noConditionFoundWarning"
+ TestRequests = "testRequests"
+ Conditions = "conditions"
+ SetVariables = "setVariables"
+ AddHeader = "addHeader"
+ ModifyHeader = "modifyHeader"
+ AddVariables = "addVariables"
+ AddVariablesSuccess = "addVariablesSuccess"
+ NoVariablesFoundWarning = "noVariablesFoundWarning"
+ Any = "any"
+ OneOf = "oneOf"
+ Id = "id"
+ GroupBy = "groupBy"
+ TestSuiteDetails = "testSuiteDetails"
+ NoTestSuiteFoundWithName = "noTestSuiteFoundWithName"
+ NoTestSuiteFoundWarning = "noTestSuiteFoundWarning"
+ Warnings = "warnings"
+ GetTestSuite = "getTestSuite"
+ ImportTestSuite = "importTestSuite"
+ TestCasesAdded = "testCasesAdded"
+ ImportTSTestCaseFailed = "importTSTestCaseFailed"
+ ImportTSVariableFailed = "importTSVariableFailed"
+ ManageTestSuite = "manageTestSuite"
+ ManageTSSuccess = "manageTSSuccess"
+ AddTestSuite = "addTestSuite"
+ EditTestSuite = "editTestSuite"
+ RemoveTestSuite = "removeTestSuite"
+ RestoreTestSuite = "restoreTestSuite"
+ TestSuiteWithChildObject = "testSuiteWithChildObject"
+ RemoveTestCase = "removeTestCase"
+ RemoveTSSuccess = "removeTSSuccess"
+ RemoveTSSuccessInBold = "removeTSSuccessInBold"
+ RestoreTSSuccess = "restoreTSSuccess"
+ GenerateDefaultTestSuite = "generateDefaultTestSuite"
+ GenerateDefaultTSSuccess = "generateDefaultTSSuccess"
+ AllExecutionObjectsIncluded = "allExecutionObjectsIncluded"
+ GetTestCase = "getTestCase"
+ AddTestCase = "addTestCase"
+ TestCaseHeader = "testCaseHeader"
+ NoTestCaseWarning = "noTestCaseWarning"
+ AddTestCaseSuccess = "addTestCaseSuccess"
+ AddTestCaseFail = "addTestCaseFail"
+ AddTestCaseNoTestSuite = "addTestCaseNoTestSuite"
+ UpdateTestCase = "updateTestCase"
+ UpdateTestCaseSuccess = "updateTestCaseSuccess"
+ UpdateTestCaseFail = "updateTestCaseFail"
+ UpdateTestCaseNoTestSuite = "updateTestCaseNoTestSuite"
+ DerivedTestCaseHeader = "derivedTestCaseHeader"
+ VariableInTestSuiteHeader = "variableInTestSuiteHeader"
+ VariableName = "variableName"
+ VariableGroup = "variableGroup"
+ GetVariables = "getVariables"
+ GetVariablesSuccess = "getVariablesSuccess"
+ VariableId = "variableId"
+ GetVariable = "getVariable"
+ GetVariableSuccess = "getVariableSuccess"
+ UpdateVariables = "updateVariables"
+ UpdateVariablesSuccess = "updateVariablesSuccess"
+ RemoveVariable = "removeVariable"
+ RemoveVariableSuccess = "removeVariableSuccess"
+ GetRawReqResForTestRun = "getRawRequestResponseForTestRun"
+ GetRawReqResForTestRunSuccess = "getRawRequestResponseForTestRunSuccess"
+ GetRawReqResForTcxs = "getRawRequestResponseForTcxs"
+ GetRawReqResForTcxsSuccesss = "getRawRequestResponseForTcxsSuccess"
+ GetFunctionResult = "getFunctionResult"
+ TestSuiteId = "testSuiteId"
+ TestCaseId = "testCaseId"
+ OrderNum = "orderNum"
+ RemoveProperty = "removeProperty"
+ StatefulStateless = "statefulStateless"
+ LockedUnlocked = "lockedUnlocked"
+ All = "all"
+ Exclusive = "exclusive"
+ TargetEnvironment = "targetEnvironment"
+ OrderNumTestCaseId = "orderNumTestCaseId"
+)
diff --git a/internal/constants.go b/internal/constants.go
deleted file mode 100644
index 3c0da6f..0000000
--- a/internal/constants.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package internal
-
-// HTTP headers
-const (
- ContentType = "Content-Type"
- IsRequestFromCli = "X-ATC-IS-CLI-REQUEST"
-)
-
-// HTTP header values
-const (
- ApplicationJson = "application/json"
- RequestIsFromCli = "YES"
-)
-
-// HTTP request methods
-const (
- Get = "GET"
- Post = "POST"
- Put = "PUT"
- Delete = "DELETE"
-)
-
-// Request header actions
-const (
- Add = "ADD"
- Modify = "MODIFY"
- Filter = "FILTER"
-)
-
-// Test Center execution / evaluation status
-const (
- Completed = "COMPLETED"
- InProgress = "IN_PROGRESS"
- Passed = "PASSED"
-)
-
-// IP versions
-const (
- Ipv4 = "IPV4"
- Ipv6 = "IPV6"
-)
-
-// Chrome Client
-const (
- Chrome = "CHROME"
-)
-
-// Environments
-const (
- Staging = "STAGING"
- Production = "PRODUCTION"
-)
-
-// constant message keys
-const (
- Short = "short"
- Long = "long"
- Json = "json"
- Example = "example"
- Missing = "missing"
- Invalid = "invalid"
- Global = "global"
- RequestParsingError = "requestParsingError"
- ResponseParsingError = "responseParsingError"
- Empty = ""
- PropertyVersionsResource = "propertyVersions"
- TestSuiteResource = "testSuite"
- TestCaseResource = "testCase"
- TestRunResource = "testRun"
- Read = "read"
- Create = "create"
- Update = "update"
- PropertyVersionNotFound = "propertyVersionNotFound"
- PropertyVersionTestSuitesNotFound = "propertyVersionTestSuitesNotFound"
- SubCommandNoArgumentPassed = "noArgumentPassed"
- SubCommandWrongArgumentPassed = "wrongArgumentPassed"
- SubCommandWithArgumentPassed = "argumentPassed"
- PropertyVersionFlagKey = "propertyVersion"
- MessageTypeSpinner = "spinner"
- MessageTypeTestCmdSpinner = "testCmdSpinner"
- MessageTypeDisplay = "display"
-)
-
-// Group by Test cases constants
-const (
- GroupByTestRequest = "test-request"
- GroupByCondition = "condition"
- GroupByIpVersion = "ipversion"
-)
-
-// Run Test Using
-const (
- RunTestUsingTestSuiteId = "testSuiteId"
- RunTestUsingTestSuiteName = "testSuiteName"
- RunTestUsingPropertyVersion = "propertyVersion"
- RunTestUsingSingleTestCase = "singleTestCase"
- RunTestUsingJsonInput = "jsonInput"
-)
-
-// Exit Status Codes
-const (
- ExitStatusCode0 = 0 // Success 1xx 2xx 3xx
- ExitStatusCode1 = 1 // Generic CLI Exception
- ExitStatusCode2 = 2 // Command arguments and flag missing/mismatch exception
- ExitStatusCode3 = 3 // Parsing Error
- BaseSubtractor = 300 // This number is subtracted from 4xx and 5xx status code API responses to get exit code. e.g. For response code 404, Exit code will be - 404-300 = 104
-)
diff --git a/internal/en_US.json b/internal/en_US.json
deleted file mode 100644
index 9b32fd5..0000000
--- a/internal/en_US.json
+++ /dev/null
@@ -1,819 +0,0 @@
-{
- "akamai": {
- "fallback": "Internal error. Try again later.",
- "global": {
- "initEdgeRc": "Check if your .edgerc file and section are specified correctly and contain valid credentials.",
- "requestParsingError": "Error parsing API request body.",
- "responseParsingError": "Error parsing API response.",
- "jsonOutputFailed": "Error occurred while printing JSON.",
- "invalidCommandInput": "Incorrect command. Either correct the input following examples or provide JSON input file for the command and try again.",
- "invalidJsonInput": "Invalid JSON input. Correct it and try again.",
- "500": "Internal server error. Try again later.",
- "502": "Bad gateway. Try again later.",
- "503": "Service unavailable. Try again later.",
- "504": "Request timed out. Try again later.",
- "405": "Method not allowed. Try again later.",
- "edgeGridError": {
- "resourceNotFound": "The requested resource can't be found.",
- "invalidHost": "The host is invalid.",
- "httpsRequired": "HTTPS is required in the host.",
- "invalidEndpoint": "The API endpoint is invalid.",
- "invalidTimestamp": "The system time for API Client is incorrect. Check system's clock synced with a time authority.",
- "notAuthorized": "The identity is not authorized to manage any context.",
- "authorizationHeaderMissing": "The authorization header is missing.",
- "invalidAuthorizationClientToken": "The authorization client token is invalid.",
- "invalidAuthorizationAccessToken": "The authorization access token is invalid.",
- "theSignatureDoesNotMatch": "The signature doesn't match client secret.",
- "theHostHeaderIsNotValidServiceConsumerToken": "The host header is not a valid service consumer token."
- }
- },
- "testCenter": {
- "short": "Test Center CLI",
- "long": "Test Center is a testing tool that checks the effect of configuration changes \non your web property. Use Test Center as part of your testing protocol to increase \nyour confidence in the safety and accuracy of your configuration changes.",
- "edgerc": "Sets the new path to the .edgerc file. Provide the full path.",
- "section": "Sets the new section name of the .edgerc file with credentials for the CLI to use.",
- "accountKey": "Switches to the account with specific Account ID when performing operations.",
- "forceColor": "Forces color to non-TTY output.",
- "json": "Prints JSON output, where applicable.",
- "help": "Help for test-center.",
- "version": "Version for test-center.",
- "conditions": {
- "short": "Lists supported condition statements.",
- "long": "This command lists condition statements that you can use when creating test cases. Make sure to substitute default \" \" with your own.",
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "getConditionTemplate": "Getting conditions"
- },
- "display": {
- "conditionsHeader": "LIST OF SUPPORTED CONDITION STATEMENTS"
- }
- }
- },
- "testSuite": {
- "short": "List commands available for test suites.",
- "long": "Test suites act as containers for functional test cases. You can create, edit, or remove test suites, \nmanage test suites using JSON input, add test cases to test suites, and generate a default test suite for a particular property.",
- "add": {
- "short": "Creates a test suite.",
- "long": "This command creates a test suite. Test suites act as containers for functional test cases. You can add a name and \ndescription to a test suite to provide more details about it and the \nincluded test cases. You can also set if the test suite needs to be locked or \nstateful. Test suites can be associated with a property version.\n\nIn stateful test suites, test cases are executed in the order they are added and \ncookies and session information are retained for subsequent test cases.\n\nLocked test suites can be modified only by their editors and owners.",
- "name": "Name of the test suite.",
- "description": "Optional. Test suite's description.",
- "unlocked": "Optional. Unlocks the test suite. By default, all test suites are locked.",
- "stateful": "Optional. Sets the test suite to stateful. By default test suites are stateless.",
- "property": "Optional. Property name you want the test suite to be associated with, for example 'example.com'. This flag needs to be combined with the '--propver' flag.",
- "propver": "Optional. Property version you want the test suite to be associated with, for example '4'. This flag needs to be combined with the '--property' flag.",
- "flag": {
- "missing": {
- "name": "Missing the required '--name' flag. Add the flag and try again.",
- "propertyVersion": "Missing one of the flags, either '--property' or '--propver'. Correct your input and try again."
- },
- "invalid": {
- "propertyVersion": "Invalid '--property' or '--propver' flag value. Enter a valid property name and its version and try again. Example: --property 'example.com' --propver '4'"
- }
- },
- "validationError": {
- "requiredFieldMissing": "The '{{requestField}}' is missing.",
- "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
- "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit.",
- "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again."
- },
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator."
- },
- "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
- "resourceNotFound": "The requested '{{requestField}}' can't be found.",
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "addTestSuite": "Creating test suite"
- },
- "display": {
- "addTestSuiteSuccess": "Test suite created"
- }
- }
- },
- "edit": {
- "short": "Edits a test suite.",
- "long": "This command edits a test suite with a specific ID. Provide only flags with values you want to edit in the current test suite.",
- "id": "Unique identifier of the test suite you want to edit.",
- "name": "Optional. Edited name of the test suite.",
- "description": "Optional. Edited test suite's description.",
- "unlocked": "Optional. Locks the test suite.",
- "stateful": "Optional. Sets the test suite to be stateful.",
- "locked": "Optional. Locks the test suite.",
- "stateless": "Optional. Sets the test suite to be stateless.",
- "property": "Optional. Property name you want the test suite to be associated to, for example 'example.com'. This flag needs to be combined with the '--propver' flag.",
- "propver": "Optional. Property version you want the test suite to be associated to, for example '4'. This flag needs to be combined with the '--property' flag.",
- "removeProperty": "Optional. Removes test suite's current association to the property version. If applicable, provide either this flag or '--property' and '--propver'.",
- "flag": {
- "missing": {
- "flagOrJsonImport": "Missing required flags or JSON input. Correct the input following examples and try again.",
- "id": "Missing the required '--id' flag. Add the flag and try again.",
- "propertyVersion": "Missing one of the flags, either '--property' or '--propver'. Correct your input and try again."
- },
- "invalid": {
- "all": "Invalid request. At least one provided value needs to be different from current settings of the test suite.",
- "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
- "propertyVersion": "Invalid '--property' or '--propver' flag value. Enter a valid property name and its version and try again. Example: --property 'example.com' --propver '4'",
- "removeProperty": "Invalid '--property', '--propver' and '--remove-property' flags usage. Provide either '--remove-property' or '--property' and '--propver' and try again.",
- "lockedUnlocked": "Invalid '--locked' and '--unlocked' flags usage. Provide either '--locked' or '--unlocked' and try again.",
- "statefulStateless": "Invalid '--stateful' and '--stateless' flags usage. Provide either '--stateful' or '--stateless' and try again."
- }
- },
- "update": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator.",
- "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved."
- },
- "validationError": {
- "alreadyAssociatedToRequirement": "This test suite is already associated with a requirement. Test suites can be associated either to a requirement or a property version, not both. Remove the association or select a different test suite and try again.",
- "resourceInDeletedState": "You can't edit this test suite because it's in the deleted state. Restore it and try again.",
- "testRunsInProgress": "You can't edit test suites involved in a test run in progress. Wait until the test run is complete and try again.",
- "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again.",
- "existingAssociatedTestCasesHaveDifferentClientProfiles": "In a stateful test suite you can add only functional test cases that use the same client profile as the test cases already included in this test suite.",
- "onlyOwnerCanChangeLockedStatus": "You can't edit the Locked status because you don't have the Owners access. Request it using the Test Center UI and try again once your request is approved.",
- "requiredFieldMissing": "The '{{requestField}}' property is missing.",
- "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
- "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit. Correct your input and try again."
- },
- "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
- "resourceNotFound": "The requested '{{requestField}}' can't be found."
- },
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to get the test suite. Contact your Account administrator."
- },
- "resourceNotFound": "The test suite with this ID can't be found. Run the 'test-suite list' command to verify the ID and try again."
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "editTestSuite": "Editing test suite"
- },
- "display": {
- "editTSSuccess": "Test suite edited"
- }
- }
- },
- "list": {
- "short": "Lists test suites available for your account.",
- "long": "This command lists test suites available for your account. You can filter the results by user, property the test suite is associated with, or a string from test suite's name or description. The list includes also the recently deleted test suites that you can restore.",
- "property": "Optional. Filters the list for a property name the test suite is associated with, for example 'example.com_pm'.",
- "propver": "Optional. Filters the list for a property version the test suite is associated with, for example '4'. This flag needs to be combined with the '--property' flag.",
- "user": "Optional. Filters the list for a username who created, modified, or deleted the test suite.",
- "search": "Optional. Filters the list for a string value present in a test suite's name or description.",
- "flag": {
- "invalid": {
- "propertyVersion": "Invalid '--propver' flag value or usage. It needs to be a number and it needs to be used together with the '--property' flag. Correct the input and try again."
- }
- },
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator."
- },
- "validationError": "The '{{requestField}}' is missing for the property.",
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "getTestSuite": "Getting test suites"
- },
- "display": {
- "noTestSuiteFoundWarning": "No test suites found"
- }
- }
- },
- "import": {
- "short": "Imports a JSON test suite.",
- "long": "This command imports a test suite from a JSON file or standard JSON input.",
- "flag": {
- "missing": {
- "json": "Missing JSON data. Pass the JSON data and try again."
- },
- "invalid": {
- "json": "Failed to import the test suite from entered JSON data. Correct the input following examples and try again."
- }
- },
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator."
- },
- "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
- "duplicateResourceInPayload": "The requested '{{requestField}}' has some duplicates. Remove the duplicates and try again.",
- "urlShouldContainPath": "Missing path in the URL. Correct the URL and try again.",
- "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
- "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
- "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
- "resourceNotFound": "The requested '{{requestField}}' can't be found.",
- "invalidCharacterFound": "The requested '{{requestField}}' contains invalid characters. Correct the values and try again.",
- "malformedExpressionFound": "The requested '{{requestField}}' contains malformed expressions. Correct the values and try again.",
- "invalidConditionExpression": "The requested '{{requestField}}' contains invalid conditions. Verify the entered values, format, and type and try again.",
- "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
- "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
- "validationError": {
- "alreadyAssociatedToRequirement": "This test suite is already associated with a requirement. Test suites can be associated either with a requirement or a property version, not both. Remove the association or select a different test suite and try again.",
- "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again.",
- "existingAssociatedTestCasesHaveDifferentClientProfiles": "In a stateful test suite you can add only functional test cases that use the same client profile as the test cases already included in this test suite.",
- "requiredFieldMissing": "The '{{requestField}}' property is missing.",
- "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
- "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit. Correct your input and try again.",
- "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
- "testRequestClientProfileLimitExceeded": "The number of test request and client profiles in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for client profiles exceeding the limit.",
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
- "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
- "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again."
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "importTestSuite": "Importing test suite"
- },
- "display": {
- "importTSTestCaseFailed": "Failed to import some test cases. Run the 'test-suite manage' command to update the test suite.",
- "importTSVariableFailed": "Failed to import some variables. Run the 'test-suite manage' command to update the test suite.",
- "testSuiteDetails": "TEST SUITE DETAILS",
- "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
- "noTestSuiteFoundWarning": "No test suites to import found",
- "testCasesAdded": "Test cases imported"
- }
- }
- },
- "generateDefault": {
- "short": "Generates a default test suite for a specific property version.",
- "long": "This command generates a default test suite for a property version using provided URLs. Based on property settings and its behaviors and the '--url' flag value, Test Center generates a test suite object with test cases and variables for you to modify and add to Test Center using the 'test-suite import' command.",
- "property": "Property name you want to generate the test suite for, for example 'example.com'. This flag needs to be combined with the '--propver' flag.",
- "propver": "Property version you want to generate the test suite for, for example '4'. This flag needs to be combined with the '--property' flag.",
- "url": "Fully qualified URL to be included in the generated test suite. Repeat this flag to provide more than one URL.",
- "flag": {
- "missing": {
- "url": "Missing the required '--url' flag. Add the flag and try again.",
- "propertyVersion": "Missing at least one of the required flags, '--property' and '--propver'. Provide all required data and try again.",
- "flagOrJsonImport": "Missing required flags or JSON input. Correct the input following examples and try again."
- },
- "invalid": {
- "propertyVersion": "Invalid '--property' or '--propver' flag value. Enter a valid property name and its version and try again. Example: --property 'example.com' --propver '4'",
- "url": "Invalid URL value. It needs to contain the protocol, hostname, path, and any applicable string parameters. For example 'https://www.example.com'. Correct your input and try again."
- }
- },
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the WRITE permission, which is required to generate the default test suite. Contact your Account administrator."
- },
- "resourceNotFound": "The requested '{{requestField}}' can't be found.",
- "validationError": {
- "hostnameAccessMissingForGivenConfig": "These hostnames doesn't belong to the given property version: '{{requestValues}}'.",
- "requiredFieldMissing": "The '{{requestField}}' property is missing.",
- "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again."
- },
- "invalidRequest": "Method not allowed",
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "generateDefaultTestSuite": "Generating default test suite"
- },
- "display": {
- "generateDefaultTSSuccess": "Default test suite based on '%s %d' generated. Review and update the JSON test suite and use the 'test-suite import' command to add it as a new test suite."
- }
- }
- },
- "manage": {
- "short": "Updates an existing test suite using a JSON file or standard JSON input.",
- "long": "This command updates an existing test suite using a JSON file or standard JSON input. Provide the whole test suite object, together with test cases and variables, to include in Test Center. Only data provided in the latest JSON input will be saved.",
- "flag": {
- "missing": {
- "json": "Missing JSON input. Correct the input following examples and try again.",
- "testSuiteId": "Missing the required '--id' flag. Run the 'test-suite list' command to get the ID value. Add the flag and try again."
- },
- "invalid": {
- "json": "Failed to parse JSON data. Correct the input following examples and try again."
- }
- },
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator.",
- "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved.",
- "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
- },
- "invalidConditionExpression": "The following conditions are invalid. Verify the values, format, and type and try again: '{{requestValues}}'",
- "resourceNotFound": "The requested '{{requestField}}' can't be found.",
- "validationError": {
- "alreadyAssociatedToRequirement": "This test suite is already associated with a requirement. Test suites can be associated either with a requirement or a property version, not both. Remove the association or select a different test suite and try again.",
- "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again.",
- "existingAssociatedTestCasesHaveDifferentClientProfiles": "In a stateful test suite you can add only functional test cases that use the same client profile as the test cases already included in this test suite.",
- "requiredFieldMissing": "The '{{requestField}}' is missing.",
- "onlyOwnerCanChangeLockedStatus": "You can't edit the Locked status because you don't have the Owners access. Request the Owner access using the Test Center UI and try again once your request is approved.",
- "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
- "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit.",
- "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
- "resourceNotFound": "The requested '{{requestField}}' can't be found for some of the fields. Verify the included objects and try again.",
- "duplicateResourceInPayload": "The requested '{{requestField}}' has some duplicates. Remove the duplicates and try again.",
- "duplicateResourceWithDifferentId": "The requested '{{requestField}}' has some duplicates with different IDs. Verify the included objects and try again.",
- "testRunsInProgress": "You can't remove test cases involved in a test run in progress. Wait until the test run is complete and try again.",
- "invalidCharacterFound": "The requested '{{requestField}}' has some invalid characters. Correct the values and try again.",
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
- "resourceInDeletedState": "You can't edit this test suite because it's in the deleted state. Restore it and try again.",
- "malformedExpressionFound": "The requested '{{requestField}}' has some malformed expressions. Correct the values and try again.",
- "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
- "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
- "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
- "invalidConditionExpression": "The requested '{{requestField}}' has some invalid conditions. Verify the entered values, format, and type and try again.",
- "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
- "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
- "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
- "testRequestClientProfileLimitExceeded": "The number of test request client profiles in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for client profiles exceeding the limit."
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "manageTestSuite": "Updating test suite"
- },
- "display": {
- "manageTSSuccess": "Test suite '%s' edited"
- }
- }
- },
- "view": {
- "short": "Returns details of a specific test suite.",
- "long": "This command returns details of a test suite with a specific ID: test suite overview, included test cases, and association with a property version.",
- "id": "Unique identifier of the test suite you want to get the details of. Run the 'test-suite list' command to get this value. Provide one of these flags, either '--id' or '--name'.",
- "name": "Name of the test suite you want ot get the details of. Run the 'test-suite list' command to get this value. Provide one of these flags, either '--name' or '--id'.",
- "groupBy": "Optional. Specifies the grouping of included cases. Available values are: 'condition', 'test-request', or 'ipversion'.",
- "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Those test cases are hidden.",
- "flag": {
- "missing": {
- "any": "Missing one of the required flags, either '--id' or '--name'. Add the flag and try again."
- },
- "invalid": {
- "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
- "groupBy": "Invalid '--group-by' flag value. Available values are: 'condition', 'test-request', or 'ipversion'. Correct the input and try again."
- }
- },
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator."
- },
- "resourceNotFound": "The test suite with this ID could not be found. Run the 'test-suite list' command to verify the ID and try again.",
- "validationError": {
- "resourceInDeletedState": "You can't view this test suite because it's in the deleted state. Restore it and try again.",
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
- }
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "getTestSuite": "Getting test suite",
- "testSuiteWithChildObject": "Getting test suite with child objects"
- },
- "display": {
- "testSuiteDetails": "TEST SUITE DETAILS",
- "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
- "noTestSuiteFoundWarning": "No test suites found",
- "testCaseHeader": "INCLUDED TEST CASES",
- "noTestCaseWarning": "No test cases found for the test suite."
- }
- }
- },
- "remove": {
- "short": "Removes a specific test suite.",
- "long": "This command removes a test suite with a specific ID. You can restore removed test suites for 30 days since their removal.",
- "id": "Unique identifier for the test suite you want to remove. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--name'.",
- "name": "Name of the test suite. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--id'.",
- "flag": {
- "missing": {
- "any": "Missing one of the required flags, either '--id' or '--name'. Add the flag and try again."
- },
- "invalid": {
- "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again."
- }
- },
- "read": {
- "authorizationError": {
- "userIsNotOwner": "Only test suite's Owners can perform this action. Request the Owner access using the Test Center UI and try again once your request is approved.",
- "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved."
- },
- "resourceNotFound": "The test suite with this ID can't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
- "validationError": {
- "resourceInDeletedState": "Test suite is already removed."
- }
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "getTestSuite": "Getting test suite",
- "removeTestSuite": "Removing test suite"
- },
- "display": {
- "removeTSSuccess": "Test suite removed. You can restore using the command ",
- "removeTSSuccessInBold": "akamai test-center test-suite restore --id %v",
- "removeTSSuccessEnd": " within 30 days.",
- "testSuiteDetails": "TEST SUITE DETAILS",
- "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
- "noTestSuiteFoundWarning": "No test suites found"
- }
- }
- },
- "restore": {
- "short": "Restores a test suite with a specific ID.",
- "long": "This command restores a test suite with a specific ID. You can restore removed test suites for 30 days since their removal.",
- "id": "Unique identifier for the test suite you want to remove. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--name'.",
- "name": "Name of the test suite. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--id'.",
- "flag": {
- "missing": {
- "any": "Missing one of the required flags, either '--id' or '--name'. Provide all required data and try again."
- },
- "invalid": {
- "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again."
- }
- },
- "read": {
- "authorizationError": {
- "userIsNotOwner": "Only test suite's Owners can perform this action. Request the Owner access using the Test Center UI and try again once your request is approved.",
- "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved."
- },
- "resourceNotFound": "The test suite with this ID could not be found. Run the 'test-suite list' command to verify the ID and try again.",
- "validationError": {
- "resourceNotInDeletedState": "Resource is not in the deleted state. Run the 'test-suite view' command to check its details."
- }
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "getTestSuite": "Getting test suite",
- "restoreTestSuite": "Restoring test suite"
- },
- "display": {
- "restoreTSSuccess": "Test suite restored",
- "testSuiteDetails": "TEST SUITE DETAILS",
- "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
- "noTestSuiteFoundWarning": "No test suites found"
- }
- }
- },
- "addTestCase": {
- "short": "Adds a functional test case to a specific test suite.",
- "long": "This command adds a functional test case to a test suite with a specific ID.",
- "testSuiteId": "Unique identifier for the test suite you want to add test cases to. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-name'.",
- "testSuiteName": "Name of the test suite you want to add test cases to. You need to provide either this flag or '--test-suite-id'.",
- "url": "Fully qualified URL of the resource to test, for example 'https://example.com/'.",
- "addHeader": "Optional. Header to be added to the request in the format: 'name: value'.",
- "modifyHeader": "Optional. Existing header to be modified in the request in the format: 'name: value'.",
- "filterHeader": "Optional. Existing header to be filtered out from the request, specified as 'name'.",
- "condition": "Condition statement from the list of supported conditions with entered required values. To get the list of supported conditions, run the 'conditions' command. Make sure to substitute default values in \" \" with your own. Examples: 'Content provider code is \"12345\"' or 'Origin server - Cache key hostname is \"www.example.com\"'.",
- "ipVersion": "Optional. IP version to execute the test case over, either 'V4' or 'V6'. It's set to 'V4' by default.",
- "flag": {
- "missing": {
- "any": "Missing at least one of the required flags,'--test-suite-id' or '--test-suite-name', '--url', '--condition'. Provide all required data and try again."
- },
- "invalid": {
- "testSuiteId": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
- "ipVersion": "Invalid IP version value. Available values are 'V4' or 'V6'. Correct the input and try again.",
- "addHeader": "Invalid '--add-header' flag value. Make sure it follows the 'name: value' format and try again.",
- "modifyHeader": "Invalid '--modify-header' flag value. Make sure it follows the 'name: value' format and try again."
- }
- },
- "messages": {
- "spinner": {
- "getTestSuite": "Getting test suite",
- "addTestCase": "Adding test case to test suite"
- },
- "display": {
- "addTestCaseSuccess": "Test cases added to '%s' test suite",
- "addTestCaseFail": "Failed to add test case to '%s' test suite",
- "addTestCaseNoTestSuite": "Failed to add test case. The '%s' test suite could not be found."
- }
- },
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to view test suites. Contact your Account administrator."
- },
- "resourceNotFound": "The test suite with this ID could not be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
- "validationError": {
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
- }
- },
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator.",
- "userIsNotOwnerOrEditor": "You don't have the Edit access to the test suite. Request the Edit access using the Test Center UI and try again once your request is approved.",
- "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
- },
- "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
- "resourceNotFound": "The test suite with this ID could not be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
- "duplicateResourceInPayload": "The requested header names have some duplicates. Remove the duplicates and try again.",
- "hostnameAccessMissing": "You don't have access to hostnames of at least one test case included in the test suite. Those test cases are hidden. Get the access or edit the hostnames and try again.",
- "urlShouldContainPath": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing a path. Edit the URL and try again.",
- "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
- "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
- "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
- "invalidConditionExpression": "The condition is invalid. Verify the entered values, format, and type and try again.",
- "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
- "entityAlreadyExists": "Such test case already exists.",
- "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
- "validationError": {
- "invalidValue": "The URL is invalid or it's an empty string. Correct your input and try again.",
- "resourceInDeletedState": "You can't add test cases to this test suite because it's in the deleted state. Restore it and try again.",
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
- "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
- "clientProfileOfExistingAssociatedTestCasesDoNotMatch": "The test suite to which you are trying to add test cases is stateful. It accepts only test cases with the same client profile as test cases already included in the test suite. Change the test cases or add it to a different test suite.",
- "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
- "requiredFieldMissing": "The '{{requestField}}' is missing.",
- "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again."
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- }
- },
- "removeTestCase": {
- "short": "Removes a test case from a test suite with a specific ID.",
- "long": "This command removes a specific test case from a test suite with a specific ID.",
- "testSuiteId": "Unique identifier for the test suite you want to remove the test case from. To get this value, run the 'test-suite list' command.",
- "orderNum": "Order number of the test case you want to remove. To get this value, run the 'test-suite view' command for the specific test suite ID.",
- "success": "Test case removed from '%s' test suite",
- "notPresent": "The test case with the order number '%s' can't be found. Run the 'test-suite view' command for the specific test suite ID to check included test cases and try again.",
- "failed": "Failed to remove the test case from '%s' test suite . Try again.",
- "flag": {
- "missing": {
- "any": "Missing at least one of the required flags, '--test-suite-id' and '--order-num'. Provide all required data and try again."
- },
- "invalid": {
- "testSuiteId": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
- "orderNum": "Invalid order number value. It needs to be a number. Run the 'test-suite view' command for the specific test suite ID to check test cases' order number and try again."
- }
- },
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to remove test cases. Contact your Account administrator."
- },
- "resourceNotFound": "The test suite with this ID could not be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
- "validationError": {
- "resourceInDeletedState": "You can't remove test cases from this test suite because it's in the deleted state. Restore it and try again.",
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
- }
- },
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator.",
- "userIsNotOwnerOrEditor": "You don't have the Edit access to the test suite. Request the Edit access using the Test Center UI and try again once your request is approved.",
- "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
- },
- "resourceNotFound": "The test suite with this ID could not be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
- "resourceInDeletedState": "You can't remove test cases from this test suite because they are in the deleted state. Restore the whole test suite and try again.",
- "testRunsInProgress": "You can't remove test cases involved in a test run in progress. Wait until the test run is complete and try again.",
- "associationNotFound": "Test cases you're trying to remove are not included in this test suite. Run the 'test-suite view' command for the specific test suite ID to check included test cases' and try again.",
- "validationError": {
- "resourceInDeletedState": "You can't remove test cases from this test suite because the test suite is in the deleted state. Restore it and try again.",
- "testRunsInProgress": "You can't remove the test case involved in a test run in progress. Wait until the test run is complete and try again.",
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "getTestSuite": "Getting test suite",
- "getTestCases": "Getting test cases",
- "removeTestCase": "Removing test case from test suite"
- }
- }
- },
- "subCommand": {
- "missing": {
- "noArgumentPassed": "Add a valid subcommand for %q."
- },
- "invalid": {
- "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
- }
- }
- },
- "test": {
- "short": "Runs a test for a test suite, single test case, or a property version.",
- "long": "This command runs a test for a specific object. You can run the test for one of the following: a test suite with a specific ID or name, a property version with specific property name and version number, or a combination of URL, condition, and IP version.",
- "testSuiteId": "Unique identifier for the test suite you want to run the test for. To get this value, run the 'test-suite list' command. To test a test suite, provide either this flag or '--test-suite-name'.",
- "testSuiteName": "Name of the test suite you want to run the test for. To get this value, run the 'test-suite list' command. To test a test suite, provide either this flag or '--test-suite-id'.",
- "url": "Fully qualified URL of the resource to test, for example 'https://example.com/'. This flag needs to be combined with '--ip-version' and '--condition' flags.",
- "addHeader": "Optional. Header to be added to the request in the format: 'name: value'. This flag needs to be combined with '--url', '--ip-version', and '--condition' flags.",
- "modifyHeader": "Optional. Existing header to be modified in the request in the format: 'name: value'. This flag needs to be combined with '--url', '--ip-version', and '--condition' flags.",
- "filterHeader": "Optional. Existing header to be filtered out from the request, specified as 'name'. This flag needs to be combined with '--url', '--ip-version', and '--condition' flags.",
- "condition": "Condition statement from the list of supported conditions with entered required values. To get the list of supported conditions, run the 'conditions' command. Make sure to substitute default values in \" \" with your own. Examples: 'Content provider code is \"12345\"' or 'Origin server - Cache key hostname is \"www.example.com\"'. This flag needs to be combined with '--ip-version' and '--url' flags.",
- "ipVersion": "Optional. IP version to execute the test case over, either 'V4' or 'V6'. This flag needs to be combined with '--url' and '--condition' flags.",
- "property": "Property name you want to run the test for, for example 'example.com'. This flag needs to be combined with the '--propver' flag.",
- "propver": "Property version you want to run the test for, for example '4'. This flag needs to be combined with the '--property' flag.",
- "env": "Optional. Target environment you want to run the test on, either 'STAGING' or 'PRODUCTION'.",
- "testSuiteNameNotFound": "The test suite with the name '%s' could not be found. Run the 'test-suite list' command to get this value and try again.",
- "testCasesNotFound": "The test suite has no test cases included. Add test cases to it and try again.",
- "propertyVersionNotFound": "The requested property name and version could not be found. Make sure the value is correct and try again.",
- "propertyVersionTestSuitesNotFound": "The requested property version is not associated with any test suites. Create a new test suite, associate it with the property, and create appropriate test cases, and try again.",
- "noTestCases": "No test cases to run. Make sure that the property version is associated with test suites that include test cases in them and try again.",
- "flag": {
- "missing": {
- "flagOrJsonImport": "Missing required flags or JSON input. Correct the input following examples and try again.",
- "any": "Missing required flags. To run the test for a test suite provide '--test-suite-id' or '--test-suite-name'. To run a test for a property version provide '--property' and '--propver'. To run a test for a single test case provide '--url', '--ip-version' and '--condition' flags.",
- "condition": "Missing the required '--condition' flag. Correct the input and try again.",
- "url": "Missing required '--url' flag. Correct the input and try again.",
- "propertyVersion": "Missing required '--property' and '--propver' flags. Correct the input and try again."
- },
- "invalid": {
- "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
- "propertyVersion": "Invalid '--property' or '--propver' flag value. Enter a valid property name and its version and try again. Example: --property 'example.com' --propver '4'",
- "ipVersion": "Invalid IP version value. Available values are 'V4' or 'V6'. Correct the input and try again.",
- "addHeader": "Invalid '--add-header' flag value. Make sure it follows the 'name: value' format and try again.",
- "modifyHeader": "Invalid '--modify-header' flag value. Make sure it follows the 'name: value' format and try again.",
- "targetEnvironment": "Invalid target environment value. Available values are uppercased 'STAGING' or 'PRODUCTION'. Correct the input and try again.",
- "exclusive": "Invalid request due to incorrect combination of flags. To run the test for a test suite provide '--test-suite-id' or '--test-suite-name'. To run a test for a property version provide '--property' and '--propver'. To run a test for a single test case provide '--url', '--ipversion' and '--condition' flags. Correct the input following examples and try again."
- }
- },
- "subCommand": {
- "invalid": {
- "argumentPassed": "Invalid %q subcommand for %q. Correct your input and try again."
- }
- },
- "messages": {
- "spinner": {
- "getTestSuite": "Getting test suite"
- },
- "testSuiteId": {
- "spinner": {
- "findTestCases": "Finding test cases",
- "startTestRun": "Running test suite",
- "runTests": "Running tests"
- }
- },
- "testSuiteName": {
- "spinner": {
- "findTestCases": "Finding test cases",
- "startTestRun": "Running test suite",
- "runTests": "Running tests"
- }
- },
- "propertyVersion": {
- "spinner": {
- "findTestSuite": "Finding test suites",
- "findTestCases": "Finding test cases",
- "findPropertyVersion": "Finding property version",
- "startTestRun": "Running property version",
- "runTests": "Running tests"
- }
- },
- "singleTestCase": {
- "spinner": {
- "startTestRun": "Running test case",
- "runTests": "Running tests"
- }
- },
- "jsonInput": {
- "spinner": {
- "startTestRun": "Running from JSON input",
- "runTests": "Running tests"
- }
- },
- "display": {
- "completed": "Completed",
- "completedNotAsExpected": "Completed, some results not as expected",
- "failed": "Failed",
- "testRunHeader": "TEST SUMMARY",
- "testRunStart": "Test run started.",
- "testSuiteText": "Test suite ",
- "testCases": "%d test cases - ",
- "passedText": "%d passed",
- "failedText": "%d failed",
- "systemErrorText": "%d system errors"
- }
- },
- "testSuite": {
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to access the test suite. Contact your Account administrator."
- },
- "validationError": "The '{{requestField}}' is missing for property."
- }
- },
- "testCase": {
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to access the test cases. Contact your Account administrator."
- },
- "resourceNotFound": "The test suite with this ID could not be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
- "validationError": {
- "resourceInDeletedState": "The test suite is in the deleted state. Restore it and try again.",
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
- }
- }
- },
- "configVersions": {
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to get the property version. Contact your Account administrator."
- },
- "resourceNotFound": "The property version could not be found. Make sure the values are correct and try again."
- }
- },
- "testRun": {
- "create": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the WRITE permission, which is required to run the test. Contact your Account administrator.",
- "hostnameAccessMissing": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again.",
- "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
- },
- "validationError": {
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
- "invalidTestRunObjectsCombination": "Invalid request due to incorrect combination of flags. To run the test for a test suite provide '--test-suite-id' or '--test-suite-name'. To run a test for a property version provide '--property' and '--propver'. To run a test for a single test case provide '--url', '--ipversion' and '--condition' flags. Correct the input following examples and try again.",
- "maxTestCasesPerTestRunExceeded": "The number of test cases in this test run exceeded the limit of '{{maxLimit}}'. Create another test suite for test cases exceeding the limit and submit another request.",
- "maxTestSuitesPerTestRunExceeded": "The number of test suites in this test run exceeded the limit of '{{maxLimit}}'. Submit another request for the test suites exceeding the limit.",
- "configVersionNotActive": "The property version is not active on the selected environment. Activate it in Property Manager or select a different environment and try again.",
- "requiredFieldMissing": "The '{{field}}' is missing.",
- "invalidValue": "The '{{field}}' is invalid. Correct the value and try again.",
- "maxLengthExceeded": "The '{{field}}' exceeds the allowed characters limit of '{{maxLength}}'.",
- "hostnameAccessMissing": "You don't have access to the hostname. Correct the value and try again.",
- "urlShouldContainPath": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing a path. Edit the URL and try again.",
- "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
- "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
- "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
- "invalidConditionExpression": "This condition is invalid. Verify the entered values, format, and type and try again.",
- "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
- "resourceNotFound": {
- "testRequestIdResourceNotFound": "Some of the test requests (combinations of the URL and headers) you included in the test run can't be found. Verify the included objects and try again.",
- "conditionIdResourceNotFound": "Some of the conditions you included in the test run can't be found. Verify the included objects and try again.",
- "requirementIdResourceNotFound": "Some of the requirements you included in the test run can't be found. Verify the included objects and try again.",
- "testSuiteIdResourceNotFound": "Some of the test suites you included in the test run can't be found. Verify the included objects and try again.",
- "testCaseIdResourceNotFound": "Some of the functional test cases you included in the test run can't be found. Verify the included objects and try again.",
- "configVersionIdResourceNotFound": "Some of the property versions you included in the test run can't be found. Verify the included objects and try again.",
- "clientProfileIdResourceNotFound": "Some of the client profiles you included in the test run can't be found. Verify the included objects and try again.",
- "testDefinitionIdResourceNotFound": "Some of the test definitions you included in the test run can't be found. Verify the included objects and try again."
- },
- "resourceInDeletedState": {
- "testRequestIdResourceInDeletedState": "Some of the test requests (combinations of URL and headers) are removed and you can't include them in the test run. Verify the included objects and try again.",
- "conditionIdResourceInDeletedState": "Some of the conditions are removed and you can't include them in the test run. Verify the included objects and try again.",
- "requirementIdResourceInDeletedState": "Some of the requirements are removed and you can't include them in the test run. Verify the included objects and try again.",
- "testSuiteIdResourceInDeletedState": "Some of the test suites are removed and you can't include them in the test run. Verify the included objects and try again.",
- "testCaseIdResourceInDeletedState": "Some of the test cases are removed and you can't include them in the test run. Verify the included objects and try again.",
- "configVersionIdResourceInDeletedState": "Some of the property versions are removed and you can't include them in the test run. Verify the included objects and try again.",
- "testDefinitionIdResourceInDeletedState": "Some of the test definitions are removed and you can't include them in the test run. Verify the included objects and try again."
- },
- "associationNotFound": {
- "requirementIdTestSuiteIdAssociationNotFound": "Some of the requirements and test suites associations could not be found. Verify the associations and try again.",
- "configVersionIdTestSuiteIdAssociationNotFound": "Some of the property versions and test suites associations could not be found. Verify the associations and try again.",
- "testSuiteIdTestCaseIdAssociationNotFound": "Some of the test suites and test cases associations could not be found. Verify the associations and try again."
- },
- "invalidClientRequestMethodCombination": "Invalid combination of client and request method. HEAD and POST request methods are allowed only with CURL client."
- },
- "rateLimitExceeded": {
- "rateLimitTestRunHostnameExceeded": "The number of test runs for a hostname exceeded the rate limit. Try again later."
- },
- "invalidRequestBody": "Invalid request. Correct the input following examples and try again."
- },
- "read": {
- "authorizationError": {
- "requiredPermissionMissing": "You don't have the READ permission, which is required to get the results of the test run. Contact your Account administrator."
- },
- "resourceNotFound": "The test run with this ID could not be found. Make sure the ID is correct and try again.",
- "validationError": {
- "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
- }
- }
- }
- },
- "messages": {
- "display": {
- "standardInputErrorMsg": "Error occurred while reading the standard input. Error : %v"
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/internal/label_and_template.go b/internal/label_and_template.go
deleted file mode 100644
index 71f28a2..0000000
--- a/internal/label_and_template.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package internal
-
-const (
- LabelId = "ID"
- LabelName = "Name"
- LabelDescription = "Description"
- LabelStateful = "Stateful"
- LabelLocked = "Locked"
- LabelVariables = "Variables"
- LabelAssociatedPropertyVersion = "Associated property version"
- LabelCreated = "Created"
- LabelLastModified = "Last modified"
- LabelDeleted = "Deleted"
- LabelExpected = "Expected"
- LabelNotRunError = "Not run - Error: "
- LabelPassed = "Passed"
- LabelFailed = "Failed"
- LabelActual = "Actual"
- LabelNotFound = "None found"
- LabelTotalItem = "Total items"
- LabelStatus = "Status"
- LabelTargetEnvironment = "Target Environment"
- LabelPropertyVersion = "Property version"
- LabelIPv4 = "IPv4"
- LabelIPv6 = "IPv6"
- LabelTSDeleteState = "Test suites with the '*' prefix in their names are in the deleted state. You can restore them for 30 days since their removal."
-)
-
-const (
- SeparatePipe = " | "
- SeparateLine = "=========================================="
- SeparateBy = " by "
-)
-
-// API CLinet Error Messages
-const (
- ApiErrorAutoGeneratePostCall = "Failed to generate the test suite. Try again later."
- ApiErrorConditionTemplateGetCall = "Failed to get the condition list. Try again later."
- ApiErrorRemoveTestCasesPostCall = "Failed to remove test cases from the test suite. Try again later."
- ApiErrorConfigVersionGetCall = "Failed to get property versions. Try again later."
- ApiErrorSubmitTestRunPostCall = "Failed to submit the test run. Try again later."
- ApiErrorTestRunGetCall = "Failed to get the test run. Try again later."
- ApiErrorTestRunContextGetCall = "Failed to get test run context. Try again later."
- ApiErrorTestSuiteV3GetCall = "Failed to get test suites. Try again later."
- ApiErrorTestSuiteV3PostCall = "Failed to create the test suite. Try again later."
- ApiErrorEditTestSuiteV3PostCall = "Failed to edit the test suite. Try again later."
- ApiErrorImportTestSuiteV3PostCall = "Failed to import the test suite. Try again later."
- ApiErrorManageTestSuiteV3PutCall = "Failed to manage the test suite. Try again later."
- ApiErrorRemoveTestSuiteDeleteCall = "Failed to remove test suite. Try again later."
- ApiErrorRestoreTestSuitePostCall = "Failed to restore the test suite. Try again later."
- ApiErrorTestSuiteWithChildObjectGetCall = "Failed to get test suites with child objects. Try again later."
- ApiErrorTestCasesAssociatedForTestSuitGetCall = "Failed to get associated test cases for test suite. Try again later."
- ApiErrorAddTestCasesToTestSuitPostCall = "Failed to add test cases to the test suite. Try again later."
-)
-
-const (
- CliErrorMessageTestRunStatus = "Failed to check the test run status. Try again later."
- CliErrorMessageTestRunContext = "Failed to transform the test run context. Try again later."
- CliErrorMessageTemplateOutputError = "Output cannot be shown because of an internal CLI error. Try again later."
-)
diff --git a/internal/errors.go b/internal/model/errors.go
similarity index 70%
rename from internal/errors.go
rename to internal/model/errors.go
index c094faa..7653bf6 100644
--- a/internal/errors.go
+++ b/internal/model/errors.go
@@ -1,4 +1,4 @@
-package internal
+package model
import (
"github.com/clarketm/json"
@@ -27,42 +27,46 @@ type ApiError struct {
type ApiSubError struct {
Type string `json:"type"`
Title string `json:"title"`
- MaxLimit int `json:"maxLimit"`
- RequestField string `json:"requestField"`
- RequestValues []interface{} `json:"requestValues"`
- ExistingEntities []interface{} `json:"existingEntities"`
+ MaxLimit int `json:"maxLimit,omitempty"`
+ RequestField string `json:"requestField,omitempty"`
+ RequestValues []interface{} `json:"requestValues,omitempty"`
+ ExistingEntities []interface{} `json:"existingEntities,omitempty"`
RequirementId int `json:"requirementId,omitempty"`
ConfigVersionId int `json:"configVersionId,omitempty"`
TestSuiteId int `json:"testSuiteId,omitempty"`
TestCaseId int `json:"testCaseId,omitempty"`
+ Hostname string `json:"hostname,omitempty"`
+ IpVersion string `json:"ipVersion,omitempty"`
+ RequestObjects []interface{} `json:"requestObjects,omitempty"`
+ Errors []ApiSubError `json:"errors,omitempty"`
}
// CliError is used to transmit errors across the app
type CliError struct {
- apiError *ApiError
- apiSubErrors []ApiSubError
- errorMessage string
- responseCode int
+ ApiError *ApiError
+ ApiSubErrors []ApiSubError
+ ErrorMessage string
+ ResponseCode int
}
func CliErrorWithMessage(message string) *CliError {
- return &CliError{errorMessage: message}
+ return &CliError{ErrorMessage: message}
}
func CliErrorFromPulsarProblemObject(apiErrorByte []byte, apiSubError []ApiSubError, responseCode int, fallbackMessage string) *CliError {
var cliError CliError
- cliError.responseCode = responseCode
+ cliError.ResponseCode = responseCode
if responseCode == 207 {
- cliError.apiSubErrors = apiSubError
+ cliError.ApiSubErrors = apiSubError
} else {
var apiError ApiError
apiParsingError := json.Unmarshal(apiErrorByte, &apiError)
if apiParsingError != nil {
- cliError.errorMessage = fallbackMessage
+ cliError.ErrorMessage = fallbackMessage
log.Debugf("Error while parsing api error response: [%s]", apiParsingError)
} else {
- cliError.apiError = &apiError
+ cliError.ApiError = &apiError
}
}
diff --git a/internal/model/types.go b/internal/model/types.go
new file mode 100644
index 0000000..2a8a0ce
--- /dev/null
+++ b/internal/model/types.go
@@ -0,0 +1,338 @@
+package model
+
+// BrowserInfo object represents a browser with its name and version
+type BrowserInfo struct {
+ Name string `json:"name"`
+ Version string `json:"version"`
+}
+
+// ClientProfile object represents a client to be used for making requests
+type ClientProfile struct {
+ ClientProfileId int `json:"clientProfileId,omitempty"`
+ GeoLocation string `json:"geoLocation,omitempty"`
+ IpVersion string `json:"ipVersion"`
+ Browser BrowserInfo `json:"browser,omitempty"`
+ Client string `json:"client,omitempty"`
+ ClientVersion string `json:"clientVersion,omitempty"`
+}
+
+type RequestHeader struct {
+ HeaderName string `json:"headerName"`
+ HeaderNameResolved string `json:"headerNameResolved,omitempty"`
+ HeaderValue string `json:"headerValue"`
+ HeaderValueResolved string `json:"headerValueResolved,omitempty"`
+ HeaderAction string `json:"headerAction,omitempty"`
+}
+
+type TestRequest struct {
+ TestRequestId int `json:"testRequestId,omitempty"`
+ TestRequestUrl string `json:"testRequestUrl"`
+ TestRequestUrlResolved string `json:"testRequestUrlResolved,omitempty"`
+ RequestMethod string `json:"requestMethod,omitempty"`
+ RequestHeaders []RequestHeader `json:"requestHeaders,omitempty"`
+ Tags []string `json:"tags,omitempty"`
+ RequestBody string `json:"requestBody,omitempty"`
+ RequestBodyResolved string `json:"requestBodyResolved,omitempty"`
+ EncodeRequestBody *bool `json:"encodeRequestBody,omitempty"`
+}
+
+type Condition struct {
+ ConditionId int `json:"conditionId,omitempty"`
+ ConditionExpression string `json:"conditionExpression"`
+ ConditionExpressionResolved string `json:"conditionExpressionResolved,omitempty"`
+}
+
+type AssociatedTestCases struct {
+ AreAllTestCasesIncluded bool `json:"areAllTestCasesIncluded"`
+ TestCases []TestCase `json:"testCases"`
+}
+
+type TestCase struct {
+ TestCaseId int `json:"testCaseId,omitempty"`
+ Order int `json:"order,omitempty"`
+ ParentOrder int `json:"parentOrder,omitempty"`
+ TestRequest TestRequest `json:"testRequest"`
+ ClientProfile ClientProfile `json:"clientProfile,omitempty"`
+ ClientProfileId int `json:"clientProfileId,omitempty"`
+ Condition Condition `json:"condition"`
+ SetVariables []DynamicVariable `json:"setVariables,omitempty"`
+ DerivedTestCases []TestCase `json:"derivedTestCases,omitempty"`
+ Warnings []ApiSubError `json:"warnings,omitempty"`
+ CreatedBy string `json:"createdBy,omitempty"`
+ CreatedDate string `json:"createdDate,omitempty"`
+ ModifiedBy string `json:"modifiedBy,omitempty"`
+ ModifiedDate string `json:"modifiedDate,omitempty"`
+}
+type TestCaseBulkResponse struct {
+ Successes []TestCase `json:"successes"`
+ Failures []ApiSubError `json:"failures"`
+}
+
+type BulkResponse struct {
+ Successes []int `json:"successes"`
+ Failures []ApiSubError `json:"failures"`
+}
+
+type VariableBulkResponse struct {
+ Successes []Variable `json:"successes"`
+ Failures []ApiSubError `json:"failures"`
+}
+
+// ListResponse We may add list responses for different objects here if needed in future e.g. variables, test-cases
+type ListResponse struct {
+ TestSuites []TestSuite `json:"testSuites,omitempty"`
+ TestRuns []TestRun `json:"testRuns,omitempty"`
+ Conditions []Condition `json:"conditions,omitempty"`
+ TestRequests []TestRequest `json:"testRequests,omitempty"`
+ Variables []Variable `json:"variables,omitempty"`
+ RawRequestResponse []RawRequestResponse `json:"functionalRequestResponse,omitempty"`
+}
+
+type TestSuiteImportResponse struct {
+ Success TestSuite `json:"success,omitempty"`
+ Failure TestSuiteImportFailure `json:"failure,omitempty"`
+}
+
+type TestSuiteImportFailure struct {
+ Variables []ApiSubError `json:"variables,omitempty"`
+ TestCases []ApiSubError `json:"testCases,omitempty"`
+}
+
+type TestSuite struct {
+ CreatedBy string `json:"createdBy,omitempty"`
+ CreatedDate string `json:"createdDate,omitempty"`
+ ModifiedBy string `json:"modifiedBy,omitempty"`
+ ModifiedDate string `json:"modifiedDate,omitempty"`
+ DeletedBy string `json:"deletedBy,omitempty"`
+ DeletedDate string `json:"deletedDate,omitempty"`
+ TestSuiteId int `json:"testSuiteId,omitempty"`
+ TestSuiteName string `json:"testSuiteName"`
+ TestSuiteDescription string `json:"testSuiteDescription,omitempty"`
+ IsLocked bool `json:"isLocked"`
+ IsStateful bool `json:"isStateful"`
+ ExecutableTestCaseCount int `json:"executableTestCaseCount"`
+ Configs AkamaiConfigs `json:"configs,omitempty"`
+ TestCases []TestCase `json:"testCases,omitempty"`
+ Variables []Variable `json:"variables,omitempty"`
+}
+
+type Variable struct {
+ VariableId int `json:"variableId,omitempty"`
+ VariableName string `json:"variableName"`
+ VariableValue string `json:"variableValue,omitempty"`
+ VariableGroupValue []VariableGroupValue `json:"variableGroupValue,omitempty"`
+ IsDynamicallyUsed *bool `json:"isDynamicallyUsed,omitempty"`
+ CreatedBy string `json:"createdBy,omitempty"`
+ CreatedDate string `json:"createdDate,omitempty"`
+ ModifiedBy string `json:"modifiedBy,omitempty"`
+ ModifiedDate string `json:"modifiedDate,omitempty"`
+}
+
+type VariableGroupValue struct {
+ ColumnHeader string `json:"columnHeader,omitempty"`
+ ColumnValues []string `json:"columnValues,omitempty"`
+}
+
+type AkamaiConfigs struct {
+ PropertyManager PropertyManager `json:"propertyManager,omitempty"`
+}
+
+type PropertyManager struct {
+ PropertyId int `json:"propertyId,omitempty"`
+ PropertyName string `json:"propertyName,omitempty"`
+ PropertyVersion int `json:"propertyVersion"`
+}
+
+type PurgeInfo struct {
+ Status string `json:"status,omitempty"`
+ Errors []ApiSubError `json:"errors,omitempty"`
+}
+
+type TestRun struct {
+ TestRunId int `json:"testRunId,omitempty"`
+ Status string `json:"status,omitempty"`
+ TargetEnvironment string `json:"targetEnvironment"`
+ SendEmailOnCompletion bool `json:"sendEmailOnCompletion,omitempty"`
+ Note string `json:"note,omitempty"`
+ Functional FunctionalTestRun `json:"functional"`
+ SubmittedBy string `json:"submittedBy,omitempty"`
+ SubmittedDate string `json:"submittedDate,omitempty"`
+ CompletedDate string `json:"completedDate,omitempty"`
+ PurgeInfo PurgeInfo `json:"purgeInfo,omitempty"`
+}
+
+type FunctionalTestRun struct {
+ Status string `json:"status,omitempty"`
+ TestSuiteExecutions []TestSuiteExecutions `json:"testSuiteExecutions,omitempty"`
+ PropertyManagerExecution PropertyManagerExecution `json:"propertyManagerExecution,omitempty"`
+ TestCaseExecution TestCaseExecution `json:"testCaseExecution,omitempty"`
+ AllExecutionObjectsIncluded *bool `json:"allExecutionObjectsIncluded,omitempty"`
+ IsReevaluationInProgress *bool `json:"isReevaluationInProgress,omitempty"`
+ NextReevaluationCompletionTime string `json:"nextReevaluationCompletionTime,omitempty"`
+ MaxReevaluationCompletionTime string `json:"maxReevaluationCompletionTime,omitempty"`
+}
+
+type PropertyManagerExecution struct {
+ PropertyId int `json:"propertyId,omitempty"`
+ PropertyName string `json:"propertyName,omitempty"`
+ PropertyVersion int `json:"propertyVersion"`
+ TestSuiteExecutions []TestSuiteExecutions `json:"testSuiteExecutions,omitempty"`
+}
+
+type TestSuiteExecutions struct {
+ TestSuiteId int `json:"testSuiteId"`
+ Status string `json:"status,omitempty"`
+ TestCaseExecutions []TestCaseExecutions `json:"testCaseExecutions"`
+ TestSuiteContext TestSuite `json:"testSuiteContext,omitempty"`
+ TestSuiteExecutionId int `json:"testSuiteExecutionId,omitempty"`
+ SubmittedBy string `json:"submittedBy,omitempty"`
+ SubmittedDate string `json:"submittedDate,omitempty"`
+ CompletedDate string `json:"completedDate,omitempty"`
+}
+
+type TestCaseExecutions struct {
+ TestCaseId int `json:"testCaseId"`
+ TestCaseExecutionId int `json:"testCaseExecutionId,omitempty"`
+ Status string `json:"status,omitempty"`
+ ConditionEvaluationResult ConditionEvaluationResult `json:"conditionEvaluationResult,omitempty"`
+ ResolvedSetVariables interface{} `json:"resolvedSetVariables,omitempty"`
+ TestCaseContext TestCase `json:"testCaseContext,omitempty"`
+ DerivedTestCaseExecutions []TestCaseExecutions `json:"derivedTestCaseExecutions,omitempty"`
+ Errors []ApiSubError `json:"errors,omitempty"`
+ SubmittedBy string `json:"submittedBy,omitempty"`
+ SubmittedDate string `json:"submittedDate,omitempty"`
+ CompletedDate string `json:"completedDate,omitempty"`
+ IsReevaluationInProgress *bool `json:"isReevaluationInProgress,omitempty"`
+}
+
+type TestCaseExecution struct {
+ TestRequest TestRequest `json:"testRequest"`
+ ClientProfile ClientProfile `json:"clientProfile,omitempty"`
+ Condition Condition `json:"condition"`
+ TestCaseExecutionId int `json:"testCaseExecutionId,omitempty"`
+ Status string `json:"status,omitempty"`
+ ConditionEvaluationResult ConditionEvaluationResult `json:"conditionEvaluationResult,omitempty"`
+ Errors []ApiSubError `json:"errors,omitempty"`
+ SubmittedBy string `json:"submittedBy,omitempty"`
+ SubmittedDate string `json:"submittedDate,omitempty"`
+ CompletedDate string `json:"completedDate,omitempty"`
+ IsReevaluationInProgress *bool `json:"isReevaluationInProgress,omitempty"`
+}
+
+type ConditionEvaluationResult struct {
+ ActualConditionData []ActualConditionData `json:"actualConditionData,omitempty"`
+ Result string `json:"result,omitempty"`
+}
+
+type ActualConditionData struct {
+ Name string `json:"name"`
+ Value string `json:"value,omitempty"`
+}
+
+type TestRunContext struct {
+ TestRunId int `json:"testRunId"`
+ Functional FunctionalContext `json:"functional"`
+}
+
+type FunctionalContext struct {
+ TestSuites []TestSuiteContext `json:"testSuites,omitempty"`
+ TestCases []TestCase `json:"testCases,omitempty"`
+ PropertyManagers []PropertyManagerContext `json:"propertyManagers,omitempty"`
+}
+
+type TestSuiteContext struct {
+ *TestSuite
+ TestCases []TestCase `json:"testCases,omitempty"`
+}
+
+type PropertyManagerContext struct {
+ *PropertyManager
+ TestSuites []TestSuiteContext `json:"testSuites,omitempty"`
+}
+
+type ResultStats struct {
+ PassedTestCasesCount int
+ FailedTestCasesCount int
+ InProgressTestCasesCount int
+ InconclusiveTestCasesCount int
+}
+
+//Condition template types
+
+type ConditionExpression struct {
+ ConditionExpressionId int `json:"conditionExpressionId,omitempty"`
+ ConditionExpression string `json:"conditionExpression,omitempty"`
+ Examples []string `json:"examples,omitempty"`
+}
+
+type PlaceHolder struct {
+ PlaceHolder string `json:"placeHolder,omitempty"`
+ ValueInputType string `json:"valueInputType,omitempty"`
+ ValueDataType string `json:"valueDataType,omitempty"`
+ IsCustomValueSupported bool `json:"isCustomValueSupported,omitempty"`
+ ValueSeparator string `json:"valueSeparator,omitempty"`
+ AvailableValues []interface{} `json:"availableValues"`
+}
+
+type ConditionType struct {
+ ConditionType string `json:"conditionType,omitempty"`
+ Label string `json:"label,omitempty"`
+ ConditionExpressions []ConditionExpression `json:"conditionExpressions,omitempty"`
+ PlaceHolders []PlaceHolder `json:"placeHolders"`
+}
+
+type ConditionTemplate struct {
+ ConditionTypes []ConditionType `json:"conditionTypes,omitempty"`
+}
+
+type DefaultTestSuiteRequest struct {
+ Configs AkamaiConfigs `json:"configs"`
+ TestRequestUrl []string `json:"testRequestUrls"`
+}
+
+type DynamicVariable struct {
+ VariableId int `json:"variableId,omitempty"`
+ VariableName string `json:"variableName"`
+ VariableValue string `json:"variableValue"`
+}
+
+type RawRequestResponse struct {
+ Request Request `json:"request,omitempty"`
+ Response Response `json:"response,omitempty"`
+ TestCaseExecutionIds []int `json:"testCaseExecutionIds,omitempty"`
+}
+
+type Request struct {
+ Method string `json:"method,omitempty"`
+ Url string `json:"url,omitempty"`
+ HttpVersion string `json:"httpVersion,omitempty"`
+ QueryString []interface{} `json:"queryString,omitempty"`
+ HeadersSize int `json:"headersSize,omitempty"`
+ BodySize int `json:"bodySize,omitempty"`
+ Comment string `json:"comment,omitempty"`
+ Cookies []interface{} `json:"cookies,omitempty"`
+ Headers []Header `json:"headers,omitempty"`
+}
+
+type TryFunction struct {
+ FunctionExpression string `json:"functionExpression"`
+ Variables []Variable `json:"variables,omitempty"`
+ TryFunctionResponseData TryFunctionResponseData `json:"responseData,omitempty"`
+ Result string `json:"result"`
+}
+
+type TryFunctionResponseData struct {
+ Response Response `json:"response,omitempty"`
+}
+
+type Response struct {
+ Status int `json:"status"`
+ StatusText string `json:"statusText,omitempty"`
+ HttpVersion string `json:"httpVersion"`
+ Headers []Header `json:"headers"`
+}
+
+type Header struct {
+ Name string `json:"name"`
+ Value string `json:"value"`
+}
diff --git a/internal/print/condition_print.go b/internal/print/condition_print.go
new file mode 100644
index 0000000..49d0239
--- /dev/null
+++ b/internal/print/condition_print.go
@@ -0,0 +1,46 @@
+package print
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/spf13/cobra"
+ "strings"
+)
+
+func PrintConditionsTemplate(cmd *cobra.Command, condTemplate model.ConditionTemplate) {
+ fmt.Println()
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty,
+ internalconstant.ConditionsTemplatesText))
+ fmt.Println()
+ fmt.Println()
+ for _, condType := range condTemplate.ConditionTypes {
+ fmt.Println(util.Bold(condType.Label))
+ for _, condExpression := range condType.ConditionExpressions {
+ fmt.Println(" ", condExpression.ConditionExpression)
+ }
+ fmt.Println()
+ }
+}
+
+func PrintConditions(cmd *cobra.Command, conditionList []model.Condition) {
+ if len(conditionList) <= 0 {
+ util.PrintWarning(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty,
+ internalconstant.ConditionNotFoundError))
+ fmt.Println()
+ return
+ }
+
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.Conditions))
+ fmt.Println()
+ fmt.Println()
+ for _, condition := range conditionList {
+ conditionExpression := strings.TrimSpace(condition.ConditionExpression)
+ fmt.Println(conditionExpression)
+ }
+ fmt.Println()
+ fmt.Print(len(conditionList))
+ fmt.Println(" items")
+
+}
diff --git a/internal/print/print_test_run.go b/internal/print/print_test_run.go
new file mode 100644
index 0000000..d1bf481
--- /dev/null
+++ b/internal/print/print_test_run.go
@@ -0,0 +1,431 @@
+package print
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/fatih/color"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+ "sort"
+ "strconv"
+ "strings"
+)
+
+func FormatAndPrintTestRunsTable(cmd *cobra.Command, testRuns []model.TestRun) {
+
+ if len(testRuns) <= 0 {
+ util.PrintWarning(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.NoTestRunsFoundWarning))
+ fmt.Println()
+ return
+ }
+
+ // sort given items by created date / ID
+ sort.SliceStable(testRuns, func(i, j int) bool {
+ return testRuns[i].SubmittedDate < testRuns[j].SubmittedDate
+ })
+
+ tableHeaders := []string{"ID", "ENVIRONMENT", "STATUS", "SUBMITTED BY", "SUBMITTED DATE", "COMPLETED DATE", "NOTE"}
+ var contents = make([][]string, len(testRuns))
+
+ // prepare data for table
+ for i, testRun := range testRuns {
+ tsId := strconv.Itoa(testRun.TestRunId)
+ row := []string{tsId, testRun.TargetEnvironment, testRun.Status, testRun.SubmittedBy, testRun.SubmittedDate, testRun.CompletedDate,
+ testRun.Note}
+ contents[i] = row
+ }
+
+ // show table
+ util.ShowTable(tableHeaders, contents, true)
+
+ fmt.Println()
+}
+
+func FormatAndPrintTestResult(cmd *cobra.Command, testRun *model.TestRun) {
+ _, tsxResultStatsMap := GetTestRunStats(*testRun)
+
+ util.PrintHeader("\n" + util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestRunHeader) + "\n\n")
+
+ statusKey, statusColour := util.GetStatusKeyAndColour(testRun.Status)
+ message := util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, statusKey)
+
+ util.PrintLabelValueWithColour(externalconstant.LabelStatus, &statusColour, message)
+ util.PrintLabelAndValue(externalconstant.LabelTargetEnvironment,
+ util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, strings.ToLower(testRun.TargetEnvironment)))
+
+ // show purge warning if present
+ printPurgeWarning(cmd, testRun)
+ // show allExecutionObjectsIncluded waring if false
+ printAllExecutionObjectsIncludedWarning(cmd, testRun)
+ fmt.Println()
+
+ propertyManagerExecution := testRun.Functional.PropertyManagerExecution
+ printPropertyManagerExecution(cmd, propertyManagerExecution, tsxResultStatsMap)
+
+ for i, testSuiteExecution := range testRun.Functional.TestSuiteExecutions {
+ printTestSuiteExecution(cmd, testSuiteExecution, tsxResultStatsMap)
+ if i < len(testRun.Functional.TestSuiteExecutions)-1 {
+ fmt.Println(externalconstant.SeparateLine)
+ }
+ }
+
+ if testRun.Functional.TestCaseExecution.TestRequest.TestRequestUrl != internalconstant.Empty {
+ logrus.Debug("Printing result for single test case execution!!!")
+ printTestCaseExecution(cmd, testRun)
+ }
+
+}
+
+func printPurgeWarning(cmd *cobra.Command, testRun *model.TestRun) {
+ if testRun.PurgeInfo.Status == internalconstant.FailedEnum {
+ util.PrintWarning(externalconstant.Star + util.GetApiSubErrorMessagesForCommand(cmd, testRun.PurgeInfo.Errors,
+ internalconstant.Empty, internalconstant.Empty, internalconstant.PurgeOperation)[0])
+ fmt.Println()
+ }
+}
+
+func printAllExecutionObjectsIncludedWarning(cmd *cobra.Command, testRun *model.TestRun) {
+ if testRun.Functional.AllExecutionObjectsIncluded != nil && *testRun.Functional.AllExecutionObjectsIncluded == false {
+ util.PrintWarning(externalconstant.Star + util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay,
+ internalconstant.Empty, internalconstant.AllExecutionObjectsIncluded))
+ fmt.Println()
+ }
+}
+
+func printPropertyManagerExecution(cmd *cobra.Command, propertyManagerExecution model.PropertyManagerExecution, tsxResultStatsMap map[int]model.ResultStats) {
+
+ for i, tsx := range propertyManagerExecution.TestSuiteExecutions {
+ printTestSuiteExecution(cmd, tsx, tsxResultStatsMap)
+ if i < len(propertyManagerExecution.TestSuiteExecutions)-1 {
+ fmt.Println(externalconstant.SeparateLine)
+ }
+ }
+}
+
+func printTestSuiteExecution(cmd *cobra.Command, testSuiteExecution model.TestSuiteExecutions, tsxResultStatsMap map[int]model.ResultStats) {
+ tsxResultStats := tsxResultStatsMap[testSuiteExecution.TestSuiteExecutionId]
+
+ testSuiteHeader := util.Bold(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestSuiteText)+externalconstant.Colon+internalconstant.Space) + testSuiteExecution.TestSuiteContext.TestSuiteName + externalconstant.SeparatePipe
+ testSuiteHeader += fmt.Sprintf(util.Bold(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestCasesText)), testSuiteExecution.TestSuiteContext.ExecutableTestCaseCount)
+
+ var testCaseResults []string
+ if tsxResultStats.InProgressTestCasesCount > 0 {
+ testCaseResults = append(testCaseResults, fmt.Sprintf(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.InProgressText), tsxResultStats.InProgressTestCasesCount))
+ }
+ if tsxResultStats.PassedTestCasesCount > 0 {
+ testCaseResults = append(testCaseResults, color.GreenString(fmt.Sprintf(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.PassedText), tsxResultStats.PassedTestCasesCount)))
+ }
+ if tsxResultStats.FailedTestCasesCount > 0 {
+ testCaseResults = append(testCaseResults, color.RedString(fmt.Sprintf(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.FailedText), tsxResultStats.FailedTestCasesCount)))
+ }
+ if tsxResultStats.InconclusiveTestCasesCount > 0 {
+ testCaseResults = append(testCaseResults, color.MagentaString(fmt.Sprintf(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.SystemErrorText), tsxResultStats.InconclusiveTestCasesCount)))
+ }
+
+ testSuiteHeader += strings.Join(testCaseResults, ", ")
+ fmt.Println(testSuiteHeader + "\n")
+
+ for _, tcx := range testSuiteExecution.TestCaseExecutions {
+ if tcx.DerivedTestCaseExecutions != nil {
+ for _, dtcx := range tcx.DerivedTestCaseExecutions {
+ printTestCaseExecutions(cmd, dtcx, strconv.Itoa(tcx.TestCaseContext.Order), strconv.Itoa(dtcx.TestCaseContext.Order))
+ }
+ } else {
+ printTestCaseExecutions(cmd, tcx, strconv.Itoa(tcx.TestCaseContext.Order), internalconstant.Empty)
+ }
+ }
+
+ fmt.Println()
+}
+
+func printTestCaseExecutions(cmd *cobra.Command, testCaseExecutions model.TestCaseExecutions, parentOrder string, childOrder string) {
+
+ // print sort test request and client profile details
+ printExecutedTestCaseDetails(testCaseExecutions.TestCaseContext.TestRequest, testCaseExecutions.TestCaseContext.ClientProfile,
+ testCaseExecutions.TestCaseContext.Condition, parentOrder, childOrder, internalconstant.TabSpace, testCaseExecutions.TestCaseExecutionId)
+
+ // print evaluation details
+ printEvaluationData(cmd, testCaseExecutions.ConditionEvaluationResult.ActualConditionData, testCaseExecutions.Status,
+ testCaseExecutions.ConditionEvaluationResult.Result, testCaseExecutions.Errors, testCaseExecutions.IsReevaluationInProgress,
+ internalconstant.TabSpace)
+}
+
+func printTestCaseExecution(cmd *cobra.Command, testRun *model.TestRun) {
+
+ testCaseExecution := &testRun.Functional.TestCaseExecution
+
+ // print sort test request and client profile details
+ printExecutedTestCaseDetails(testCaseExecution.TestRequest, testCaseExecution.ClientProfile, testCaseExecution.Condition,
+ internalconstant.Empty, internalconstant.Empty, internalconstant.Empty, testCaseExecution.TestCaseExecutionId)
+
+ // print evaluation details
+ printEvaluationData(cmd, testCaseExecution.ConditionEvaluationResult.ActualConditionData, testCaseExecution.Status,
+ testCaseExecution.ConditionEvaluationResult.Result, testCaseExecution.Errors, testCaseExecution.IsReevaluationInProgress,
+ internalconstant.Empty)
+}
+
+func printExecutedTestCaseDetails(testRequest model.TestRequest, clientProfile model.ClientProfile, condition model.Condition,
+ parentOrder, childOrder, tabSpaces string, testCaseExecutionId int) {
+
+ // print order number
+ if parentOrder != internalconstant.Empty {
+ if childOrder != internalconstant.Empty {
+ childOrder = externalconstant.Dot + childOrder
+ }
+ fmt.Print(tabSpaces + parentOrder + childOrder + internalconstant.Space)
+ }
+
+ // print url and client profiles
+ printRequestUrlAndClientProfile(testRequest, clientProfile)
+
+ // print test case execution id
+ util.PrintLabelAndValue(tabSpaces+externalconstant.LabelTestCaseExecutionId, testCaseExecutionId)
+
+ // print request headers if available
+ printRequestHeaders(testRequest.RequestHeaders, tabSpaces)
+
+ // print the encode request body and request body if applicable
+ printRequestBody(testRequest, tabSpaces)
+
+ // print condition
+ printCondition(condition, tabSpaces)
+
+}
+
+func printRequestUrlAndClientProfile(testRequest model.TestRequest, clientProfile model.ClientProfile) {
+ methodColour := util.GetColourForEnum(testRequest.RequestMethod, true)
+ _, _ = methodColour.Printf(testRequest.RequestMethod)
+
+ testRequestUrl := testRequest.TestRequestUrl
+ if testRequest.TestRequestUrlResolved != internalconstant.Empty {
+ testRequestUrl = testRequest.TestRequestUrlResolved
+ }
+
+ if clientProfile.ClientVersion != internalconstant.Empty {
+ fmt.Print(internalconstant.Space + testRequestUrl + externalconstant.SeparatePipe +
+ util.Bold(clientProfile.Client+externalconstant.Colon+clientProfile.ClientVersion) +
+ externalconstant.PlusSign)
+ } else {
+ fmt.Print(internalconstant.Space + testRequestUrl + externalconstant.SeparatePipe +
+ util.Bold(clientProfile.Client) + externalconstant.PlusSign)
+ }
+
+ if clientProfile.IpVersion == internalconstant.Ipv4 {
+ fmt.Print(util.Bold(externalconstant.LabelIPv4))
+ } else {
+ fmt.Print(util.Bold(externalconstant.LabelIPv6))
+ }
+ fmt.Println()
+}
+
+func printRequestHeaders(headers []model.RequestHeader, tabSpaces string) {
+ if headers != nil {
+ var formattedRequestHeaders []string
+ for _, header := range headers {
+
+ // get header name
+ var headerName = header.HeaderName
+ if header.HeaderNameResolved != internalconstant.Empty {
+ headerName = header.HeaderNameResolved
+ }
+
+ // get header value
+ var headerValue = header.HeaderValue
+ if header.HeaderValueResolved != internalconstant.Empty {
+ headerValue = header.HeaderValueResolved
+ }
+
+ formattedRequestHeader := util.RequestHeaderInCLIOutputFormat(headerName, header.HeaderAction, headerValue)
+ formattedRequestHeaders = append(formattedRequestHeaders, formattedRequestHeader)
+ }
+ util.PrintLabelAndValue(tabSpaces+externalconstant.LabelRequestHeaders, strings.Join(formattedRequestHeaders, ", "))
+ }
+}
+
+func printRequestBody(testRequest model.TestRequest, tabSpaces string) {
+ requestBody := testRequest.RequestBody
+ if requestBody != internalconstant.Empty {
+ if testRequest.RequestBodyResolved != internalconstant.Empty {
+ requestBody = testRequest.RequestBodyResolved
+ }
+ // print condition details
+ if testRequest.EncodeRequestBody != nil {
+ util.PrintLabelAndValue(tabSpaces+externalconstant.LabelEncodeRequestBody, util.Italic(*testRequest.EncodeRequestBody))
+ }
+ util.PrintLabelAndValue(tabSpaces+externalconstant.LabelRequestBody, util.Italic(requestBody))
+ }
+}
+
+func printCondition(condition model.Condition, tabSpaces string) {
+ conditionExpression := condition.ConditionExpression
+ if condition.ConditionExpressionResolved != internalconstant.Empty {
+ conditionExpression = condition.ConditionExpressionResolved
+ }
+
+ // print condition details
+ util.PrintLabelAndValue(tabSpaces+externalconstant.LabelExpected, util.Italic(conditionExpression))
+}
+
+func printEvaluationData(cmd *cobra.Command, actualConditionData []model.ActualConditionData, testCaseExecutionStatus string,
+ testCaseExecutionResultStatus string, testCaseExecutionErrors []model.ApiSubError, isReevaluationInProgress *bool, tabSpaces string) {
+ var actualDataList []string
+ for _, actualDataItem := range actualConditionData {
+ keyValuePair := actualDataItem.Name + externalconstant.Colon + internalconstant.Space
+ if actualDataItem.Value != internalconstant.Empty {
+ keyValuePair += externalconstant.Quote + actualDataItem.Value + externalconstant.Quote
+ } else {
+ keyValuePair += util.Italic(externalconstant.LabelNotFound)
+ }
+ actualDataList = append(actualDataList, keyValuePair)
+ }
+
+ if actualDataList != nil {
+ util.PrintLabelAndValue(tabSpaces+externalconstant.LabelActual, strings.Join(actualDataList, ", "))
+ }
+
+ fmt.Print(tabSpaces + util.Bold(externalconstant.LabelStatus+externalconstant.Colon+internalconstant.Space))
+ if testCaseExecutionStatus == internalconstant.CompletedEnum {
+ if testCaseExecutionResultStatus == internalconstant.PassedEnum {
+ util.PrintSuccess(externalconstant.LabelPassed + "\n")
+ } else if testCaseExecutionResultStatus == internalconstant.Inconclusive {
+ fmt.Print(color.MagentaString(externalconstant.LabelInconclusive))
+ if isReevaluationInProgress != nil {
+ if *isReevaluationInProgress {
+ fmt.Printf(" ( %s )", util.Italic(externalconstant.LabelIsReevaluationInProgress))
+ } else {
+ fmt.Printf(" ( %s )", util.Italic(externalconstant.LabelIsReevaluationCompleted))
+ }
+ }
+ fmt.Println()
+ } else {
+ util.PrintError(externalconstant.LabelFailed + "\n")
+ }
+ } else {
+ if testCaseExecutionStatus == internalconstant.InProgressEnum {
+ fmt.Println(externalconstant.LabelInProgress)
+ } else {
+ fmt.Println(color.MagentaString(externalconstant.LabelInconclusive))
+ errorMessages := util.GetApiSubErrorMessagesForCommand(cmd, testCaseExecutionErrors, internalconstant.Empty,
+ internalconstant.Empty, internalconstant.EvaluationErrors)
+ for _, errorMessage := range errorMessages {
+ util.PrintError(tabSpaces + externalconstant.LabelNotRunError + errorMessage + "\n")
+ }
+ }
+ }
+
+ fmt.Println()
+}
+
+func GetTestRunStats(testRun model.TestRun) (model.ResultStats, map[int]model.ResultStats) {
+ resultStats := model.ResultStats{}
+ tsxResultStatsMap := make(map[int]model.ResultStats)
+
+ pmx := testRun.Functional.PropertyManagerExecution
+ pmxResultStats := getPropertyManagerExecutionStats(pmx, tsxResultStatsMap)
+ addResultStats(&resultStats, &pmxResultStats)
+
+ for _, tsx := range testRun.Functional.TestSuiteExecutions {
+ tsxResultStats := getTestSuiteExecutionStats(tsx)
+ addResultStats(&resultStats, &tsxResultStats)
+ tsxResultStatsMap[tsx.TestSuiteExecutionId] = tsxResultStats
+ }
+
+ return resultStats, tsxResultStatsMap
+}
+
+func getPropertyManagerExecutionStats(pmExecution model.PropertyManagerExecution, tsxResultStatsMap map[int]model.ResultStats) model.ResultStats {
+ resultStats := model.ResultStats{}
+ for _, tsx := range pmExecution.TestSuiteExecutions {
+ tsxResultStats := getTestSuiteExecutionStats(tsx)
+ addResultStats(&resultStats, &tsxResultStats)
+ tsxResultStatsMap[tsx.TestSuiteExecutionId] = tsxResultStats
+ }
+ return resultStats
+}
+
+func getTestSuiteExecutionStats(testSuiteExecution model.TestSuiteExecutions) model.ResultStats {
+ resultStats := getTestCaseExecutionsStats(testSuiteExecution.TestCaseExecutions)
+ return resultStats
+}
+
+func getTestCaseExecutionsStats(testCaseExecutions []model.TestCaseExecutions) model.ResultStats {
+ resultStats := model.ResultStats{}
+ for _, tcx := range testCaseExecutions {
+ if tcx.DerivedTestCaseExecutions != nil {
+ for _, dtcx := range tcx.DerivedTestCaseExecutions {
+ resultStats = getResultStats(dtcx, resultStats)
+ }
+ } else {
+ resultStats = getResultStats(tcx, resultStats)
+ }
+ }
+ return resultStats
+}
+
+func getResultStats(tcx model.TestCaseExecutions, resultStats model.ResultStats) model.ResultStats {
+ if tcx.Status == internalconstant.CompletedEnum {
+ if tcx.ConditionEvaluationResult.Result == internalconstant.PassedEnum {
+ resultStats.PassedTestCasesCount += 1
+ } else if tcx.ConditionEvaluationResult.Result == internalconstant.Inconclusive {
+ resultStats.InconclusiveTestCasesCount += 1
+ } else {
+ resultStats.FailedTestCasesCount += 1
+ }
+ } else {
+ if tcx.Status == internalconstant.InProgressEnum {
+ resultStats.InProgressTestCasesCount += 1
+ } else {
+ resultStats.InconclusiveTestCasesCount += 1
+ }
+ }
+
+ return resultStats
+}
+
+func addResultStats(destResultStats *model.ResultStats, resultStats *model.ResultStats) {
+ destResultStats.PassedTestCasesCount += resultStats.PassedTestCasesCount
+ destResultStats.FailedTestCasesCount += resultStats.FailedTestCasesCount
+ destResultStats.InProgressTestCasesCount += resultStats.InProgressTestCasesCount
+ destResultStats.InconclusiveTestCasesCount += resultStats.InconclusiveTestCasesCount
+}
+
+func PrintRawRequestResponse(RawReqResArray []model.RawRequestResponse, isTcx bool) {
+
+ for i, tcx := range RawReqResArray {
+ //print text case execution ids only for raw request response of test run
+ if !isTcx {
+ ids := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(tcx.TestCaseExecutionIds)), externalconstant.Comma), internalconstant.EmptyArray)
+ util.PrintLabelAndValue(externalconstant.TestCaseExecutionIds, ids)
+ fmt.Println()
+ }
+
+ fmt.Println(util.Bold(externalconstant.Request))
+ fmt.Print(tcx.Request.Method + internalconstant.Space)
+ fmt.Print(tcx.Request.Url + internalconstant.Space)
+ fmt.Println(tcx.Request.HttpVersion)
+ util.PrintRawRequestResponseHeaders(tcx.Request.Headers)
+ fmt.Println()
+
+ fmt.Println(util.Bold(externalconstant.Response))
+ fmt.Print(tcx.Response.HttpVersion + internalconstant.Space)
+ fmt.Print(tcx.Response.Status)
+ fmt.Println(internalconstant.Space + tcx.Response.StatusText)
+ util.PrintRawRequestResponseHeaders(tcx.Response.Headers)
+ fmt.Println()
+
+ //print dash lines only for test case execution from index 0 to len-2
+ lastIndex := len(RawReqResArray) - 1
+ if !isTcx && i != lastIndex {
+ fmt.Println(externalconstant.SeparateLine)
+ fmt.Println()
+ }
+ }
+
+ if !isTcx {
+ util.PrintTotalItems(len(RawReqResArray))
+ }
+
+}
diff --git a/internal/print/test_case_print.go b/internal/print/test_case_print.go
new file mode 100644
index 0000000..3d0f7f3
--- /dev/null
+++ b/internal/print/test_case_print.go
@@ -0,0 +1,102 @@
+package print
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+ "strconv"
+ "strings"
+)
+
+func PrintTestCases(cmd *cobra.Command, testCases []model.TestCase, areAllTestCasesIncluded bool, groupBy string) {
+
+ //Print All associated Test Cases
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestCaseHeader) + "\n")
+
+ if len(testCases) <= 0 {
+ util.PrintWarning(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.NoTestCaseWarning))
+ //Printing warning here only and returning from method so that empty table does not print
+ printMissingTestCasesWarning(cmd, areAllTestCasesIncluded)
+ fmt.Println()
+ fmt.Println()
+ return
+ }
+
+ if groupBy == internalconstant.Empty {
+ PrintTestCaseDetails(cmd, testCases, false, internalconstant.Empty, 0)
+ fmt.Println()
+ util.PrintTotalItems(util.GetTotalTestCasesCount(testCases))
+ } else {
+ printGroupedTestCases(testCases, groupBy)
+ }
+
+ printMissingTestCasesWarning(cmd, areAllTestCasesIncluded)
+ fmt.Println()
+ fmt.Println()
+}
+
+func PrintTestCaseDetails(cmd *cobra.Command, testCases []model.TestCase, areDerivedTestCases bool, indentationSpace string, parentOrder int) {
+
+ for i, testCase := range testCases {
+ // do not print id for derived test cases.
+ if parentOrder == 0 {
+ util.PrintLabelAndValue(externalconstant.LabelId, testCase.TestCaseId)
+ util.PrintLabelAndValue(indentationSpace+externalconstant.LabelOrder, testCase.Order)
+ } else {
+ util.PrintLabelAndValue(indentationSpace+externalconstant.LabelOrder, strconv.Itoa(parentOrder)+externalconstant.Dot+strconv.Itoa(testCase.Order))
+ }
+ //test request
+ PrintTestRequestObjects([]model.TestRequest{testCase.TestRequest}, indentationSpace)
+ // condition
+ util.PrintLabelAndValue(indentationSpace+externalconstant.LabelCondition, util.GetResolvedOrUnResolvedCondition(testCase.Condition))
+ // client profile
+ util.PrintLabelAndValue(indentationSpace+externalconstant.LabelClientProfile, util.ClientProfileInCLIOutputFormat(testCase.ClientProfile))
+ // set variables
+ PrintSetVariables(testCase, indentationSpace)
+ // audit info
+ if !areDerivedTestCases {
+ PrintAuditInfo(testCase, indentationSpace)
+ }
+
+ if len(testCase.DerivedTestCases) != 0 {
+ fmt.Println()
+ fmt.Print(externalconstant.IndentationSpace)
+ util.PrintHeader(indentationSpace + util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.DerivedTestCaseHeader) + "\n")
+ PrintTestCaseDetails(cmd, testCase.DerivedTestCases, true, externalconstant.IndentationSpace, testCase.Order)
+ }
+
+ if i != len(testCases)-1 {
+ fmt.Println()
+ if areDerivedTestCases {
+ fmt.Println(indentationSpace + externalconstant.SeparateLineStar)
+ } else {
+ fmt.Println(externalconstant.SeparateLine)
+ }
+ fmt.Println()
+ }
+ }
+ areDerivedTestCases = false
+ parentOrder = 0
+}
+
+func PrintSetVariables(testCase model.TestCase, indentationSpace string) {
+ if len(testCase.SetVariables) != 0 {
+ var setVariables strings.Builder
+ for i, variable := range testCase.SetVariables {
+ setVariables.WriteString(util.SetVariablesInCLIOutputFormat(variable))
+ if i != len(testCase.SetVariables)-1 {
+ setVariables.WriteString("\n")
+ setVariables.WriteString(indentationSpace + " ")
+ }
+ }
+ util.PrintLabelAndValue(indentationSpace+externalconstant.LabelSetVariables, setVariables.String())
+ }
+}
+
+func PrintAuditInfo(testCase model.TestCase, indentationSpace string) {
+ util.PrintLabelAndValue(indentationSpace+externalconstant.LabelCreated, util.FormatTime(testCase.CreatedDate)+externalconstant.SeparateBy+testCase.CreatedBy)
+ util.PrintLabelAndValue(indentationSpace+externalconstant.LabelLastModified, util.FormatTime(testCase.ModifiedDate)+externalconstant.SeparateBy+testCase.ModifiedBy)
+}
diff --git a/internal/print/test_request_print.go b/internal/print/test_request_print.go
new file mode 100644
index 0000000..e97a350
--- /dev/null
+++ b/internal/print/test_request_print.go
@@ -0,0 +1,66 @@
+package print
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+ "strings"
+)
+
+func PrintTestRequests(cmd *cobra.Command, testRequests []model.TestRequest) {
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestRequests))
+ fmt.Println()
+ fmt.Println()
+
+ if len(testRequests) <= 0 {
+ util.PrintWarning(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestRequestNotFoundError))
+ fmt.Println()
+ return
+ }
+
+ PrintTestRequestObjects(testRequests, internalconstant.Empty)
+ fmt.Println()
+ util.PrintTotalItems(len(testRequests))
+ fmt.Println()
+
+}
+
+func PrintTestRequestObjects(testRequests []model.TestRequest, indentationSpaces string) {
+
+ for i, tr := range testRequests {
+ util.PrintLabelAndValue(indentationSpaces+externalconstant.LabelRequestMethod, tr.RequestMethod)
+ util.PrintLabelAndValue(indentationSpaces+externalconstant.LabelTRUrl, util.GetResolvedOrUnResolvedRequestURL(tr))
+
+ //tags
+ if len(tr.Tags) > 0 {
+ util.PrintLabelAndValue(indentationSpaces+externalconstant.LabelTags, strings.Join(tr.Tags, externalconstant.Comma))
+ }
+
+ //request headers
+ if len(tr.RequestHeaders) > 0 {
+ var headers = strings.Builder{}
+ for j, header := range tr.RequestHeaders {
+ headers.WriteString(util.GetResolvedOrUnResolvedHeaders(header))
+ if j != len(tr.RequestHeaders)-1 {
+ headers.WriteString("\n")
+ headers.WriteString(indentationSpaces + " ")
+ }
+ }
+ util.PrintLabelAndValue(indentationSpaces+externalconstant.LabelRequestHeaders, headers.String())
+ }
+
+ if tr.RequestMethod == internalconstant.Post {
+ util.PrintLabelAndValue(indentationSpaces+externalconstant.LabelRequestBody, util.GetResolvedOrUnResolvedRequestBody(tr))
+ util.PrintLabelAndValue(indentationSpaces+externalconstant.LabelEncodeRequestBody, *tr.EncodeRequestBody)
+ }
+
+ if i != len(testRequests)-1 {
+ fmt.Println()
+ fmt.Println(externalconstant.SeparateLine)
+ fmt.Println()
+ }
+ }
+}
diff --git a/internal/print/test_suite_print.go b/internal/print/test_suite_print.go
new file mode 100644
index 0000000..6ecf12a
--- /dev/null
+++ b/internal/print/test_suite_print.go
@@ -0,0 +1,260 @@
+package print
+
+// This class will have all test center related print common methods
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "sort"
+ "strconv"
+ "strings"
+
+ "github.com/spf13/cobra"
+)
+
+type GroupedTestCases struct {
+ Key string
+ Order int
+ Value []model.TestCase
+}
+
+func PrintTestSuite(cmd *cobra.Command, testSuiteV3 model.TestSuite) {
+
+ util.PrintLabelAndValue(externalconstant.LabelId, testSuiteV3.TestSuiteId)
+ util.PrintLabelAndValue(externalconstant.LabelName, testSuiteV3.TestSuiteName)
+ util.PrintLabelAndValue(externalconstant.LabelDescription, testSuiteV3.TestSuiteDescription)
+ util.PrintLabelAndValue(externalconstant.LabelStateful, util.ConvertBooleanToYesOrNo(testSuiteV3.IsStateful))
+ util.PrintLabelAndValue(externalconstant.LabelLocked, util.ConvertBooleanToYesOrNo(testSuiteV3.IsLocked))
+
+ if testSuiteV3.Configs.PropertyManager.PropertyId != 0 {
+ util.PrintLabelAndValue(externalconstant.LabelAssociatedProperty, fmt.Sprintf("(Id=%d) %s v%d",
+ testSuiteV3.Configs.PropertyManager.PropertyId,
+ testSuiteV3.Configs.PropertyManager.PropertyName,
+ testSuiteV3.Configs.PropertyManager.PropertyVersion))
+ }
+
+ util.PrintLabelAndValue(externalconstant.LabelCreated, util.FormatTime(testSuiteV3.CreatedDate)+externalconstant.SeparateBy+testSuiteV3.CreatedBy)
+ util.PrintLabelAndValue(externalconstant.LabelLastModified, util.FormatTime(testSuiteV3.ModifiedDate)+externalconstant.SeparateBy+testSuiteV3.ModifiedBy)
+
+ if testSuiteV3.DeletedBy != internalconstant.Empty {
+ util.PrintLabelAndValue(externalconstant.LabelDeleted, util.FormatTime(testSuiteV3.DeletedDate)+externalconstant.SeparateBy+testSuiteV3.DeletedBy)
+ }
+
+ // print variables if available
+ if len(testSuiteV3.Variables) > 0 {
+ fmt.Println()
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.VariableInTestSuiteHeader) + "\n")
+ PrintVariablesResult(cmd, testSuiteV3.Variables, true)
+ }
+
+ fmt.Println()
+}
+
+func PrintTestSuiteForRemovedTestSuite(testSuiteV3 model.TestSuite) {
+
+ util.PrintLabelAndValue(externalconstant.LabelId, testSuiteV3.TestSuiteId)
+ util.PrintLabelAndValue(externalconstant.LabelName, testSuiteV3.TestSuiteName)
+ util.PrintLabelAndValue(externalconstant.LabelDescription, testSuiteV3.TestSuiteDescription)
+ var configVersion string
+ if testSuiteV3.Configs.PropertyManager.PropertyName != internalconstant.Empty {
+ configVersion = testSuiteV3.Configs.PropertyManager.PropertyName + " " + strconv.Itoa(testSuiteV3.Configs.PropertyManager.PropertyVersion)
+ }
+ util.PrintLabelAndValue(externalconstant.LabelPropertyVersion, configVersion)
+}
+
+// PrintTestSuitesResult details and return test suiteId to print test cases only if single test suite is present in array else return 0
+func PrintTestSuitesResult(cmd *cobra.Command, testSuiteV3 []model.TestSuite, name string) {
+
+ util.PrintHeader("\n" + util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestSuiteDetails) + "\n")
+
+ size := len(testSuiteV3)
+ switch size {
+ case 0:
+ fmt.Printf(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.NoTestSuiteFoundWithName)+"\n\n", name)
+ case 1:
+ PrintTestSuite(cmd, testSuiteV3[0])
+ default:
+ PrintTestSuitesTable(cmd, testSuiteV3)
+ }
+}
+
+func PrintTestSuitesTable(cmd *cobra.Command, testSuites []model.TestSuite) {
+
+ if len(testSuites) <= 0 {
+ util.PrintWarning(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.NoTestSuiteFoundWarning))
+ fmt.Println()
+ return
+ }
+
+ // sort given items by created date / ID
+ sort.SliceStable(testSuites, func(i, j int) bool {
+ return testSuites[i].TestSuiteId < testSuites[j].TestSuiteId
+ })
+
+ tableHeaders := []string{"ID", "NAME", "DESCRIPTION", "PROPERTY VERSION", "TEST CASES"}
+ var contents = make([][]string, len(testSuites))
+
+ var isDeletedPresent = false
+
+ // prepare data for table
+ for i, ts := range testSuites {
+
+ // if deleted test-suite, add '*' at the beginning
+ if ts.DeletedBy != internalconstant.Empty {
+ ts.TestSuiteName = "* " + ts.TestSuiteName
+ isDeletedPresent = true
+ }
+
+ // form property-version string
+ propertyVersionStr := internalconstant.Empty
+ if ts.Configs.PropertyManager.PropertyVersion != 0 {
+ propertyVersionStr = fmt.Sprintf("%s v%d", ts.Configs.PropertyManager.PropertyName, ts.Configs.PropertyManager.PropertyVersion)
+ }
+ tsId := strconv.Itoa(ts.TestSuiteId)
+ tcCount := strconv.Itoa(ts.ExecutableTestCaseCount)
+
+ row := []string{tsId, ts.TestSuiteName, ts.TestSuiteDescription, propertyVersionStr, tcCount}
+ contents[i] = row
+ }
+
+ // show table
+ util.ShowTable(tableHeaders, contents, true)
+
+ if isDeletedPresent {
+ fmt.Println(externalconstant.LabelTSDeleteState)
+ }
+ fmt.Println()
+}
+
+func printGroupedTestCases(testCases []model.TestCase, groupBy string) {
+ var groupedTestCases = make(map[string][]model.TestCase)
+
+ switch strings.ToLower(groupBy) {
+ case internalconstant.GroupByTestRequest:
+ for _, testCase := range testCases {
+ //Get test request hash
+ if len(testCase.DerivedTestCases) != 0 {
+ for _, dtc := range testCase.DerivedTestCases {
+ testRequestHash := getTestRequestHashCode(dtc.TestRequest)
+ tcs, _ := groupedTestCases[testRequestHash]
+ dtc.ParentOrder = testCase.Order
+ groupedTestCases[testRequestHash] = append(tcs, dtc)
+ }
+ } else {
+ testRequestHash := getTestRequestHashCode(testCase.TestRequest)
+ tcs, _ := groupedTestCases[testRequestHash]
+ groupedTestCases[testRequestHash] = append(tcs, testCase)
+ }
+
+ }
+ util.PrintTemplate(externalconstant.GroupByTestRequest, sortTestCasesByOrder(groupedTestCases))
+
+ case internalconstant.GroupByCondition:
+ for _, testCase := range testCases {
+
+ if len(testCase.DerivedTestCases) != 0 {
+ for _, dtc := range testCase.DerivedTestCases {
+ var condition = util.GetResolvedOrUnResolvedCondition(dtc.Condition)
+ tcs, _ := groupedTestCases[condition]
+ dtc.ParentOrder = testCase.Order
+ groupedTestCases[condition] = append(tcs, dtc)
+ }
+ } else {
+ var condition = util.GetResolvedOrUnResolvedCondition(testCase.Condition)
+ tcs, _ := groupedTestCases[condition]
+ groupedTestCases[condition] = append(tcs, testCase)
+ }
+ }
+ util.PrintTemplate(externalconstant.GroupByCondition, sortTestCasesByOrder(groupedTestCases))
+
+ case internalconstant.GroupByClientProfile:
+ for _, testCase := range testCases {
+ if len(testCase.DerivedTestCases) != 0 {
+ for _, dtc := range testCase.DerivedTestCases {
+ clientProfileHash := util.ClientProfileInCLIOutputFormat(dtc.ClientProfile)
+ tcs, _ := groupedTestCases[clientProfileHash]
+ dtc.ParentOrder = testCase.Order
+ groupedTestCases[clientProfileHash] = append(tcs, dtc)
+ }
+ } else {
+ clientProfileHash := util.ClientProfileInCLIOutputFormat(testCase.ClientProfile)
+ tcs, _ := groupedTestCases[clientProfileHash]
+ groupedTestCases[clientProfileHash] = append(tcs, testCase)
+ }
+ }
+
+ util.PrintTemplate(externalconstant.GroupByClientProfile, sortTestCasesByOrder(groupedTestCases))
+ }
+}
+
+func getTestRequestHashCode(testRequest model.TestRequest) string {
+
+ //sort tags first so that sequence of tags is always matching in different test requests.
+ sort.Strings(testRequest.Tags)
+ tags := strings.Join(testRequest.Tags, externalconstant.Comma)
+
+ sort.Slice(testRequest.RequestHeaders, func(i, j int) bool {
+ return testRequest.RequestHeaders[i].HeaderName < testRequest.RequestHeaders[j].HeaderName
+ })
+
+ var headersArray []string
+ for _, v := range testRequest.RequestHeaders {
+ var resolvedHeaders = util.GetResolvedOrUnResolvedHeaders(v)
+ headersArray = append(headersArray, resolvedHeaders)
+ }
+ headers := strings.Join(headersArray, externalconstant.Comma)
+
+ var requestBody = internalconstant.Empty
+ var encodeRequestBody = internalconstant.Empty
+ if testRequest.RequestMethod == internalconstant.PostRequestMethod {
+ requestBody = util.GetResolvedOrUnResolvedRequestBody(testRequest)
+ encodeRequestBody = strconv.FormatBool(*testRequest.EncodeRequestBody)
+ }
+ var testRequestURL = util.GetResolvedOrUnResolvedRequestURL(testRequest)
+
+ return fmt.Sprintf("%s/%s/%s/%s/%s/%s", testRequestURL, testRequest.RequestMethod, tags, headers, requestBody, encodeRequestBody)
+
+}
+
+// Sort test cases values of map by order number and also get map of the lowest order number from test cases to values in map
+// The user should be able to view the test cases sorted by the order number in the list view and group by view. Grouped by object with the smallest order number test case will be at the top.
+func sortTestCasesByOrder(testCaseMap map[string][]model.TestCase) []GroupedTestCases {
+
+ var groupedTestCasesMap = make([]GroupedTestCases, 0)
+ for key, testCases := range testCaseMap {
+ sort.Slice(testCases, func(i, j int) bool {
+ // considered derived test cases also for sorting.
+ var order1 = testCases[i].Order
+ var order2 = testCases[j].Order
+ if testCases[i].ParentOrder != 0 {
+ order1 = testCases[i].ParentOrder
+ }
+ if testCases[j].ParentOrder != 0 {
+ order2 = testCases[j].ParentOrder
+ }
+ return order1 < order2
+ })
+ groupedTestCasesMap = append(groupedTestCasesMap, GroupedTestCases{
+ Key: key,
+ Order: testCases[0].Order,
+ Value: testCases,
+ })
+ }
+
+ sort.Slice(groupedTestCasesMap, func(i, j int) bool {
+ return groupedTestCasesMap[i].Order < groupedTestCasesMap[j].Order
+ })
+
+ //use new key and values list in struct to print values
+ return groupedTestCasesMap
+}
+
+func printMissingTestCasesWarning(cmd *cobra.Command, areAllTestCasesIncluded bool) {
+ if !areAllTestCasesIncluded {
+ fmt.Println()
+ fmt.Println()
+ util.PrintWarning(util.GetMessageForKey(cmd, "hostnameAccessMissing"))
+ }
+}
diff --git a/internal/print/try_function_print.go b/internal/print/try_function_print.go
new file mode 100644
index 0000000..8265459
--- /dev/null
+++ b/internal/print/try_function_print.go
@@ -0,0 +1,19 @@
+package print
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+)
+
+func PrintTryFunctionResponse(tryFunction *model.TryFunction) {
+ util.PrintLabelAndValue(externalconstant.LabelFunctionExpression, tryFunction.FunctionExpression)
+ var result = tryFunction.Result
+ if result == internalconstant.Empty {
+ result = externalconstant.TryFunctionEmptyResult
+ }
+ util.PrintLabelAndValue(externalconstant.LabelFunctionResult, result)
+ fmt.Println()
+}
diff --git a/internal/print/variable_print.go b/internal/print/variable_print.go
new file mode 100644
index 0000000..1d362ec
--- /dev/null
+++ b/internal/print/variable_print.go
@@ -0,0 +1,84 @@
+package print
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+ "strings"
+)
+
+func PrintVariablesResult(cmd *cobra.Command, variables []model.Variable, forTestSuite bool) {
+
+ size := len(variables)
+ switch size {
+ case 0:
+ util.PrintWarning(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.NoVariablesFoundWarning) + "\n")
+ default:
+ PrintVariables(variables, forTestSuite)
+ }
+}
+
+func PrintVariables(variables []model.Variable, forTestSuite bool) {
+
+ var variableGroup []model.Variable
+ for _, variable := range variables {
+ if variable.VariableValue != internalconstant.Empty {
+ if !forTestSuite {
+ util.PrintLabelAndValue(externalconstant.VariableId, variable.VariableId)
+ util.PrintLabelAndValue(externalconstant.VariableName, variable.VariableName)
+ util.PrintLabelAndValue(externalconstant.VariableValue, variable.VariableValue)
+ util.PrintLabelAndValue(externalconstant.LabelCreated, util.FormatTime(variable.CreatedDate)+externalconstant.SeparateBy+variable.CreatedBy)
+ util.PrintLabelAndValue(externalconstant.LabelLastModified, util.FormatTime(variable.ModifiedDate)+externalconstant.SeparateBy+variable.ModifiedBy)
+ fmt.Println()
+ } else {
+ fmt.Printf("%v=%v\n", variable.VariableName, variable.VariableValue)
+ }
+ } else {
+ variableGroup = append(variableGroup, variable)
+ }
+ }
+ fmt.Println()
+
+ if len(variableGroup) > 0 {
+ printVariablesGroupTables(variableGroup, forTestSuite)
+ }
+}
+
+func printVariablesGroupTables(varGroup []model.Variable, forTestSuite bool) {
+
+ for _, variableGroup := range varGroup {
+ if !forTestSuite {
+ util.PrintLabelAndValue(externalconstant.VariableId, variableGroup.VariableId)
+ util.PrintLabelAndValue(externalconstant.VariableName, variableGroup.VariableName)
+ util.PrintLabelAndValue(externalconstant.LabelCreated, util.FormatTime(variableGroup.CreatedDate)+externalconstant.SeparateBy+variableGroup.CreatedBy)
+ util.PrintLabelAndValue(externalconstant.LabelLastModified, util.FormatTime(variableGroup.ModifiedDate)+externalconstant.SeparateBy+variableGroup.ModifiedBy)
+ } else {
+ fmt.Printf("%v\n", variableGroup.VariableName)
+ }
+
+ //printing table for particular variableGroup
+ printVariableGroupTable(&variableGroup)
+ }
+}
+
+func printVariableGroupTable(variableGroup *model.Variable) {
+
+ var columnHeaders []string
+ // Assigning length of first columnValues of group value
+ var columnValues = make([][]string, len(variableGroup.VariableGroupValue[0].ColumnValues))
+
+ for _, variableGroupValue := range variableGroup.VariableGroupValue {
+ // Setting headers formatting to Uppercase
+ columnHeader := strings.ToUpper(variableGroupValue.ColumnHeader)
+
+ columnHeaders = append(columnHeaders, columnHeader)
+ for i, columnValue := range variableGroupValue.ColumnValues {
+ columnValues[i] = append(columnValues[i], columnValue)
+ }
+ }
+ util.ShowTable(columnHeaders, columnValues, false)
+ fmt.Println()
+}
diff --git a/internal/print_test_center_utils.go b/internal/print_test_center_utils.go
deleted file mode 100644
index 30e88c1..0000000
--- a/internal/print_test_center_utils.go
+++ /dev/null
@@ -1,543 +0,0 @@
-package internal
-
-// This class will have all test center related print common methods
-import (
- "fmt"
- "sort"
- "strconv"
- "strings"
-
- "github.com/fatih/color"
- "github.com/jinzhu/copier"
- log "github.com/sirupsen/logrus"
- "github.com/spf13/cobra"
-)
-
-type GroupedTestCases struct {
- Key string
- Order int
- Value []TestCase
-}
-
-func GetFunctionalContextMap(testRun *TestRun) (*FunctionalContextMap, *CliError) {
- testSuiteExecutions := testRun.Functional.TestSuiteExecutionsV3
- var functionalContextMap = FunctionalContextMap{}
- functionalContextMap.PropertyManagersMap = make(map[int]PropertyManagerContextMap)
-
- propertyManagerContext := testRun.Functional.PropertyManagerExecution
-
- var propertyManagerContextMap PropertyManagerContextMap
- err := copier.Copy(&propertyManagerContextMap, &propertyManagerContext.PropertyVersion)
- if err != nil {
- log.Errorln(err)
- return nil, CliErrorWithMessage(CliErrorMessageTestRunContext)
- }
- propertyManagerContextMap.TestSuitesMap = testSuiteContextListToMap(propertyManagerContext.TestSuiteExecutionsV3)
- functionalContextMap.PropertyManagersMap[propertyManagerContext.PropertyId] = propertyManagerContextMap
-
- functionalContextMap.TestSuitesMap = testSuiteContextListToMap(testSuiteExecutions)
-
- return &functionalContextMap, nil
-}
-
-func testSuiteContextListToMap(testSuiteExecutionV3s []TestSuiteExecutionV3) map[int]TestSuiteContextMap {
- testSuitesContextMap := make(map[int]TestSuiteContextMap)
- for _, testSuiteContext := range testSuiteExecutionV3s {
- var testSuiteContextMap TestSuiteContextMap
- err := copier.Copy(&testSuiteContextMap, &testSuiteContext.TestSuiteContext)
- if err != nil {
- return nil
- }
- testSuiteContextMap.TestCasesMap = testCasesListToMap(testSuiteContext.TestCaseExecutionsV3)
- testSuitesContextMap[testSuiteContext.TestSuiteId] = testSuiteContextMap
- }
- return testSuitesContextMap
-}
-
-func testCasesListToMap(testCases []TestCaseExecutionV3) map[int]TestCase {
- testCasesMap := make(map[int]TestCase)
- for _, testCase := range testCases {
- testCasesMap[testCase.TestCaseId] = testCase.TestCaseContext
- }
- return testCasesMap
-}
-
-func GetTestRunStats(testRun TestRun) (ResultStats, map[int]ResultStats) {
- resultStats := ResultStats{}
- tsxResultStatsMap := make(map[int]ResultStats)
-
- pmx := testRun.Functional.PropertyManagerExecution
- pmxResultStats := getPropertyManagerExecutionStats(pmx, tsxResultStatsMap)
- addResultStats(&resultStats, &pmxResultStats)
-
- for _, tsx := range testRun.Functional.TestSuiteExecutionsV3 {
- tsxResultStats := getTestSuiteExecutionStats(tsx)
- addResultStats(&resultStats, &tsxResultStats)
- tsxResultStatsMap[tsx.TestSuiteExecutionId] = tsxResultStats
- }
-
- return resultStats, tsxResultStatsMap
-}
-
-func getPropertyManagerExecutionStats(pmExecution PropertyManagerExecution, tsxResultStatsMap map[int]ResultStats) ResultStats {
- resultStats := ResultStats{}
- for _, tsx := range pmExecution.TestSuiteExecutionsV3 {
- tsxResultStats := getTestSuiteExecutionStats(tsx)
- addResultStats(&resultStats, &tsxResultStats)
- tsxResultStatsMap[tsx.TestSuiteExecutionId] = tsxResultStats
- }
- return resultStats
-}
-
-func getTestCaseExecutionsStats(testCaseExecutions []TestCaseExecutionV3) ResultStats {
- resultStats := ResultStats{}
- for _, tcx := range testCaseExecutions {
- resultStats.TotalTestCasesCount += 1
- if tcx.Status == Completed {
- if tcx.ConditionEvaluationResult.Result == Passed {
- resultStats.PassedTestCasesCount += 1
- } else {
- resultStats.FailedTestCasesCount += 1
- }
- } else {
- resultStats.FailedTestCasesCount += 1
- }
- }
- return resultStats
-}
-
-func getTestSuiteExecutionStats(testSuiteExecution TestSuiteExecutionV3) ResultStats {
- resultStats := getTestCaseExecutionsStats(testSuiteExecution.TestCaseExecutionsV3)
- return resultStats
-}
-
-func addResultStats(destResultStats *ResultStats, resultStats *ResultStats) {
- destResultStats.TotalTestCasesCount += resultStats.TotalTestCasesCount
- destResultStats.PassedTestCasesCount += resultStats.PassedTestCasesCount
- destResultStats.FailedTestCasesCount += resultStats.FailedTestCasesCount
- destResultStats.SystemErrorTestCasesCount += resultStats.SystemErrorTestCasesCount
-}
-
-func PrintTestResult(cmd *cobra.Command, testRun *TestRun) {
- testRunStats, tsxResultStatsMap := GetTestRunStats(*testRun)
- functionalContextMap, err := GetFunctionalContextMap(testRun)
- if err != nil {
- AbortForCommand(cmd, err)
- }
-
- var testRunStatus string
- if testRunStats.PassedTestCasesCount == testRunStats.TotalTestCasesCount {
- testRunStatus = color.GreenString(GetServiceMessage(cmd, MessageTypeDisplay, "", "completed"))
- } else if testRunStats.PassedTestCasesCount < testRunStats.TotalTestCasesCount {
- testRunStatus = color.YellowString(GetServiceMessage(cmd, MessageTypeDisplay, "", "completedNotAsExpected"))
- } else if testRunStats.FailedTestCasesCount == testRunStats.TotalTestCasesCount {
- testRunStatus = color.RedString(GetServiceMessage(cmd, MessageTypeDisplay, "", "failed"))
- }
- PrintHeader("\n" + GetServiceMessage(cmd, MessageTypeDisplay, "", "testRunHeader") + "\n\n")
- printLabelAndValue(LabelStatus, testRunStatus)
- printLabelAndValue(LabelTargetEnvironment, CamelToTitle(testRun.TargetEnvironment))
- fmt.Println()
-
- propertyManagerExecution := testRun.Functional.PropertyManagerExecution
- PrintPropertyManagerExecution(cmd, propertyManagerExecution, functionalContextMap.PropertyManagersMap, tsxResultStatsMap)
-
- for i, testSuiteExecution := range testRun.Functional.TestSuiteExecutionsV3 {
- PrintTestSuiteExecution(cmd, testSuiteExecution, functionalContextMap.TestSuitesMap, tsxResultStatsMap)
- if i < len(testRun.Functional.TestSuiteExecutionsV3)-1 {
- fmt.Println(SeparateLine)
- }
- }
-
- if testRun.Functional.TestCaseExecution.TestRequest.TestRequestUrl != Empty {
- log.Debug("Printing result for single test case execution!!!")
- PrintTestCaseExecution(testRun)
- }
-
-}
-
-func PrintTestSuiteExecution(cmd *cobra.Command, testSuiteExecution TestSuiteExecutionV3, testSuitesContextMap map[int]TestSuiteContextMap, tsxResultStatsMap map[int]ResultStats) {
- testSuite := testSuitesContextMap[testSuiteExecution.TestSuiteId]
- tsxResultStats := tsxResultStatsMap[testSuiteExecution.TestSuiteExecutionId]
-
- testSuiteHeader := bold(GetServiceMessage(cmd, MessageTypeDisplay, "", "testSuiteText")) + testSuite.TestSuiteName + SeparatePipe
- testSuiteHeader += fmt.Sprintf(GetServiceMessage(cmd, MessageTypeDisplay, "", "testCases"), tsxResultStats.TotalTestCasesCount)
-
- var testCaseResults []string
- if tsxResultStats.PassedTestCasesCount > 0 {
- testCaseResults = append(testCaseResults, fmt.Sprintf(GetServiceMessage(cmd, MessageTypeDisplay, "", "passedText"), tsxResultStats.PassedTestCasesCount))
- }
- if tsxResultStats.FailedTestCasesCount > 0 {
- testCaseResults = append(testCaseResults, color.RedString(fmt.Sprintf(GetServiceMessage(cmd, MessageTypeDisplay, "", "failedText"), tsxResultStats.FailedTestCasesCount)))
- }
- if tsxResultStats.SystemErrorTestCasesCount > 0 {
- testCaseResults = append(testCaseResults, color.YellowString(fmt.Sprintf(GetServiceMessage(cmd, MessageTypeDisplay, "", "systemErrorText"), tsxResultStats.SystemErrorTestCasesCount)))
- }
-
- testSuiteHeader += strings.Join(testCaseResults, ", ")
- fmt.Println(testSuiteHeader + "\n")
-
- for _, tcx := range testSuiteExecution.TestCaseExecutionsV3 {
- PrintTestCasesExecution(tcx, testSuite.TestCasesMap)
- }
-
- fmt.Println()
-}
-
-func PrintTestCasesExecution(testCaseExecution TestCaseExecutionV3, testCasesMap map[int]TestCase) {
- testCase := testCasesMap[testCaseExecution.TestCaseId]
-
- if testCase.ClientProfile.IpVersion == Ipv4 {
- fmt.Println(testCase.TestRequest.TestRequestUrl + SeparatePipe + bold(LabelIPv4))
- } else {
- fmt.Println(testCase.TestRequest.TestRequestUrl + SeparatePipe + bold(LabelIPv6))
- }
-
- printLabelAndValue(LabelExpected, italic(testCase.Condition.ConditionExpression))
-
- var actualDataList []string
- for _, actualDataItem := range testCaseExecution.ConditionEvaluationResult.ActualConditionData {
- keyValuePair := CamelToTitle(actualDataItem.Name) + ": "
- if actualDataItem.Value != "" {
- keyValuePair += actualDataItem.Value
- } else {
- keyValuePair += italic(LabelNotFound)
- }
- actualDataList = append(actualDataList, keyValuePair)
- }
- printLabelAndValue(LabelActual, strings.Join(actualDataList, ", "))
-
- if testCaseExecution.Status == Completed {
- if testCaseExecution.ConditionEvaluationResult.Result == Passed {
- PrintSuccess(LabelPassed + "\n")
- } else {
- PrintError(LabelFailed + "\n")
- }
- } else {
- var errorMessages []string
- for _, errorObject := range testCaseExecution.Errors {
- errorMessages = append(errorMessages, errorObject.Title)
- }
- PrintError(LabelNotRunError + strings.Join(errorMessages, ", ") + "\n")
- }
-
- fmt.Println()
-}
-
-func PrintPropertyManagerExecution(cmd *cobra.Command, propertyManagerExecution PropertyManagerExecution, propertyManagersContextMap map[int]PropertyManagerContextMap, tsxResultStatsMap map[int]ResultStats) {
- propertyVersion := propertyManagersContextMap[propertyManagerExecution.PropertyId]
-
- for i, tsx := range propertyManagerExecution.TestSuiteExecutionsV3 {
- PrintTestSuiteExecution(cmd, tsx, propertyVersion.TestSuitesMap, tsxResultStatsMap)
- if i < len(propertyManagerExecution.TestSuiteExecutionsV3)-1 {
- fmt.Println(SeparateLine)
- }
- }
-}
-
-func PrintTestCaseExecution(testRun *TestRun) {
-
- testCaseExecution := &testRun.Functional.TestCaseExecution
- if testCaseExecution.ClientProfile.IpVersion == Ipv4 {
- fmt.Println(testCaseExecution.TestRequest.TestRequestUrl + SeparatePipe + bold(LabelIPv4))
- } else {
- fmt.Println(testCaseExecution.TestRequest.TestRequestUrl + SeparatePipe + bold(LabelIPv6))
- }
-
- printLabelAndValue(LabelExpected, italic(testCaseExecution.Condition.ConditionExpression))
-
- var actualDataList []string
- for _, actualDataItem := range testCaseExecution.ConditionEvaluationResult.ActualConditionData {
- keyValuePair := CamelToTitle(actualDataItem.Name) + ": "
- if actualDataItem.Value != "" {
- keyValuePair += actualDataItem.Value
- } else {
- keyValuePair += italic(LabelNotFound)
- }
- actualDataList = append(actualDataList, keyValuePair)
- }
- printLabelAndValue(LabelActual, strings.Join(actualDataList, ", "))
-
- if testCaseExecution.Status == Completed {
- if testCaseExecution.ConditionEvaluationResult.Result == Passed {
- PrintSuccess(LabelPassed + "\n")
- } else {
- PrintError(LabelFailed + "\n")
- }
- } else {
- var errorMessages []string
- for _, errorObject := range testCaseExecution.Errors {
- errorMessages = append(errorMessages, errorObject.Title)
- }
- PrintError(LabelNotRunError + strings.Join(errorMessages, ", ") + "\n")
- }
-
- fmt.Println()
-}
-
-func PrintTestSuite(testSuiteV3 TestSuiteV3) {
-
- printLabelAndValue(LabelId, testSuiteV3.TestSuiteId)
- printLabelAndValue(LabelName, testSuiteV3.TestSuiteName)
- printLabelAndValue(LabelDescription, testSuiteV3.TestSuiteDescription)
- printLabelAndValue(LabelStateful, ConvertBooleanToYesOrNo(testSuiteV3.IsStateful))
- printLabelAndValue(LabelLocked, ConvertBooleanToYesOrNo(testSuiteV3.IsLocked))
- printLabelAndValue(LabelVariables, "")
- printVariables(testSuiteV3.Variables)
- if testSuiteV3.Configs.PropertyManager.PropertyVersion != 0 {
- printLabelAndValue(LabelAssociatedPropertyVersion, fmt.Sprintf("%s %d",
- testSuiteV3.Configs.PropertyManager.PropertyName, testSuiteV3.Configs.PropertyManager.PropertyVersion))
- } else {
- printLabelAndValue(LabelAssociatedPropertyVersion, fmt.Sprintf("%s", testSuiteV3.Configs.PropertyManager.PropertyName))
- }
-
- printLabelAndValue(LabelCreated, FormatTime(testSuiteV3.CreatedDate)+SeparateBy+testSuiteV3.CreatedBy)
- printLabelAndValue(LabelLastModified, FormatTime(testSuiteV3.ModifiedDate)+SeparateBy+testSuiteV3.ModifiedBy)
-
- if testSuiteV3.DeletedBy != "" {
- printLabelAndValue(LabelDeleted, FormatTime(testSuiteV3.DeletedDate)+SeparateBy+testSuiteV3.DeletedBy)
- }
-
- fmt.Println()
-}
-
-func PrintTestSuiteForRemovedTestSuite(testSuiteV3 TestSuiteV3) {
-
- printLabelAndValue(LabelId, testSuiteV3.TestSuiteId)
- printLabelAndValue(LabelName, testSuiteV3.TestSuiteName)
- printLabelAndValue(LabelDescription, testSuiteV3.TestSuiteDescription)
- var configVersion string
- if testSuiteV3.Configs.PropertyManager.PropertyName != "" {
- configVersion = testSuiteV3.Configs.PropertyManager.PropertyName + " " + strconv.Itoa(testSuiteV3.Configs.PropertyManager.PropertyVersion)
- }
- printLabelAndValue(LabelPropertyVersion, configVersion)
-}
-
-// PrintViewTestSuite details and return test suiteId to print test cases only if single test suite is present in array else return 0
-func PrintViewTestSuite(cmd *cobra.Command, testSuiteV3 []TestSuiteV3, name string) {
-
- PrintHeader("\n" + GetServiceMessage(cmd, MessageTypeDisplay, "", "testSuiteDetails") + "\n")
-
- size := len(testSuiteV3)
- switch size {
- case 0:
- fmt.Printf(GetServiceMessage(cmd, MessageTypeDisplay, "", "noTestSuiteFoundWithName")+"\n\n", name)
- case 1:
- PrintTestSuite(testSuiteV3[0])
- default:
- PrintTestSuitesTable(cmd, testSuiteV3)
- }
-}
-
-func printVariables(variables []Variable) {
-
- for _, variable := range variables {
- fmt.Printf("%v= %v\n", variable.VariableName, variable.VariableValue)
- }
-}
-
-func PrintTestSuitesTable(cmd *cobra.Command, testSuites []TestSuiteV3) {
-
- if len(testSuites) <= 0 {
- PrintWarning(GetServiceMessage(cmd, MessageTypeDisplay, "", "noTestSuiteFoundWarning"))
- fmt.Println()
- return
- }
-
- // sort given items by created date / ID
- sort.SliceStable(testSuites, func(i, j int) bool {
- return testSuites[i].TestSuiteId < testSuites[j].TestSuiteId
- })
-
- tableHeaders := []string{"ID", "Name", "Description", "Property Version", "Test Cases"}
- var contents = make([][]string, len(testSuites))
-
- var isDeletedPresent = false
-
- // prepare data for table
- for i, ts := range testSuites {
-
- // if deleted test-suite, add '*' at the beginning
- if ts.DeletedBy != "" {
- ts.TestSuiteName = "* " + ts.TestSuiteName
- isDeletedPresent = true
- }
-
- // form property-version string
- propertyVersionStr := ""
- if ts.Configs.PropertyManager.PropertyVersion != 0 {
- propertyVersionStr = fmt.Sprintf("%s v%d", ts.Configs.PropertyManager.PropertyName, ts.Configs.PropertyManager.PropertyVersion)
- }
- tsId := strconv.Itoa(ts.TestSuiteId)
- tcCount := strconv.Itoa(ts.ExecutableTestCaseCount)
-
- row := []string{tsId, ts.TestSuiteName, ts.TestSuiteDescription, propertyVersionStr, tcCount}
- contents[i] = row
- }
-
- // show table
- ShowTable(tableHeaders, contents)
-
- if isDeletedPresent {
- fmt.Println(LabelTSDeleteState)
- }
- fmt.Println()
-}
-
-func PrintTestCases(cmd *cobra.Command, testCases []TestCase, areAllTestCasesIncluded bool, groupBy string) {
-
- //Print All associated Test Cases
- PrintHeader(GetServiceMessage(cmd, MessageTypeDisplay, "", "testCaseHeader") + "\n")
-
- if len(testCases) <= 0 {
- PrintWarning(GetServiceMessage(cmd, MessageTypeDisplay, "", "noTestCaseWarning"))
- //Printing warning here only and returning from method so that empty table does not print
- printMissingTestCasesWarning(cmd, areAllTestCasesIncluded)
- fmt.Println()
- fmt.Println()
- return
- }
-
- if groupBy == "" {
- printTestCasesTable(testCases)
- } else {
- printGroupedTestCases(testCases, groupBy)
- }
-
- printMissingTestCasesWarning(cmd, areAllTestCasesIncluded)
- fmt.Println()
- fmt.Println()
-}
-
-func printTestCasesTable(testCases []TestCase) {
- // sort given items by orderId
- sort.SliceStable(testCases, func(i, j int) bool {
- return testCases[i].Order < testCases[j].Order
- })
-
- tableHeaders := []string{"Order Number", "Test Request", "Condition", "Ip Version"}
- var contents = make([][]string, len(testCases))
-
- // prepare data for table
- for i, tc := range testCases {
-
- var testRequest strings.Builder
- testRequest.WriteString(tc.TestRequest.TestRequestUrl)
- testRequest.WriteString("\n")
- if len(tc.TestRequest.Tags) != 0 {
- testRequest.WriteString("Keywords: ")
- testRequest.WriteString(strings.Join(tc.TestRequest.Tags, ","))
- testRequest.WriteString("\n")
- }
-
- if len(tc.TestRequest.RequestHeaders) != 0 {
- testRequest.WriteString("Request Headers: ")
- for _, header := range tc.TestRequest.RequestHeaders {
- testRequest.WriteString(RequestHeaderInCLIOutputFormat(header.HeaderName, header.HeaderAction, header.HeaderValue))
- testRequest.WriteString("\n")
- }
- }
-
- var clientProfile = ClientProfileInCLIOutputFormat(tc.ClientProfile.IpVersion)
- row := []string{strconv.Itoa(tc.Order), testRequest.String(), tc.Condition.ConditionExpression, clientProfile}
- contents[i] = row
- }
-
- // show table
- ShowTable(tableHeaders, contents)
-}
-
-func printGroupedTestCases(testCases []TestCase, groupBy string) {
- var groupedTestCases = make(map[string][]TestCase)
-
- switch strings.ToLower(groupBy) {
- case GroupByTestRequest:
- for _, testCase := range testCases {
- //Get test request hash
- testRequestHash := getTestRequestHashCode(testCase.TestRequest)
- tcs, _ := groupedTestCases[testRequestHash]
- groupedTestCases[testRequestHash] = append(tcs, testCase)
- }
- printTemplate(groupByTestRequest, sortTestCasesByOrder(groupedTestCases))
-
- case GroupByCondition:
- for _, testCase := range testCases {
- tcs, _ := groupedTestCases[testCase.Condition.ConditionExpression]
- groupedTestCases[testCase.Condition.ConditionExpression] = append(tcs, testCase)
- }
- printTemplate(groupByCondition, sortTestCasesByOrder(groupedTestCases))
-
- case GroupByIpVersion:
- for _, testCase := range testCases {
- tcs, _ := groupedTestCases[testCase.ClientProfile.IpVersion]
- groupedTestCases[testCase.ClientProfile.IpVersion] = append(tcs, testCase)
- }
-
- printTemplate(groupByIpVersion, sortTestCasesByOrder(groupedTestCases))
- }
-}
-
-func getTestRequestHashCode(testRequest TestRequest) string {
-
- //sort tags first so that sequence of tags is always matching in different test requests.
- sort.Strings(testRequest.Tags)
- tags := strings.Join(testRequest.Tags, ",")
-
- sort.Slice(testRequest.RequestHeaders, func(i, j int) bool {
- return testRequest.RequestHeaders[i].HeaderName < testRequest.RequestHeaders[j].HeaderName
- })
-
- var headersArray []string
- for _, v := range testRequest.RequestHeaders {
- headersArray = append(headersArray, v.HeaderName, v.HeaderValue, v.HeaderAction)
- }
- headers := strings.Join(headersArray, ",")
-
- return fmt.Sprintf("%s/%s/%s", testRequest.TestRequestUrl, tags, headers)
-}
-
-// Sort test cases values of map by order number and also get map of the lowest order number from test cases to values in map
-// The user should be able to view the test cases sorted by the order number in the list view and group by view. Grouped by object with the smallest order number test case will be at the top.
-func sortTestCasesByOrder(testCaseMap map[string][]TestCase) []GroupedTestCases {
-
- var groupedTestCasesMap = make([]GroupedTestCases, 0)
- for key, testCases := range testCaseMap {
- sort.Slice(testCases, func(i, j int) bool {
- return testCases[i].Order < testCases[j].Order
- })
-
- groupedTestCasesMap = append(groupedTestCasesMap, GroupedTestCases{
- Key: key,
- Order: testCases[0].Order,
- Value: testCases,
- })
- }
-
- sort.Slice(groupedTestCasesMap, func(i, j int) bool {
- return groupedTestCasesMap[i].Order < groupedTestCasesMap[j].Order
- })
-
- //use new key and values list in struct to print values
- return groupedTestCasesMap
-}
-
-func printMissingTestCasesWarning(cmd *cobra.Command, areAllTestCasesIncluded bool) {
- if !areAllTestCasesIncluded {
- fmt.Println()
- fmt.Println()
- PrintWarning(GetMessageForKey(cmd, "hostnameAccessMissing"))
- }
-}
-
-func PrintConditions(cmd *cobra.Command, condTemplate ConditionTemplate) {
- fmt.Println()
- PrintHeader(GetServiceMessage(cmd, MessageTypeDisplay, "", "conditionsHeader"))
- fmt.Println()
- fmt.Println()
- for _, condType := range condTemplate.ConditionTypes {
- fmt.Println(bold(condType.Label))
- for _, condExpression := range condType.ConditionExpressions {
- fmt.Println(" ", condExpression.ConditionExpression)
- }
- fmt.Println()
- }
-}
diff --git a/internal/service.go b/internal/service.go
deleted file mode 100644
index c3da906..0000000
--- a/internal/service.go
+++ /dev/null
@@ -1,768 +0,0 @@
-package internal
-
-import (
- "fmt"
- "strconv"
- "strings"
- "time"
-
- log "github.com/sirupsen/logrus"
- "github.com/spf13/cobra"
-)
-
-type Service struct {
- api ApiClient
- cmd *cobra.Command
- jsonOutput bool
-}
-
-func NewService(api ApiClient, cmd *cobra.Command, jsonOutput bool) *Service {
- return &Service{api, cmd, jsonOutput}
-}
-
-func (svc Service) GetTestSuites(propertyName, propVersion, user, searchString string) []TestSuiteV3 {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "getTestSuite"), !svc.jsonOutput).Start()
- testSuitesV3, err := svc.api.GetTestSuitesV3(propertyName, propVersion, user, true)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
- spinner.StopWithSuccess()
-
- filteredTestSuites := filterTestSuitesByString(searchString, false, true, testSuitesV3)
-
- if svc.jsonOutput {
- PrintJsonAndExit(filteredTestSuites)
- }
-
- return filteredTestSuites
-}
-
-func (svc Service) ImportTestSuites(testSuiteImport TestSuiteV3) {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "importTestSuite"), !svc.jsonOutput).Start()
- svc.setClientAndRequestMethod(&testSuiteImport)
- testSuiteImportResponseV3, err := svc.api.ImportTestSuite(testSuiteImport)
-
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
- spinner.StopWithSuccess()
-
- if svc.jsonOutput {
- PrintJsonAndExit(testSuiteImportResponseV3)
- }
-
- PrintViewTestSuite(svc.cmd, []TestSuiteV3{testSuiteImportResponseV3.Success}, testSuiteImportResponseV3.Success.TestSuiteName)
- printLabelAndValue(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "testCasesAdded"), testSuiteImportResponseV3.Success.ExecutableTestCaseCount)
-
- if testSuiteImportResponseV3.Failure.TestCases != nil {
- PrintError("\n" + GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "importTSTestCaseFailed") + "\n")
- printErrorMessages(GetApiSubErrorMessagesForCommand(svc.cmd, testSuiteImportResponseV3.Failure.TestCases, "", Empty, Empty))
- }
- if testSuiteImportResponseV3.Failure.Variables != nil {
- PrintError("\n" + GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "importTSVariableFailed") + "\n")
- printErrorMessages(GetApiSubErrorMessagesForCommand(svc.cmd, testSuiteImportResponseV3.Failure.Variables, "", Empty, Empty))
- }
-}
-
-func (svc Service) ManageTestSuites(testSuiteManage TestSuiteV3) {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "manageTestSuite"), !svc.jsonOutput).Start()
- svc.setClientAndRequestMethod(&testSuiteManage)
- testSuiteManageResponseV3, err := svc.api.ManageTestSuite(testSuiteManage, testSuiteManage.TestSuiteId)
-
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
- spinner.StopWithSuccess()
-
- if svc.jsonOutput {
- PrintJsonAndExit(testSuiteManageResponseV3)
- }
- PrintSuccess(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "manageTSSuccess")+"\n", testSuiteManageResponseV3.TestSuiteName)
-}
-
-func (svc Service) AddTestSuite(name, description, propertyName string, propVersion int, unlocked, stateful bool) *TestSuiteV3 {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "addTestSuite"), !svc.jsonOutput).Start()
-
- testSuite := TestSuiteV3{
- TestSuiteName: name,
- TestSuiteDescription: description,
- IsLocked: !unlocked,
- IsStateful: stateful,
- Configs: AkamaiConfigs{
- PropertyManager: PropertyManager{
- PropertyName: propertyName,
- PropertyVersion: propVersion,
- }},
- }
-
- testSuitesV3, err := svc.api.AddTestSuitesV3(testSuite)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
- spinner.StopWithSuccess()
-
- if svc.jsonOutput {
- PrintJsonAndExit(testSuitesV3)
- }
-
- return testSuitesV3
-}
-
-func (svc Service) EditTestSuite(id, name, description, propertyName string, propVersion int, unlocked, stateful, removeProperty bool, locked bool, stateless bool) *TestSuiteV3 {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "editTestSuite"), !svc.jsonOutput).Start()
- getTestSuite, err := svc.api.GetTestSuiteV3(id)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, Empty, Read)
- }
-
- var updatedTestSuite, isChanged = updateModifiedTestSuiteFields(*getTestSuite, name, description, propertyName, propVersion, unlocked, stateful, removeProperty, locked, stateless)
-
- // Check if at least value changed to edit test suite.
- if !isChanged {
- spinner.StopWithFailure()
- NewValidator(svc.cmd, []byte{}).EditTestSuiteAllFlagCheck()
- }
-
- testSuitesV3, err := svc.api.EditTestSuitesV3(*updatedTestSuite, id)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, Empty, Update)
- }
-
- spinner.StopWithSuccess()
-
- if svc.jsonOutput {
- PrintJsonAndExit(testSuitesV3)
- }
-
- return testSuitesV3
-}
-
-func (svc Service) RemoveTestSuiteById(id string) {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "removeTestSuite"), !svc.jsonOutput).Start()
- err := svc.api.RemoveTestSuite(id)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, Empty, Read)
- }
-
-}
-
-func (svc Service) RestoreTestSuiteById(id string) *TestSuiteV3 {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "restoreTestSuite"), !svc.jsonOutput).Start()
- testSuitesV3, err := svc.api.RestoreTestSuite(id)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, Empty, Read)
- }
- return testSuitesV3
-
-}
-
-func (svc Service) GetTestSuitesByIdOrName(id, name, subResource string, exactMatch, shouldMatchDescription, includeDeleted bool) []TestSuiteV3 {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "getTestSuite"), !svc.jsonOutput).Start()
-
- if id != "" {
-
- testSuite, err := svc.api.GetTestSuiteV3(id)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, subResource, Read)
- }
- spinner.StopWithSuccess()
-
- return []TestSuiteV3{*testSuite}
- } else {
-
- testSuitesV3, err := svc.api.GetTestSuitesV3("", "", "", includeDeleted)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, subResource, Read)
- }
- spinner.StopWithSuccess()
-
- return filterTestSuitesByString(name, exactMatch, shouldMatchDescription, testSuitesV3)
- }
-}
-
-func (svc Service) GetSingleTestSuiteByIdOrName(id, name, subResource string, includeDeleted bool) *TestSuiteV3 {
-
- testSuites := svc.GetTestSuitesByIdOrName(id, name, subResource, true, false, includeDeleted)
-
- if len(testSuites) == 1 {
- return &testSuites[0]
- }
-
- return nil
-}
-
-func (svc Service) GetV3AssociatedTestCasesForTestSuite(testSuiteId int) ([]TestCase, bool) {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "getTestCases"), !svc.jsonOutput).Start()
- associatedTestCases, err := svc.api.GetV3AssociatedTestCasesForTestSuite(testSuiteId)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, Empty, Read)
- }
-
- spinner.StopWithSuccess()
- return associatedTestCases.TestCases, associatedTestCases.AreAllTestCasesIncluded
-}
-
-func (svc Service) GetTestSuiteWithChildObjects(testSuiteId int) TestSuiteV3 {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "testSuiteWithChildObject"), !svc.jsonOutput).Start()
- testSuiteDetailsWithChildObjects, err := svc.api.GetTestSuitesWithChildObjects(testSuiteId)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, Empty, Read)
- }
-
- spinner.StopWithSuccess()
- return *testSuiteDetailsWithChildObjects
-}
-
-func (svc Service) AddTestCaseToTestSuite(testSuiteId int, url, condition, ipVersion string, addHeader, modifyHeader, filterHeader []string) ([]TestCase, *CliError) {
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "addTestCase"), !svc.jsonOutput).Start()
-
- var testCase = constructTestCase(url, addHeader, modifyHeader, filterHeader, condition, ipVersion)
- log.Debugf("Add test case [%+v] with the test suite id [%d]\n", testCase, testSuiteId)
-
- testCases, err := svc.api.AddTestCaseToTestSuite(testSuiteId, []TestCase{testCase})
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
-
- if len(testCases.Failures) != 0 {
- spinner.StopWithFailure()
- return nil, CliErrorFromPulsarProblemObject(nil, testCases.Failures, 207, ApiErrorAddTestCasesToTestSuitPostCall)
- }
-
- spinner.StopWithSuccess()
- return testCases.Successes, nil
-}
-
-func (svc Service) RemoveTestCasesFromTestSuite(testSuiteId int, testCaseIds []int) (*BulkResponse, *CliError) {
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "removeTestCase"), !svc.jsonOutput).Start()
- log.Debugf("Removing test cases [%d] from the test suite id [%d]\n", testCaseIds, testSuiteId)
-
- removeTestCaseResponse, err := svc.api.RemoveTestCasesFromTestSuite(testSuiteId, testCaseIds)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
-
- if len(removeTestCaseResponse.Failures) != 0 {
- spinner.StopWithFailure()
- return nil, CliErrorFromPulsarProblemObject(nil, removeTestCaseResponse.Failures, 207, ApiErrorRemoveTestCasesPostCall)
- }
-
- spinner.StopWithSuccess()
- return removeTestCaseResponse, nil
-}
-
-func (svc Service) GetTestSuiteOrTestSuiteDetailsWithChildObjects(id, name string) ([]TestSuiteV3, TestSuiteV3) {
-
- var testSuiteDetailsWithChildObjects = TestSuiteV3{}
- if name != "" {
- testSuites := svc.GetTestSuitesByIdOrName(id, name, Empty, false, false, true)
- if len(testSuites) > 1 {
- return testSuites, testSuiteDetailsWithChildObjects
- }
- testSuiteDetailsWithChildObjects = svc.GetTestSuiteWithChildObjects(testSuites[0].TestSuiteId)
- } else {
- testSuiteId, _ := strconv.Atoi(id)
- testSuiteDetailsWithChildObjects = svc.GetTestSuiteWithChildObjects(testSuiteId)
- }
- return nil, testSuiteDetailsWithChildObjects
-}
-
-func (svc Service) ViewTestSuite(id string, name string, groupBy string) {
-
- var testSuites = []TestSuiteV3{}
- var testSuiteDetailsWithChildObjects = TestSuiteV3{}
- areAllTestCasesIncluded := false
- testSuites, testSuiteDetailsWithChildObjects = svc.GetTestSuiteOrTestSuiteDetailsWithChildObjects(id, name)
-
- if len(testSuites) > 1 {
- if svc.jsonOutput {
- PrintJsonAndExit(testSuites)
- }
- PrintViewTestSuite(svc.cmd, testSuites, name)
- } else {
- if svc.jsonOutput {
- PrintJsonAndExit(testSuiteDetailsWithChildObjects)
- } else {
- PrintViewTestSuite(svc.cmd, []TestSuiteV3{TestSuiteV3(testSuiteDetailsWithChildObjects)}, name)
- if testSuiteDetailsWithChildObjects.ExecutableTestCaseCount == len(testSuiteDetailsWithChildObjects.TestCases) {
- areAllTestCasesIncluded = true
- }
- PrintTestCases(svc.cmd, testSuiteDetailsWithChildObjects.TestCases, areAllTestCasesIncluded, groupBy)
- }
- }
-}
-
-func (svc Service) RemoveTestSuiteByIdOrName(id string, name string) {
-
- testSuites := svc.GetTestSuitesByIdOrName(id, name, Empty, false, false, true)
-
- if len(testSuites) == 1 {
- testSuiteId := strconv.Itoa(testSuites[0].TestSuiteId)
- svc.RemoveTestSuiteById(testSuiteId)
- if !svc.jsonOutput {
- PrintSuccess("\n" + GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "removeTSSuccess"))
- PrintSuccessInBold(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "removeTSSuccessInBold"), testSuiteId)
- PrintSuccess(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "removeTSSuccessEnd") + "\n")
- PrintTestSuiteForRemovedTestSuite(testSuites[0])
- }
- } else {
- if svc.jsonOutput {
- PrintJsonAndExit(testSuites)
- }
- PrintViewTestSuite(svc.cmd, testSuites, name)
- }
-
-}
-
-func (svc Service) RestoreTestSuiteByIdOrName(id string, name string) {
-
- testSuites := svc.GetTestSuitesByIdOrName(id, name, Empty, false, false, true)
- if len(testSuites) == 1 {
- testSuiteId := strconv.Itoa(testSuites[0].TestSuiteId)
- testSuite := svc.RestoreTestSuiteById(testSuiteId)
- if svc.jsonOutput {
- PrintJsonAndExit(testSuite)
- }
- PrintSuccess("\n" + GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "restoreTSSuccess") + "\n")
- PrintTestSuiteForRemovedTestSuite(testSuites[0])
- } else {
- if svc.jsonOutput {
- PrintJsonAndExit(testSuites)
- }
- PrintViewTestSuite(svc.cmd, testSuites, name)
- }
-}
-
-func (svc Service) AddTestCaseWithTestSuite(testSuites []TestSuiteV3, searchedName, url, condition, ipVersion string, addHeader, modifyHeader, filterHeader []string) {
-
- if len(testSuites) == 1 {
- testCases, err := svc.AddTestCaseToTestSuite(testSuites[0].TestSuiteId, url, condition, ipVersion, addHeader, modifyHeader, filterHeader)
-
- if testCases != nil {
- if svc.jsonOutput {
- PrintJsonAndExit(testCases)
- }
-
- PrintSuccess(fmt.Sprintf(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "addTestCaseSuccess")+"\n\n", testSuites[0].TestSuiteName))
- } else {
- PrintError(fmt.Sprintf(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "addTestCaseFail")+"\n\n", testSuites[0].TestSuiteName))
- AbortForCommand(svc.cmd, err)
- }
- } else {
- PrintError(fmt.Sprintf(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "addTestCaseNoTestSuite")+"\n\n", searchedName))
- }
-}
-
-func (svc Service) RemoveTestCaseFromTestSuiteUsingOrderNumber(testSuite *TestSuiteV3, testCases []TestCase, orderNumber string) {
-
- if testSuite != nil {
-
- orderNum, _ := strconv.Atoi(orderNumber)
- testCase := filterTestCaseUsingOrderNumber(testCases, orderNum)
-
- if testCase != nil {
- removeTestCaseResponse, err := svc.RemoveTestCasesFromTestSuite(testSuite.TestSuiteId, []int{testCase.TestCaseId})
- if err != nil {
- PrintError(fmt.Sprintf(GetMessageForKey(svc.cmd, "failed")+"\n\n", testSuite.TestSuiteName))
- AbortForCommand(svc.cmd, err)
- } else {
- if svc.jsonOutput {
- PrintJsonAndExit(removeTestCaseResponse)
- }
-
- PrintSuccess(fmt.Sprintf(GetMessageForKey(svc.cmd, "success")+"\n\n", testSuite.TestSuiteName))
- }
- } else {
- PrintError(fmt.Sprintf(GetMessageForKey(svc.cmd, "notPresent")+"\n\n", orderNumber))
- }
- }
-}
-
-func (svc Service) RunTest(runTestUsing, testSuiteId, testSuiteName, propertyName, propVersion,
- url, condition, ipVersion, targetEnvironment string, addHeader, modifyHeader, filterHeader []string,
- testRunRequestFromJson TestRun) {
-
- targetEnvironment = strings.ToUpper(targetEnvironment)
- var testRun *TestRun
-
- switch runTestUsing {
- case RunTestUsingTestSuiteId:
- testSuiteId, _ := strconv.Atoi(testSuiteId)
- testRun = svc.runTestSuiteWithId(testSuiteId, targetEnvironment, runTestUsing)
- case RunTestUsingTestSuiteName:
- testRun = svc.findAndRunTestSuite(testSuiteName, targetEnvironment, runTestUsing)
- case RunTestUsingPropertyVersion:
- testRun = svc.runPropertyVersion(propertyName, propVersion, targetEnvironment, runTestUsing)
- case RunTestUsingSingleTestCase:
- testRun = svc.runTestCase(url, condition, ipVersion, addHeader, modifyHeader, filterHeader, targetEnvironment, runTestUsing)
- case RunTestUsingJsonInput:
- testRun = svc.startTestRun(testRunRequestFromJson, runTestUsing)
- }
-
- // Wait for test run results
- testResult, err := svc.waitForTestRunCompletion(testRun.TestRunId, runTestUsing)
- if err != nil {
- AbortForCommandWithSubResource(svc.cmd, err, TestRunResource, Read)
- }
-
- // Print test run result
- PrintTestResult(svc.cmd, testResult)
-
-}
-
-func (svc Service) findAndRunTestSuite(testSuiteName, targetEnvironment string, runTestUsing string) *TestRun {
- testSuite := svc.GetSingleTestSuiteByIdOrName("", testSuiteName, TestSuiteResource, false)
- if testSuite == nil {
- AbortWithExitCode(fmt.Sprintf(GetMessageForKey(svc.cmd, "testSuiteNameNotFound")+"\n", testSuiteName), ExitStatusCode0)
- }
-
- return svc.runTestSuiteWithId(testSuite.TestSuiteId, targetEnvironment, runTestUsing)
-}
-
-func (svc Service) runTestSuiteWithId(testSuiteId int, environment string, runTestUsing string) *TestRun {
-
- testRun := TestRun{
- SendEmailOnCompletion: false,
- TargetEnvironment: environment,
- Functional: FunctionalTestRun{
- TestSuiteExecutionsV3: []TestSuiteExecutionV3{
- {
- TestSuiteId: testSuiteId,
- },
- },
- },
- }
-
- return svc.startTestRun(testRun, runTestUsing)
-}
-
-func (svc Service) runPropertyVersion(propertyName, propVersion, environment string, runTestUsing string) *TestRun {
- propertyVersion, _ := strconv.Atoi(propVersion)
- testRun := TestRun{
- SendEmailOnCompletion: false,
- TargetEnvironment: environment,
- Functional: FunctionalTestRun{
- PropertyManagerExecution: PropertyManagerExecution{
- PropertyName: propertyName,
- PropertyVersion: propertyVersion,
- },
- },
- }
-
- return svc.startTestRun(testRun, runTestUsing)
-}
-
-func (svc Service) runTestCase(url, condition, ipVersion string, addHeader, modifyHeader,
- filterHeader []string, targetEnvironment string, runTestUsing string) *TestRun {
-
- var clientProfile = ClientProfile{IpVersion: Ipv4, Client: Chrome}
- if strings.ToUpper(ipVersion) == "V6" {
- clientProfile = ClientProfile{IpVersion: Ipv6, Client: Chrome}
- }
-
- testRun := TestRun{
- SendEmailOnCompletion: false,
- TargetEnvironment: targetEnvironment,
- Functional: FunctionalTestRun{
- TestCaseExecution: TestCaseExecution{
- TestRequest: TestRequest{
- TestRequestUrl: url,
- RequestMethod: Get,
- RequestHeaders: getRequestHeaders(addHeader, modifyHeader, filterHeader),
- },
- Condition: Condition{
- ConditionExpression: strings.TrimSpace(condition),
- },
- ClientProfile: clientProfile,
- },
- },
- }
-
- return svc.startTestRun(testRun, runTestUsing)
-}
-
-func (svc Service) startTestRun(testRun TestRun, runTestUsing string) *TestRun {
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeTestCmdSpinner, runTestUsing, "startTestRun"), !svc.jsonOutput).Start()
- createdTestRun, err := svc.api.SubmitTestRun(testRun)
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommandWithSubResource(svc.cmd, err, TestRunResource, Create)
- return nil
- }
-
- spinner.StopWithSuccess()
-
- if svc.jsonOutput {
- PrintJsonAndExit(createdTestRun)
- }
-
- PrintSuccess(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "testRunStart") + "\n\n")
- return createdTestRun
-}
-
-func (svc Service) waitForTestRunCompletion(testRunId int, runTestUsing string) (*TestRun, *CliError) {
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeTestCmdSpinner, runTestUsing, "runTests"), !svc.jsonOutput).Start()
- ticker := time.NewTicker(15 * time.Second)
- failureCount := 0
-
- for range ticker.C {
- log.Debugln("Polling test run status...")
- testRun, err := svc.api.GetTestRun(testRunId)
- if err != nil {
- failureCount++
- if failureCount > 3 {
- spinner.StopWithFailure()
- return nil, err
- }
- continue
- }
-
- // Reset failure count on success, so we only stop when 3 successive tries fail
- failureCount = 0
-
- if testRun != nil && testRun.Status != InProgress {
- spinner.StopWithSuccess()
- ticker.Stop()
-
- return testRun, nil
- }
- }
-
- return nil, CliErrorWithMessage(CliErrorMessageTestRunStatus)
-}
-
-func constructTestCase(url string, addHeader, modifyHeader, filterHeader []string, condition, ipVersion string) TestCase {
- var (
- testCase TestCase
- testRequest TestRequest
- conditionObject Condition
- clientProfileId int
- clientProfile ClientProfile
- )
-
- testRequest = TestRequest{
- TestRequestUrl: url,
- RequestMethod: Get,
- RequestHeaders: getRequestHeaders(addHeader, modifyHeader, filterHeader),
- }
-
- conditionObject = Condition{
- ConditionExpression: strings.TrimSpace(condition),
- }
-
- clientProfileId = 2 // Use default IPv4
- clientProfile = ClientProfile{IpVersion: Ipv4, Client: Chrome}
- if strings.ToUpper(ipVersion) == "V6" {
- clientProfileId = 1
- clientProfile = ClientProfile{IpVersion: Ipv6, Client: Chrome}
- }
-
- testCase = TestCase{
- TestRequest: testRequest,
- Condition: conditionObject,
- ClientProfileId: clientProfileId,
- ClientProfile: clientProfile,
- }
-
- return testCase
-}
-
-func filterTestCaseUsingOrderNumber(testCases []TestCase, orderNumber int) *TestCase {
-
- for _, testCase := range testCases {
- if testCase.Order == orderNumber {
- return &testCase
- }
- }
-
- return nil
-}
-
-func updateModifiedTestSuiteFields(testSuiteV3 TestSuiteV3, name, description, propertyName string, propVersion int, unlocked, stateful, removeProperty bool, locked bool, stateless bool) (*TestSuiteV3, bool) {
-
- var isChanged = false
- if name != "" && testSuiteV3.TestSuiteName != name {
- testSuiteV3.TestSuiteName = name
- isChanged = true
- }
-
- if description != "" && testSuiteV3.TestSuiteDescription != description {
- testSuiteV3.TestSuiteDescription = description
- isChanged = true
- }
-
- if locked || unlocked {
- if locked {
- testSuiteV3.IsLocked = locked
- } else {
- testSuiteV3.IsLocked = !unlocked
- }
- isChanged = true
- }
-
- if stateful || stateless {
- if stateful {
- testSuiteV3.IsStateful = stateful
- } else {
- testSuiteV3.IsStateful = !stateless
- }
- isChanged = true
- }
-
- if testSuiteV3.Configs.PropertyManager.PropertyName != "" && removeProperty {
- testSuiteV3.Configs = AkamaiConfigs{}
- isChanged = true
- }
-
- if propertyName != Empty && (testSuiteV3.Configs.PropertyManager.PropertyName != propertyName ||
- testSuiteV3.Configs.PropertyManager.PropertyVersion != propVersion) {
-
- testSuiteV3.Configs.PropertyManager.PropertyName = propertyName
- testSuiteV3.Configs.PropertyManager.PropertyVersion = propVersion
- isChanged = true
- }
-
- return &testSuiteV3, isChanged
-}
-
-// Returns testSuites containing searchString in either name or description
-func filterTestSuitesByString(searchString string, exactMatch, shouldMatchDescription bool, testSuites []TestSuiteV3) []TestSuiteV3 {
- var filteredItems []TestSuiteV3
-
- for _, testSuite := range testSuites {
- if exactMatch {
- if strings.EqualFold(testSuite.TestSuiteName, searchString) ||
- (shouldMatchDescription && strings.EqualFold(testSuite.TestSuiteDescription, searchString)) {
- filteredItems = append(filteredItems, testSuite)
- }
- } else {
- if ContainsIgnoreCase(testSuite.TestSuiteName, searchString) ||
- (shouldMatchDescription && ContainsIgnoreCase(testSuite.TestSuiteDescription, searchString)) {
- filteredItems = append(filteredItems, testSuite)
- }
- }
- }
-
- return filteredItems
-}
-
-func getRequestHeaders(headerAdd []string, headerModify []string, headerFilter []string) []RequestHeader {
- var requestHeaders []RequestHeader
-
- for _, header := range headerAdd {
- headerComponents := strings.Split(header, ":")
- requestHeaders = append(requestHeaders, RequestHeader{
- HeaderName: strings.TrimSpace(headerComponents[0]),
- HeaderValue: strings.TrimSpace(headerComponents[1]),
- HeaderAction: Add,
- })
- }
-
- for _, header := range headerModify {
- headerComponents := strings.Split(header, ":")
- requestHeaders = append(requestHeaders, RequestHeader{
- HeaderName: strings.TrimSpace(headerComponents[0]),
- HeaderValue: strings.TrimSpace(headerComponents[1]),
- HeaderAction: Modify,
- })
- }
-
- for _, header := range headerFilter {
- requestHeaders = append(requestHeaders, RequestHeader{
- HeaderName: strings.TrimSpace(header),
- HeaderAction: Filter,
- })
- }
-
- return requestHeaders
-}
-
-func (svc Service) GetConditionTemplate() *ConditionTemplate {
-
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "getConditionTemplate"), !svc.jsonOutput).Start()
- condTemplate, err := svc.api.GetConditionTemplate()
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
- spinner.StopWithSuccess()
-
- if svc.jsonOutput {
- PrintJsonAndExit(condTemplate)
- }
-
- return condTemplate
-}
-
-func (svc Service) GenerateTestSuite(propertyName string, propVersion int, urls []string,
- defaultTestSuiteRequest DefaultTestSuiteRequest, isJsonInputPresent bool) {
- spinner := NewSpinner(GetServiceMessage(svc.cmd, MessageTypeSpinner, "", "generateDefaultTestSuite"), !svc.jsonOutput).Start()
-
- defaultTsReq := DefaultTestSuiteRequest{}
-
- // form request
- if isJsonInputPresent {
- defaultTsReq = defaultTestSuiteRequest
- } else {
- defaultTsReq = DefaultTestSuiteRequest{
- TestRequestUrl: urls,
- Configs: AkamaiConfigs{
- PropertyManager: PropertyManager{
- PropertyName: propertyName,
- PropertyVersion: propVersion,
- }},
- }
- }
-
- // get default ts
- generatedTs, err := svc.api.GenerateTestSuite(defaultTsReq)
-
- if err != nil {
- spinner.StopWithFailure()
- AbortForCommand(svc.cmd, err)
- }
- spinner.StopWithSuccess()
-
- // print output
- if !svc.jsonOutput {
- PrintSuccess(fmt.Sprintf(GetServiceMessage(svc.cmd, MessageTypeDisplay, "", "generateDefaultTSSuccess")+"\n\n", propertyName, propVersion))
- }
- PrintJsonAndExit(generatedTs)
-}
-
-// setClientAndRequestMethod set Client and RequestMethod to defaults
-func (svc Service) setClientAndRequestMethod(testSuiteV3 *TestSuiteV3) {
- if testSuiteV3 != nil && len(testSuiteV3.TestCases) > 0 {
- var updatedTestCases []TestCase
- for _, tc := range testSuiteV3.TestCases {
- tc.TestRequest.RequestMethod = Get
- tc.ClientProfile.Client = Chrome
- updatedTestCases = append(updatedTestCases, tc)
- }
- testSuiteV3.TestCases = updatedTestCases
- }
-}
diff --git a/internal/service/condition_service.go b/internal/service/condition_service.go
new file mode 100644
index 0000000..d62157b
--- /dev/null
+++ b/internal/service/condition_service.go
@@ -0,0 +1,55 @@
+package service
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/print"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/spf13/cobra"
+)
+
+func (svc Service) GetConditionTemplateAndPrintResult(cmd *cobra.Command) {
+ condTemplate := svc.GetConditionTemplate()
+ print.PrintConditionsTemplate(cmd, *condTemplate)
+}
+
+func (svc Service) GetConditionTemplate() *model.ConditionTemplate {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner,
+ internalconstant.Empty, internalconstant.GetConditionTemplate), !svc.jsonOutput).Start()
+ condTemplate, err := svc.api.GetConditionTemplate()
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(condTemplate)
+ }
+
+ return condTemplate
+}
+
+func (svc Service) GetConditionListAndPrintResult(cmd *cobra.Command) {
+ condList := svc.GetConditionList()
+ print.PrintConditions(cmd, condList)
+}
+
+func (svc Service) GetConditionList() []model.Condition {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty,
+ internalconstant.GetConditions), !svc.jsonOutput).Start()
+ conditions, err := svc.api.GetConditionsV3()
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(conditions)
+ }
+ return conditions
+
+}
diff --git a/internal/service/test_case_service.go b/internal/service/test_case_service.go
new file mode 100644
index 0000000..e47e21e
--- /dev/null
+++ b/internal/service/test_case_service.go
@@ -0,0 +1,282 @@
+package service
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/print"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ log "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+ "strconv"
+ "strings"
+)
+
+func (svc Service) AddTestCaseWithTestSuite(cmd *cobra.Command, testSuiteIdStr, testSuiteName, url, condition, ipVersion string, addHeader, modifyHeader, filterHeader []string, testCaseId, client, requestMethod, requestBody string, encodeRequestBody bool, setVariables []string) {
+
+ testSuites := svc.GetTestSuitesByIdOrName(testSuiteIdStr, testSuiteName, internalconstant.Empty, true, false, true)
+
+ if len(testSuites) == 1 {
+ testCases, err := svc.ConstructRequestAndPrintResponseForAddTestCase(testSuites[0].TestSuiteId, url, condition, ipVersion, addHeader, modifyHeader, filterHeader, testCaseId, client, requestMethod, requestBody, encodeRequestBody, setVariables)
+ if testCases != nil {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testCases)
+ }
+ util.PrintSuccess(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.AddTestCaseSuccess)+"\n\n", testSuites[0].TestSuiteName))
+ if len(testCases.Successes[0].Warnings) != 0 {
+ util.PrintWarnings(util.GetApiSubErrorMessagesForCommand(cmd, testCases.Successes[0].Warnings, internalconstant.Empty, internalconstant.Warnings, internalconstant.Empty))
+ }
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.AddTestCaseFail)+"\n\n", testSuites[0].TestSuiteName))
+ util.AbortForCommand(svc.cmd, err)
+ }
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.AddTestCaseNoTestSuite)+"\n\n", testSuiteName))
+ }
+}
+
+func (svc Service) EditTestCaseWithTestSuite(cmd *cobra.Command, testSuiteIdStr, testSuiteName, url, condition, ipVersion string, addHeader, modifyHeader, filterHeader []string, testCaseId, client, requestMethod, requestBody string, encodeRequestBody bool, setVariables []string) {
+
+ testSuites := svc.GetTestSuitesByIdOrName(testSuiteIdStr, testSuiteName, internalconstant.Empty, true, false, true)
+
+ if len(testSuites) == 1 {
+ testCases, err := svc.ConstructRequestAndPrintResponseForEditTestCase(testSuites[0].TestSuiteId, url, condition, ipVersion, addHeader, modifyHeader, filterHeader, testCaseId, client, requestMethod, requestBody, encodeRequestBody, setVariables)
+ if testCases != nil {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testCases)
+ }
+ util.PrintSuccess(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.UpdateTestCaseSuccess)+"\n\n", testSuites[0].TestSuiteName))
+ if len(testCases.Successes[0].Warnings) != 0 {
+ util.PrintWarnings(util.GetApiSubErrorMessagesForCommand(cmd, testCases.Successes[0].Warnings, internalconstant.Empty, internalconstant.Warnings, internalconstant.Empty))
+ }
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.UpdateTestCaseFail)+"\n\n", testSuites[0].TestSuiteName))
+ util.AbortForCommand(svc.cmd, err)
+ }
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.UpdateTestCaseNoTestSuite)+"\n\n", testSuiteName))
+ }
+}
+
+func (svc Service) ConstructRequestAndPrintResponseForAddTestCase(testSuiteId int, url, condition, ipVersion string, addHeader, modifyHeader, filterHeader []string, testCaseId, client, requestMethod, requestBody string, encodeRequestBody bool, setVariables []string) (*model.TestCaseBulkResponse, *model.CliError) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.AddTestCase), !svc.jsonOutput).Start()
+
+ var testCase = constructTestCase(url, addHeader, modifyHeader, filterHeader, condition, ipVersion, testCaseId, client, requestMethod, requestBody, encodeRequestBody, setVariables)
+ log.Debugf("Add test case [%+v] with the test suite id [%d]\n", testCase, testSuiteId)
+
+ testCases, err := svc.api.AddTestCaseToTestSuite(testSuiteId, []model.TestCase{testCase})
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ if len(testCases.Failures) != 0 {
+ spinner.StopWithFailure()
+ return nil, model.CliErrorFromPulsarProblemObject(nil, testCases.Failures, 207, externalconstant.ApiErrorAddTestCasesToTestSuitPostCall)
+ }
+
+ spinner.StopWithSuccess()
+ return testCases, nil
+}
+
+func (svc Service) ConstructRequestAndPrintResponseForEditTestCase(testSuiteId int, url, condition, ipVersion string, addHeader, modifyHeader, filterHeader []string, testCaseId, client, requestMethod, requestBody string, encodeRequestBody bool, setVariables []string) (*model.TestCaseBulkResponse, *model.CliError) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.UpdateTestCase), !svc.jsonOutput).Start()
+
+ var testCase = constructTestCase(url, addHeader, modifyHeader, filterHeader, condition, ipVersion, testCaseId, client, requestMethod, requestBody, encodeRequestBody, setVariables)
+ log.Debugf("Update test case [%+v] with the test suite id [%d]\n", testCase, testSuiteId)
+
+ testCases, err := svc.api.EditTestCaseToTestSuite(testSuiteId, []model.TestCase{testCase})
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ if len(testCases.Failures) != 0 {
+ spinner.StopWithFailure()
+ return nil, model.CliErrorFromPulsarProblemObject(nil, testCases.Failures, 207, externalconstant.ApiErrorAddTestCasesToTestSuitPostCall)
+ }
+
+ spinner.StopWithSuccess()
+ return testCases, nil
+}
+
+func constructTestCase(url string, addHeader, modifyHeader, filterHeader []string, condition, ipVersion, testCaseId, client, requestMethod, requestBody string, encodeRequestBody bool, dynamicVariables []string) model.TestCase {
+ var (
+ testCase model.TestCase
+ testRequest model.TestRequest
+ conditionObject model.Condition
+ clientProfileId int
+ clientProfile model.ClientProfile
+ )
+
+ testRequest = model.TestRequest{
+ TestRequestUrl: url,
+ RequestMethod: requestMethod,
+ RequestHeaders: getRequestHeaders(addHeader, modifyHeader, filterHeader),
+ RequestBody: requestBody,
+ EncodeRequestBody: &encodeRequestBody,
+ }
+
+ conditionObject = model.Condition{
+ ConditionExpression: strings.TrimSpace(condition),
+ }
+
+ // Use default IPv4
+ clientProfile = model.ClientProfile{IpVersion: internalconstant.Ipv4, Client: client}
+ if strings.ToUpper(ipVersion) == "V6" {
+ clientProfile = model.ClientProfile{IpVersion: internalconstant.Ipv6, Client: client}
+ }
+ testCase = model.TestCase{
+ TestRequest: testRequest,
+ Condition: conditionObject,
+ ClientProfileId: clientProfileId,
+ ClientProfile: clientProfile,
+ SetVariables: getSetVariables(dynamicVariables),
+ }
+
+ // test case id should be present for update test case request body.
+ if testCaseId != internalconstant.Empty {
+ tcId, _ := strconv.Atoi(testCaseId)
+ testCase.TestCaseId = tcId
+ }
+
+ return testCase
+}
+
+func (svc Service) GetTestCaseByIdToTestSuite(cmd *cobra.Command, testSuiteIdStr, testSuiteName string, testCaseId string, resolveVariables bool) {
+
+ testSuites := svc.GetTestSuitesByIdOrName(testSuiteIdStr, testSuiteName, internalconstant.Empty, true, false, true)
+
+ if len(testSuites) == 1 {
+ tcId, _ := strconv.Atoi(testCaseId)
+ testCase, err := svc.GetTestCaseById(testSuites, tcId, resolveVariables)
+ if testCase != nil {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testCase)
+ }
+ fmt.Println()
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, "testCaseHeader") + "\n")
+ print.PrintTestCaseDetails(cmd, []model.TestCase{*testCase}, false, internalconstant.Empty, 0)
+ fmt.Println()
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, "getTestCaseFail")+"\n\n", testSuites[0].TestSuiteName))
+ util.AbortForCommand(svc.cmd, err)
+ }
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, "getTestCaseNoTestSuite")+"\n\n", testSuiteName))
+ }
+
+}
+
+func (svc Service) GetTestCaseById(testSuites []model.TestSuite, testCaseId int, resolveVariables bool) (*model.TestCase, *model.CliError) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, "getTestCase"), !svc.jsonOutput).Start()
+
+ testCase, err := svc.api.GetTestCaseById(testCaseId, testSuites[0].TestSuiteId, resolveVariables)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+ return testCase, nil
+}
+
+func (svc Service) GetTestCasesWithTestSuite(testSuiteIdStr, testSuiteName, groupBy string, resolveVariables bool) {
+
+ testSuites := svc.GetTestSuitesByIdOrName(testSuiteIdStr, testSuiteName, internalconstant.Empty, true, false, true)
+
+ if len(testSuites) == 1 {
+ associatedTestCases, err := svc.GetTestCasesToTestSuite(testSuites[0].TestSuiteId, resolveVariables)
+
+ if associatedTestCases != nil {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(associatedTestCases)
+ }
+ print.PrintTestCases(svc.cmd, associatedTestCases.TestCases, associatedTestCases.AreAllTestCasesIncluded, groupBy)
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, "getTestCaseFail")+"\n\n", testSuites[0].TestSuiteName))
+ util.AbortForCommand(svc.cmd, err)
+ }
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, "getTestCaseNoTestSuite")+"\n\n", testSuiteName))
+ }
+}
+
+func (svc Service) GetTestCasesToTestSuite(testSuiteId int, resolveVariables bool) (*model.AssociatedTestCases, *model.CliError) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetTestCase), !svc.jsonOutput).Start()
+
+ log.Debugf("Get test cases for the test suite id [%d]\n", testSuiteId)
+
+ associatedTestCases, err := svc.api.GetV3AssociatedTestCasesForTestSuite(testSuiteId, resolveVariables)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+ fmt.Println()
+ return associatedTestCases, nil
+}
+
+func (svc Service) RemoveTestCaseFromTestSuiteUsingOrderNumberOrTestCaseId(testSuiteIdStr, orderNumber, testCaseIdStr string) {
+
+ testSuiteId, _ := strconv.Atoi(testSuiteIdStr)
+ testSuite := svc.GetSingleTestSuiteByIdOrName(testSuiteIdStr, internalconstant.Empty, internalconstant.Empty, true)
+
+ if testSuite != nil {
+
+ testCases, _ := svc.GetV3AssociatedTestCasesForTestSuite(testSuiteId)
+
+ testCase := svc.filterTestCaseUsingOrderNumberOrTestCaseId(testCases, orderNumber, testCaseIdStr)
+
+ if testCase != nil {
+ removeTestCaseResponse, err := svc.RemoveTestCasesFromTestSuite(testSuite.TestSuiteId, []int{testCase.TestCaseId})
+ if err != nil {
+ util.PrintError(fmt.Sprintf(util.GetMessageForKey(svc.cmd, internalconstant.FailedKey)+"\n\n", testSuite.TestSuiteName))
+ util.AbortForCommand(svc.cmd, err)
+ } else {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(removeTestCaseResponse)
+ }
+
+ util.PrintSuccess(fmt.Sprintf(util.GetMessageForKey(svc.cmd, "success")+"\n\n", testSuite.TestSuiteName))
+ }
+ } else {
+ util.PrintError(fmt.Sprintf(util.GetMessageForKey(svc.cmd, "notPresent")+"\n\n", orderNumber))
+ }
+ }
+}
+
+func (svc Service) GetV3AssociatedTestCasesForTestSuite(testSuiteId int) ([]model.TestCase, bool) {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, "getTestCases"), !svc.jsonOutput).Start()
+ associatedTestCases, err := svc.api.GetV3AssociatedTestCasesForTestSuite(testSuiteId, false)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.Empty, internalconstant.Read)
+ }
+
+ spinner.StopWithSuccess()
+ return associatedTestCases.TestCases, associatedTestCases.AreAllTestCasesIncluded
+}
+
+func (svc Service) filterTestCaseUsingOrderNumberOrTestCaseId(testCases []model.TestCase, orderNumber, testCaseId string) *model.TestCase {
+
+ if orderNumber != internalconstant.Empty {
+ orderNum, _ := strconv.Atoi(orderNumber)
+ for _, testCase := range testCases {
+ if testCase.Order == orderNum {
+ return &testCase
+ }
+ }
+ }
+ tcId, _ := strconv.Atoi(testCaseId)
+ for _, testCase := range testCases {
+ if testCase.TestCaseId == tcId {
+ return &testCase
+ }
+ }
+ return nil
+}
diff --git a/internal/service/test_center_functions_service.go b/internal/service/test_center_functions_service.go
new file mode 100644
index 0000000..e1c5338
--- /dev/null
+++ b/internal/service/test_center_functions_service.go
@@ -0,0 +1,25 @@
+package service
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/print"
+ "github.com/akamai/cli-test-center/internal/util"
+)
+
+func (svc Service) EvaluateFunction(tryFunction *model.TryFunction) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetFunctionResult), !svc.jsonOutput).Start()
+ tryFunctionResponse, err := svc.api.EvaluateFunction(tryFunction)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+ fmt.Println()
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(tryFunctionResponse)
+ }
+ print.PrintTryFunctionResponse(tryFunctionResponse)
+}
diff --git a/internal/service/test_request_service.go b/internal/service/test_request_service.go
new file mode 100644
index 0000000..a5109d8
--- /dev/null
+++ b/internal/service/test_request_service.go
@@ -0,0 +1,33 @@
+package service
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/print"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/spf13/cobra"
+)
+
+func (svc Service) GetTestRequestAndPrintResult(cmd *cobra.Command) {
+ testReqList := svc.GetTestRequests()
+ print.PrintTestRequests(cmd, testReqList)
+}
+
+func (svc Service) GetTestRequests() []model.TestRequest {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner,
+ internalconstant.Empty, internalconstant.GetTestRequests), !svc.jsonOutput).Start()
+
+ testRequests, err := svc.api.GetTestRequestsV3()
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testRequests)
+ }
+ return testRequests
+
+}
diff --git a/internal/service/test_run_service.go b/internal/service/test_run_service.go
new file mode 100644
index 0000000..e08c689
--- /dev/null
+++ b/internal/service/test_run_service.go
@@ -0,0 +1,281 @@
+package service
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/print"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ log "github.com/sirupsen/logrus"
+ "strconv"
+ "strings"
+ "time"
+)
+
+func (svc Service) GetTestRunsAndPrint() {
+ testRuns := svc.GetTestRuns()
+ print.FormatAndPrintTestRunsTable(svc.cmd, testRuns)
+}
+
+func (svc Service) GetTestRuns() []model.TestRun {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetTestRuns), !svc.jsonOutput).Start()
+ testRuns, err := svc.api.GetTestRuns()
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testRuns)
+ }
+
+ return testRuns
+}
+
+func (svc Service) GetTestRunAndPrintResult(testRunId string) {
+
+ testRunResult := svc.GetTestRun(testRunId)
+ // Print test run result
+ print.FormatAndPrintTestResult(svc.cmd, testRunResult)
+}
+
+func (svc Service) GetTestRun(testRunId string) *model.TestRun {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetTestRun), !svc.jsonOutput).Start()
+ id, _ := strconv.Atoi(testRunId)
+ testRun, err := svc.api.GetTestRun(id)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testRun)
+ }
+
+ return testRun
+}
+
+func (svc Service) RunTest(runTestUsing, testSuiteId, testSuiteName, propertyIdStr, propertyName, propVersion, url, condition, ipVersion,
+ targetEnvironment, client, location, method, requestBody string, addHeader, modifyHeader, filterHeader []string,
+ testRunRequestFromJson model.TestRun, encodeRequestBody bool) {
+
+ targetEnvironment = strings.ToUpper(targetEnvironment)
+ var testRun *model.TestRun
+
+ switch runTestUsing {
+ case internalconstant.RunTestUsingTestSuiteId:
+ testSuiteId, _ := strconv.Atoi(testSuiteId)
+ testRun = svc.runTestSuiteWithId(testSuiteId, targetEnvironment, runTestUsing)
+ case internalconstant.RunTestUsingTestSuiteName:
+ testRun = svc.findAndRunTestSuite(testSuiteName, targetEnvironment, runTestUsing)
+ case internalconstant.RunTestUsingPropertyVersion:
+ testRun = svc.runPropertyVersion(propertyIdStr, propertyName, propVersion, targetEnvironment, runTestUsing)
+ case internalconstant.RunTestUsingSingleTestCase:
+ testRun = svc.runTestCase(url, condition, ipVersion, addHeader, modifyHeader, filterHeader, targetEnvironment, runTestUsing,
+ client, location, method, requestBody, encodeRequestBody)
+ case internalconstant.RunTestUsingJsonInput:
+ testRun = svc.startTestRun(testRunRequestFromJson, runTestUsing)
+ }
+
+ // Wait for test run results
+ testResult, err := svc.waitForTestRunCompletion(testRun.TestRunId, runTestUsing)
+ if err != nil {
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.TestRunResource, internalconstant.Read)
+ }
+
+ // Print test run result
+ print.FormatAndPrintTestResult(svc.cmd, testResult)
+
+}
+
+func (svc Service) findAndRunTestSuite(testSuiteName, targetEnvironment string, runTestUsing string) *model.TestRun {
+ testSuite := svc.GetSingleTestSuiteByIdOrName(internalconstant.Empty, testSuiteName, internalconstant.TestSuiteResource, false)
+ if testSuite == nil {
+ util.AbortWithExitCode(fmt.Sprintf(util.GetMessageForKey(svc.cmd, internalconstant.TestSuiteNameNotFound)+"\n", testSuiteName), internalconstant.ExitStatusCode0)
+ }
+
+ return svc.runTestSuiteWithId(testSuite.TestSuiteId, targetEnvironment, runTestUsing)
+}
+
+func (svc Service) runTestSuiteWithId(testSuiteId int, environment string, runTestUsing string) *model.TestRun {
+
+ testRun := model.TestRun{
+ SendEmailOnCompletion: false,
+ TargetEnvironment: environment,
+ Functional: model.FunctionalTestRun{
+ TestSuiteExecutions: []model.TestSuiteExecutions{
+ {
+ TestSuiteId: testSuiteId,
+ },
+ },
+ },
+ }
+
+ return svc.startTestRun(testRun, runTestUsing)
+}
+
+func (svc Service) runPropertyVersion(propertyIdStr, propertyName, propVersion, environment string, runTestUsing string) *model.TestRun {
+ testRun := model.TestRun{
+ SendEmailOnCompletion: false,
+ TargetEnvironment: environment,
+ Functional: model.FunctionalTestRun{
+ PropertyManagerExecution: model.PropertyManagerExecution{
+ PropertyId: util.GetConvertedInteger(propertyIdStr),
+ PropertyName: propertyName,
+ PropertyVersion: util.GetConvertedInteger(propVersion),
+ },
+ },
+ }
+
+ return svc.startTestRun(testRun, runTestUsing)
+}
+
+func (svc Service) runTestCase(url, condition, ipVersion string, addHeader, modifyHeader, filterHeader []string, targetEnvironment,
+ runTestUsing, client, location, method, requestBody string, encodeRequestBody bool) *model.TestRun {
+
+ var clientProfile = model.ClientProfile{IpVersion: internalconstant.Ipv4, Client: client, GeoLocation: location}
+ if strings.ToUpper(ipVersion) == "V6" {
+ clientProfile = model.ClientProfile{IpVersion: internalconstant.Ipv6, Client: client, GeoLocation: location}
+ }
+
+ testRun := model.TestRun{
+ SendEmailOnCompletion: false,
+ TargetEnvironment: targetEnvironment,
+ Functional: model.FunctionalTestRun{
+ TestCaseExecution: model.TestCaseExecution{
+ TestRequest: model.TestRequest{
+ TestRequestUrl: url,
+ RequestMethod: method,
+ RequestHeaders: getRequestHeaders(addHeader, modifyHeader, filterHeader),
+ RequestBody: requestBody,
+ EncodeRequestBody: &encodeRequestBody,
+ },
+ Condition: model.Condition{
+ ConditionExpression: strings.TrimSpace(condition),
+ },
+ ClientProfile: clientProfile,
+ },
+ },
+ }
+
+ return svc.startTestRun(testRun, runTestUsing)
+}
+
+func (svc Service) startTestRun(testRun model.TestRun, runTestUsing string) *model.TestRun {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeTestCmdSpinner, runTestUsing, internalconstant.StartTestRun), !svc.jsonOutput).Start()
+ createdTestRun, err := svc.api.SubmitTestRun(testRun)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.TestRunResource, internalconstant.Create)
+ return nil
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(createdTestRun)
+ }
+
+ successMessage := util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestRunStart)
+ util.PrintSuccess(successMessage+"\n\n", createdTestRun.TestRunId)
+ return createdTestRun
+}
+
+func (svc Service) waitForTestRunCompletion(testRunId int, runTestUsing string) (*model.TestRun, *model.CliError) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeTestCmdSpinner, runTestUsing, internalconstant.RunTests), !svc.jsonOutput).Start()
+ ticker := time.NewTicker(15 * time.Second)
+ failureCount := 0
+
+ for range ticker.C {
+ log.Debugln("Polling test run status...")
+ testRun, err := svc.api.GetTestRun(testRunId)
+ if err != nil {
+ failureCount++
+ if failureCount > 3 {
+ spinner.StopWithFailure()
+ return nil, err
+ }
+ continue
+ }
+
+ // Reset failure count on success, so we only stop when 3 successive tries fail
+ failureCount = 0
+
+ if testRun != nil && testRun.Status != internalconstant.InProgressEnum {
+ spinner.StopWithSuccess()
+ ticker.Stop()
+
+ return testRun, nil
+ }
+ }
+
+ return nil, model.CliErrorWithMessage(externalconstant.CliErrorMessageTestRunStatus)
+}
+
+func (svc Service) GetRawRequestResponseAndPrintResult(testRunId, tcxId string) {
+
+ if testRunId != internalconstant.Empty {
+ rawReqResArray := svc.GetRawRequestResponseForRunId(testRunId)
+ util.PrintHeader(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.GetRawReqResForTestRunSuccess) + "\n")
+ fmt.Println()
+ print.PrintRawRequestResponse(rawReqResArray, false)
+ } else {
+ rawRequestResponse := svc.GetRawRequestResponseForTcxId(tcxId)
+ rawReqResArray := []model.RawRequestResponse{*rawRequestResponse}
+ util.PrintHeader(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.GetRawReqResForTcxsSuccesss) + "\n")
+ fmt.Println()
+ print.PrintRawRequestResponse(rawReqResArray, true)
+ }
+}
+
+func (svc Service) GetRawRequestResponseForRunId(testRunId string) []model.RawRequestResponse {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetRawReqResForTestRun), !svc.jsonOutput).Start()
+ rawReqRes, err := svc.api.GetRawReqResForRunId(testRunId)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.RawRequestUsingTestRunId, internalconstant.Empty)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(rawReqRes)
+ }
+
+ return rawReqRes
+}
+
+func (svc Service) GetRawRequestResponseForTcxId(testCaseExecutionId string) *model.RawRequestResponse {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetRawReqResForTcxs), !svc.jsonOutput).Start()
+ rawRequestResponse, err := svc.api.GetRawReqResForTcxId(testCaseExecutionId)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.RawRequestUsingTestCaseExecutionId, internalconstant.Empty)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(rawRequestResponse)
+ }
+
+ return rawRequestResponse
+}
+
+func (svc Service) GetTestLogLinesAndPrintJson(tcxId string) {
+ id, _ := strconv.Atoi(tcxId)
+ logLines, err := svc.api.GetLogLines(id)
+
+ if err != nil {
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ util.PrintJsonAndExit(logLines)
+}
diff --git a/internal/service/test_suite_service.go b/internal/service/test_suite_service.go
new file mode 100644
index 0000000..5557be1
--- /dev/null
+++ b/internal/service/test_suite_service.go
@@ -0,0 +1,534 @@
+package service
+
+import (
+ "fmt"
+ "github.com/akamai/cli-test-center/internal/api"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/print"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/akamai/cli-test-center/internal/validator"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ log "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+ "strconv"
+ "strings"
+)
+
+type Service struct {
+ api api.ApiClient
+ cmd *cobra.Command
+ jsonOutput bool
+}
+
+func NewService(api api.ApiClient, cmd *cobra.Command, jsonOutput bool) *Service {
+ return &Service{api, cmd, jsonOutput}
+}
+
+func (svc Service) GetTestSuitesAndPrint(cmd *cobra.Command, propertyId, propertyName, propVersion, user, searchString string) {
+
+ testSuites := svc.GetTestSuites(propertyId, propertyName, propVersion, user, searchString)
+ print.PrintTestSuitesTable(cmd, testSuites)
+}
+
+func (svc Service) GetTestSuites(propertyId, propertyName, propVersion, user, searchString string) []model.TestSuite {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetTestSuite), !svc.jsonOutput).Start()
+ testSuitesV3, err := svc.api.GetTestSuites(propertyId, propertyName, propVersion, user, true)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+
+ filteredTestSuites := filterTestSuitesByString(searchString, false, true, testSuitesV3)
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(filteredTestSuites)
+ }
+
+ return filteredTestSuites
+}
+
+func (svc Service) ImportTestSuites(testSuiteImport model.TestSuite) {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.ImportTestSuite), !svc.jsonOutput).Start()
+ testSuiteImportResponseV3, err := svc.api.ImportTestSuite(testSuiteImport)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuiteImportResponseV3)
+ }
+
+ print.PrintTestSuitesResult(svc.cmd, []model.TestSuite{testSuiteImportResponseV3.Success}, testSuiteImportResponseV3.Success.TestSuiteName)
+ util.PrintLabelAndValue(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.TestCasesAdded), testSuiteImportResponseV3.Success.ExecutableTestCaseCount)
+
+ if testSuiteImportResponseV3.Failure.TestCases != nil {
+ util.PrintError("\n" + util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.ImportTSTestCaseFailed) + "\n")
+ util.PrintErrorMessages(util.GetApiSubErrorMessagesForCommand(svc.cmd, testSuiteImportResponseV3.Failure.TestCases, internalconstant.Empty, internalconstant.Empty, internalconstant.Empty))
+ }
+ if testSuiteImportResponseV3.Failure.Variables != nil {
+ util.PrintError("\n" + util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.ImportTSVariableFailed) + "\n")
+ util.PrintErrorMessages(util.GetApiSubErrorMessagesForCommand(svc.cmd, testSuiteImportResponseV3.Failure.Variables, internalconstant.Empty, internalconstant.Empty, internalconstant.Empty))
+ }
+}
+
+func (svc Service) ManageTestSuites(testSuiteManage model.TestSuite) {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.ManageTestSuite), !svc.jsonOutput).Start()
+ testSuiteManageResponseV3, err := svc.api.ManageTestSuite(testSuiteManage, testSuiteManage.TestSuiteId)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuiteManageResponseV3)
+ }
+ util.PrintSuccess(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.ManageTSSuccess)+"\n", testSuiteManageResponseV3.TestSuiteName)
+}
+
+func (svc Service) AddTestSuiteAndPrint(cmd *cobra.Command, name, description, propertyId, propertyName, propVersion string, unlocked, stateful, isStandardInputAvailable bool, jsonInputTestSuite model.TestSuite) {
+
+ testSuite := svc.AddTestSuite(name, description, propertyId, propertyName, propVersion, unlocked, stateful, isStandardInputAvailable, jsonInputTestSuite)
+
+ util.PrintSuccess(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.AddTestSuiteSuccess) + "\n")
+ print.PrintTestSuite(cmd, *testSuite)
+}
+
+func (svc Service) AddTestSuite(name, description, propertyId, propertyName, propVersion string, unlocked, stateful, isStandardInputAvailable bool, jsonInputTestSuite model.TestSuite) *model.TestSuite {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.AddTestSuite), !svc.jsonOutput).Start()
+
+ testSuite := model.TestSuite{
+ TestSuiteName: name,
+ TestSuiteDescription: description,
+ IsLocked: !unlocked,
+ IsStateful: stateful,
+ Configs: model.AkamaiConfigs{
+ PropertyManager: model.PropertyManager{
+ PropertyId: util.GetConvertedInteger(propertyId),
+ PropertyName: propertyName,
+ PropertyVersion: util.GetConvertedInteger(propVersion),
+ }},
+ }
+
+ // assign json input provided by user
+ if isStandardInputAvailable {
+ testSuite = jsonInputTestSuite
+ }
+
+ testSuitesV3, err := svc.api.AddTestSuitesV3(testSuite)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuitesV3)
+ }
+
+ return testSuitesV3
+}
+
+func (svc Service) EditTestSuiteAndPrint(cmd *cobra.Command, id, name, description, propertyId, propertyName, propVersion string,
+ unlocked, stateful, removeProperty, locked, stateless, isStandardInputAvailable bool, jsonInputTestSuite model.TestSuite) {
+ versionNumber, _ := strconv.Atoi(propVersion)
+ testSuite := svc.EditTestSuite(id, name, description, propertyId, propertyName, versionNumber, unlocked, stateful, removeProperty, locked, stateless, isStandardInputAvailable, jsonInputTestSuite)
+
+ util.PrintSuccess(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.EditTSSuccess) + "\n")
+ print.PrintTestSuite(cmd, *testSuite)
+}
+
+func (svc Service) EditTestSuite(id, name, description, propertyId, propertyName string, propVersion int, unlocked, stateful,
+ removeProperty, locked, stateless, isStandardInputAvailable bool, jsonInputTestSuite model.TestSuite) *model.TestSuite {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.EditTestSuite), !svc.jsonOutput).Start()
+
+ var updatedTestSuite *model.TestSuite
+ var isChanged = false
+ if !isStandardInputAvailable {
+
+ getTestSuite, err := svc.api.GetTestSuiteV3(id)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.Empty, internalconstant.Read)
+ }
+
+ updatedTestSuite, isChanged = updateModifiedTestSuiteFields(*getTestSuite, name, description, propertyId, propertyName, propVersion, unlocked, stateful, removeProperty, locked, stateless)
+
+ // Check if at least value changed to edit test suite.
+ if !isChanged {
+ spinner.StopWithFailure()
+ validator.NewValidator(svc.cmd, []byte{}).EditTestSuiteAllFlagCheck()
+ }
+ } else {
+ updatedTestSuite = &jsonInputTestSuite
+ id = strconv.Itoa(jsonInputTestSuite.TestSuiteId)
+ }
+
+ testSuitesV3, err := svc.api.EditTestSuitesV3(*updatedTestSuite, id)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.Empty, internalconstant.Update)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuitesV3)
+ }
+
+ return testSuitesV3
+}
+
+func (svc Service) RemoveTestSuiteById(id string) {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.RemoveTestSuite), !svc.jsonOutput).Start()
+ err := svc.api.RemoveTestSuite(id)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.Empty, internalconstant.Read)
+ }
+
+}
+
+func (svc Service) RestoreTestSuiteById(id string) *model.TestSuite {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.RestoreTestSuite), !svc.jsonOutput).Start()
+ testSuitesV3, err := svc.api.RestoreTestSuite(id)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.Empty, internalconstant.Read)
+ }
+ return testSuitesV3
+
+}
+
+func (svc Service) GetTestSuitesByIdOrName(id, name, subResource string, exactMatch, shouldMatchDescription, includeDeleted bool) []model.TestSuite {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GetTestSuite), !svc.jsonOutput).Start()
+
+ if id != internalconstant.Empty {
+
+ testSuite, err := svc.api.GetTestSuiteV3(id)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, subResource, internalconstant.Read)
+ }
+ spinner.StopWithSuccess()
+
+ return []model.TestSuite{*testSuite}
+ } else {
+
+ testSuitesV3, err := svc.api.GetTestSuites(internalconstant.Empty, internalconstant.Empty, internalconstant.Empty, internalconstant.Empty, includeDeleted)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, subResource, internalconstant.Read)
+ }
+ spinner.StopWithSuccess()
+
+ return filterTestSuitesByString(name, exactMatch, shouldMatchDescription, testSuitesV3)
+ }
+}
+
+func (svc Service) GetSingleTestSuiteByIdOrName(id, name, subResource string, includeDeleted bool) *model.TestSuite {
+
+ testSuites := svc.GetTestSuitesByIdOrName(id, name, subResource, true, false, includeDeleted)
+
+ if len(testSuites) == 1 {
+ return &testSuites[0]
+ }
+
+ return nil
+}
+
+func (svc Service) GetTestSuiteWithChildObjects(testSuiteId int, resolveVariables bool) model.TestSuite {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.TestSuiteWithChildObject), !svc.jsonOutput).Start()
+ testSuiteDetailsWithChildObjects, err := svc.api.GetTestSuitesWithChildObjects(testSuiteId, resolveVariables)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommandWithSubResource(svc.cmd, err, internalconstant.Empty, internalconstant.Read)
+ }
+
+ spinner.StopWithSuccess()
+ return *testSuiteDetailsWithChildObjects
+}
+func (svc Service) RemoveTestCasesFromTestSuite(testSuiteId int, testCaseIds []int) (*model.BulkResponse, *model.CliError) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.RemoveTestCase), !svc.jsonOutput).Start()
+ log.Debugf("Removing test cases [%d] from the test suite id [%d]\n", testCaseIds, testSuiteId)
+
+ removeTestCaseResponse, err := svc.api.RemoveTestCasesFromTestSuite(testSuiteId, testCaseIds)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ if len(removeTestCaseResponse.Failures) != 0 {
+ spinner.StopWithFailure()
+ return nil, model.CliErrorFromPulsarProblemObject(nil, removeTestCaseResponse.Failures, 207, externalconstant.ApiErrorRemoveTestCasesPostCall)
+ }
+
+ spinner.StopWithSuccess()
+ return removeTestCaseResponse, nil
+}
+
+func (svc Service) GetTestSuiteOrTestSuiteDetailsWithChildObjects(id, name string, resolveVariables bool) ([]model.TestSuite, *model.TestSuite) {
+ if name != internalconstant.Empty {
+ testSuites := svc.GetTestSuitesByIdOrName(id, name, internalconstant.Empty, false, false, true)
+ if len(testSuites) == 1 {
+ var testSuiteDetailsWithChildObjects = svc.GetTestSuiteWithChildObjects(testSuites[0].TestSuiteId, resolveVariables)
+ return nil, &testSuiteDetailsWithChildObjects
+ }
+ return testSuites, nil
+ } else {
+ testSuiteId, _ := strconv.Atoi(id)
+ var testSuiteDetailsWithChildObjects = svc.GetTestSuiteWithChildObjects(testSuiteId, resolveVariables)
+ return nil, &testSuiteDetailsWithChildObjects
+ }
+}
+
+func (svc Service) GetTestSuiteAndPrint(id, name string) {
+
+ testSuites := svc.GetTestSuitesByIdOrName(id, name, internalconstant.Empty, false, false, false)
+
+ // print json output if flag is passed
+ if svc.jsonOutput {
+ if len(testSuites) == 1 {
+ util.PrintJsonAndExit(testSuites[0])
+ } else {
+ util.PrintJsonAndExit(testSuites)
+ }
+ }
+
+ // valid test suite if returned 1 else either no test suite found or multiple test suites found
+ print.PrintTestSuitesResult(svc.cmd, testSuites, name)
+
+}
+
+func (svc Service) GetTestSuiteWithChildObjectsAndPrint(id string, name string, groupBy string, resolveVariables bool) {
+
+ var testSuites []model.TestSuite
+ var testSuiteDetailsWithChildObjects *model.TestSuite
+ areAllTestCasesIncluded := false
+ testSuites, testSuiteDetailsWithChildObjects = svc.GetTestSuiteOrTestSuiteDetailsWithChildObjects(id, name, resolveVariables)
+
+ if testSuiteDetailsWithChildObjects != nil {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuiteDetailsWithChildObjects)
+ } else {
+ print.PrintTestSuitesResult(svc.cmd, []model.TestSuite{*testSuiteDetailsWithChildObjects}, name)
+ if testSuiteDetailsWithChildObjects.ExecutableTestCaseCount == len(testSuiteDetailsWithChildObjects.TestCases) {
+ areAllTestCasesIncluded = true
+ }
+ print.PrintTestCases(svc.cmd, testSuiteDetailsWithChildObjects.TestCases, areAllTestCasesIncluded, groupBy)
+ }
+ } else {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuites)
+ }
+ print.PrintTestSuitesResult(svc.cmd, testSuites, name)
+ }
+}
+
+func (svc Service) RemoveTestSuiteByIdOrName(id string, name string) {
+
+ testSuites := svc.GetTestSuitesByIdOrName(id, name, internalconstant.Empty, false, false, true)
+
+ if len(testSuites) == 1 {
+ testSuiteId := strconv.Itoa(testSuites[0].TestSuiteId)
+ svc.RemoveTestSuiteById(testSuiteId)
+ if !svc.jsonOutput {
+ util.PrintSuccess("\n" + util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.RemoveTSSuccess))
+ util.PrintSuccessInBold(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.RemoveTSSuccessInBold), testSuiteId)
+ util.PrintSuccess(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, "removeTSSuccessEnd") + "\n")
+ print.PrintTestSuiteForRemovedTestSuite(testSuites[0])
+ }
+ } else {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuites)
+ }
+ print.PrintTestSuitesResult(svc.cmd, testSuites, name)
+ }
+
+}
+
+func (svc Service) RestoreTestSuiteByIdOrName(id string, name string) {
+
+ testSuites := svc.GetTestSuitesByIdOrName(id, name, internalconstant.Empty, false, false, true)
+ if len(testSuites) == 1 {
+ testSuiteId := strconv.Itoa(testSuites[0].TestSuiteId)
+ testSuite := svc.RestoreTestSuiteById(testSuiteId)
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuite)
+ }
+ util.PrintSuccess("\n" + util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.RestoreTSSuccess) + "\n")
+ print.PrintTestSuiteForRemovedTestSuite(testSuites[0])
+ } else {
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(testSuites)
+ }
+ print.PrintTestSuitesResult(svc.cmd, testSuites, name)
+ }
+}
+
+func updateModifiedTestSuiteFields(testSuiteV3 model.TestSuite, name, description, propertyId, propertyName string, propVersion int, unlocked, stateful, removeProperty bool, locked bool, stateless bool) (*model.TestSuite, bool) {
+
+ var isChanged = false
+ if name != internalconstant.Empty && testSuiteV3.TestSuiteName != name {
+ testSuiteV3.TestSuiteName = name
+ isChanged = true
+ }
+
+ if description != internalconstant.Empty && testSuiteV3.TestSuiteDescription != description {
+ testSuiteV3.TestSuiteDescription = description
+ isChanged = true
+ }
+
+ if locked || unlocked {
+ if locked {
+ testSuiteV3.IsLocked = locked
+ } else {
+ testSuiteV3.IsLocked = !unlocked
+ }
+ isChanged = true
+ }
+
+ if stateful || stateless {
+ if stateful {
+ testSuiteV3.IsStateful = stateful
+ } else {
+ testSuiteV3.IsStateful = !stateless
+ }
+ isChanged = true
+ }
+
+ if testSuiteV3.Configs.PropertyManager.PropertyName != internalconstant.Empty && removeProperty {
+ testSuiteV3.Configs = model.AkamaiConfigs{}
+ isChanged = true
+ }
+
+ if (propertyName != internalconstant.Empty || propertyId != internalconstant.Empty) &&
+ (testSuiteV3.Configs.PropertyManager.PropertyName != propertyName ||
+ testSuiteV3.Configs.PropertyManager.PropertyId != util.GetConvertedInteger(propertyId) ||
+ testSuiteV3.Configs.PropertyManager.PropertyVersion != propVersion) {
+
+ testSuiteV3.Configs.PropertyManager.PropertyName = propertyName
+ testSuiteV3.Configs.PropertyManager.PropertyId = util.GetConvertedInteger(propertyId)
+ testSuiteV3.Configs.PropertyManager.PropertyVersion = propVersion
+ isChanged = true
+ }
+
+ return &testSuiteV3, isChanged
+}
+
+// Returns testSuites containing searchString in either name or description
+func filterTestSuitesByString(searchString string, exactMatch, shouldMatchDescription bool, testSuites []model.TestSuite) []model.TestSuite {
+ var filteredItems []model.TestSuite
+
+ for _, testSuite := range testSuites {
+ if exactMatch {
+ if strings.EqualFold(testSuite.TestSuiteName, searchString) ||
+ (shouldMatchDescription && strings.EqualFold(testSuite.TestSuiteDescription, searchString)) {
+ filteredItems = append(filteredItems, testSuite)
+ }
+ } else {
+ if util.ContainsIgnoreCase(testSuite.TestSuiteName, searchString) ||
+ (shouldMatchDescription && util.ContainsIgnoreCase(testSuite.TestSuiteDescription, searchString)) {
+ filteredItems = append(filteredItems, testSuite)
+ }
+ }
+ }
+
+ return filteredItems
+}
+
+func getRequestHeaders(headerAdd []string, headerModify []string, headerFilter []string) []model.RequestHeader {
+ var requestHeaders []model.RequestHeader
+
+ for _, header := range headerAdd {
+ headerComponents := strings.Split(header, ":")
+ requestHeaders = append(requestHeaders, model.RequestHeader{
+ HeaderName: strings.TrimSpace(headerComponents[0]),
+ HeaderValue: strings.TrimSpace(headerComponents[1]),
+ HeaderAction: internalconstant.Add,
+ })
+ }
+
+ for _, header := range headerModify {
+ headerComponents := strings.Split(header, ":")
+ requestHeaders = append(requestHeaders, model.RequestHeader{
+ HeaderName: strings.TrimSpace(headerComponents[0]),
+ HeaderValue: strings.TrimSpace(headerComponents[1]),
+ HeaderAction: internalconstant.Modify,
+ })
+ }
+
+ for _, header := range headerFilter {
+ requestHeaders = append(requestHeaders, model.RequestHeader{
+ HeaderName: strings.TrimSpace(header),
+ HeaderAction: internalconstant.Filter,
+ })
+ }
+
+ return requestHeaders
+}
+
+func getSetVariables(setVariables []string) []model.DynamicVariable {
+ var variables []model.DynamicVariable
+
+ for _, variable := range setVariables {
+ variableComponent := strings.Split(variable, ":")
+ variables = append(variables, model.DynamicVariable{
+ VariableName: strings.TrimSpace(variableComponent[0]),
+ VariableValue: strings.TrimSpace(variableComponent[1]),
+ })
+ }
+ return variables
+}
+
+func (svc Service) GenerateTestSuite(propertyId, propertyName, propVersion string, urls []string,
+ defaultTestSuiteRequest model.DefaultTestSuiteRequest, isJsonInputPresent bool) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.GenerateDefaultTestSuite), !svc.jsonOutput).Start()
+
+ defaultTsReq := model.DefaultTestSuiteRequest{}
+
+ // form request
+ if isJsonInputPresent {
+ defaultTsReq = defaultTestSuiteRequest
+ } else {
+ defaultTsReq = model.DefaultTestSuiteRequest{
+ TestRequestUrl: urls,
+ Configs: model.AkamaiConfigs{
+ PropertyManager: model.PropertyManager{
+ PropertyId: util.GetConvertedInteger(propertyId),
+ PropertyName: propertyName,
+ PropertyVersion: util.GetConvertedInteger(propVersion),
+ }},
+ }
+ }
+
+ // get default ts
+ generatedTs, err := svc.api.GenerateTestSuite(defaultTsReq)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+ spinner.StopWithSuccess()
+
+ // print output
+ if !svc.jsonOutput {
+ util.PrintSuccess(fmt.Sprintf(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.GenerateDefaultTSSuccess)+"\n\n", generatedTs.Configs.PropertyManager.PropertyName, generatedTs.Configs.PropertyManager.PropertyVersion))
+ }
+ util.PrintJsonAndExit(generatedTs)
+}
diff --git a/internal/service/variable_service.go b/internal/service/variable_service.go
new file mode 100644
index 0000000..46b7a5a
--- /dev/null
+++ b/internal/service/variable_service.go
@@ -0,0 +1,221 @@
+package service
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/print"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ log "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+ "strconv"
+ "strings"
+)
+
+func (svc Service) CreateVariablesAndPrintResult(cmd *cobra.Command, varname, value, testSuiteId string, varGroupValue []string) {
+ variables, err := svc.CreateVariable(varname, value, testSuiteId, varGroupValue)
+
+ if err != nil {
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ if len(variables.Successes) != 0 {
+ util.PrintSuccess(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.AddVariablesSuccess) + "\n")
+ fmt.Println()
+ print.PrintVariables(variables.Successes, false)
+ }
+
+ if len(variables.Failures) != 0 {
+ util.PrintErrorMessages(util.GetApiSubErrorMessagesForCommand(svc.cmd, variables.Failures, internalconstant.Empty, internalconstant.Empty, internalconstant.Empty))
+ }
+
+}
+
+func (svc Service) CreateVariable(varname, value, testSuiteId string, varGroupValue []string) (*model.VariableBulkResponse, *model.CliError) {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.AddVariables), !svc.jsonOutput).Start()
+
+ variables := []model.Variable{
+ {
+ VariableName: varname,
+ VariableValue: value,
+ VariableGroupValue: GetVarGroupArray(varGroupValue),
+ },
+ }
+
+ varBulkResp, err := svc.api.CreateVariables(variables, testSuiteId)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(varBulkResp)
+ }
+
+ return varBulkResp, nil
+
+}
+
+func GetVarGroupArray(varGroup []string) []model.VariableGroupValue {
+ var varGroupArray []model.VariableGroupValue
+ for _, userProvidedGroupValue := range varGroup {
+ var vg model.VariableGroupValue
+
+ // Get the header and values parts of the variable group
+ parts := strings.SplitN(userProvidedGroupValue, externalconstant.Colon, 2)
+ vg.ColumnHeader = parts[0]
+ vg.ColumnValues = strings.Split(parts[1], externalconstant.Comma)
+
+ // Assign the header and values parts of the variable group in request body format
+ varGroupArray = append(varGroupArray, vg)
+ }
+
+ return varGroupArray
+}
+
+func (svc Service) GetVariablesAndPrintResult(cmd *cobra.Command, testSuiteId string) {
+ variableList := svc.GetVariablesList(testSuiteId)
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.GetVariablesSuccess) + "\n\n")
+
+ print.PrintVariablesResult(cmd, variableList, false)
+ fmt.Printf("\n"+externalconstant.LabelTotalItem+": %d\n", len(variableList))
+
+}
+
+func (svc Service) GetVariablesList(testSuiteId string) []model.Variable {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty,
+ internalconstant.GetVariables), !svc.jsonOutput).Start()
+ variables, err := svc.api.GetVariables(testSuiteId)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(variables)
+ }
+ return variables
+}
+
+func (svc Service) GetVariableAndPrintResult(cmd *cobra.Command, testSuiteId, variableId string) {
+ variable := svc.GetVariable(testSuiteId, variableId)
+ var variables []model.Variable
+ variables = append(variables, *variable)
+
+ util.PrintHeader(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.GetVariableSuccess) + "\n\n")
+ print.PrintVariablesResult(cmd, variables, false)
+}
+
+func (svc Service) GetVariable(testSuiteId, variableId string) *model.Variable {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty,
+ internalconstant.GetVariable), !svc.jsonOutput).Start()
+
+ variable, err := svc.api.GetVariable(testSuiteId, variableId)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(variable)
+ }
+ return variable
+}
+
+func (svc Service) UpdateVariablesAndPrintResult(cmd *cobra.Command, testSuiteId, variableId, variableName, value string, variableGroupValue []string) {
+ variables, err := svc.UpdateVariable(testSuiteId, variableId, variableName, value, variableGroupValue)
+
+ if err != nil {
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ if len(variables.Successes) != 0 {
+ util.PrintSuccess(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.UpdateVariablesSuccess) + "\n")
+ fmt.Println()
+ print.PrintVariables(variables.Successes, false)
+ }
+
+ if len(variables.Failures) != 0 {
+ util.PrintErrorMessages(util.GetApiSubErrorMessagesForCommand(svc.cmd, variables.Failures, internalconstant.Empty, internalconstant.Empty, internalconstant.Empty))
+ }
+
+}
+
+func (svc Service) UpdateVariable(testSuiteId, variableId, variableName, value string, variableGroupValue []string) (*model.VariableBulkResponse, *model.CliError) {
+
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.UpdateVariables), !svc.jsonOutput).Start()
+
+ variables := constructVariablesForUpdate(variableId, variableName, value, variableGroupValue)
+
+ varBulkResp, err := svc.api.UpdateVariables(variables, testSuiteId)
+
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(varBulkResp)
+ }
+
+ return varBulkResp, nil
+
+}
+
+func constructVariablesForUpdate(variableId, variablename, value string, varGroupValue []string) []model.Variable {
+
+ varId, _ := strconv.Atoi(variableId)
+ variables := []model.Variable{
+ {
+ VariableId: varId,
+ VariableName: variablename,
+ VariableValue: value,
+ VariableGroupValue: GetVarGroupArray(varGroupValue),
+ },
+ }
+ return variables
+}
+
+func (svc Service) RemoveVariablesAndPrintResult(cmd *cobra.Command, testSuiteId, variableId string) {
+ variables, err := svc.RemoveVariable(testSuiteId, variableId)
+
+ if err != nil {
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ if len(variables.Successes) != 0 {
+ util.PrintSuccess(util.GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, internalconstant.Empty, internalconstant.RemoveVariableSuccess) + "\n")
+ }
+
+ if len(variables.Failures) != 0 {
+ util.PrintErrorMessages(util.GetApiSubErrorMessagesForCommand(svc.cmd, variables.Failures, internalconstant.Empty, internalconstant.Empty, internalconstant.Empty))
+ }
+
+}
+
+func (svc Service) RemoveVariable(testSuiteId, variableId string) (*model.BulkResponse, *model.CliError) {
+ spinner := util.NewSpinner(util.GetServiceMessage(svc.cmd, internalconstant.MessageTypeSpinner, internalconstant.Empty, internalconstant.RemoveVariable), !svc.jsonOutput).Start()
+ log.Debugf("Removing test cases [%d] from the test suite id [%d]\n", variableId, testSuiteId)
+
+ removeVariableResponse, err := svc.api.RemoveVariableFromTestSuite(testSuiteId, variableId)
+ if err != nil {
+ spinner.StopWithFailure()
+ util.AbortForCommand(svc.cmd, err)
+ }
+
+ spinner.StopWithSuccess()
+ if svc.jsonOutput {
+ util.PrintJsonAndExit(removeVariableResponse)
+ }
+
+ return removeVariableResponse, nil
+}
diff --git a/internal/template.go b/internal/template.go
deleted file mode 100644
index e729209..0000000
--- a/internal/template.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package internal
-
-/**
-This class will be used for all output print templates. Do not modify spaces/newlines for existing templates unless
-there is a requirement.
-*/
-
-var groupByTestRequest = "{{ $count := 1 }}" +
- "{{ range $mapKey, $mapValue := . }}" +
- "{{ range $key, $value := $mapValue.Value }}" +
- "{{if eq $key 0}}|-- {{ bold \"TR\" }}{{ bold $count }} {{$value.TestRequest.TestRequestUrl}}{{ end }}" +
- "{{ $length := len $value.TestRequest.Tags }}{{ if ne $length 0 }}{{if eq $key 0}}\n| Keywords: {{ join $value.TestRequest.Tags }}{{ end }}{{ end }}" +
- "{{ $length := len $value.TestRequest.RequestHeaders }}{{ if ne $length 0 }}{{if eq $key 0}}{{ range $headerIndex, $header := $value.TestRequest.RequestHeaders }}\n| {{ printHeader $header.HeaderName $header.HeaderAction $header.HeaderValue }}{{ end }}{{ end }}{{ end }}" +
- "\n| |-- {{ bold $value.Order }} {{ $value.Condition.ConditionExpression }} {{ $ipVersion := printClientProfile $value.ClientProfile.IpVersion }}{{ bold $ipVersion }}" +
- "{{ end }}\n" +
- "{{ $count = inc $count }}{{end}}"
-
-var groupByCondition = "{{ $count := 1 }}" +
- "{{ range $mapKey, $mapValue := . }}" +
- "|-- {{ bold \"C\" }}{{ bold $count }} {{$mapValue.Key}}" +
- "{{ range $key, $value := $mapValue.Value }}" +
- "\n| |-- {{ bold $value.Order }} {{ $value.TestRequest.TestRequestUrl }}" +
- "{{ $length := len $value.TestRequest.Tags }}{{ if ne $length 0 }}\n| Keywords: {{ join $value.TestRequest.Tags }}{{ end }}" +
- "{{ $length := len $value.TestRequest.RequestHeaders }}{{ if ne $length 0 }}{{ range $headerIndex, $header := $value.TestRequest.RequestHeaders }}\n| {{ printHeader $header.HeaderName $header.HeaderAction $header.HeaderValue }}{{ end }}{{ end }}" +
- "\n| {{ $ipVersion := printClientProfile $value.ClientProfile.IpVersion }}{{ bold $ipVersion }}" +
- "{{ end }}\n" +
- "{{ $count = inc $count }}{{ end }}"
-
-var groupByIpVersion = "{{ range $mapKey, $mapValue := . }}" +
- "|-- {{ $ipVersion := printClientProfile $mapValue.Key }}{{ bold $ipVersion }}" +
- "{{ range $key, $value := $mapValue.Value }}" +
- "\n| |-- {{ bold $value.Order }} {{ $value.TestRequest.TestRequestUrl }}" +
- "{{ $length := len $value.TestRequest.Tags }}{{ if ne $length 0 }}\n| Keywords: {{ join $value.TestRequest.Tags }}{{ end }}" +
- "{{ $length := len $value.TestRequest.RequestHeaders }}{{ if ne $length 0 }}{{ range $headerIndex, $header := $value.TestRequest.RequestHeaders }}\n| {{ printHeader $header.HeaderName $header.HeaderAction $header.HeaderValue }}{{ end }}{{ end }}" +
- "\n| {{ $value.Condition.ConditionExpression }}" +
- "{{ end }}\n{{end}}"
diff --git a/internal/types.go b/internal/types.go
deleted file mode 100644
index 7cd74f1..0000000
--- a/internal/types.go
+++ /dev/null
@@ -1,278 +0,0 @@
-package internal
-
-// BrowserInfo object represents a browser with its name and version
-type BrowserInfo struct {
- Name string `json:"name"`
- Version string `json:"version"`
-}
-
-// ClientProfile object represents a client to be used for making requests
-type ClientProfile struct {
- ClientProfileId int `json:"clientProfileId,omitempty"`
- GeoLocation string `json:"geoLocation,omitempty"`
- IpVersion string `json:"ipVersion"`
- Browser BrowserInfo `json:"browser,omitempty"`
- Client string `json:"client,omitempty"`
-}
-
-type RequestHeader struct {
- HeaderName string `json:"headerName"`
- HeaderValue string `json:"headerValue"`
- HeaderAction string `json:"headerAction,omitempty"`
-}
-
-type TestRequest struct {
- TestRequestId int `json:"testRequestId,omitempty"`
- TestRequestUrl string `json:"testRequestUrl"`
- RequestMethod string `json:"requestMethod,omitempty"`
- RequestHeaders []RequestHeader `json:"requestHeaders,omitempty"`
- Tags []string `json:"tags,omitempty"`
-}
-
-type Condition struct {
- ConditionId int `json:"conditionId,omitempty"`
- ConditionExpression string `json:"conditionExpression"`
-}
-
-type AssociatedTestCases struct {
- AreAllTestCasesIncluded bool `json:"areAllTestCasesIncluded"`
- TestCases []TestCase `json:"testCases"`
-}
-
-type TestCase struct {
- TestCaseId int `json:"testCaseId,omitempty"`
- Order int `json:"order,omitempty"`
- TestRequest TestRequest `json:"testRequest"`
- ClientProfile ClientProfile `json:"clientProfile,omitempty"`
- ClientProfileId int `json:"clientProfileId,omitempty"`
- Condition Condition `json:"condition"`
-}
-
-type TestCaseBulkResponse struct {
- Successes []TestCase `json:"successes"`
- Failures []ApiSubError `json:"failures"`
-}
-
-type BulkResponse struct {
- Successes []int `json:"successes"`
- Failures []ApiSubError `json:"failures"`
-}
-
-type TestSuite struct {
- CreatedBy string `json:"createdBy,omitempty"`
- CreatedDate string `json:"createdDate,omitempty"`
- ModifiedBy string `json:"modifiedBy,omitempty"`
- ModifiedDate string `json:"modifiedDate,omitempty"`
- TestSuiteId int `json:"testSuiteId,omitempty"`
- TestSuiteName string `json:"testSuiteName"`
- TestSuiteDescription string `json:"testSuiteDescription,omitempty"`
- IsLocked bool `json:"isLocked"`
- IsStateful bool `json:"isStateful"`
-}
-
-// We may add list responses for different objects here if needed in future e.g. variables, test-cases
-type ListResponse struct {
- TestSuites []TestSuiteV3 `json:"testSuites,omitempty"`
-}
-
-type TestSuiteImportResponseV3 struct {
- Success TestSuiteV3 `json:"success,omitempty"`
- Failure TestSuiteImportFailure `json:"failure,omitempty"`
-}
-
-type TestSuiteImportFailure struct {
- Variables []ApiSubError `json:"variables,omitempty"`
- TestCases []ApiSubError `json:"testCases,omitempty"`
-}
-
-type TestSuiteV3 struct {
- CreatedBy string `json:"createdBy,omitempty"`
- CreatedDate string `json:"createdDate,omitempty"`
- ModifiedBy string `json:"modifiedBy,omitempty"`
- ModifiedDate string `json:"modifiedDate,omitempty"`
- DeletedBy string `json:"deletedBy,omitempty"`
- DeletedDate string `json:"deletedDate,omitempty"`
- TestSuiteId int `json:"testSuiteId,omitempty"`
- TestSuiteName string `json:"testSuiteName"`
- TestSuiteDescription string `json:"testSuiteDescription,omitempty"`
- IsLocked bool `json:"isLocked"`
- IsStateful bool `json:"isStateful"`
- ExecutableTestCaseCount int `json:"executableTestCaseCount"`
- Configs AkamaiConfigs `json:"configs,omitempty"`
- TestCases []TestCase `json:"testCases,omitempty"`
- Variables []Variable `json:"variables,omitempty"`
-}
-
-type Variable struct {
- VariableId int `json:"variableId,omitempty"`
- VariableName string `json:"variableName"`
- VariableValue string `json:"variableValue,omitempty"`
-}
-
-type AkamaiConfigs struct {
- PropertyManager PropertyManager `json:"propertyManager,omitempty"`
-}
-
-type PropertyManager struct {
- PropertyId int `json:"propertyId,omitempty"`
- PropertyName string `json:"propertyName,omitempty"`
- PropertyVersion int `json:"propertyVersion"`
-}
-
-type ConfigVersion struct {
- ModifiedBy string `json:"modifiedBy,omitempty"`
- ModifiedDate string `json:"modifiedDate,omitempty"`
- ConfigVersionId int `json:"configVersionId,omitempty"`
- ArlFileId int `json:"arlFileId"`
- PropertyName string `json:"propertyName"`
- PropertyVersion int `json:"propertyVersion"`
- LastSync string `json:"lastSync,omitempty"`
-}
-
-type TestRun struct {
- TestRunId int `json:"testRunId,omitempty"`
- Status string `json:"status,omitempty"`
- TargetEnvironment string `json:"targetEnvironment"`
- SendEmailOnCompletion bool `json:"sendEmailOnCompletion"`
- Note string `json:"note,omitempty"`
- Functional FunctionalTestRun `json:"functional"`
- SubmittedBy string `json:"submittedBy,omitempty"`
- SubmittedDate string `json:"submittedDate,omitempty"`
- CompletedDate string `json:"completedDate,omitempty"`
-}
-
-type FunctionalTestRun struct {
- Status string `json:"status,omitempty"`
- TestSuiteExecutionsV3 []TestSuiteExecutionV3 `json:"testSuiteExecutions,omitempty"`
- PropertyManagerExecution PropertyManagerExecution `json:"propertyManagerExecution,omitempty"`
- TestCaseExecution TestCaseExecution `json:"testCaseExecution,omitempty"`
-}
-
-type PropertyManagerExecution struct {
- PropertyId int `json:"propertyId,omitempty"`
- PropertyName string `json:"propertyName"`
- PropertyVersion int `json:"propertyVersion"`
- TestSuiteExecutionsV3 []TestSuiteExecutionV3 `json:"testSuiteExecutions,omitempty"`
-}
-
-type TestSuiteExecutionV3 struct {
- TestSuiteId int `json:"testSuiteId"`
- Status string `json:"status,omitempty"`
- TestCaseExecutionsV3 []TestCaseExecutionV3 `json:"testCaseExecutions"`
- TestSuiteContext TestSuiteV3
- TestSuiteExecutionId int `json:"testSuiteExecutionId,omitempty"`
- SubmittedBy string `json:"submittedBy,omitempty"`
- SubmittedDate string `json:"submittedDate,omitempty"`
- CompletedDate string `json:"completedDate,omitempty"`
-}
-
-type TestCaseExecutionV3 struct {
- TestCaseId int `json:"testCaseId"`
- TestCaseExecutionId int `json:"testCaseExecutionId,omitempty"`
- Status string `json:"status,omitempty"`
- ConditionEvaluationResult ConditionEvaluationResult `json:"conditionEvaluationResult,omitempty"`
- TestCaseContext TestCase `json:"testCaseContext,omitempty"`
- Errors []ApiSubError `json:"errors,omitempty"`
- SubmittedBy string `json:"submittedBy,omitempty"`
- SubmittedDate string `json:"submittedDate,omitempty"`
- CompletedDate string `json:"completedDate,omitempty"`
-}
-
-type TestCaseExecution struct {
- TestRequest TestRequest `json:"testRequest"`
- ClientProfile ClientProfile `json:"clientProfile,omitempty"`
- Condition Condition `json:"condition"`
- TestCaseExecutionId int `json:"testCaseExecutionId,omitempty"`
- Status string `json:"status,omitempty"`
- ConditionEvaluationResult ConditionEvaluationResult `json:"conditionEvaluationResult,omitempty"`
- Errors []ApiSubError `json:"errors,omitempty"`
- SubmittedBy string `json:"submittedBy,omitempty"`
- SubmittedDate string `json:"submittedDate,omitempty"`
- CompletedDate string `json:"completedDate,omitempty"`
-}
-
-type ConditionEvaluationResult struct {
- ActualConditionData []ActualConditionData `json:"actualConditionData,omitempty"`
- Result string `json:"result,omitempty"`
-}
-
-type ActualConditionData struct {
- Name string `json:"name"`
- Value string `json:"value"`
-}
-
-type TestRunContext struct {
- TestRunId int `json:"testRunId"`
- Functional FunctionalContext `json:"functional"`
-}
-
-type FunctionalContext struct {
- TestSuites []TestSuiteContext `json:"testSuites,omitempty"`
- TestCases []TestCase `json:"testCases,omitempty"`
- PropertyManagers []PropertyManagerContext `json:"propertyManagers,omitempty"`
-}
-
-type FunctionalContextMap struct {
- TestSuitesMap map[int]TestSuiteContextMap
- TestCasesMap map[int]TestCase
- PropertyManagersMap map[int]PropertyManagerContextMap
-}
-
-type TestSuiteContext struct {
- *TestSuite
- TestCases []TestCase `json:"testCases,omitempty"`
-}
-
-type TestSuiteContextMap struct {
- *TestSuite
- TestCasesMap map[int]TestCase
-}
-type PropertyManagerContext struct {
- *PropertyManager
- TestSuites []TestSuiteContext `json:"testSuites,omitempty"`
-}
-
-type PropertyManagerContextMap struct {
- *PropertyManager
- TestSuitesMap map[int]TestSuiteContextMap
-}
-
-type ResultStats struct {
- TotalTestCasesCount int
- PassedTestCasesCount int
- FailedTestCasesCount int
- SystemErrorTestCasesCount int
-}
-
-//Condition template types
-
-type ConditionExpression struct {
- ConditionExpressionId int `json:"conditionExpressionId,omitempty"`
- ConditionExpression string `json:"conditionExpression,omitempty"`
- Examples []string `json:"examples,omitempty"`
-}
-
-type PlaceHolder struct {
- PlaceHolder string `json:"placeHolder,omitempty"`
- ValueInputType string `json:"valueInputType,omitempty"`
- ValueDataType string `json:"valueDataType,omitempty"`
- IsCustomValueSupported bool `json:"isCustomValueSupported,omitempty"`
- ValueSeparator string `json:"valueSeparator,omitempty"`
- AvailableValues []interface{} `json:"availableValues"`
-}
-
-type ConditionType struct {
- ConditionType string `json:"conditionType,omitempty"`
- Label string `json:"label,omitempty"`
- ConditionExpressions []ConditionExpression `json:"conditionExpressions,omitempty"`
- PlaceHolders []PlaceHolder `json:"placeHolders"`
-}
-
-type ConditionTemplate struct {
- ConditionTypes []ConditionType `json:"conditionTypes,omitempty"`
-}
-
-type DefaultTestSuiteRequest struct {
- Configs AkamaiConfigs `json:"configs"`
- TestRequestUrl []string `json:"testRequestUrls"`
-}
diff --git a/internal/util/en_US.json b/internal/util/en_US.json
new file mode 100644
index 0000000..6257238
--- /dev/null
+++ b/internal/util/en_US.json
@@ -0,0 +1,1730 @@
+{
+ "akamai": {
+ "fallback": "Internal error. Try again later.",
+ "global": {
+ "initEdgeRc": "Check if your .edgerc file and section are specified correctly and contain valid credentials.",
+ "requestParsingError": "Error parsing API request body.",
+ "responseParsingError": "Error parsing API response.",
+ "jsonOutputFailed": "Error occurred while printing JSON.",
+ "invalidCommandInput": "Incorrect command. Either correct the input following examples or provide JSON input file for the command and try again.",
+ "invalidJsonInput": "Invalid JSON input. Correct it and try again.",
+ "jsonInputNotAllowed": "JSON input is not allowed for given command. Correct it and try again.",
+ "500": "Internal server error. Try again later.",
+ "502": "Bad gateway. Try again later.",
+ "503": "Service unavailable. Try again later.",
+ "504": "Request timed out. Try again later.",
+ "405": "Method not allowed. Try again later.",
+ "edgeGridError": {
+ "resourceNotFound": "The requested resource can't be found.",
+ "invalidHost": "The host is invalid.",
+ "httpsRequired": "HTTPS is required in the host.",
+ "invalidEndpoint": "The API endpoint is invalid.",
+ "invalidTimestamp": "The system time for API Client is incorrect. Check system's clock synced with a time authority.",
+ "notAuthorized": "The identity is not authorized to manage any context.",
+ "authorizationHeaderMissing": "The authorization header is missing.",
+ "invalidAuthorizationClientToken": "The authorization client token is invalid.",
+ "invalidAuthorizationAccessToken": "The authorization access token is invalid.",
+ "theSignatureDoesNotMatch": "The signature doesn't match client secret.",
+ "theHostHeaderIsNotValidServiceConsumerToken": "The host header is not a valid service consumer token."
+ }
+ },
+ "testCenter": {
+ "short": "Test Center CLI",
+ "long": "Test Center is a testing tool that checks the effect of configuration changes \non your web property. Use Test Center as part of your testing protocol to increase \nyour confidence in the safety and accuracy of your configuration changes.",
+ "edgerc": "Sets the new path to the .edgerc file. Provide the full path.",
+ "section": "Sets the new section name of the .edgerc file with credentials for the CLI to use.",
+ "accountKey": "Switches to the account with specific Account ID when performing operations.",
+ "forceColor": "Forces color to non-TTY output.",
+ "json": "Prints JSON output, where applicable.",
+ "help": "Help for test-center.",
+ "version": "Version for test-center.",
+ "messages": {
+ "display": {
+ "standardInputErrorMsg": "Error occurred while reading the standard input. Error : %v"
+ }
+ },
+ "testSuite": {
+ "short": "List commands available for test suites.",
+ "long": "Test suites act as containers for functional test cases. You can create, edit, or remove test suites, \nmanage test suites using JSON input, add test cases to test suites, and generate a default test suite for a particular property.",
+ "subCommand": {
+ "invalid": {
+ "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
+ }
+ },
+ "create": {
+ "short": "Creates a test suite.",
+ "long": "This command creates a test suite. Test suites act as containers for functional test cases. You can add a name and \ndescription to a test suite to provide more details about it and the \nincluded test cases. You can also set if the test suite needs to be locked or \nstateful. Test suites can be associated with a property version.\n\nIn stateful test suites, test cases are executed in the order they are added and \ncookies and session information are retained for subsequent test cases.\n\nLocked test suites can be modified only by their editors and owners.",
+ "testSuiteName": "Name of the test suite.",
+ "description": "Optional. Test suite's description.",
+ "unlocked": "Optional. Unlocks the test suite. By default, all test suites are locked.",
+ "stateful": "Optional. Sets the test suite to stateful. By default test suites are stateless.",
+ "propertyId": "Optional. Property ID you want the test suite to be associated with, for example '4567'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyName": "Optional. Property name you want the test suite to be associated with, for example 'example.com'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyVersion": "Optional. Property version you want the test suite to be associated with, for example '4'. This flag needs to be combined with either the '--property-id' or '--property-name' flag.",
+ "flag": {
+ "missing": {
+ "flagOrJsonImport": "Missing required flags or JSON input. Correct the input following examples and try again.",
+ "name": "Missing the required '--test-suite-name' flag. Add the flag and try again.",
+ "missingVersionWithId": "Missing the '--property-version' flag. Correct your input and try again. Example: --property-id '4567' --property-version '4'",
+ "missingVersionWithName": "Missing the '--property-version' flag. Correct your input and try again. Example: --property-name 'example.com' --property-version '4'",
+ "missingIdOrNameWithVersion": "Missing one of the flags, either '--property-id' or '--property-name'. Correct your input and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'"
+ },
+ "invalid": {
+ "propertyIdError": "Invalid '--property-id' flag value. It needs to be a number and it needs to be used together with the '--property-version' flag. Correct the input and try again. Example: --property-id '4567' --property-version '4'",
+ "propertyVersionError": "Invalid '--property-version' flag value. It needs to be a number and it needs to be used together with the '--property-id' or '--property-name' flag. Correct the input and try again. Example: --property-name 'example.com' --property-version '4' or --property-id '4567' --property-version '4'",
+ "propertyCombinationError": "Invalid combination of '--property-id' and '--property-name' flag values. Enter a valid property id or property name along with its version and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'"
+ }
+ },
+ "validationError": {
+ "requiredFieldMissing": "The '{{requestField}}' is missing.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit.",
+ "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again."
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator."
+ },
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
+ "resourceNotFound": "The requested '{{requestField}}' can't be found.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "addTestSuite": "Creating test suite"
+ },
+ "display": {
+ "addTestSuiteSuccess": "Test suite created"
+ }
+ }
+ },
+ "update": {
+ "short": "Edits a test suite.",
+ "long": "This command edits a test suite with a specific ID. Provide only flags with values you want to edit in the current test suite.",
+ "testSuiteId": "Unique identifier of the test suite you want to edit.",
+ "testSuiteName": "Optional. Edited name of the test suite.",
+ "description": "Optional. Edited test suite's description.",
+ "unlocked": "Optional. Unlocks the test suite.",
+ "stateful": "Optional. Sets the test suite to be stateful.",
+ "locked": "Optional. Locks the test suite.",
+ "stateless": "Optional. Sets the test suite to be stateless.",
+ "propertyId": "Optional. Property ID you want the test suite to be associated with, for example '4567'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyName": "Optional. Property name you want the test suite to be associated to, for example 'example.com'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyVersion": "Optional. Property version you want the test suite to be associated to, for example '4'. This flag needs to be combined with the '--property-id' or '--property-name' flag.",
+ "removeProperty": "Optional. Removes test suite's current association to the property version. If applicable, provide either this flag or '--property-name' or '--property-id' and '--property-version'.",
+ "flag": {
+ "missing": {
+ "flagOrJsonImport": "Missing required flags or JSON input. Correct the input following examples and try again.",
+ "id": "Missing the required '--test-suite-id' flag. Add the flag and try again.",
+ "missingVersionWithId": "Missing flag '--property-version'. Correct your input and try again. Example: --property-id '4567' --property-version '4'",
+ "missingVersionWithName": "Missing flag '--property-version'. Correct your input and try again. Example: --property-name 'example.com' --property-version '4'",
+ "missingIdOrNameWithVersion": "Missing one of the flags, either '--property-id' or '--property-name'. Correct your input and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "testSuiteId": "Missing the required test suite id in json. Run the 'test-suite list' command to get the ID value. Add the value and try again."
+ },
+ "invalid": {
+ "all": "Invalid request. At least one provided value needs to be different from current settings of the test suite.",
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "propertyIdError": "Invalid '--property-id' flag value. It needs to be a number and it needs to be used together with the '--property-version' flag. Correct the input and try again. Example: --property-id '4567' --property-version '4'",
+ "propertyVersionError": "Invalid '--property-version' flag value. It needs to be a number and it needs to be used together with the '--property-id' or '--property-name' flag. Correct the input and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "propertyCombinationError": "Invalid combination of '--property-id' and '--property-name' flag value. Enter a valid property id or property name along with its version and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "removeProperty": "Invalid '--property-name', '--property-version' and '--remove-property' flags usage. Provide either '--remove-property' or '--property-name' and '--property-version' and try again.",
+ "lockedUnlocked": "Invalid '--locked' and '--unlocked' flags usage. Provide either '--locked' or '--unlocked' and try again.",
+ "statefulStateless": "Invalid '--stateful' and '--stateless' flags usage. Provide either '--stateful' or '--stateless' and try again."
+ }
+ },
+ "update": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator.",
+ "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved."
+ },
+ "validationError": {
+ "alreadyAssociatedToRequirement": "This test suite is already associated with a requirement. Test suites can be associated either to a requirement or a property version, not both. Remove the association or select a different test suite and try again.",
+ "resourceInDeletedState": "You can't edit this test suite because it's in the deleted state. Restore it and try again.",
+ "testRunsInProgress": "You can't edit test suites involved in a test run in progress. Wait until the test run is complete and try again.",
+ "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again.",
+ "existingAssociatedTestCasesHaveDifferentClientProfiles": "In a stateful test suite you can add only functional test cases that use the same client profile as the test cases already included in this test suite.",
+ "onlyOwnerCanChangeLockedStatus": "You can't edit the Locked status because you don't have the Owners access. Request it using the Test Center UI and try again once your request is approved.",
+ "requiredFieldMissing": "The '{{requestField}}' property is missing.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit. Correct your input and try again.",
+ "setVariablesUsedWithStatelessTestSuite": "You cannot change the state of a test suite if it contains one or more test cases with variables assigned dynamically. Remove these variables and try again."
+ },
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
+ "resourceNotFound": "The requested '{{requestField}}' can't be found."
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to get the test suite. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID can't be found. Run the 'test-suite list' command to verify the ID and try again."
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "editTestSuite": "Editing test suite"
+ },
+ "display": {
+ "editTSSuccess": "Test suite edited"
+ }
+ }
+ },
+ "list": {
+ "short": "Lists test suites available for your account.",
+ "long": "This command lists test suites available for your account. You can filter the results by user, property the test suite is associated with, or a string from test suite's name or description. The list includes also the recently deleted test suites that you can restore.",
+ "propertyId": "Optional. Property ID you want the test suite to be associated with, for example '4567'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyName": "Optional. Filters the list for a property name the test suite is associated with, for example 'example.com_pm'.",
+ "propertyVersion": "Optional. Filters the list for a property version the test suite is associated with, for example '4'. This flag needs to be combined with either the '--property-id' or '--property-name' flag.",
+ "user": "Optional. Filters the list for a username who created, modified, or deleted the test suite.",
+ "search": "Optional. Filters the list for a string value present in a test suite's name or description.",
+ "flag": {
+ "missing": {
+ "missingVersionWithId": "Missing flag '--property-version'. Correct your input and try again. Example: --property-id '4567' --property-version '4'",
+ "missingVersionWithName": "Missing flag '--property-version'. Correct your input and try again. Example: --property-name 'example.com' --property-version '4'",
+ "missingIdOrNameWithVersion": "Missing one of the flags, either '--property-id' or '--property-name'. Correct your input and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'"
+ },
+ "invalid": {
+ "propertyIdError": "Invalid '--property-id' flag value. It needs to be a number and it needs to be used together with the '--property-version' flag. Correct the input and try again. Example: --property-id '4567' --property-version '4'",
+ "propertyVersionError": "Invalid '--property-version' flag value. It needs to be a number and it needs to be used together with the '--property-id' or '--property-name' flag. Correct the input and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "propertyCombinationError": "Invalid combination of '--property-id' and '--property-name' flag value. Enter a valid property id or property name along with its version and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'"
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator."
+ },
+ "validationError": "The '{{requestField}}' is missing for the property.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suites"
+ },
+ "display": {
+ "noTestSuiteFoundWarning": "No test suites found"
+ }
+ }
+ },
+ "get": {
+ "short": "Returns overview of a specific test suite.",
+ "long": "This command returns overview of a test suite with a specific ID.",
+ "testSuiteId": "Unique identifier of the test suite you want to get the details of. Run the 'test-suite list' command to get this value. Provide one of these flags, either '--test-suite-id' or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite you want ot get the details of. Run the 'test-suite list' command to get this value. Provide one of these flags, either '--test-suite-name' or '--test-suite-id'.",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Those test cases are hidden.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "flag": {
+ "missing": {
+ "any": "Missing one of the required flags, either '--test-suite-id' or '--test-suite-name'. Add the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite"
+ },
+ "display": {
+ "testSuiteDetails": "TEST SUITE OVERVIEW",
+ "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
+ "noTestSuiteFoundWarning": "No test suites found"
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to verify the ID and try again.",
+ "validationError": {
+ "resourceInDeletedState": "You can't view this test suite because it's in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ }
+ },
+ "createWithChildObjects": {
+ "short": "Imports a JSON test suite.",
+ "long": "This command imports a test suite from a JSON file or standard JSON input.",
+ "flag": {
+ "missing": {
+ "json": "Missing JSON data. Pass the JSON data and try again."
+ },
+ "invalid": {
+ "json": "Failed to import the test suite from entered JSON data. Correct the input following examples and try again."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator."
+ },
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
+ "duplicateResourceInPayload": "The requested '{{requestField}}' has some duplicates. Remove the duplicates and try again.",
+ "urlShouldContainPath": "Missing path in the URL. Correct the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
+ "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
+ "resourceNotFound": "The '{{requestField}}' couldn't be found. Make sure the request values '{{requestValues}}' are present and try again.",
+ "invalidCharacterFound": "The requested '{{requestField}}' contains invalid characters. Correct the values and try again.",
+ "malformedExpressionFound": "The requested '{{requestField}}' contains malformed expressions. Correct the values and try again.",
+ "invalidConditionExpression": "The requested '{{requestField}}' contains invalid conditions. Verify the entered values, format, and type and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
+ "validationError": {
+ "alreadyAssociatedToRequirement": "This test suite is already associated with a requirement. Test suites can be associated either with a requirement or a property version, not both. Remove the association or select a different test suite and try again.",
+ "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again.",
+ "existingAssociatedTestCasesHaveDifferentClientProfiles": "In a stateful test suite you can add only functional test cases that use the same client profile as the test cases already included in this test suite.",
+ "requiredFieldMissing": "The '{{requestField}}' property is missing.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit. Correct your input and try again.",
+ "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
+ "testRequestClientProfileLimitExceeded": "The number of test request and client profiles in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for client profiles exceeding the limit.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
+ "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "invalidClientRequestMethodCombination": "Invalid combination of client and request method. HEAD and POST request methods are allowed only with CURL client.",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again."
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "importTestSuite": "Importing test suite"
+ },
+ "display": {
+ "importTSTestCaseFailed": "Failed to import some test cases. Run the 'test-suite manage' command to update the test suite.",
+ "importTSVariableFailed": "Failed to import some variables. Run the 'test-suite manage' command to update the test suite.",
+ "testSuiteDetails": "TEST SUITE DETAILS",
+ "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
+ "noTestSuiteFoundWarning": "No test suites to import found",
+ "testCasesAdded": "Test cases imported",
+ "variableInTestSuiteHeader": "VARIABLES IN TEST SUITE"
+ }
+ }
+ },
+ "updateWithChildObjects": {
+ "short": "Updates an existing test suite using a JSON file or standard JSON input.",
+ "long": "This command updates an existing test suite using a JSON file or standard JSON input. Provide the whole test suite object, together with test cases and variables, to include in Test Center. Only data provided in the latest JSON input will be saved.",
+ "flag": {
+ "missing": {
+ "json": "Missing JSON input. Correct the input following examples and try again.",
+ "testSuiteId": "The JSON file is missing the required 'testSuiteId' key. Run the 'test-suite list' command to get the ID value. Add the key and try again."
+ },
+ "invalid": {
+ "json": "Failed to parse JSON data. Correct the input following examples and try again."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator.",
+ "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved.",
+ "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
+ },
+ "invalidConditionExpression": "The following conditions are invalid. Verify the values, format, and type and try again: '{{requestValues}}'",
+ "resourceNotFound": "The requested '{{requestField}}' can't be found.",
+ "validationError": {
+ "alreadyAssociatedToRequirement": "This test suite is already associated with a requirement. Test suites can be associated either with a requirement or a property version, not both. Remove the association or select a different test suite and try again.",
+ "entityAlreadyExists": "The test suite with such name already exists. Provide a new name and try again.",
+ "existingAssociatedTestCasesHaveDifferentClientProfiles": "In a stateful test suite you can add only functional test cases that use the same client profile as the test cases already included in this test suite.",
+ "requiredFieldMissing": "The '{{requestField}}' is missing.",
+ "onlyOwnerCanChangeLockedStatus": "You can't edit the Locked status because you don't have the Owners access. Request the Owner access using the Test Center UI and try again once your request is approved.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit.",
+ "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
+ "resourceNotFound": "The requested '{{requestField}}' can't be found for some of the fields. Verify the included objects and try again.",
+ "duplicateResourceInPayload": "The requested '{{requestField}}' has some duplicates. Remove the duplicates and try again.",
+ "duplicateResourceWithDifferentId": "The requested '{{requestField}}' has some duplicates with different IDs. Verify the included objects and try again.",
+ "testRunsInProgress": "You can't remove test cases involved in a test run in progress. Wait until the test run is complete and try again.",
+ "invalidCharacterFound": "The requested '{{requestField}}' has some invalid characters. Correct the values and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
+ "resourceInDeletedState": "You can't edit this test suite because it's in the deleted state. Restore it and try again.",
+ "malformedExpressionFound": "The requested '{{requestField}}' has some malformed expressions. Correct the values and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
+ "invalidConditionExpression": "The requested '{{requestField}}' has some invalid conditions. Verify the entered values, format, and type and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
+ "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
+ "testRequestClientProfileLimitExceeded": "The number of test request client profiles in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for client profiles exceeding the limit."
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "manageTestSuite": "Updating test suite"
+ },
+ "display": {
+ "manageTSSuccess": "Test suite '%s' edited"
+ }
+ }
+ },
+ "getWithChildObjects": {
+ "short": "Returns details of a specific test suite and child objects, test cases and variables.",
+ "long": "This command returns details of a test suite with a specific ID: test suite overview, included test cases and variables, and association with a property version.",
+ "testSuiteId": "Unique identifier of the test suite you want to get the details of. Run the 'test-suite list' command to get this value. Provide one of these flags, either '--test-suite-id' or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite you want ot get the details of. Run the 'test-suite list' command to get this value. Provide one of these flags, either '--test-suite-name' or '--test-suite-id'.",
+ "groupBy": "Optional. Specifies the grouping of included cases. Available values are: 'condition', 'test-request', or 'client-profile'.",
+ "resolveVariables": "Returns test cases with statically assigned variables resolved, `false` by default",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Those test cases are hidden.",
+ "flag": {
+ "missing": {
+ "any": "Missing one of the required flags, either '--test-suite-id' or '--test-suite-name'. Add the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "groupBy": "Invalid '--group-by' flag value. Available values are: 'condition', 'test-request', or 'client-profile'. Correct the input and try again."
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view the test suites. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to verify the ID and try again.",
+ "validationError": {
+ "resourceInDeletedState": "You can't view this test suite because it's in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "testSuiteWithChildObject": "Getting test suite with child objects"
+ },
+ "display": {
+ "testSuiteDetails": "TEST SUITE DETAILS",
+ "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
+ "noTestSuiteFoundWarning": "No test suites found",
+ "testCaseHeader": "INCLUDED TEST CASES",
+ "variableInTestSuiteHeader": "INCLUDED VARIABLES",
+ "noTestCaseWarning": "No test cases found for the test suite.",
+ "noVariablesFoundWarning": "No variables found for the test suite.",
+ "derivedTestCaseHeader": "DERIVED TEST CASES"
+ }
+ }
+ },
+ "generateDefault": {
+ "short": "Generates a default test suite for a specific property version.",
+ "long": "This command generates a default test suite for a property version using provided URLs. Based on property settings and its behaviors and the '--url' flag value, Test Center generates a test suite object with test cases and variables for you to modify and add to Test Center using the 'test-suite import' command.",
+ "propertyId": "Optional. Property ID you want the test suite to be associated with, for example '4567'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyName": "Property name you want to generate the test suite for, for example 'example.com'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyVersion": "Property version you want to generate the test suite for, for example '4'. This flag needs to be combined with either the '--property-id' or '--property-name' flag.",
+ "url": "Fully qualified URL to be included in the generated test suite. Repeat this flag to provide more than one URL.",
+ "flag": {
+ "missing": {
+ "url": "Missing the required '--url' flag. Add the flag and try again.",
+ "propertyVersion": "Missing required flags,'--property-id' or '--property-name', and --property-version. Provide all required data and try again. Examples: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "missingVersionWithId": "Missing flag '--property-version'. Correct your input and try again. Example: --property-id '4567' --property-version '4'",
+ "missingVersionWithName": "Missing flag '--property-version'. Correct your input and try again. Example: --property-name 'example.com' --property-version '4'",
+ "missingIdOrNameWithVersion": "Missing one of the flags, either '--property-id' or '--property-name'. Correct your input and try again. Examples: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "flagOrJsonImport": "Missing required flags or JSON input. Correct the input following examples and try again."
+ },
+ "invalid": {
+ "url": "Invalid URL value. It needs to contain the protocol, hostname, path, and any applicable string parameters. For example 'https://www.example.com'. Correct your input and try again.",
+ "propertyIdError": "Invalid '--property-id' flag value. It needs to be a number and it needs to be used together with the '--property-version' flag. Correct the input and try again. Example: --property-id '4567' --property-version '4'",
+ "propertyVersionError": "Invalid '--property-version' flag value. It needs to be a number and it needs to be used together with the '--property-id' or '--property-name' flag. Correct the input and try again. Examples: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "propertyCombinationError": "Invalid combination of '--property-id' and '--property-name' flag value. Enter a valid property id or property name along with its version and try again. Examples: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "json": "Failed to parse JSON data. Correct the input following examples and try again."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to generate the default test suite. Contact your Account administrator."
+ },
+ "resourceNotFound": "The requested '{{requestField}}' can't be found.",
+ "validationError": {
+ "hostnameAccessMissingForGivenConfig": "These hostnames doesn't belong to the given property version: '{{requestValues}}'.",
+ "requiredFieldMissing": "The '{{requestField}}' property is missing.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again."
+ },
+ "invalidRequest": "Method not allowed",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "generateDefaultTestSuite": "Generating default test suite"
+ },
+ "display": {
+ "generateDefaultTSSuccess": "Default test suite based on '%s %d' generated. Review and update the JSON test suite and use the 'test-suite import' command to add it as a new test suite."
+ }
+ }
+ },
+ "remove": {
+ "short": "Removes a specific test suite.",
+ "long": "This command removes a test suite with a specific ID. You can restore removed test suites for 30 days since their removal.",
+ "testSuiteId": "Unique identifier for the test suite you want to remove. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-id'.",
+ "flag": {
+ "missing": {
+ "any": "Missing one of the required flags, either '--test-suite-id' or '--test-suite-name'. Add the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again."
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "userIsNotOwner": "Only test suite's Owners can perform this action. Request the Owner access using the Test Center UI and try again once your request is approved.",
+ "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved."
+ },
+ "resourceNotFound": "The test suite with this ID can't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "validationError": {
+ "resourceInDeletedState": "Test suite is already removed."
+ }
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "removeTestSuite": "Removing test suite"
+ },
+ "display": {
+ "removeTSSuccess": "Test suite removed. You can restore using the command ",
+ "removeTSSuccessInBold": "akamai test-center test-suite restore --id %v",
+ "removeTSSuccessEnd": " within 30 days.",
+ "testSuiteDetails": "TEST SUITE DETAILS",
+ "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
+ "noTestSuiteFoundWarning": "No test suites found"
+ }
+ }
+ },
+ "restore": {
+ "short": "Restores a test suite with a specific ID.",
+ "long": "This command restores a test suite with a specific ID. You can restore removed test suites for 30 days since their removal.",
+ "testSuiteId": "Unique identifier for the test suite you want to remove. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-id'.",
+ "flag": {
+ "missing": {
+ "any": "Missing one of the required flags, either '--test-suite-id' or '--test-suite-name'. Provide all required data and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again."
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "userIsNotOwner": "Only test suite's Owners can perform this action. Request the Owner access using the Test Center UI and try again once your request is approved.",
+ "userIsNotOwnerOrEditor": "You don't have the Edit access to this test suite. Request the Edit access using the Test Center UI and try again once your request is approved."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to verify the ID and try again.",
+ "validationError": {
+ "resourceNotInDeletedState": "Resource is not in the deleted state. Run the 'test-suite view' command to check its details."
+ }
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "restoreTestSuite": "Restoring test suite"
+ },
+ "display": {
+ "restoreTSSuccess": "Test suite restored",
+ "testSuiteDetails": "TEST SUITE DETAILS",
+ "noTestSuiteFoundWithName": "Test suite with '%s' name can't be found.",
+ "noTestSuiteFoundWarning": "No test suites found"
+ }
+ }
+ }
+ },
+ "testCase": {
+ "short": "List commands available for test cases.",
+ "long": "Test cases are the smallest unit of testing. You can get, create, edit, or remove test cases.",
+ "subCommand": {
+ "invalid": {
+ "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
+ }
+ },
+ "create": {
+ "short": "Adds a functional test case to a specific test suite.",
+ "long": "This command adds a functional test case to a test suite with a specific ID.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "testSuiteId": "Unique identifier for the test suite you want to add test cases to. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite you want to add test cases to. You need to provide either this flag or '--test-suite-id'.",
+ "url": "Fully qualified URL of the resource to test, for example 'https://example.com/'.",
+ "addHeader": "Optional. Header to be added to the request in the format: 'name: value'.",
+ "modifyHeader": "Optional. Existing header to be modified in the request in the format: 'name: value'.",
+ "filterHeader": "Optional. Existing header to be filtered out from the request, specified as 'name'.",
+ "condition": "Condition statement from the list of supported conditions with entered required values. To get the list of supported conditions, run the 'conditions' command. Make sure to substitute default values in \" \" with your own. Examples: 'Content provider code is \"12345\"', 'Origin server - Cache key hostname is \"www.example.com\"'.",
+ "ipVersion": "Optional. IP version to execute the test case over, either 'v4' or 'v6'. It's set to 'v4' by default.",
+ "client": "Optional. Client profile you want to create the test case with, either 'CURL' or 'CHROME'.",
+ "requestMethod": "Optional. Request method for the test requests, either 'GET', 'HEAD', or 'POST'. The 'CHROME' client type supports only the 'GET' method.",
+ "encodeRequestBody": "Optional. Encodes the request body. Its applicable only for the 'CURL' client type and the 'POST' request method.",
+ "requestBody": "Optional. Request body you want to send while running the test. Its applicable only for the 'CURL' client type and the 'POST' request method.",
+ "setVariables": "Optional. Variables you want to create or to be resolve at run time, in the format: 'variableName:variableValue'.",
+ "flag": {
+ "missing": {
+ "any": "Missing at least one of the required flags,'--test-suite-id' or '--test-suite-name', '--url', or '--condition'. Provide all required data and try again."
+ },
+ "invalid": {
+ "testSuiteId": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "ipVersion": "Invalid IP version value. Available values are 'v4' or 'v6'. Correct the input and try again.",
+ "addHeader": "Invalid '--add-header' flag value. Make sure it follows the 'name: value' format and try again.",
+ "modifyHeader": "Invalid '--modify-header' flag value. Make sure it follows the 'name: value' format and try again.",
+ "client": "Invalid client value. Available values are 'CURL' or 'CHROME'. Correct the input and try again.",
+ "requestMethod": "Invalid request method value. Available request method are either 'GET', 'HEAD', or 'POST'. The 'CHROME' client type supports only the 'GET' method. Correct the input and try again.",
+ "requestMethodWithClient": "The 'CHROME' Client type supports only the 'GET' method. Correct the input and try again.",
+ "requestBody": "Redundant request body value. Request body is applicable only for the 'CURL' client type and the 'POST' request method.",
+ "encodeRequestBody": "Redundant '--encodeRequestBody' flag. Encoding of request body applies only for non-empty request body, 'CURL' client type, and 'POST' request method.",
+ "setVariables": "Invalid '--set-variables' flag value. Make sure it follows the 'VariableName: VariableValue' format and try again."
+ }
+ },
+ "warnings": {
+ "duplicateDerivedTestcasesIgnored": "Duplicate derived test cases generated have been ignored."
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "addTestCase": "Adding test case to test suite"
+ },
+ "display": {
+ "addTestCaseSuccess": "Test cases added to '%s' test suite",
+ "addTestCaseFail": "Failed to add test case to '%s' test suite",
+ "addTestCaseNoTestSuite": "Failed to add test case. The '%s' test suite couldn't be found."
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view test suites. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "validationError": {
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator.",
+ "userIsNotOwnerOrEditor": "You don't have the Edit access to the test suite. Request the Edit access using the Test Center UI and try again once your request is approved.",
+ "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
+ },
+ "validationError": {
+ "resourceInDeletedState": "You can't add test cases to this test suite because it's in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
+ "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
+ "clientProfileOfExistingAssociatedTestCasesDoNotMatch": "The test suite to which you are trying to add test cases is stateful. It accepts only test cases with the same client profile as test cases already included in the test suite. Change the test cases or add it to a different test suite.",
+ "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
+ "variableGroupNotAllowedInSetVariable": "You can't use variable groups in the setVariables section. Correct the input and try again.",
+ "errorInDerivedTestcase": {
+ "hostnameAccessMissing": "You don't have access to at least one of the the hostnames of included derived test cases. Get the access or edit the hostnames and try again.",
+ "duplicateResourceInPayload": "The requested header names have some duplicates in the derived test cases. Check the input and try again.",
+ "malformedExpressionFound": "Request contains unsupported data format in derived test cases, Correct the input and try again.",
+ "invalidConditionExpression": "The condition in derived test cases is invalid. Verify the entered values, format, and type and try again.",
+ "urlShouldContainPath": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing a path in derived test cases. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters in derived test cases. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters in derived test cases. Edit the URL and try again."
+ },
+ "malformedExpressionFound": "Request contains unsupported data format, Correct the input and try again.",
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
+ "resourceNotFound": {
+ "testSuiteIdResourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "variableNameResourceNotFound": "The {{requestField}} couldn't be found. Make sure the request values {{requestValues}} are present and try again."
+ },
+ "duplicateResourceInPayload": "The requested header or set variable names have some duplicates. Remove the duplicates and try again.",
+ "urlShouldContainPath": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing a path. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
+ "invalidConditionExpression": "The condition is invalid. Verify the entered values, format, and type and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
+ "entityAlreadyExists": "Such test case already exists.",
+ "invalidClientRequestMethodCombination": "Invalid combination of client and request method. HEAD and POST request methods are allowed only with CURL client.",
+ "setVariablesUsedWithStatelessTestSuite": "You can't use setVariables with stateless test suites. Edit the test suite and try again."
+ },
+ "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
+ "entityAlreadyExists": "Such test case already exists.",
+ "resourceInDeletedState": "You can't add test cases to this test suite because it's in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
+ "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
+ "requiredFieldMissing": "The '{{requestField}}' is missing.",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
+ "variableGroupNotAllowedInSetVariable": "You can't use variable groups in the setVariables section. Correct the input and try again.",
+ "errorInDerivedTestcase": {
+ "hostnameAccessMissing": "You don't have access to at least one of the the hostnames of included derived test cases. Get the access or edit the hostnames and try again.",
+ "duplicateResourceInPayload": "The requested header names have some duplicates in the derived test cases. Check the input and try again.",
+ "malformedExpressionFound": "Request contains unsupported data format in derived test cases, Correct the input and try again.",
+ "invalidConditionExpression": "The condition in derived test cases is invalid. Verify the entered values, format, and type and try again.",
+ "urlShouldContainPath": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing a path in derived test cases. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters in derived test cases. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters in derived test cases. Edit the URL and try again."
+ },
+ "malformedExpressionFound": "Request contains unsupported data format. Correct the input and try again.",
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
+ "resourceNotFound": {
+ "testSuiteIdResourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "variableNameResourceNotFound": "The {{requestField}} couldn't be found. Make sure the request values {{requestValues}} are present and try again."
+ },
+ "duplicateResourceInPayload": "The requested header or set variable names have some duplicates. Remove the duplicates and try again.",
+ "urlShouldContainPath": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing a path. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
+ "invalidConditionExpression": "The condition is invalid. Verify the entered values, format, and type and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "invalidClientRequestMethodCombination": "Invalid combination of client and request method. HEAD and POST request methods are allowed only with CURL client."
+ },
+ "update": {
+ "short": "Updates a functional test case of a specific test suite.",
+ "long": "This command updates a functional test case of a test suite.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "testSuiteId": "Unique identifier for the test suite you want to add test cases to. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite you want to get the test cases for. To get this value, run the 'test-suite list' command. To test a test suite, provide either this flag or '--test-suite-id'.",
+ "testCaseId": "Test case ID of the test case you want to update. To get this value, run the 'test-case list' command for the specific test suite ID.",
+ "url": "Fully qualified URL of the resource to test, for example 'https://example.com/'.",
+ "addHeader": "Optional. Header to be added to the request in the format: 'name: value'.",
+ "modifyHeader": "Optional. Existing header to be modified in the request in the format: 'name: value'.",
+ "filterHeader": "Optional. Existing header to be filtered out from the request, specified as 'name'.",
+ "condition": "Condition statement from the list of supported conditions with entered required values. To get the list of supported conditions, run the 'conditions' command. Make sure to substitute default values in \" \" with your own. Examples: 'Content provider code is \"12345\"' or 'Origin server - Cache key hostname is \"www.example.com\"'.",
+ "ipVersion": "Optional. IP version to execute the test case over, either 'v4' or 'v6'. It's set to 'v4' by default.",
+ "client": "Optional. Client profile you want to create the test case with, either 'CURL' or 'CHROME'.",
+ "requestMethod": "Optional. Request method for the test requests, either 'GET', 'HEAD', or 'POST'. The 'CHROME' client type supports only the 'GET' method.",
+ "encodeRequestBody": "Optional. Encodes the request body. Its applicable only for the 'CURL' client type and the 'POST' request method.",
+ "requestBody": "Optional. Request body you want to send while running the test. Its applicable only for the 'CURL' client type and the 'POST' request method.",
+ "setVariables": "Optional. Variables you want to create or to be resolve at run time, in the format: 'variableName:variableValue'.",
+ "flag": {
+ "missing": {
+ "any": "Missing at least one of the required flags,'--test-suite-id',--test-case-id, '--url', '--condition'. Provide all required data and try again.",
+ "testCaseId": "Missing the required '--test-case-id' flag. Provide required data and try again."
+ },
+ "invalid": {
+ "testSuiteId": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "testCaseId": "Invalid test case ID value. It needs to be a number. To get this value, run the 'test-case list' command. Correct the input and try again.",
+ "ipVersion": "Invalid IP version value. Available values are 'v4' or 'v6'. Correct the input and try again.",
+ "addHeader": "Invalid '--add-header' flag value. Make sure it follows the 'name: value' format and try again.",
+ "modifyHeader": "Invalid '--modify-header' flag value. Make sure it follows the 'name: value' format and try again.",
+ "client": "Invalid client value. Available values are 'CURL' or 'CHROME'. Correct the input and try again.",
+ "requestMethod": "Invalid request method value. Available request method are either 'GET', 'HEAD', or 'POST'. The 'CHROME' client type supports only the 'GET' method. Correct the input and try again.",
+ "requestMethodWithClient": "The 'CHROME' Client type supports only the 'GET' method. Correct the input and try again.",
+ "requestBody": "Redundant request body value. Request body is applicable only for the 'CURL' client type and the 'POST' request method.",
+ "encodeRequestBody": "Redundant '--encodeRequestBody' flag. Encoding of request body applies only for non-empty request body, 'CURL' client type, and 'POST' request method.",
+ "setVariables": "Invalid '--set-variables' flag value. Make sure it follows the 'VariableName: VariableValue' format and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "updateTestCase": "Updating test case of a test suite"
+ },
+ "display": {
+ "updateTestCaseSuccess": "Test case updated of a '%s' test suite",
+ "updateTestCaseFail": "Failed to update test case to '%s' test suite",
+ "updateTestCaseNoTestSuite": "Failed to update test case. The '%s' test suite couldn't be found."
+ }
+ },
+ "warnings": {
+ "duplicateDerivedTestcasesIgnored": "Duplicate derived test cases generated have been ignored."
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view test suites. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "validationError": {
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator.",
+ "userIsNotOwnerOrEditor": "You don't have the Edit access to the test suite. Request the Edit access using the Test Center UI and try again once your request is approved.",
+ "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
+ },
+ "validationError": {
+ "resourceInDeletedState": "You can't add test cases to this test suite because it's in the deleted state. Restore test suite and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
+ "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
+ "clientProfileOfExistingAssociatedTestCasesDoNotMatch": "The test suite to which you are trying to add test cases is stateful. It accepts only test cases with the same client profile as test cases already included in the test suite. Change the test cases or add it to a different test suite.",
+ "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
+ "requiredFieldMissing": "The '{{requestField}}' is missing.",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
+ "variableGroupNotAllowedInSetVariable": "You can not use variable group under setVariables section. Correct the input and try again.",
+ "errorInDerivedTestcase": {
+ "hostnameAccessMissing": "You don't have access to at least one of the the hostnames of included derived test cases. Get the access or edit the hostnames and try again.",
+ "duplicateResourceInPayload": "The requested header names have some duplicates in the derived test cases. Check the input and try again.",
+ "malformedExpressionFound": "Request contains unsupported data format in derived test cases, Correct the input and try again.",
+ "invalidConditionExpression": "The condition in derived test cases is invalid. Verify the entered values, format, and type and try again.",
+ "urlShouldContainPath": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing a path in derived test cases. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters in derived test cases. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters in derived test cases. Edit the URL and try again."
+ },
+ "malformedExpressionFound": "Request contains unsupported data format, Correct the input and try again.",
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
+ "resourceNotFound": {
+ "testSuiteIdResourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "testCaseIdResourceNotFound": "The test case with this ID couldn't be found. Run the 'test-case list' command to make sure the ID is correct and try again.",
+ "variableNameResourceNotFound": "The {{requestField}} couldn't be found. Make sure the request values {{requestValues}} are present and try again."
+ },
+ "duplicateResourceInPayload": "The requested header or set variable names have some duplicates. Remove the duplicates and try again.",
+ "urlShouldContainPath": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing a path. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
+ "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
+ "invalidConditionExpression": "The condition is invalid. Verify the entered values, format, and type and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "entityAlreadyExists": "Such test case already exists.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "invalidClientRequestMethodCombination": "Invalid combination of client and request method. HEAD and POST request methods are allowed only with CURL client.",
+ "setVariablesUsedWithStatelessTestSuite": "You can't use setVariables with stateless test suites. Edit the test suite and try again."
+ },
+ "resourceInDeletedState": "You can't add test cases to this test suite because it's in the deleted state. Restore test suite and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
+ "maxAssociationsExceeded": "The number of test cases in this test suite exceeded the limit of '{{maxLimit}}'. Create a new test suite for test cases exceeding the limit.",
+ "clientProfileOfExistingAssociatedTestCasesDoNotMatch": "The test suite to which you are trying to add test cases is stateful. It accepts only test cases with the same client profile as test cases already included in the test suite. Change the test cases or add it to a different test suite.",
+ "testCasesContainsHeterogeneousClientProfiles": "In stateful test suites, test cases need to have the same client profile. Edit the test cases and try again.",
+ "requiredFieldMissing": "The '{{requestField}}' is missing.",
+ "hostnameAccessMissing": "You don't have access to all the hostnames of included test cases. Get the access or edit the hostnames and try again.",
+ "variableGroupNotAllowedInSetVariable": "You can't use variable groups in the setVariables section. Correct the input and try again.",
+ "errorInDerivedTestcase": {
+ "hostnameAccessMissing": "You don't have access to at least one of the the hostnames of included derived test cases. Get the access or edit the hostnames and try again.",
+ "duplicateResourceInPayload": "The requested header names have some duplicates in the derived test cases. Check the input and try again.",
+ "malformedExpressionFound": "Request contains unsupported data format in derived test cases, Correct the input and try again.",
+ "invalidConditionExpression": "The condition in derived test cases is invalid. Verify the entered values, format, and type and try again.",
+ "urlShouldContainPath": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing a path in derived test cases. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters in derived test cases. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters in derived test cases. Edit the URL and try again."
+ },
+ "malformedExpressionFound": "Request contains unsupported data format, Correct the input and try again.",
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again.",
+ "resourceNotFound": {
+ "testSuiteIdResourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "testCaseIdResourceNotFound": "The test case with this ID couldn't be found. Run the 'test-case list' command to make sure the ID is correct and try again.",
+ "variableNameResourceNotFound": "The {{requestField}} couldn't be found. Make sure the request values {{requestValues}} are present and try again."
+ },
+ "duplicateResourceInPayload": "The requested header or set variable names have some duplicates. Remove the duplicates and try again.",
+ "urlShouldContainPath": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing a path. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to update a test case for the 'Ignore case in cache key' condition. The URL is missing query parameters. Edit the URL and try again.",
+ "dataTypeMismatch": "The value of a variable in condition doesn't match the expected data type of the condition. Verify the entered condition and the value and try again.",
+ "invalidConditionExpression": "The condition is invalid. Verify the entered values, format, and type and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "entityAlreadyExists": "Such test case already exists.",
+ "invalidValue": "The '{{requestField}}' is invalid or it's an empty string. Correct your input and try again.",
+ "invalidClientRequestMethodCombination": "Invalid combination of client and request method. HEAD and POST request methods are allowed only with CURL client."
+ },
+ "remove": {
+ "short": "Removes a test case from a test suite with a specific ID.",
+ "long": "This command removes a specific test case from a test suite with a specific ID.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "getTestCases": "Getting test cases",
+ "removeTestCase": "Removing test case from test suite"
+ }
+ },
+ "testSuiteId": "Unique identifier for the test suite you want to remove the test case from. To get this value, run the 'test-suite list' command.",
+ "orderNum": "Order number of the test case you want to remove. To get this value, run the 'test-case list' command for the specific test suite ID. To remove a test case, provide either this flag or '--test-case-id'",
+ "testCaseId": "Test case ID of the test case you want to remove. To get this value, run the 'test-case list' command for the specific test suite ID. To remove a test case, provide either this flag or '--order-num'",
+ "success": "Test case removed from '%s' test suite",
+ "notPresent": "The test case with the order number or the test case id '%s' can't be found. Run the 'test-case list' command for the specific test suite ID to check included test cases and try again.",
+ "failed": "Failed to remove the test case from '%s' test suite . Try again.",
+ "flag": {
+ "missing": {
+ "any": "Missing at least one of the required flags, '--test-suite-id' and '--order-num' or '--test-case-id'. Provide all required data and try again."
+ },
+ "invalid": {
+ "testSuiteId": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "orderNum": "Invalid order number value. It needs to be a number. Run the 'test-suite view' command for the specific test suite ID to check test cases' order number and try again.",
+ "testCaseId": "Invalid test case ID value. It needs to be a number. Run the 'test-suite view' command for the specific test suite ID to check test cases' test case ID and try again.",
+ "orderNumTestCaseId": "Invalid '--order-num' and '--test-case-id' flags usage. Provide either '--order-num' or '--test-case-id' and try again."
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to remove test cases. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "validationError": {
+ "resourceInDeletedState": "You can't remove test cases from this test suite because it's in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator.",
+ "userIsNotOwnerOrEditor": "You don't have the Edit access to the test suite. Request the Edit access using the Test Center UI and try again once your request is approved.",
+ "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "resourceInDeletedState": "You can't remove test cases from this test suite because they are in the deleted state. Restore the whole test suite and try again.",
+ "associationNotFound": "Test cases you're trying to remove are not included in this test suite. Run the 'test-suite view' command for the specific test suite ID to check included test cases' and try again.",
+ "validationError": {
+ "resourceInDeletedState": "You can't remove test cases from this test suite because the test suite is in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ },
+ "get": {
+ "short": "Get a functional test case of a specific test suite.",
+ "long": "This command returns a functional test case of a specific test suite.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "testSuiteId": "Unique identifier for the test suite you want to get test cases for. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite you want to get the test cases for. To get this value, run the 'test-suite list' command. To test a test suite, provide either this flag or '--test-suite-id'.",
+ "testCaseId": "Unique identifier for the test case you want to get test cases for. To get this value, run the 'test-case list' command with particular test suite ID.",
+ "resolveVariables": "Returns test cases with statically assigned variables resolved, `false` by default.",
+ "flag": {
+ "missing": {
+ "any": "Missing at least one of the required flags,'--test-suite-id' or '--test-suite-name' or '--test-case-id' . Provide all required data and try again.",
+ "testCaseId": "Missing the required '--test-case-id' flag. Provide required data and try again"
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "testCaseId": "Invalid test case ID value. It needs to be a number. To get this value, run the 'test-case list' command. Correct the input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "getTestCase": "Getting test case of test suite"
+ },
+ "display": {
+ "getTestCaseFail": "Failed to get test cases to '%s' test suite",
+ "getTestCaseNoTestSuite": "Failed to get test cases. The '%s' test suite couldn't be found.",
+ "testCaseHeader": "TEST CASE DETAILS",
+ "variableInTestSuiteHeader": "INCLUDED VARIABLES",
+ "derivedTestCaseHeader": "DERIVED TEST CASES"
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view test suites. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again."
+ },
+ "authorizationError": {
+ "hostnameAccessMissing": "You don't have access to the hostname for the test case or the derived test cases. Get the access or edit the hostname and try again."
+ },
+ "validationError": {
+ "resourceInDeletedState": "You can't get test cases to this test suite because it's in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ },
+ "resourceNotFound": "The test case with this ID couldn't be found. Run the 'test-case list' command to make sure the ID is correct and try again."
+ },
+ "list": {
+ "short": "List all functional test case of a specific test suite.",
+ "long": "This command lists all functional test case included in a specific test suite.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "testSuiteId": "Unique identifier for the test suite you want to get test cases to. To get this value, run the 'test-suite list' command. You need to provide either this flag or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite you want to get the test cases for. To get this value, run the 'test-suite list' command. To test a test suite, provide either this flag or '--test-suite-id'.",
+ "resolveVariables": "Returns test cases with statically assigned variables resolved, `false` by default.",
+ "groupBy": "Optional. Specifies the grouping of included cases. Available values are: 'condition', 'test-request', or 'client-profile'.",
+ "flag": {
+ "missing": {
+ "any": "Missing one of the required flags,'--test-suite-id' or '--test-suite-name'. Provide all required data and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "groupBy": "Invalid '--group-by' flag value. Available values are: 'condition', 'test-request', or 'client-profile'. Correct the input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite",
+ "getTestCase": "Getting test cases of test suite"
+ },
+ "display": {
+ "getTestCaseFail": "Failed to get test cases to '%s' test suite",
+ "getTestCaseNoTestSuite": "Failed to get test cases. The '%s' test suite couldn't be found.",
+ "testCaseHeader": "INCLUDED TEST CASES",
+ "variableInTestSuiteHeader": "INCLUDED VARIABLES",
+ "noTestCaseWarning": "No test cases found for the test suite.",
+ "noVariablesFoundWarning": "No variables found for the test suite.",
+ "derivedTestCaseHeader": "DERIVED TEST CASES"
+ }
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to view test suites. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again."
+ },
+ "validationError": {
+ "resourceInDeletedState": "You can't get test cases to this test suite because it's in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again."
+ }
+ },
+ "test": {
+ "short": "List commands available for test runs.",
+ "long": "This command lets you list test runs, view a specific test run, or run a test for a property version, test suite, or a simple test case.",
+ "subCommand": {
+ "invalid": {
+ "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
+ }
+ },
+ "list": {
+ "short": "Lists test runs.",
+ "long": "This command lists test runs created by users of your account.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestRuns": "Getting test runs"
+ },
+ "display": {
+ "noTestRunsFoundWarning": "No test runs found."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to get the test runs. Contact your Account administrator."
+ },
+ "validationError": {
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ },
+ "get": {
+ "short": "Returns details of a test run.",
+ "long": "This command returns details and results of a specific test run.",
+ "testRunId": "Unique identifier of the test run you want to get the details of. Run the 'test list' command to get this value.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestRun": "Getting the test run"
+ },
+ "display": {
+ "completed": "Completed",
+ "inProgress": "In progress",
+ "completedWithUnexpectedResults": "Completed, some results not as expected",
+ "failed": "Failed",
+ "testRunHeader": "TEST SUMMARY",
+ "testRunStart": "Test run with %d ID started.",
+ "testSuiteText": "Test suite",
+ "testCasesText": "Total %d test cases - ",
+ "inProgressText": "%d in progress",
+ "passedText": "%d passed",
+ "failedText": "%d failed",
+ "systemErrorText": "%d Inconclusive",
+ "staging": "Akamai staging",
+ "production": "Akamai production",
+ "allExecutionObjectsIncluded": "You do not have access to all the hostnames of test cases included in the test run. Those test cases are hidden."
+ }
+ },
+ "flag": {
+ "missing": {
+ "testRunId": "Missing the required '--test-run-id' or '-i' flag. Add the flag and try again."
+ },
+ "invalid": {
+ "testRunId": "Invalid test run ID value. It needs to be a number. To get this value, run the 'test list' command. Correct the input and try again."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to get the results of the test run. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test run with this ID couldn't be found. Run the 'test list' command to make sure the ID is correct and try again.",
+ "validationError": {
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ },
+ "purgeOperation": {
+ "purgeAttemptFailed": "Purge operation failed.",
+ "purgeAllowedOnlyOnStaging": "Purge operation is allowed only on the staging environment.",
+ "requiredPermissionMissing": "You do not have the WRITE permission, which is required to purge cache. Contact Control Center administrator."
+ },
+ "evaluationErrors": {
+ "systemError": "System error. Rerun the test later.",
+ "cnameResolutionFailed": "Failed to resolve CNAME for {{hostname}}. Verify your DNS configuration and rerun the test.",
+ "hostnameNotAkamaized": "The tested hostname does not resolve in DNS to an Akamai edge server. CNAME the hostname to an Akamai edge hostname.",
+ "ipVersionNotSupported": "The tested hostname does not support {{ipVersion}}. Make sure the hostname supports the IP version and rerun the test.",
+ "sourceHostnameNotAccessible": "The tested hostname is not public. Make the hostname publicly available and rerun the test.",
+ "noPmPropertyFoundForTargetHostname": "The tested hostname has no corresponding active property version in Property Manager for the selected environment. Activate the property version and rerun the test.",
+ "pragmaHeadersNotFound": "The tested hostname blocks Pragma headers required to process results. Allow Pragma headers for Test Center and rerun the test.",
+ "noResponseReceived": "Either the tested hostname did not respond in time or the file size exceeded the limit. Rerun the test",
+ "failedToGetEdgeHostname": "Either the tested hostname does not have an edge hostname associated to it or Test Center couldn't get the edge hostname. Review the configuration and rerun the test",
+ "ipResolutionFailed": "Failed to resolve IP Address for {{hostname}}. Verify your DNS configuration and rerun the test.",
+ "statefulTestCaseSkipped": "Test case skipped as preceding test case encountered error.",
+ "functionExpressionResolvesToMultipleResults": "You cannot see details of test cases with dynamically assigned variables that return inconclusive values.",
+ "invalidValue": "Invalid value. The variable results in invalid values in one or more test cases where it is used."
+ }
+ },
+ "run": {
+ "short": "Runs a test for a test suite, single test case, or a property version.",
+ "long": "This command runs a test for a specific object. You can run the test for one of the following: a test suite with a specific ID or name, a property version with specific property name and version number, or a combination of URL, condition, and IP version.",
+ "testSuiteId": "Unique identifier for the test suite you want to run the test for. To get this value, run the 'test-suite list' command. To test a test suite, provide either this flag or '--test-suite-name'.",
+ "testSuiteName": "Name of the test suite you want to run the test for. To get this value, run the 'test-suite list' command. To test a test suite, provide either this flag or '--test-suite-id'.",
+ "url": "Fully qualified URL of the resource to test, for example 'https://example.com/'. This flag needs to be combined with '--ip-version' and '--condition' flags.",
+ "addHeader": "Optional. Header to be added to the request in the format: 'name: value'. This flag needs to be combined with '--url', '--ip-version', and '--condition' flags.",
+ "modifyHeader": "Optional. Existing header to be modified in the request in the format: 'name: value'. This flag needs to be combined with '--url', '--ip-version', and '--condition' flags.",
+ "filterHeader": "Optional. Existing header to be filtered out from the request, specified as 'name'. This flag needs to be combined with '--url', '--ip-version', and '--condition' flags.",
+ "condition": "Condition statement from the list of supported conditions with entered required values. To get the list of supported conditions, run the 'conditions' command. Make sure to substitute default values in '\" \"' with your own. Examples: 'Content provider code is \"12345\"' or 'Origin server - Cache key hostname is \"www.example.com\"'. This flag needs to be combined with '--ip-version' and '--url' flags.",
+ "ipVersion": "Optional. IP version to execute the test case over, either 'v4' or 'v6'. This flag needs to be combined with '--url' and '--condition' flags.",
+ "propertyId": "Optional. Property Id you want the test suite to be associated with, for example '4567'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyName": "Property name you want to run the test for, for example 'example.com'. This flag needs to be combined with the '--property-version' flag.",
+ "propertyVersion": "Property version you want to run the test for, for example '4'. This flag needs to be combined with the '--property-id' or '--property-name' flag.",
+ "env": "Optional. Target environment you want to run the test on, either 'STAGING' or 'PRODUCTION'.",
+ "client": "Optional. client you want to run the test with, either 'CURL' or 'CHROME'.",
+ "location": "Optional. location where you want to run the test, Current supported location is 'US' only.",
+ "requestMethod": "Optional. Request Method for the test requests, either 'GET' or 'HEAD' or 'POST'. client type - 'CHROME' only supports 'GET' method.",
+ "encodeRequestBody": "Optional. Whether you want to encode request body while making request for the test run, Supported with client type 'CURL' and request method 'POST' only.",
+ "requestBody": "Optional. Request Body you want to send while making request for the test run, Supported with client type 'CURL' and request method 'POST' only.",
+ "testSuiteNameNotFound": "The test suite with the name '%s' couldn't be found. Run the 'test-suite list' command to get this value and try again.",
+ "testCasesNotFound": "The test suite has no test cases included. Add test cases to it and try again.",
+ "propertyVersionNotFound": "The requested property name and version couldn't be found. Make sure the value is correct and try again.",
+ "propertyVersionTestSuitesNotFound": "The requested property version is not associated with any test suites. Create a new test suite, associate it with the property, and create appropriate test cases, and try again.",
+ "noTestCases": "No test cases to run. Make sure that the property version is associated with test suites that include test cases in them and try again.",
+ "flag": {
+ "missing": {
+ "flagOrJsonImport": "Missing required flags or JSON input. Correct the input following examples and try again.",
+ "any": "Missing required flags. To run the test for a test suite provide '--test-suite-id' or '--test-suite-name'. To run a test for a property version provide '--property-name' and '--property-version'. To run a test for a single test case provide '--url', '--ip-version' and '--condition' flags.",
+ "condition": "Missing the required '--condition' flag. Correct the input and try again.",
+ "url": "Missing the required '--url' flag. Correct the input and try again.",
+ "missingVersionWithId": "Missing the '--property-version' flag. Correct your input and try again. Example: --property-id '4567' --property-version '4'",
+ "missingVersionWithName": "Missing the '--property-version' flag. Correct your input and try again. Example: --property-name 'example.com' --property-version '4'",
+ "missingIdOrNameWithVersion": "Missing one of the flags, either '--property-id' or '--property-name'. Correct your input and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'"
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test-suite list' command. Correct the input and try again.",
+ "propertyIdError": "Invalid '--property-id' flag value. It needs to be a number and it needs to be used together with the '--property-version' flag. Correct the input and try again. Example: --property-id '4567' --property-version '4'",
+ "propertyVersionError": "Invalid '--property-version' flag value. It needs to be a number and it needs to be used together with the '--property-id' or '--property-name' flag. Correct the input and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "propertyCombinationError": "Invalid combination of '--property-id' and '--property-name' flag value. Enter a valid property id or property name along with its version and try again. Example: --property-name 'example.com' --property-version '4', --property-id '4567' --property-version '4'",
+ "ipVersion": "Invalid IP version value. Available values are 'v4' or 'v6'. Correct the input and try again.",
+ "addHeader": "Invalid '--add-header' flag value. Make sure it follows the 'name: value' format and try again.",
+ "modifyHeader": "Invalid '--modify-header' flag value. Make sure it follows the 'name: value' format and try again.",
+ "targetEnvironment": "Invalid target environment value. Available values are uppercase 'STAGING' or 'PRODUCTION'. Correct the input and try again.",
+ "exclusive": "Invalid request due to incorrect combination of flags. To run the test for a test suite provide '--test-suite-id' or '--test-suite-name'. To run a test for a property version provide '--property-name' and '--property-version'. To run a test for a single test case provide '--url', '--ip-version' and '--condition' flags. Correct the input following examples and try again.",
+ "client": "Invalid client value. Available values are 'CURL' or 'CHROME'. Correct the input and try again.",
+ "location": "Invalid location value. By default current supported location is 'US' only.",
+ "requestMethod": "Invalid request method value. Request Method for the test requests, either 'GET' or 'HEAD' or 'POST'. client type - 'CHROME' only supports 'GET' method. Correct the input and try again.",
+ "requestMethodWithClient": "Client type - 'CHROME' only supports 'GET' method. Correct the input and try again.",
+ "requestBody": "No Use of request body value. Request Body you want to send while making request for the test run will not be used, Supported with client type 'CURL' and request method 'POST' only.",
+ "encodeRequestBody": "No Use of encode request body value. Encoding of request body can be done for non empty request body and supported with client type 'CURL' and request method 'POST' only.",
+ "json": "Failed to parse JSON data. Correct the input following examples and try again."
+ }
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "purgeOperation": {
+ "purgeAttemptFailed": "Purge operation failed.",
+ "purgeAllowedOnlyOnStaging": "Purge operation is allowed only on the staging environment.",
+ "requiredPermissionMissing": "You do not have the Write permission, which is required to purge cache. Contact Control Center administrator."
+ },
+ "evaluationErrors": {
+ "systemError": "System error. Rerun the test later.",
+ "cnameResolutionFailed": "Failed to resolve CNAME for {{hostname}}. Verify your DNS configuration and rerun the test.",
+ "hostnameNotAkamaized": "The tested hostname does not resolve in DNS to an Akamai edge server. CNAME the hostname to an Akamai edge hostname.",
+ "ipVersionNotSupported": "The tested hostname does not support {{ipVersion}}. Make sure the hostname supports the IP version and rerun the test.",
+ "sourceHostnameNotAccessible": "The tested hostname is not public. Make the hostname publicly available and rerun the test.",
+ "noPmPropertyFoundForTargetHostname": "The tested hostname has no corresponding active property version in Property Manager for the selected environment. Activate the property version and rerun the test.",
+ "pragmaHeadersNotFound": "The tested hostname blocks Pragma headers required to process results. Allow Pragma headers for Test Center and rerun the test.",
+ "noResponseReceived": "Either the tested hostname did not respond in time or the file size exceeded the limit. Rerun the test",
+ "failedToGetEdgeHostname": "Either the tested hostname does not have an edge hostname associated to it or Test Center couldn't get the edge hostname. Review the configuration and rerun the test",
+ "ipResolutionFailed": "Failed to resolve IP Address for {{hostname}}. Verify your DNS configuration and rerun the test.",
+ "statefulTestCaseSkipped": "Test case skipped as preceding test case encountered error.",
+ "functionExpressionResolvesToMultipleResults": "You cannot see details of test cases with dynamically assigned variables that return inconclusive values.",
+ "invalidValue": "Invalid value. The variable results in invalid values in one or more test cases where it is used."
+ },
+ "messages": {
+ "spinner": {
+ "getTestSuite": "Getting test suite"
+ },
+ "testSuiteId": {
+ "spinner": {
+ "findTestCases": "Finding test cases",
+ "startTestRun": "Running test suite",
+ "runTests": "Running tests"
+ }
+ },
+ "testSuiteName": {
+ "spinner": {
+ "findTestCases": "Finding test cases",
+ "startTestRun": "Running test suite",
+ "runTests": "Running tests"
+ }
+ },
+ "propertyVersion": {
+ "spinner": {
+ "findTestSuite": "Finding test suites",
+ "findTestCases": "Finding test cases",
+ "findPropertyVersion": "Finding property version",
+ "startTestRun": "Running property version",
+ "runTests": "Running tests"
+ }
+ },
+ "singleTestCase": {
+ "spinner": {
+ "startTestRun": "Running test case",
+ "runTests": "Running tests"
+ }
+ },
+ "jsonInput": {
+ "spinner": {
+ "startTestRun": "Running from JSON input",
+ "runTests": "Running tests"
+ }
+ },
+ "display": {
+ "completed": "Completed",
+ "inProgress": "In progress",
+ "completedWithUnexpectedResults": "Completed, some results not as expected",
+ "failed": "Failed",
+ "testRunHeader": "TEST SUMMARY",
+ "testRunStart": "Test run with id %d started.",
+ "testSuiteText": "Test suite",
+ "testCasesText": "%d test cases - ",
+ "inProgressText": "%d in progress",
+ "passedText": "%d passed",
+ "failedText": "%d failed",
+ "systemErrorText": "%d Inconclusive",
+ "staging": "Akamai staging",
+ "production": "Akamai production",
+ "allExecutionObjectsIncluded": "You do not have access to all the hostnames of test cases included in the test run. Those test cases are hidden."
+ }
+ },
+ "testSuite": {
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to access the test suite. Contact your Account administrator."
+ },
+ "validationError": "The '{{requestField}}' is missing for property."
+ }
+ },
+ "testCase": {
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to access the test cases. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test suite with this ID couldn't be found. Run the 'test-suite list' command to make sure the ID is correct and try again.",
+ "validationError": {
+ "resourceInDeletedState": "The test suite is in the deleted state. Restore it and try again.",
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ }
+ },
+ "testRun": {
+ "create": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to run the test. Contact your Account administrator.",
+ "hostnameAccessMissing": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again.",
+ "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
+ },
+ "validationError": {
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this.",
+ "invalidTestRunObjectsCombination": "Invalid request due to incorrect combination of flags. To run the test for a test suite provide '--test-suite-id' or '--test-suite-name'. To run a test for a property version provide '--property-name' and '--property-version'. To run a test for a single test case provide '--url', '--ip-version' and '--condition' flags. Correct the input following examples and try again.",
+ "maxTestCasesPerTestRunExceeded": "The number of test cases in this test run exceeded the limit of '{{maxLimit}}'. Create another test suite for test cases exceeding the limit and submit another request.",
+ "maxTestSuitesPerTestRunExceeded": "The number of test suites in this test run exceeded the limit of '{{maxLimit}}'. Submit another request for the test suites exceeding the limit.",
+ "configVersionNotActive": "The property version is not active on the selected environment. Activate it in Property Manager or select a different environment and try again.",
+ "requiredFieldMissing": "The '{{field}}' is missing.",
+ "invalidValue": "The '{{field}}' is invalid. Correct the value and try again.",
+ "maxLengthExceeded": "The '{{field}}' exceeds the allowed characters limit of '{{maxLength}}'.",
+ "hostnameAccessMissing": "You don't have access to the hostname. Correct the value and try again.",
+ "urlShouldContainPath": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing a path. Edit the URL and try again.",
+ "urlPathShouldContainAlphabeticCharacters": "Failed to create a test case for the 'Ignore case in cache key' condition. The URL is missing alphabetic characters. Edit the URL and try again.",
+ "urlShouldContainQueryParam": "Failed to create a test case for the 'Cache query parameter' condition. The URL is missing query parameters. Edit the URL and try again.",
+ "dataTypeMismatch": "The value of a condition expression is invalid. Verify the entered condition and the value and try again.",
+ "invalidConditionExpression": "This condition is invalid. Verify the entered values, format, and type and try again.",
+ "customValueNotSupported": "Invalid condition statement. You can only use default available values for this condition. Use the condition template to create a valid condition and try again.",
+ "duplicateResourceInPayload": "The requested request headers have some duplicates. Remove the duplicates and try again.",
+ "noAssociationsFound": {
+ "testSuiteIdNoAssociationsFound": "Test case associations couldn't be found for test suite with id '{{testSuiteId}}'. Verify the associations and try again or try json input with test suites having associations.",
+ "propertyNameNoAssociationsFound": "Test suite associations couldn't be found for given property. Verify the associations and try again or try json input with test suites having associations."
+ },
+ "resourceNotFound": {
+ "testRequestIdResourceNotFound": "Some of the test requests (combinations of the URL and headers) you included in the test run can't be found. Verify the included objects and try again.",
+ "conditionIdResourceNotFound": "Some of the conditions you included in the test run can't be found. Verify the included objects and try again.",
+ "requirementIdResourceNotFound": "Some of the requirements you included in the test run can't be found. Verify the included objects and try again.",
+ "testSuiteIdResourceNotFound": "Some of the test suites you included in the test run can't be found. Verify the included objects and try again.",
+ "testCaseIdResourceNotFound": "Some of the functional test cases you included in the test run can't be found. Verify the included objects and try again.",
+ "configVersionIdResourceNotFound": "Some of the property versions you included in the test run can't be found. Verify the included objects and try again.",
+ "clientProfileIdResourceNotFound": "Some of the client profiles you included in the test run can't be found. Verify the included objects and try again.",
+ "testDefinitionIdResourceNotFound": "Some of the test definitions you included in the test run can't be found. Verify the included objects and try again."
+ },
+ "resourceInDeletedState": {
+ "testRequestIdResourceInDeletedState": "Some of the test requests (combinations of URL and headers) are removed and you can't include them in the test run. Verify the included objects and try again.",
+ "conditionIdResourceInDeletedState": "Some of the conditions are removed and you can't include them in the test run. Verify the included objects and try again.",
+ "requirementIdResourceInDeletedState": "Some of the requirements are removed and you can't include them in the test run. Verify the included objects and try again.",
+ "testSuiteIdResourceInDeletedState": "Some of the test suites are removed and you can't include them in the test run. Verify the included objects and try again.",
+ "testCaseIdResourceInDeletedState": "Some of the test cases are removed and you can't include them in the test run. Verify the included objects and try again.",
+ "configVersionIdResourceInDeletedState": "Some of the property versions are removed and you can't include them in the test run. Verify the included objects and try again.",
+ "testDefinitionIdResourceInDeletedState": "Some of the test definitions are removed and you can't include them in the test run. Verify the included objects and try again."
+ },
+ "associationNotFound": {
+ "requirementIdTestSuiteIdAssociationNotFound": "Some of the requirements and test suites associations couldn't be found. Verify the associations and try again.",
+ "configVersionIdTestSuiteIdAssociationNotFound": "Some of the property versions and test suites associations couldn't be found. Verify the associations and try again.",
+ "testSuiteIdTestCaseIdAssociationNotFound": "Some of the test suites and test cases associations couldn't be found. Verify the associations and try again."
+ },
+ "invalidClientRequestMethodCombination": "Invalid combination of client and request method. HEAD and POST request methods are allowed only with CURL client."
+ },
+ "rateLimitExceeded": {
+ "rateLimitTestRunHostnameExceeded": "The number of test runs for a hostname exceeded the rate limit. Try again later."
+ },
+ "invalidRequestBody": "Invalid request. Correct the input following examples and try again."
+ },
+ "read": {
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to get the results of the test run. Contact your Account administrator."
+ },
+ "resourceNotFound": "The test run with this ID couldn't be found. Make sure the ID is correct and try again.",
+ "validationError": {
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ }
+ }
+ }
+ },
+ "rawRequestResponse": {
+ "short": "Gets a raw request and response for a test run or test case execution.",
+ "long": "This command returns a raw request response for a specific test run or a test case execution.",
+ "tcxId": "Unique identifier of the test case execution for which you want to get the raw request response for.",
+ "testRunId": "Unique identifier of the test run for which you want to get the raw request response for.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "flag": {
+ "missing": {
+ "any": "Missing the required flag, either '--tcx-id' or '--test-run-id'. Add the flag and try again."
+ },
+ "invalid": {
+ "tcxId": "Invalid test case execution ID value. It needs to be a number. Correct the input and try again.",
+ "testRunId": "Invalid test run ID value. It needs to be a number. Correct the input and try again.",
+ "oneOf": "Only one of the flag is required. Provide either '--tcx-id' or '--test-run-id'. Correct the input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getRawRequestResponseForTestRun": "Getting raw request response for test run",
+ "getRawRequestResponseForTcxs": "Getting raw request response for test case execution"
+ },
+ "display": {
+ "getRawRequestResponseForTestRunSuccess": "RAW REQUEST RESPONSE FOR TEST RUN",
+ "getRawRequestResponseForTcxsSuccess": "RAW REQUEST RESPONSE FOR TEST CASE EXECUTION"
+ }
+ },
+ "testRun": {
+ "resourceNotFound": "The test run ID could not be found. Run the 'test list' command to make sure the ID is correct and try again.",
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to get the results of the test run. Contact your Account administrator."
+ },
+ "validationError": {
+ "testRunNotCompleted": "You can't get raw request response involved in a test run which in progress. Wait until the test run is complete and try again."
+ }
+ },
+ "testCaseExecution": {
+ "resourceNotFound": "The test case execution ID could not be found. Run the 'test get' command to make sure the ID is correct and try again.",
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to get the results of the test run. Contact your Account administrator."
+ },
+ "validationError": {
+ "testCaseExecutionNotInCompletedState": "You can't get raw request response involved in a test run in progress. Wait until the test run is complete and try again.",
+ "parentTcxResponseFetchError": "You can't get raw request response for parent test case executions. Run the 'test get' command to make sure the ID is correct and try again."
+ }
+ }
+ },
+ "logLines": {
+ "short": "Gets log lines for a test case execution.",
+ "long": "This command returns log lines for a specific test case execution.",
+ "tcxId": "Unique identifier of the test case execution which you want to get the log lines for. Run the 'test get' command to get it. ",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "flag": {
+ "missing": {
+ "tcxId": "Missing required '--tcx-id' flag. Add the flag and try again."
+ },
+ "invalid": {
+ "tcxId": "Invalid test case execution ID value. It needs to be a number. Correct the input and try again."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the READ permission, which is required to get the results of the test run. Contact your Account administrator.",
+ "hostnameAccessMissingForAssociatedTestCases": "You don't have access to hostnames of at least one test case included in the test suite. Get the access or edit the hostnames and try again."
+ },
+ "resourceNotFound": "The test case execution ID could not be found. Run the 'test get' command to make sure the ID is correct and try again."
+ }
+ },
+ "condition": {
+ "short": "List commands available for conditions.",
+ "long": "This command lets you either get the condition template or the list of conditions created by users of your account.",
+ "subCommand": {
+ "invalid": {
+ "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
+ }
+ },
+ "template": {
+ "short": "Returns supported condition statements.",
+ "long": "This command lists condition statements that you can use when creating test cases. Make sure to substitute default \" \" values with your own.",
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator."
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getConditionTemplate": "Getting condition template"
+ },
+ "display": {
+ "conditionsTemplatesText": "CONDITION STATEMENTS TEMPLATE"
+ }
+ }
+ },
+ "list": {
+ "short": "List created conditions.",
+ "long": "This command lists conditions created by users of your account while creating test cases that you can reuse.",
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator."
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getConditions": "Getting conditions"
+ },
+ "display": {
+ "conditions": "LIST OF CONDITIONS",
+ "noConditionFoundWarning": "No conditions found"
+ }
+ }
+ }
+ },
+ "testRequest": {
+ "short": "List commands available for test requests.",
+ "long": "Test request are constituents of test cases and consist of a URL, request method, request headers, and request body. You can use test request to test specific URLs with headers and request body.",
+ "subCommand": {
+ "invalid": {
+ "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
+ }
+ },
+ "list": {
+ "short": "List all test requests.",
+ "long": "Lists test requests created in your organization.",
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator."
+ },
+ "validationError": {
+ "externalApiDataError": "At least one property in your account is tied to multiple groups in Control Center. Test Center requires the property to be tied to exactly one group. Contact Akamai technical support to fix this."
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getTestRequests": "Getting test requests"
+ },
+ "display": {
+ "testRequests": "LIST OF TEST REQUESTS",
+ "noTestRequestFoundWarning": "No test requests found"
+ }
+ }
+ }
+ },
+ "variable": {
+ "short": "List commands available for variables.",
+ "long": "The variables feature allows you to define variables, assign values to them, and reuse them in functional test cases.",
+ "subCommand": {
+ "invalid": {
+ "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
+ }
+ },
+ "create": {
+ "short": "Add a variable to a specific test suite.",
+ "long": "This command lets you add variable to a specific test suite.",
+ "name": "Name of the variable.",
+ "value": "Value you want to assign to the variable name.",
+ "testSuiteId": "Unique identifier for the test suite you want to create variable in. To get this value, run the 'test-suite list' command.",
+ "groupValue": "Value of the variable in group form, which can be organized in table format.",
+ "flag": {
+ "missing": {
+ "id": "Missing the required '--test-suite-id' flag. Add the flag and try again.",
+ "variableName": "Missing the required '--name' flag. Add the flag and try again.",
+ "any": "Missing one of the required flags, '--value' or '--group-value'. Provide one of the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test suite list' command. Correct the input and try again.",
+ "variableGroup": "Invalid variable group value. It should contain column header and column values separated by ':'. Correct the input and try again."
+ }
+ },
+ "variableGroupColumnLengthMismatch": "Variable group columns length are mismatched. Correct your input and try again.",
+ "resourceNotFound": "The requested '{{requestField}}' can't be found. Correct your input and try again.",
+ "entityAlreadyExists": "The variable with such name already exists. Provide a new name and try again.",
+ "duplicateResourceFoundInPayload": "The variable have a duplicate resource in payload. Provide a new name and try again.",
+ "invalidCharacterFound": "Invalid character present in variable, refer Test Center documentation for more details.",
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the variable. Contact your Account administrator.",
+ "userIsNotOwnerOrEditor": "You don't have the edit access to this variable. Request the edit access using the Test Center UI and try again once your request is approved."
+ },
+ "validationError": {
+ "requiredFieldMissing": "The '{{requestField}}' is missing.",
+ "atleastOneOfTheRequiredFieldMissing": "Either a single value or a group value is missing. Provide one of them and try again.",
+ "resourceInDeletedState": "You can't edit this variable because it's in the deleted state. Restore it and try again.",
+ "onlyOneFieldAllowed": "Only one of the flags is allowed, either provide '--value' or '--group-value'. Correct your input and try again.",
+ "invalidValue": "Invalid variable value. Correct your input and try again.",
+ "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit. Correct your input and try again.",
+ "maxArrayLengthExceeded": "Maximum length of the array exceeded. Correct your input and try again."
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "addVariables": "Creating variable"
+ },
+ "display": {
+ "addVariablesSuccess": "Variable created",
+ "noVariablesFoundWarning": "No variables found"
+ }
+ }
+ },
+ "list": {
+ "short": "List variables available for a test suite.",
+ "long": "This command lists all variables that are created in a specific test suite.",
+ "testSuiteId": "Unique identifier for the test suite you want to list variable for. To get this value, run the 'test-suite list' command.",
+ "flag": {
+ "missing": {
+ "id": "Missing the required '--test-suite-id' flag. Add the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test suite list' command. Correct the input and try again."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the test suites. Contact your Account administrator."
+ },
+ "resourceNotFound": "The requested '{{requestField}}' can't be found.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getVariables": "Getting variables"
+ },
+ "display": {
+ "getVariablesSuccess": "LIST OF VARIABLES",
+ "noVariablesFoundWarning": "No variables found"
+ }
+ }
+ },
+ "get": {
+ "short": "Returns a single variable in a test suite.",
+ "long": "This command lets you get the details of a single variable in the test suite.",
+ "testSuiteId": "Unique identifier for the test suite you want to get variable for. To get this value, run the 'test-suite list' command.",
+ "variableId": "Unique identifier for the specific variable you want to get. To get this value, run the 'variable list' command.",
+ "flag": {
+ "missing": {
+ "id": "Missing the required '--test-suite-id' flag. Add the flag and try again.",
+ "variableId": "Missing the required '--variable-id' flag. Add the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test suite list' command. Correct the input and try again.",
+ "variableId": "Invalid variable ID value. It needs to be a number. To get this value, run the 'variable list' command. Correct the input and try again."
+ }
+ },
+ "resourceNotFound": "The requested '{{requestField}}' can't be found.",
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getVariable": "Getting variable"
+ },
+ "display": {
+ "getVariableSuccess": "VARIABLE"
+ }
+ }
+ },
+ "update": {
+ "short": "Update variable of a specific test suite.",
+ "long": "This command updates a variable of a specific test suite.",
+ "name": "Name of the variable you want to update.",
+ "value": "Value you want to assign to the variable name.",
+ "testSuiteId": "Unique identifier for the test suite you want to update variable in. To get this value, run the 'test-suite list' command.",
+ "variableId": "Unique identifier for the specific variable you want to update. To get this value, run the 'variable list' command.",
+ "groupValue": "Value of the variable in group form, which can be organized in table format.",
+ "flag": {
+ "missing": {
+ "id": "Missing the required '--test-suite-id' flag. Add the flag and try again.",
+ "variableId": "Missing the required '--variable-id' flag. Add the flag and try again.",
+ "variableName": "Missing the required '--name' flag. Add the flag and try again.",
+ "any": "Missing the required flag, '--value' or '--group-value'. Provide one of the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test suite list' command. Correct the input and try again.",
+ "variableId": "Invalid variable ID value. It needs to be a number. To get this value, run the 'variable list' command. Correct the input and try again.",
+ "variableGroup": "Invalid variable group value. It should contain column header and column values separated by ':'. Correct the input and try again."
+ }
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "resourceNotFound": "The requested '{{requestField}}' can't be found. Correct your input and try again.",
+ "validationError": {
+ "resourceInDeletedState": "You can't edit this variable because it's in the deleted state. Restore it and try again.",
+ "onlyOneFieldAllowed": "Only one of the flags is allowed, provide either '--value' or '--group-value'. Correct your input and try again.",
+ "resourceNotFound": "The requested '{{requestField}}' can't be found. Correct your input and try again.",
+ "variableGroupColumnInUse": "Variable group column cannot be removed during edit variable operation when the column is in use. Correct your input and try again.",
+ "variableTypeChangeNotAllowed": "Variables can't be changed from a variable group to a single variable or vice versa. Correct your input and try again.",
+ "emptyVariableGroupColumnInTestCase": "Variable group columns referred in test case doesn't contain any values. Correct your input and try again.",
+ "atleastOneOfTheRequiredFieldMissing": "Either a value or group-value is missing. Provide one of them and try again.",
+ "invalidValue": "Invalid variable value. Correct your input and try again.",
+ "maxLengthExceeded": "The '{{requestField}}' exceeds the allowed characters limit. Correct your input and try again.",
+ "maxArrayLengthExceeded": "Maximum length of the array exceeded. Correct your input and try again.",
+ "variableGroupColumnLengthMismatch": "Variable group columns length are mismatched. Correct your input and try again.",
+ "entityAlreadyExists": "The variable with such name already exists. Provide a new name and try again."
+ },
+ "messages": {
+ "spinner": {
+ "updateVariables": "Updating Variable"
+ },
+ "display": {
+ "updateVariablesSuccess": "Variable updated"
+ }
+ }
+ },
+ "remove": {
+ "short": "Remove a variable from a specific test suite.",
+ "long": "This command removes a variable from a specific test suite.",
+ "testSuiteId": "Unique identifier for the test suite you want to remove variable from. To get this value, run the 'test-suite list' command.",
+ "variableId": "Unique identifier for the specific variable you want to remove. To get this value, run the 'variable list' command.",
+ "flag": {
+ "missing": {
+ "id": "Missing the required '--test-suite-id' flag. Add the flag and try again.",
+ "variableId": "Missing the required '--variable-id' flag. Add the flag and try again."
+ },
+ "invalid": {
+ "id": "Invalid test suite ID value. It needs to be a number. To get this value, run the 'test suite list' command. Correct the input and try again.",
+ "variableId": "Invalid variable ID value. It needs to be a number. To get this value, run the 'variable list' command. Correct the input and try again."
+ }
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Correct your input and try again."
+ }
+ },
+ "authorizationError": {
+ "requiredPermissionMissing": "You don't have the WRITE permission, which is required to access the variables. Contact your Account administrator.",
+ "userIsNotOwnerOrEditor": "You don't have the remove access to this variable. Request the remove access using the Test Center UI and try again once your request is approved."
+ },
+ "resourceNotFound": "The requested '{{requestField}}' can't be found. Correct your input and try again.",
+ "resourceUsedInTestCaseOrNestedVariable": "You can't remove this variable because it is used in test case or nested variable.",
+ "validationError": {
+ "resourceInDeletedState": "You can't remove this variable because it's in the deleted state. Restore it and try again."
+ },
+ "messages": {
+ "spinner": {
+ "removeVariable": "Removing variable"
+ },
+ "display": {
+ "removeVariableSuccess": "Variable removed"
+ }
+ }
+ }
+ },
+ "function": {
+ "short": "Check how functions work.",
+ "long": "To extract a value from the test case response and assign it to a variable dynamically, you need to use functions.",
+ "subCommand": {
+ "invalid": {
+ "wrongArgumentPassed": "Invalid %q subcommand for %q. Correct your input and try again.%s"
+ }
+ },
+ "tryIt": {
+ "short": "Test function expression.",
+ "long": "This command runs a created function on sample data to check whether it returns the expected value. A function is valid for use in a test case if the response's value returns only one value.",
+ "flag": {
+ "missing": {
+ "json": "Missing JSON data. Pass the JSON data and try again."
+ },
+ "invalid": {
+ "json": "Failed to parse JSON data. Correct the input following examples and try again."
+ }
+ },
+ "subCommand": {
+ "invalid": {
+ "argumentNotAllowed": "Invalid %q subcommand for %q. Provide correct json input and try again."
+ }
+ },
+ "messages": {
+ "spinner": {
+ "getFunctionResult": "Getting function result"
+ }
+ },
+ "validationError": {
+ "requiredFieldMissing": "The '{{requestField}}' is missing. Correct your json input and try again.",
+ "resourceNotFound": {
+ "variableNameResourceNotFound": "The {{requestField}} couldn't be found. Make sure the request values {{requestValues}} are present and try again."
+ },
+ "malformedExpressionFound": "The requested '{{requestField}}' contains malformed expressions. Correct the values and try again.",
+ "functionExpressionResolvesToMultipleValues": "One of the function expression resolves to multiple results. Correct the input and try again."
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+
+
diff --git a/internal/message_utils.go b/internal/util/message_utils.go
similarity index 65%
rename from internal/message_utils.go
rename to internal/util/message_utils.go
index afc8bb2..071bd6e 100644
--- a/internal/message_utils.go
+++ b/internal/util/message_utils.go
@@ -1,8 +1,10 @@
-package internal
+package util
import (
_ "embed"
"fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
"os"
"strings"
@@ -16,25 +18,26 @@ var (
//go:embed en_US.json
messageJsonBytes []byte
- messageJson gjson.Result
- rootCommandName = "akamai"
- jsonPathSeparator = "."
- flagKey = "flag"
- subCommandKey = "subCommand"
- placeHolderRegex = "{{(.*?)}}"
- edgeGridError = "edgeGridError"
- fallbackKey = "fallback"
- messagesKey = "messages"
+ messageJson gjson.Result
+ rootCommandName = "akamai"
+ jsonPathSeparator = "."
+ flagCamelCaseOperator = "-"
+ flagKey = "flag"
+ subCommandKey = "subCommand"
+ placeHolderRegex = "{{(.*?)}}"
+ edgeGridError = "edgeGridError"
+ fallbackKey = "fallback"
+ messagesKey = "messages"
)
-//Get global errors for given key
+// Get global errors for given key
func GetGlobalErrorMessage(key string) string {
- return getMessageForJsonPathOrFallback(strings.Join([]string{rootCommandName, Global, key}, jsonPathSeparator))
+ return getMessageForJsonPathOrFallback(strings.Join([]string{rootCommandName, internalconstant.Global, key}, jsonPathSeparator))
}
-//Get edge grid errors for given key
+// Get edge grid errors for given key
func GetEdgeGridErrorMessage(key string) string {
- return getMessageForJsonPathOrFallback(strings.Join([]string{rootCommandName, Global, edgeGridError, key}, jsonPathSeparator))
+ return getMessageForJsonPathOrFallback(strings.Join([]string{rootCommandName, internalconstant.Global, edgeGridError, key}, jsonPathSeparator))
}
// Return message for given key under command.
@@ -48,21 +51,21 @@ func GetErrorMessageForFlag(cmd *cobra.Command, errorType, flagKeyInJson string)
jsonPath := getJsonPathForCommand(cmd.CommandPath())
switch errorType {
- case Missing:
- jsonPath = strings.Join([]string{jsonPath, flagKey, Missing, flagKeyInJson}, jsonPathSeparator)
- case Invalid:
- jsonPath = strings.Join([]string{jsonPath, flagKey, Invalid, flagKeyInJson}, jsonPathSeparator)
+ case internalconstant.Missing:
+ jsonPath = strings.Join([]string{jsonPath, flagKey, internalconstant.Missing, flagKeyInJson}, jsonPathSeparator)
+ case internalconstant.Invalid:
+ jsonPath = strings.Join([]string{jsonPath, flagKey, internalconstant.Invalid, flagKeyInJson}, jsonPathSeparator)
}
log.Debugf("Get message for json path [%s], error type - [%s], flag key in json - [%s]", jsonPath, errorType, flagKeyInJson)
return getMessageForJsonPathOrFallback(jsonPath)
}
-func GetApiErrorMessagesForCommand(cmd *cobra.Command, apiError ApiError, subResource, operation, responseCode string) []string {
+func GetApiErrorMessagesForCommand(cmd *cobra.Command, apiError model.ApiError, subResource, operation, responseCode string) []string {
jsonPathForCommand := getJsonPathForCommand(cmd.CommandPath())
- if (apiError.ClientIp != Empty && apiError.ServerIp != Empty && apiError.RequestId != Empty) || (responseCode == "401" && apiError.Code != Empty) {
+ if (apiError.ClientIp != internalconstant.Empty && apiError.ServerIp != internalconstant.Empty && apiError.RequestId != internalconstant.Empty) || (responseCode == "401" && apiError.Code != internalconstant.Empty) {
- if (apiError.Status == 400 || apiError.Status == 401) && apiError.Detail != Empty {
+ if (apiError.Status == 400 || apiError.Status == 401) && apiError.Detail != internalconstant.Empty {
PrintError(GetEdgeGridErrorMessage(getErrorJsonKeyForDetail(apiError.Detail)) + "\n")
}
@@ -70,10 +73,10 @@ func GetApiErrorMessagesForCommand(cmd *cobra.Command, apiError ApiError, subRes
PrintError(GetEdgeGridErrorMessage("resourceNotFound") + "\n")
}
- if responseCode == "401" && apiError.Code != Empty {
+ if responseCode == "401" && apiError.Code != internalconstant.Empty {
PrintError(GetEdgeGridErrorMessage("notAuthorized") + "\n")
}
- PrintError(GetGlobalErrorMessage("initEdgeRc") + "\n")
+ PrintError(GetGlobalErrorMessage(internalconstant.InitEdgeRc) + "\n")
// Get equivalent exit status code for corresponding http status code
statusCode := GetHttpExitCode(responseCode)
os.Exit(statusCode)
@@ -90,11 +93,11 @@ func GetApiErrorMessagesForCommand(cmd *cobra.Command, apiError ApiError, subRes
}
// Get All the error messages for api sub errors
-func GetApiSubErrorMessagesForCommand(cmd *cobra.Command, apiSubError []ApiSubError, parentErrorKey, subResource, operation string) []string {
+func GetApiSubErrorMessagesForCommand(cmd *cobra.Command, apiSubError []model.ApiSubError, parentErrorKey, subResource, operation string) []string {
jsonPathForCommand := getJsonPathForCommand(cmd.CommandPath())
- var errorMessages = make([]string, len(apiSubError))
+ var errorMessages = make([]string, 0)
- for i, subError := range apiSubError {
+ for _, subError := range apiSubError {
subErrorKey := getErrorJsonKeyForErrorType(subError.Type)
errorPath := getJsonPathForCommand(strings.Join([]string{jsonPathForCommand, subResource, operation, parentErrorKey, subErrorKey}, " "))
@@ -108,7 +111,7 @@ func GetApiSubErrorMessagesForCommand(cmd *cobra.Command, apiSubError []ApiSubEr
errorMessage := getMessageForJsonPathOrFallback(errorPath + jsonPathSeparator + subError.RequestField + strings.Title(subErrorKey))
// Replace placeholder values in string from json if there are any
- errorMessages[i] = getReplacedPlaceholderMessage(subError, errorMessage)
+ errorMessages = append(errorMessages, getReplacedPlaceholderMessage(subError, errorMessage))
continue
}
@@ -117,28 +120,52 @@ func GetApiSubErrorMessagesForCommand(cmd *cobra.Command, apiSubError []ApiSubEr
if subError.RequirementId != 0 && checkIfMessageExist(errorPath+jsonPathSeparator+"requirementId"+"TestSuiteId"+strings.Title(subErrorKey)) {
errorMessage := getMessageForJsonPathOrFallback(errorPath + jsonPathSeparator + "requirementId" + "TestSuiteId" + strings.Title(subErrorKey))
- errorMessages[i] = getReplacedPlaceholderMessage(subError, errorMessage)
+ errorMessages = append(errorMessages, getReplacedPlaceholderMessage(subError, errorMessage))
continue
}
if subError.ConfigVersionId != 0 && checkIfMessageExist(errorPath+jsonPathSeparator+"configVersionId"+"TestSuiteId"+strings.Title(subErrorKey)) {
errorMessage := getMessageForJsonPathOrFallback(errorPath + jsonPathSeparator + "configVersionId" + "TestSuiteId" + strings.Title(subErrorKey))
- errorMessages[i] = getReplacedPlaceholderMessage(subError, errorMessage)
+ errorMessages = append(errorMessages, getReplacedPlaceholderMessage(subError, errorMessage))
continue
}
if subError.TestSuiteId != 0 && checkIfMessageExist(errorPath+jsonPathSeparator+"testSuiteId"+"TestCaseId"+strings.Title(subErrorKey)) {
errorMessage := getMessageForJsonPathOrFallback(errorPath + jsonPathSeparator + "testSuiteId" + "TestCaseId" + strings.Title(subErrorKey))
- errorMessages[i] = getReplacedPlaceholderMessage(subError, errorMessage)
+ errorMessages = append(errorMessages, getReplacedPlaceholderMessage(subError, errorMessage))
+ continue
+ }
+ }
+
+ // Third custom logic
+ if strings.Contains("noAssociationsFound", subErrorKey) {
+ if subError.TestSuiteId != 0 && checkIfMessageExist(errorPath+jsonPathSeparator+"testSuiteId"+strings.Title(subErrorKey)) {
+ errorMessage := getMessageForJsonPathOrFallback(errorPath + jsonPathSeparator + "testSuiteId" + strings.Title(subErrorKey))
+ errorMessages = append(errorMessages, getReplacedPlaceholderMessage(subError, errorMessage))
+ continue
+ } else {
+ errorMessage := getMessageForJsonPathOrFallback(errorPath + jsonPathSeparator + "propertyName" + strings.Title(subErrorKey))
+ errorMessages = append(errorMessages, getReplacedPlaceholderMessage(subError, errorMessage))
continue
}
}
/*Custom logic ends here*/
+ // when the subError contains nested subError.
+ if len(subError.Errors) != 0 {
+ if parentErrorKey != internalconstant.Empty {
+ parentErrorKey = parentErrorKey + jsonPathSeparator + getErrorJsonKeyForErrorType(subError.Type)
+ } else {
+ parentErrorKey = getErrorJsonKeyForErrorType(subError.Type)
+ }
+ recursiveMessages := GetApiSubErrorMessagesForCommand(cmd, subError.Errors, parentErrorKey, internalconstant.Empty, internalconstant.Empty)
+ errorMessages = append(errorMessages, recursiveMessages...)
+ continue
+ }
errorMessage := getMessageForJsonPathOrFallback(errorPath)
// Replace placeholder values in string from json if there are any
- errorMessages[i] = getReplacedPlaceholderMessage(subError, errorMessage)
+ errorMessages = append(errorMessages, getReplacedPlaceholderMessage(subError, errorMessage))
}
return errorMessages
}
@@ -146,6 +173,15 @@ func GetApiSubErrorMessagesForCommand(cmd *cobra.Command, apiSubError []ApiSubEr
func getErrorJsonKeyForErrorType(errorType string) string {
str := strings.Split(errorType, jsonPathSeparator)
+ return getCamelCaseValue(str)
+}
+
+func GetJsonKeyForFlag(flag string) string {
+ str := strings.Split(flag, flagCamelCaseOperator)
+ return getCamelCaseValue(str)
+}
+
+func getCamelCaseValue(str []string) string {
var jsonPath = make([]string, len(str))
for i2, s := range str {
if i2 == 0 {
@@ -154,7 +190,7 @@ func getErrorJsonKeyForErrorType(errorType string) string {
jsonPath[i2] = strings.Title(s)
}
}
- return strings.Join(jsonPath, "")
+ return strings.Join(jsonPath, internalconstant.Empty)
}
func getErrorJsonKeyForDetail(errorType string) string {
@@ -233,10 +269,10 @@ func GetErrorMessageForSubArgument(cmd *cobra.Command, errorType, subCommandKeyI
jsonPath := getJsonPathForCommand(cmd.CommandPath())
switch errorType {
- case Missing:
- jsonPath = strings.Join([]string{jsonPath, subCommandKey, Missing, subCommandKeyInJson}, jsonPathSeparator)
- case Invalid:
- jsonPath = strings.Join([]string{jsonPath, subCommandKey, Invalid, subCommandKeyInJson}, jsonPathSeparator)
+ case internalconstant.Missing:
+ jsonPath = strings.Join([]string{jsonPath, subCommandKey, internalconstant.Missing, subCommandKeyInJson}, jsonPathSeparator)
+ case internalconstant.Invalid:
+ jsonPath = strings.Join([]string{jsonPath, subCommandKey, internalconstant.Invalid, subCommandKeyInJson}, jsonPathSeparator)
}
log.Debugf("Get message for json path [%s], error type - [%s], flag key in json - [%s]", jsonPath, errorType, subCommandKeyInJson)
@@ -248,12 +284,12 @@ func GetServiceMessage(cmd *cobra.Command, messageType string, subresource strin
jsonPath := getJsonPathForCommand(cmd.CommandPath())
switch messageType {
- case MessageTypeSpinner:
- jsonPath = strings.Join([]string{jsonPath, messagesKey, MessageTypeSpinner, jsonKey}, jsonPathSeparator)
- case MessageTypeDisplay:
- jsonPath = strings.Join([]string{jsonPath, messagesKey, MessageTypeDisplay, jsonKey}, jsonPathSeparator)
- case MessageTypeTestCmdSpinner:
- jsonPath = strings.Join([]string{jsonPath, messagesKey, subresource, MessageTypeSpinner, jsonKey}, jsonPathSeparator)
+ case internalconstant.MessageTypeSpinner:
+ jsonPath = strings.Join([]string{jsonPath, messagesKey, internalconstant.MessageTypeSpinner, jsonKey}, jsonPathSeparator)
+ case internalconstant.MessageTypeDisplay:
+ jsonPath = strings.Join([]string{jsonPath, messagesKey, internalconstant.MessageTypeDisplay, jsonKey}, jsonPathSeparator)
+ case internalconstant.MessageTypeTestCmdSpinner:
+ jsonPath = strings.Join([]string{jsonPath, messagesKey, subresource, internalconstant.MessageTypeSpinner, jsonKey}, jsonPathSeparator)
}
log.Debugf("Get message for json path [%s], message type - [%s], subresource type - [%s], flag key in json - [%s]", jsonPath, messageType, subresource, jsonKey)
diff --git a/internal/print_utils.go b/internal/util/print_utils.go
similarity index 50%
rename from internal/print_utils.go
rename to internal/util/print_utils.go
index 14f8899..5d90564 100644
--- a/internal/print_utils.go
+++ b/internal/util/print_utils.go
@@ -1,9 +1,12 @@
-package internal
+package util
// This class will have only akamai/global cli standard print functions
import (
"fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
"os"
"strconv"
"strings"
@@ -43,29 +46,43 @@ func PrintSuccessInBold(message string, args ...interface{}) {
_, _ = c.Printf(message, args...)
}
-func bold(a ...interface{}) string {
+func Bold(a ...interface{}) string {
c := color.New(color.Bold)
return c.Sprint(a...)
}
-func italic(a ...interface{}) string {
+func Italic(a ...interface{}) string {
c := color.New(color.Italic)
return c.Sprint(a...)
}
-func printLabelAndValue(label string, value interface{}) {
+func PrintLabelAndValue(label string, value interface{}) {
c := color.New(color.Bold)
- _, _ = c.Printf(label + ": ")
+ _, _ = c.Printf(label + externalconstant.Colon + internalconstant.Space)
fmt.Printf("%v\n", value)
}
+func PrintLabelValueWithColour(label string, clr *color.Color, value interface{}) {
+ c := color.New(color.Bold)
+ _, _ = c.Printf(label + externalconstant.Colon + internalconstant.Space)
+ _, _ = clr.Printf("%v\n", value)
+}
+
+// print json output if flag is passed
+func CheckAndPrintJson(jsonOutput bool, data interface{}) {
+ // print json output if flag is passed
+ if jsonOutput {
+ PrintJsonAndExit(data)
+ }
+}
+
func PrintJsonAndExit(data interface{}) {
// This uses a third-party replacement (github.com/clarketm/json) for Go's default JSON encoder.
// It considers empty structs (as opposed to just nil pointer to struct) for omitempty.
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
log.Fatal(err)
- AbortWithExitCode(GetGlobalErrorMessage("jsonOutputFailed"), ExitStatusCode1)
+ AbortWithExitCode(GetGlobalErrorMessage("jsonOutputFailed"), internalconstant.ExitStatusCode1)
}
if string(b) != "null" {
@@ -73,7 +90,7 @@ func PrintJsonAndExit(data interface{}) {
} else {
fmt.Println("[]\n")
}
- os.Exit(ExitStatusCode0)
+ os.Exit(internalconstant.ExitStatusCode0)
}
func AbortWithExitCode(message string, code int) {
@@ -82,7 +99,7 @@ func AbortWithExitCode(message string, code int) {
}
func AbortWithUsageAndMessageAndCode(cmd *cobra.Command, message string, code int) {
- if message != Empty {
+ if message != internalconstant.Empty {
PrintError(message + "\n\n")
}
err := cmd.Usage()
@@ -92,58 +109,75 @@ func AbortWithUsageAndMessageAndCode(cmd *cobra.Command, message string, code in
}
os.Exit(code)
}
-func AbortForCommand(cmd *cobra.Command, cliError *CliError) {
- AbortForCommandWithSubResource(cmd, cliError, Empty, Empty)
+func AbortForCommand(cmd *cobra.Command, cliError *model.CliError) {
+ AbortForCommandWithSubResource(cmd, cliError, internalconstant.Empty, internalconstant.Empty)
}
-func AbortForCommandWithSubResource(cmd *cobra.Command, cliError *CliError, subResource, operation string) {
+func AbortForCommandWithSubResource(cmd *cobra.Command, cliError *model.CliError, subResource, operation string) {
- responseCode := strconv.Itoa(cliError.responseCode)
+ responseCode := strconv.Itoa(cliError.ResponseCode)
if len(responseCode) == 3 && strings.Contains("500,502,503,504,405", responseCode) {
PrintError(GetGlobalErrorMessage(responseCode) + "\n\n")
- } else if cliError.apiError != nil {
- printErrorMessages(GetApiErrorMessagesForCommand(cmd, *cliError.apiError, subResource, operation, responseCode))
+ } else if cliError.ApiError != nil {
+ PrintErrorMessages(GetApiErrorMessagesForCommand(cmd, *cliError.ApiError, subResource, operation, responseCode))
println()
- } else if len(cliError.apiSubErrors) != 0 {
- printErrorMessages(GetApiSubErrorMessagesForCommand(cmd, cliError.apiSubErrors, "", subResource, operation))
+ } else if len(cliError.ApiSubErrors) != 0 {
+ PrintErrorMessages(GetApiSubErrorMessagesForCommand(cmd, cliError.ApiSubErrors, "", subResource, operation))
println()
} else {
- PrintError(cliError.errorMessage + "\n\n")
+ PrintError(cliError.ErrorMessage + "\n\n")
}
// Get equivalent exit status code for corresponding http status code
statusCode := GetHttpExitCode(responseCode)
os.Exit(statusCode)
}
-func printErrorMessages(errorMessages []string) {
+func PrintErrorMessages(errorMessages []string) {
for _, message := range errorMessages {
PrintError(message + "\n")
}
}
+func PrintWarnings(waringMessages []string) {
+ for _, message := range waringMessages {
+ PrintWarning(message + "\n")
+ }
+}
+
// ShowTable Standard function to show table in same format across Test Center CLI
-func ShowTable(tableHeaders []string, tableContents [][]string) {
+func ShowTable(tableHeaders []string, tableContents [][]string, showTotal bool) {
table := tablewriter.NewWriter(os.Stdout)
table.SetRowLine(true)
table.SetHeader(tableHeaders)
table.AppendBulk(tableContents)
+ table.SetAutoFormatHeaders(false)
table.Render()
- fmt.Printf("\n"+LabelTotalItem+": %d\n", len(tableContents))
+
+ if showTotal {
+ PrintTotalItems(len(tableContents))
+ }
}
-func printTemplate(templateToParse string, data interface{}) {
+func PrintTemplate(templateToParse string, data interface{}) {
// standard functions for templates
funcMap := template.FuncMap{
"inc": func(i int) int {
return i + 1
},
- "printHeader": RequestHeaderInCLIOutputFormat,
+ "dec": func(i int) int {
+ return i - 1
+ },
+ "printRequestURL": GetResolvedOrUnResolvedRequestURL,
+ "printHeader": GetResolvedOrUnResolvedHeaders,
+ "printRequestBody": GetResolvedOrUnResolvedRequestBody,
"printClientProfile": ClientProfileInCLIOutputFormat,
- "bold": bold,
+ "printCondition": GetResolvedOrUnResolvedCondition,
+ "printSetVariables": SetVariablesInCLIOutputFormat,
+ "bold": Bold,
"join": func(elements []string) string {
- return strings.Join(elements, ",")
+ return strings.Join(elements, externalconstant.Comma)
},
}
@@ -152,16 +186,25 @@ func printTemplate(templateToParse string, data interface{}) {
// if there is error,
if err != nil {
log.Error(err)
- PrintError(CliErrorMessageTemplateOutputError + "\n")
- os.Exit(ExitStatusCode1)
+ PrintError(externalconstant.CliErrorMessageTemplateOutputError + "\n")
+ os.Exit(internalconstant.ExitStatusCode1)
} else {
// standard output to print merged data
err = tmp.Execute(os.Stdout, data)
println()
if err != nil {
log.Error(err)
- PrintError(CliErrorMessageTemplateOutputError + "\n")
- os.Exit(ExitStatusCode1)
+ PrintError(externalconstant.CliErrorMessageTemplateOutputError + "\n")
+ os.Exit(internalconstant.ExitStatusCode1)
}
}
}
+func PrintTotalItems(count int) {
+ fmt.Printf("\n"+externalconstant.LabelTotalItem+": %d\n", count)
+}
+
+func PrintRawRequestResponseHeaders(requestResponseHeaders []model.Header) {
+ for _, header := range requestResponseHeaders {
+ fmt.Println(header.Name + externalconstant.Colon + header.Value)
+ }
+}
diff --git a/internal/utils.go b/internal/util/utils.go
similarity index 51%
rename from internal/utils.go
rename to internal/util/utils.go
index efd0952..3d9d293 100644
--- a/internal/utils.go
+++ b/internal/util/utils.go
@@ -1,8 +1,11 @@
-package internal
+package util
import (
"bufio"
"fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"io/ioutil"
@@ -62,7 +65,7 @@ func (s Spinner) StopWithFailure() {
func stopSpinner(s *spinner.Spinner, terminalMessage string) {
s.FinalMSG = s.Prefix + "...... " + terminalMessage
s.Stop()
- fmt.Fprintln(s.Writer)
+ _, _ = fmt.Fprintln(s.Writer)
}
// Check contains and irrespective of case.
@@ -83,26 +86,24 @@ func ContainsInArray(array []string, inputString string) bool {
return result
}
-func ClientProfileInCLIOutputFormat(ipVersion string) string {
- switch strings.ToLower(ipVersion) {
- case "ipv6":
- return "IPv6"
- case "ipv4":
- return "IPv4"
- default:
- return "IPv4"
+func ClientProfileInCLIOutputFormat(clientProfile model.ClientProfile) string {
+
+ if clientProfile.IpVersion == internalconstant.Ipv6 {
+ return clientProfile.Client + externalconstant.PlusSign + "IPv6"
+ } else {
+ return clientProfile.Client + externalconstant.PlusSign + "IPv4"
}
}
func RequestHeaderInCLIOutputFormat(headerName, headerAction, headerValue string) string {
- switch strings.ToLower(headerAction) {
- case Add:
- return fmt.Sprintf("%s (%s): %s", headerName, "added", headerValue)
- case Modify:
- return fmt.Sprintf("%s (%s): %s", headerName, "modified", headerValue)
- case Filter:
- return fmt.Sprintf("%s (%s): %s", headerName, "filtered", "N/A")
+ switch strings.ToUpper(headerAction) {
+ case internalconstant.Add:
+ return fmt.Sprintf("(%s): %s: %s", "Added", headerName, headerValue)
+ case internalconstant.Modify:
+ return fmt.Sprintf("(%s): %s: %s", "Modified", headerName, headerValue)
+ case internalconstant.Filter:
+ return fmt.Sprintf("(%s): %s: %s", "Filtered", headerName, "N/A")
}
return ""
}
@@ -124,7 +125,7 @@ func FormatTime(inputTime string) string {
return myDate.Format("01/02/2006, 15:04 PM -07:00")
}
-//Get all placeholders in string inside {{}}
+// Get all placeholders in string inside {{}}
func GetPlaceHoldersInString(errorMessage, regex string) []string {
r := regexp.MustCompile(regex)
@@ -141,7 +142,7 @@ func ReadStdin(cmd *cobra.Command) (bool, []byte) {
file := os.Stdin
fi, err := file.Stat()
if err != nil {
- AbortWithExitCode(fmt.Sprintf(GetServiceMessage(cmd, MessageTypeDisplay, "", "standardInputErrorMsg"), err), ExitStatusCode1)
+ AbortWithExitCode(fmt.Sprintf(GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, "", "standardInputErrorMsg"), err), internalconstant.ExitStatusCode1)
}
size := fi.Size()
isStandardInputAvailable := false
@@ -154,7 +155,7 @@ func ReadStdin(cmd *cobra.Command) (bool, []byte) {
log.Debug("%v bytes available in Stdin\n", size)
jsonData, err := ioutil.ReadAll(bufio.NewReader(os.Stdin))
if err != nil {
- AbortWithExitCode(fmt.Sprintf(GetServiceMessage(cmd, MessageTypeDisplay, "", "standardInputErrorMsg"), err), ExitStatusCode1)
+ AbortWithExitCode(fmt.Sprintf(GetServiceMessage(cmd, internalconstant.MessageTypeDisplay, "", "standardInputErrorMsg"), err), internalconstant.ExitStatusCode1)
}
return isStandardInputAvailable, jsonData
@@ -166,27 +167,30 @@ func ReadStdin(cmd *cobra.Command) (bool, []byte) {
func ByteArrayToStruct(cmd *cobra.Command, byt []byte, payloadObject interface{}) {
if err := json.Unmarshal(byt, payloadObject); err != nil {
log.Debug(err)
- AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, Invalid, Json), ExitStatusCode3)
+ AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, internalconstant.Invalid, internalconstant.Json), internalconstant.ExitStatusCode3)
}
}
-// CheckIfBothJsonAndFlagAreSetForCommand method returns true if any subcommand flag is set, otherwise false
+// CheckIfBothJsonAndFlagAreSetForCommand method returns true if json input is set, otherwise false
func CheckIfBothJsonAndFlagAreSetForCommand(cmd *cobra.Command, jsonData []byte, isStandardInputAvailable bool) bool {
checkIfSubCommandFlagsAreNonEmpty := checkIfAnySubCommandFlagIsSet(cmd)
if checkIfSubCommandFlagsAreNonEmpty && jsonData != nil {
- AbortWithUsageAndMessageAndCode(cmd, GetGlobalErrorMessage("invalidCommandInput"), ExitStatusCode2)
+ AbortWithUsageAndMessageAndCode(cmd, GetGlobalErrorMessage("invalidCommandInput"), internalconstant.ExitStatusCode2)
} else if !checkIfSubCommandFlagsAreNonEmpty && !isStandardInputAvailable {
// If command is provided without JSON input and flags, we simply through flag missing error and abort with usage
- AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, Missing, "flagOrJsonImport"), ExitStatusCode2)
+ AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, internalconstant.Missing, "flagOrJsonImport"), internalconstant.ExitStatusCode2)
} else if !checkIfSubCommandFlagsAreNonEmpty && jsonData == nil {
- AbortWithUsageAndMessageAndCode(cmd, GetGlobalErrorMessage("invalidJsonInput"), ExitStatusCode3)
+ AbortWithUsageAndMessageAndCode(cmd, GetGlobalErrorMessage("invalidJsonInput"), internalconstant.ExitStatusCode3)
}
- return checkIfSubCommandFlagsAreNonEmpty
+ return !checkIfSubCommandFlagsAreNonEmpty
}
-/* Returns true/false if any flag has been set/modified for the child level sub-command. e.g. akamai test-center ts
-generate-default, here flags for generate-default will be checked and global flags will be not be included in check. */
+/*
+ Returns true/false if any flag has been set/modified for the child level sub-command. e.g. akamai test-center ts
+
+generate-default, here flags for generate-default will be checked and global flags will be not be included in check.
+*/
func checkIfAnySubCommandFlagIsSet(cmd *cobra.Command) bool {
isSubCommandFlagSet := false
@@ -200,33 +204,34 @@ func checkIfAnySubCommandFlagIsSet(cmd *cobra.Command) bool {
return isSubCommandFlagSet
}
-//LegacyArgs is used to invalidate unknown subcommands took reference from cobra.args legacyArgs() library
+// LegacyArgs is used to invalidate unknown subcommands took reference from cobra.args legacyArgs() library
func LegacyArgs(cmd *cobra.Command, args []string) error {
+ // we will not show error when no subcommand is given for parent command, but we will show help section.
if len(args) <= 0 {
- return fmt.Errorf(GetErrorMessageForSubArgument(cmd, Missing, SubCommandNoArgumentPassed), cmd.Name())
+ return nil
}
// no subcommand, always take args
if cmd.HasSubCommands() {
- return fmt.Errorf(GetErrorMessageForSubArgument(cmd, Invalid, SubCommandWrongArgumentPassed), args[0], cmd.Name(), FindSuggestions(cmd, args[0]))
+ return fmt.Errorf(GetErrorMessageForSubArgument(cmd, internalconstant.Invalid, internalconstant.SubCommandWrongArgumentPassed), args[0], cmd.Name(), FindSuggestions(cmd, args[0]))
}
// root command with subcommands, do subcommand checking.
if !cmd.HasParent() && len(args) > 0 {
- return fmt.Errorf(GetErrorMessageForSubArgument(cmd, Invalid, SubCommandWrongArgumentPassed), args[0], cmd.Name(), FindSuggestions(cmd, args[0]))
+ return fmt.Errorf(GetErrorMessageForSubArgument(cmd, internalconstant.Invalid, internalconstant.SubCommandWrongArgumentPassed), args[0], cmd.Name(), FindSuggestions(cmd, args[0]))
}
return nil
}
-//FindSuggestions returns a list possible subcommands referenced cobra.command findSuggestions() library
+// FindSuggestions returns a list possible subcommands referenced cobra.command findSuggestions() library
func FindSuggestions(cmd *cobra.Command, arg string) string {
if cmd.DisableSuggestions {
- return Empty
+ return internalconstant.Empty
}
if cmd.SuggestionsMinimumDistance <= 0 {
cmd.SuggestionsMinimumDistance = 2
}
- suggestionsString := Empty
+ suggestionsString := internalconstant.Empty
if suggestions := cmd.SuggestionsFor(arg); len(suggestions) > 0 {
suggestionsString += "\n\nDid you mean this?\n"
for _, s := range suggestions {
@@ -236,18 +241,10 @@ func FindSuggestions(cmd *cobra.Command, arg string) string {
return suggestionsString
}
-// NotValidSubcommandCheck returns an error if no valid subcommand is included.
-func NotValidSubcommandCheck(cmd *cobra.Command, args []string) error {
- if len(args) <= 0 {
- return fmt.Errorf(GetErrorMessageForSubArgument(cmd, Missing, SubCommandNoArgumentPassed), cmd.Name())
- }
- return nil
-}
-
// NoArgsCheck returns an error if any args are included.
func NoArgsCheck(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
- return fmt.Errorf(GetErrorMessageForSubArgument(cmd, Invalid, SubCommandWithArgumentPassed), args[0], cmd.Name())
+ return fmt.Errorf(GetErrorMessageForSubArgument(cmd, internalconstant.Invalid, internalconstant.SubCommandWithArgumentNotAllowed), args[0], cmd.Name())
}
return nil
}
@@ -257,15 +254,106 @@ func GetHttpExitCode(responseCode string) int {
log.Debugf("Response Status Code [%q] ", responseCode)
statusCode, err := strconv.Atoi(responseCode)
if err != nil {
- statusCode = ExitStatusCode1
+ statusCode = internalconstant.ExitStatusCode1
}
if statusCode >= 400 && statusCode <= 550 { // Difference used for 4xx and 5xx errors
- statusCode = statusCode - BaseSubtractor
+ statusCode = statusCode - internalconstant.BaseSubtractor
} else if statusCode >= 100 && statusCode <= 399 { // 1xx 2xx & 3xx errors are treated as success
- statusCode = ExitStatusCode0
+ statusCode = internalconstant.ExitStatusCode0
} else {
- statusCode = ExitStatusCode1
+ statusCode = internalconstant.ExitStatusCode1
}
log.Debugf("Exit Status Code [%v] ", statusCode)
return statusCode
}
+
+func GetStatusKeyAndColour(status string) (string, color.Color) {
+ if status == internalconstant.CompletedEnum {
+ c := color.New(color.FgGreen)
+ return internalconstant.CompletedKey, *c
+
+ } else if status == internalconstant.CompletedWithUnexpectedResultsEnum {
+ c := color.New(color.FgYellow)
+ return internalconstant.CompletedWithUnexpectedResultsKey, *c
+
+ } else if status == internalconstant.InProgressEnum {
+ return internalconstant.InProgressKey, *color.New()
+
+ } else {
+ c := color.New(color.FgRed)
+ return internalconstant.FailedKey, *c
+ }
+}
+
+func GetColourForEnum(enum string, bold bool) color.Color {
+ c := color.New()
+
+ if bold {
+ c.Add(color.Bold)
+ }
+
+ if enum == internalconstant.GetRequestMethod {
+ c.Add(color.FgBlue)
+
+ } else if enum == internalconstant.HeadRequestMethod {
+ c.Add(color.FgYellow)
+
+ } else if enum == internalconstant.PostRequestMethod {
+ c.Add(color.FgGreen)
+ }
+
+ return *c
+}
+func GetResolvedOrUnResolvedHeaders(header model.RequestHeader) string {
+ var headerName = header.HeaderName
+ var headerAction = header.HeaderAction
+ var headerValue = header.HeaderValue
+ if header.HeaderNameResolved != internalconstant.Empty {
+ headerName = header.HeaderNameResolved
+ }
+ if header.HeaderValueResolved != internalconstant.Empty {
+ headerValue = header.HeaderValueResolved
+ }
+ return RequestHeaderInCLIOutputFormat(headerName, headerAction, headerValue)
+}
+
+func GetResolvedOrUnResolvedCondition(condition model.Condition) string {
+ var cond = condition.ConditionExpression
+ if condition.ConditionExpressionResolved != internalconstant.Empty {
+ cond = condition.ConditionExpressionResolved
+ }
+ return cond
+}
+
+func GetResolvedOrUnResolvedRequestBody(testRequest model.TestRequest) string {
+ var requestBody = testRequest.RequestBody
+ if testRequest.RequestBodyResolved != internalconstant.Empty {
+ requestBody = testRequest.RequestBodyResolved
+ }
+ return requestBody
+}
+
+func GetResolvedOrUnResolvedRequestURL(testRequest model.TestRequest) string {
+ var url = testRequest.TestRequestUrl
+ if testRequest.TestRequestUrlResolved != internalconstant.Empty {
+ url = testRequest.TestRequestUrlResolved
+ }
+ return url
+}
+
+func SetVariablesInCLIOutputFormat(variable model.DynamicVariable) string {
+ return variable.VariableName + externalconstant.Equals + variable.VariableValue
+}
+
+func GetConvertedInteger(number string) int {
+ num, _ := strconv.Atoi(number)
+ return num
+}
+
+func GetTotalTestCasesCount(testCases []model.TestCase) int {
+ count := len(testCases)
+ for _, testcase := range testCases {
+ count += len(testcase.DerivedTestCases)
+ }
+ return count
+}
diff --git a/internal/validator.go b/internal/validator.go
deleted file mode 100644
index 23644ca..0000000
--- a/internal/validator.go
+++ /dev/null
@@ -1,373 +0,0 @@
-package internal
-
-import (
- log "github.com/sirupsen/logrus"
- "net/url"
- "strconv"
- "strings"
-
- "github.com/spf13/cobra"
-)
-
-type Validator struct {
- cmd *cobra.Command
- jsonData []byte
-}
-
-func NewValidator(cmd *cobra.Command, jsonData []byte) *Validator {
- return &Validator{cmd, jsonData}
-}
-
-func (validator Validator) ConfigFlagCheck(configVersionString string, isOptional bool) (string, int) {
-
- if configVersionString != "" {
- configVersionSplit := strings.Split(configVersionString, " ")
-
- if len(configVersionSplit) != 2 {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "configVersion"), ExitStatusCode2)
- }
-
- configName, version := configVersionSplit[0], configVersionSplit[1]
-
- versionNumber, err := strconv.Atoi(version)
- if err != nil || configName == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "configVersion"), ExitStatusCode2)
- }
-
- return configName, versionNumber
- }
-
- if !isOptional {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "configVersion"), ExitStatusCode2)
- }
-
- return "", 0
-}
-
-func (validator Validator) ConfigFlagCheckForListTestSuites(propVersion string, propertyName string) {
- // validate configVersion usage
- if propVersion != Empty {
- version, err := strconv.Atoi(propVersion)
-
- if err != nil || propertyName == Empty || version == 0 {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, PropertyVersionFlagKey), ExitStatusCode2)
- }
- }
-}
-
-func (validator Validator) RemoveConfigFlagCheck(property string, removeProperty bool) {
- if removeProperty && property != "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "removeProperty"), ExitStatusCode2)
- }
-}
-
-func (validator Validator) EditTestSuiteAllFlagCheck() {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "all"), ExitStatusCode2)
-}
-
-func (validator Validator) AddTestSuiteNameFlagCheck(name string) {
- if name == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "name"), ExitStatusCode2)
- }
-}
-
-func (validator Validator) EditTestSuiteIdFlagCheck(testSuiteId string) {
-
- if testSuiteId == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "id"), ExitStatusCode2)
- }
-
- id, err := strconv.Atoi(testSuiteId)
- if err != nil || id == 0 {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "id"), ExitStatusCode2)
- }
-}
-
-func (validator Validator) ValidateViewTestSuiteFlags(testSuiteId, testSuiteName, groupBy string) {
-
- validator.TestSuiteIdAndNameFlagCheck(testSuiteId, testSuiteName)
-
- // validate if group by flag value is - condition, test-request, ipversion only
- validator.GroupByFlagCheck(groupBy)
-}
-
-func (validator Validator) GroupByFlagCheck(groupBy string) {
-
- if groupBy != "" && !ContainsInArray([]string{GroupByTestRequest, GroupByCondition, GroupByIpVersion}, groupBy) {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "groupBy"), ExitStatusCode2)
- }
-}
-
-func (validator Validator) ValidateImportFields(testSuitesImport *TestSuiteV3) {
-
- if len(validator.jsonData) == 0 {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, Json), ExitStatusCode2)
- }
-
- if validator.jsonData != nil {
- ByteArrayToStruct(validator.cmd, validator.jsonData, &testSuitesImport)
- return
- }
-}
-
-func (validator Validator) ValidateManageFields(testSuitesManage *TestSuiteV3) {
-
- if len(validator.jsonData) == 0 {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, Json), ExitStatusCode2)
- }
-
- if validator.jsonData != nil {
- ByteArrayToStruct(validator.cmd, validator.jsonData, &testSuitesManage)
- testSuiteId := strconv.Itoa(testSuitesManage.TestSuiteId)
- if testSuiteId == "0" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "testSuiteId"), ExitStatusCode2)
- }
- return
- }
-}
-
-func (validator Validator) ValidateDefaultTestSuiteFields(propertyName string, propertyVersion string, urls []string, jsonData []byte,
- defaultTestSuite *DefaultTestSuiteRequest, isStandardInputAvailable bool) (string, int) {
- // throw invalid or missing errors if any and abort
- checkIfSubCommandFlagsAreNonEmpty := CheckIfBothJsonAndFlagAreSetForCommand(validator.cmd, jsonData, isStandardInputAvailable)
-
- if !checkIfSubCommandFlagsAreNonEmpty {
- log.Debug("Generating default test suite with input json data!!!!")
- ByteArrayToStruct(validator.cmd, validator.jsonData, defaultTestSuite)
- // the below returned values are not used anywhere for now as JSON payload is passed directly to the api
- return defaultTestSuite.Configs.PropertyManager.PropertyName, defaultTestSuite.Configs.PropertyManager.PropertyVersion
- } else {
- log.Debug("Generating default test suite with flags!!!!")
- // validate configVersion usage.
- name, version := validator.PropertyAndVersionFlagCheck(propertyName, propertyVersion, false)
- validator.UrlsFlagCheck(urls)
- return name, version
- }
-}
-
-func (validator Validator) AddTestCaseToTestSuiteFlagCheck(testSuiteId, testSuiteName, url, condition, ipVersion string, addHeader, modifyHeader []string) {
-
- if url == "" || condition == "" || (testSuiteName == "" && testSuiteId == "") {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "any"), ExitStatusCode2)
- }
-
- id, err := strconv.Atoi(testSuiteId)
- if testSuiteId != "" && (err != nil || id == 0) {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "testSuiteId"), ExitStatusCode2)
- }
-
- //Check if ip version is sent properly
- ipVersionFlagCheck(validator.cmd, ipVersion)
-
- //Check if headers are sent properly
- headerFlagCheck(validator.cmd, addHeader, modifyHeader)
-}
-
-func (validator Validator) RemoveTestCaseFromTestSuiteFlagCheck(testSuiteId, orderNumber string) {
-
- if testSuiteId == "" || orderNumber == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "any"), ExitStatusCode2)
- }
-
- id, err := strconv.Atoi(testSuiteId)
- if testSuiteId != "" && (err != nil || id == 0) {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "testSuiteId"), ExitStatusCode2)
- }
-
- orderNum, orderError := strconv.Atoi(orderNumber)
- if orderNumber != "" && (orderError != nil || orderNum == 0) {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "orderNum"), ExitStatusCode2)
- }
-}
-
-func (validator Validator) TestSuiteIdAndNameFlagCheck(testSuiteId, testSuiteName string) {
-
- if testSuiteName == "" && testSuiteId == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "any"), ExitStatusCode2)
- }
-
- id, err := strconv.Atoi(testSuiteId)
- if testSuiteId != "" && (err != nil || id == 0) {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "id"), ExitStatusCode2)
- }
-
-}
-
-func (validator Validator) ValidateTestRunFlagsAndGetRunEnum(testSuiteId, testSuiteName, propertyName, propVersion,
- url, condition, ipVersion, targetEnvironment string, addHeader, modifyHeader []string, jsonData []byte,
- testRunRequest *TestRun, isStandardInputAvailable bool) string {
-
- var runTestUsing = make([]string, 0)
-
- checkIfSubCommandFlagsAreNonEmpty := CheckIfBothJsonAndFlagAreSetForCommand(validator.cmd, jsonData, isStandardInputAvailable)
-
- if !checkIfSubCommandFlagsAreNonEmpty {
- log.Debug("Test Run Using JSON Input!!!!!")
- ByteArrayToStruct(validator.cmd, validator.jsonData, testRunRequest)
- runTestUsing = append(runTestUsing, RunTestUsingJsonInput)
- return runTestUsing[0]
- }
-
- // Check if target environment flag value is from given enums only.
- environmentFlagCheck(validator.cmd, strings.ToUpper(targetEnvironment))
-
- if testSuiteName != "" {
- runTestUsing = append(runTestUsing, RunTestUsingTestSuiteName)
- }
-
- if testSuiteId != "" {
- // validate if other flag is not already set to run test
- checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
-
- validator.EditTestSuiteIdFlagCheck(testSuiteId)
- runTestUsing = append(runTestUsing, RunTestUsingTestSuiteId)
- }
-
- if propertyName != "" || propVersion != "" {
- // validate if other flag is not already set to run test
- checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
-
- validator.PropertyAndVersionFlagCheck(propertyName, propVersion, true)
- runTestUsing = append(runTestUsing, RunTestUsingPropertyVersion)
- }
-
- if url != "" || condition != "" {
- // validate if other flag is not already set to run test
- checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
-
- if url == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "url"), ExitStatusCode2)
- }
-
- if condition == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "condition"), ExitStatusCode2)
- }
-
- //Check if ip version is set properly
- ipVersionFlagCheck(validator.cmd, strings.ToUpper(ipVersion))
-
- //Check if headers are sent properly
- headerFlagCheck(validator.cmd, addHeader, modifyHeader)
-
- runTestUsing = append(runTestUsing, RunTestUsingSingleTestCase)
- }
-
- switch len(runTestUsing) {
- case 0:
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "any"), ExitStatusCode2)
- return ""
- case 1:
- return runTestUsing[0]
- default:
- // validate if other flag is not already set to run test
- checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
- return ""
- }
-}
-
-func (validator Validator) UrlsFlagCheck(urls []string) {
-
- if len(urls) < 1 {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, "url"), ExitStatusCode2)
- }
-
- for _, fullUrl := range urls {
-
- u, err := url.Parse(fullUrl)
- if err != nil {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "url"), ExitStatusCode2)
- }
-
- proto := u.Scheme
- hn := u.Host
- if proto == "" || hn == "" {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "url"), ExitStatusCode2)
- }
- }
-}
-
-// Check if length of run test using list has more than one different king of flag.
-func checkExclusiveTestRunFlags(cmd *cobra.Command, runTestUsing []string) {
- if len(runTestUsing) != 0 {
- AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, Invalid, "exclusive"), ExitStatusCode2)
- }
-}
-
-func environmentFlagCheck(cmd *cobra.Command, environment string) {
-
- if environment != "" && !(environment == Staging || environment == Production) {
- AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, Invalid, "targetEnvironment"), ExitStatusCode2)
- }
-}
-
-func ipVersionFlagCheck(cmd *cobra.Command, ipVersion string) {
-
- if ipVersion != "" && !(ipVersion == "v6" || ipVersion == "v4" || ipVersion == "V6" || ipVersion == "V4") {
- AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, Invalid, "ipVersion"), ExitStatusCode2)
- }
-}
-
-func headerFlagCheck(cmd *cobra.Command, addHeader, modifyHeader []string) {
-
- if len(addHeader) > 0 {
- for _, header := range addHeader {
- headerComponents := strings.Split(header, ":")
- if len(headerComponents) < 2 {
- AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, Invalid, "addHeader"), ExitStatusCode2)
- }
- }
- }
-
- if len(modifyHeader) > 0 {
- for _, header := range modifyHeader {
- headerComponents := strings.Split(header, ":")
- if len(headerComponents) < 2 {
- AbortWithUsageAndMessageAndCode(cmd, GetErrorMessageForFlag(cmd, Invalid, "modifyHeader"), ExitStatusCode2)
- }
- }
- }
-}
-
-func (validator Validator) PropertyAndVersionFlagCheck(propertyString string, versionString string, isOptional bool) (string, int) {
- if (propertyString != Empty && versionString == Empty) || (propertyString == Empty && versionString != Empty) {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, PropertyVersionFlagKey), ExitStatusCode2)
- }
- if propertyString != "" {
- versionNumber, err := strconv.Atoi(versionString)
- if err != nil {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, PropertyVersionFlagKey), ExitStatusCode2)
- }
- return propertyString, versionNumber
- }
- if !isOptional {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Missing, PropertyVersionFlagKey), ExitStatusCode2)
- }
- return "", 0
-}
-
-func (validator Validator) ValidateSubcommandsNoArgCheck(cmd *cobra.Command, args []string) {
- if err := NoArgsCheck(cmd, args); err != nil {
- AbortWithUsageAndMessageAndCode(validator.cmd, err.Error(), ExitStatusCode2)
- }
-}
-
-func (validator Validator) NotValidSubcommandCheck(cmd *cobra.Command, args []string) {
- if err := NotValidSubcommandCheck(cmd, args); err != nil {
- AbortWithUsageAndMessageAndCode(validator.cmd, err.Error(), ExitStatusCode2)
- }
-}
-
-func (validator Validator) ValidSubcommandLegacyArgsCheck(cmd *cobra.Command, args []string) {
- if err := LegacyArgs(cmd, args); err != nil {
- AbortWithUsageAndMessageAndCode(validator.cmd, err.Error(), ExitStatusCode2)
- }
-}
-
-func (validator Validator) LockedAndStatefulFlagCheck(locked bool, unlocked bool, stateful bool, stateless bool) {
- if locked && unlocked {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "lockedUnlocked"), ExitStatusCode2)
- }
- if stateful && stateless {
- AbortWithUsageAndMessageAndCode(validator.cmd, GetErrorMessageForFlag(validator.cmd, Invalid, "statefulStateless"), ExitStatusCode2)
- }
-}
diff --git a/internal/validator/function_validator.go b/internal/validator/function_validator.go
new file mode 100644
index 0000000..1189bdc
--- /dev/null
+++ b/internal/validator/function_validator.go
@@ -0,0 +1,21 @@
+package validator
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+)
+
+//This validator class will have the test center functions related validate methods.
+
+func (validator Validator) ValidateTryItFunctionInputFields(tryFunction *model.TryFunction) {
+
+ if len(validator.jsonData) == 0 {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Json), internalconstant.ExitStatusCode2)
+ }
+
+ if validator.jsonData != nil {
+ util.ByteArrayToStruct(validator.cmd, validator.jsonData, &tryFunction)
+ return
+ }
+}
diff --git a/internal/validator/global_validator.go b/internal/validator/global_validator.go
new file mode 100644
index 0000000..06488d9
--- /dev/null
+++ b/internal/validator/global_validator.go
@@ -0,0 +1,52 @@
+package validator
+
+import (
+ "fmt"
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ "github.com/spf13/cobra"
+)
+
+type GlobalValidator struct {
+ cmd *cobra.Command
+ jsonData []byte
+}
+
+func NewGlobalValidator(cmd *cobra.Command, jsonData []byte) *GlobalValidator {
+ return &GlobalValidator{cmd, jsonData}
+}
+
+// Use this function to validate commands where json input is not allowed. Keep the order always one for parent commands
+func (globalValidator GlobalValidator) ValidateJsonInputNotAllowed(cmd *cobra.Command, jsonData []byte) {
+ if jsonData != nil {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetGlobalErrorMessage(internalconstant.JsonInputNotAllowed),
+ internalconstant.ExitStatusCode2)
+ }
+}
+
+// Use this function to validate root/parent subcommands/argument, gives suggestion as well if keywords match.
+func (globalValidator GlobalValidator) ValidateParentSubCommands(cmd *cobra.Command, args []string, isJsonInputAllowed bool) {
+
+ if !isJsonInputAllowed {
+ globalValidator.ValidateJsonInputNotAllowed(cmd, globalValidator.jsonData)
+ }
+
+ err := util.LegacyArgs(cmd, args)
+ if err != nil {
+ util.AbortWithUsageAndMessageAndCode(globalValidator.cmd, err.Error(), internalconstant.ExitStatusCode2)
+ } else {
+ util.AbortWithUsageAndMessageAndCode(globalValidator.cmd, fmt.Errorf(internalconstant.Empty).Error(),
+ internalconstant.ExitStatusCode0)
+ }
+}
+
+// Use this function to validate commands where no subcommands are allowed, mostly used in child level commands.
+func (globalValidator GlobalValidator) ValidateSubCommandsNotAllowed(cmd *cobra.Command, args []string, isJsonInputAllowed bool) {
+ if !isJsonInputAllowed {
+ globalValidator.ValidateJsonInputNotAllowed(cmd, globalValidator.jsonData)
+ }
+
+ if err := util.NoArgsCheck(cmd, args); err != nil {
+ util.AbortWithUsageAndMessageAndCode(globalValidator.cmd, err.Error(), internalconstant.ExitStatusCode2)
+ }
+}
diff --git a/internal/validator/test_case_validator.go b/internal/validator/test_case_validator.go
new file mode 100644
index 0000000..7d90687
--- /dev/null
+++ b/internal/validator/test_case_validator.go
@@ -0,0 +1,96 @@
+package validator
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "github.com/spf13/cobra"
+ "strconv"
+ "strings"
+)
+
+//This validator class will have the test case related validate methods.
+
+func (validator Validator) AddTestCaseToTestSuiteFlagCheck(testSuiteId, testSuiteName, url, condition, ipVersion string, addHeader,
+ modifyHeader []string, client string, method string, requestBody string, encodeRequestBody bool, setVariables []string) {
+
+ if url == internalconstant.Empty || condition == internalconstant.Empty || (testSuiteName == internalconstant.Empty && testSuiteId == internalconstant.Empty) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Any), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testSuiteId)
+ if testSuiteId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.TestSuiteId), internalconstant.ExitStatusCode2)
+ }
+
+ //Check if ip version is sent properly
+ ipVersionFlagCheck(validator.cmd, ipVersion)
+
+ //Check if headers are sent properly
+ headerFlagCheck(validator.cmd, addHeader, modifyHeader)
+
+ // Check if client flag value is from given enums only.
+ clientTypeFlagCheck(validator.cmd, strings.ToUpper(client))
+
+ // Check if requestMethod flag value is from given enums only.
+ methodFlagCheck(validator.cmd, strings.ToUpper(method), strings.ToUpper(client))
+
+ // Check if requestBody flag value is given for post request only.
+ requestBodyFlagCheck(validator.cmd, requestBody, strings.ToUpper(method), strings.ToUpper(client))
+
+ // Check if encodeRequestBody flag value is given for POST request and client type CURL only.
+ encodeRequestBodyFlagCheck(validator.cmd, encodeRequestBody, strings.ToUpper(method), strings.ToUpper(client))
+
+ // Check if setVariables values are sent properly
+ setVariablesFlagCheck(validator.cmd, setVariables)
+
+}
+
+func (validator Validator) RemoveTestCaseFromTestSuiteFlagCheck(testSuiteId, orderNumber, testCaseIdStr string) {
+
+ if testSuiteId == internalconstant.Empty || (orderNumber == internalconstant.Empty && testCaseIdStr == internalconstant.Empty) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Any), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testSuiteId)
+ if testSuiteId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.TestSuiteId), internalconstant.ExitStatusCode2)
+ }
+
+ if orderNumber != internalconstant.Empty && testCaseIdStr != internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.OrderNumTestCaseId), internalconstant.ExitStatusCode2)
+ }
+
+ orderNum, orderError := strconv.Atoi(orderNumber)
+ if orderNumber != internalconstant.Empty && (orderError != nil || orderNum == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.OrderNum), internalconstant.ExitStatusCode2)
+ }
+
+ testCaseId, err := strconv.Atoi(testCaseIdStr)
+ if testCaseIdStr != internalconstant.Empty && (err != nil || testCaseId == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.TestCaseId), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateTestCaseFlagCheck(testCaseId string) {
+ if testCaseId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.TestCaseId), internalconstant.ExitStatusCode2)
+ }
+
+ tcId, err := strconv.Atoi(testCaseId)
+ if testCaseId != internalconstant.Empty && (err != nil || tcId == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.TestCaseId), internalconstant.ExitStatusCode2)
+ }
+}
+
+func setVariablesFlagCheck(cmd *cobra.Command, setVariables []string) {
+
+ if len(setVariables) > 0 {
+ for _, variable := range setVariables {
+ setVariableComponents := strings.Split(variable, externalconstant.Colon)
+ if len(setVariableComponents) < 2 {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, internalconstant.SetVariables), internalconstant.ExitStatusCode2)
+ }
+ }
+ }
+}
diff --git a/internal/validator/test_run_validator.go b/internal/validator/test_run_validator.go
new file mode 100644
index 0000000..3682805
--- /dev/null
+++ b/internal/validator/test_run_validator.go
@@ -0,0 +1,175 @@
+package validator
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ log "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+ "strconv"
+ "strings"
+)
+
+//This validator class will have the test run related validate methods.
+
+func (validator Validator) ValidateGetTestRunFlag(testRunId string) {
+
+ if testRunId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing,
+ util.GetJsonKeyForFlag(externalconstant.FlagTestRunId)), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testRunId)
+ if testRunId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid,
+ util.GetJsonKeyForFlag(externalconstant.FlagTestRunId)), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateTestRunFlagsAndGetRunEnum(testSuiteId, testSuiteName, propertyId, propertyName, propVersion, url, condition, ipVersion,
+ targetEnvironment, client, location, requestMethod, requestBody string, addHeader, modifyHeader []string, jsonData []byte, testRunRequest *model.TestRun,
+ isStandardInputAvailable, encodeRequestBody bool) string {
+
+ var runTestUsing = make([]string, 0)
+
+ isJsonInput := util.CheckIfBothJsonAndFlagAreSetForCommand(validator.cmd, jsonData, isStandardInputAvailable)
+
+ if isJsonInput {
+ log.Debug("Test Run Using JSON Input!!!!!")
+ util.ByteArrayToStruct(validator.cmd, validator.jsonData, testRunRequest)
+ runTestUsing = append(runTestUsing, internalconstant.RunTestUsingJsonInput)
+ return runTestUsing[0]
+ }
+
+ // Check if target environment flag value is from given enums only.
+ environmentFlagCheck(validator.cmd, strings.ToUpper(targetEnvironment))
+
+ if testSuiteName != internalconstant.Empty {
+ runTestUsing = append(runTestUsing, internalconstant.RunTestUsingTestSuiteName)
+ }
+
+ if testSuiteId != internalconstant.Empty {
+ // validate if other flag is not already set to run test
+ checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
+
+ validator.EditTestSuiteIdFlagCheck(testSuiteId)
+ runTestUsing = append(runTestUsing, internalconstant.RunTestUsingTestSuiteId)
+ }
+
+ if propertyName != internalconstant.Empty || propVersion != internalconstant.Empty {
+ // validate if other flag is not already set to run test
+ checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
+
+ validator.PropertyAndVersionFlagCheck(propertyId, propertyName, propVersion, true)
+ runTestUsing = append(runTestUsing, internalconstant.RunTestUsingPropertyVersion)
+ }
+
+ if url != internalconstant.Empty || condition != internalconstant.Empty {
+ // validate if other flag is not already set to run test
+ checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
+
+ if url == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, "url"), internalconstant.ExitStatusCode2)
+ }
+
+ if condition == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, "condition"), internalconstant.ExitStatusCode2)
+ }
+
+ //Check if ip version is set properly
+ ipVersionFlagCheck(validator.cmd, strings.ToUpper(ipVersion))
+
+ //Check if headers are sent properly
+ headerFlagCheck(validator.cmd, addHeader, modifyHeader)
+
+ // Check if client flag value is from given enums only.
+ clientTypeFlagCheck(validator.cmd, strings.ToUpper(client))
+
+ // Check if location flag value is from given enums only.
+ locationFlagCheck(validator.cmd, strings.ToUpper(location))
+
+ // Check if requestMethod flag value is from given enums only.
+ methodFlagCheck(validator.cmd, strings.ToUpper(requestMethod), strings.ToUpper(client))
+
+ // Check if requestBody flag value is given for post request only.
+ requestBodyFlagCheck(validator.cmd, requestBody, strings.ToUpper(requestMethod), strings.ToUpper(client))
+
+ // Check if encodeRequestBody flag value is given for POST request and client type CURL only.
+ encodeRequestBodyFlagCheck(validator.cmd, encodeRequestBody, strings.ToUpper(requestMethod), strings.ToUpper(client))
+
+ runTestUsing = append(runTestUsing, internalconstant.RunTestUsingSingleTestCase)
+ }
+
+ switch len(runTestUsing) {
+ case 0:
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Any), internalconstant.ExitStatusCode2)
+ return internalconstant.Empty
+ case 1:
+ return runTestUsing[0]
+ default:
+ // validate if other flag is not already set to run test
+ checkExclusiveTestRunFlags(validator.cmd, runTestUsing)
+ return internalconstant.Empty
+ }
+}
+
+// Check if length of run test using list has more than one different king of flag.
+func checkExclusiveTestRunFlags(cmd *cobra.Command, runTestUsing []string) {
+ if len(runTestUsing) != 0 {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, internalconstant.Exclusive), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateGetRawRequestResponseFlag(testRunId, testCaseExecutionId string) {
+
+ if testRunId == internalconstant.Empty && testCaseExecutionId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing,
+ util.GetJsonKeyForFlag(internalconstant.Any)), internalconstant.ExitStatusCode2)
+ }
+
+ if testRunId != internalconstant.Empty && testCaseExecutionId != internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid,
+ util.GetJsonKeyForFlag(internalconstant.OneOf)), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testRunId)
+ if testRunId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid,
+ util.GetJsonKeyForFlag(externalconstant.FlagTestRunId)), internalconstant.ExitStatusCode2)
+ }
+
+ tcxId, err := strconv.Atoi(testCaseExecutionId)
+ if testCaseExecutionId != internalconstant.Empty && (err != nil || tcxId == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid,
+ util.GetJsonKeyForFlag(externalconstant.FlagTestCaseExecId)), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateGetLogLinesFlag(tcxId string) {
+
+ if tcxId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing,
+ util.GetJsonKeyForFlag(externalconstant.FlagTestCaseExecId)), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(tcxId)
+ if tcxId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid,
+ util.GetJsonKeyForFlag(externalconstant.FlagTestCaseExecId)), internalconstant.ExitStatusCode2)
+ }
+
+}
+
+func locationFlagCheck(cmd *cobra.Command, location string) {
+ if location != internalconstant.Empty && !(location == internalconstant.DefaultLocation) {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, externalconstant.FlagLocation), internalconstant.ExitStatusCode2)
+ }
+}
+
+func environmentFlagCheck(cmd *cobra.Command, environment string) {
+
+ if environment != internalconstant.Empty && !(environment == internalconstant.Staging || environment == internalconstant.Production) {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, internalconstant.TargetEnvironment), internalconstant.ExitStatusCode2)
+ }
+}
diff --git a/internal/validator/test_suite_validator.go b/internal/validator/test_suite_validator.go
new file mode 100644
index 0000000..9409733
--- /dev/null
+++ b/internal/validator/test_suite_validator.go
@@ -0,0 +1,154 @@
+package validator
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/model"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ log "github.com/sirupsen/logrus"
+ "net/url"
+ "strconv"
+)
+
+//This validator class will have the test suite related validate methods.
+
+func (validator Validator) EditTestSuiteAllFlagCheck() {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.All), internalconstant.ExitStatusCode2)
+}
+
+func (validator Validator) AddTestSuiteNameFlagCheck(name string) {
+ if name == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, externalconstant.FlagVariableName), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateCreateTestSuiteFields(testSuite *model.TestSuite, isStandardInputAvailable bool, name, propertyId, propName, propVersion string) {
+
+ // throw invalid or missing errors if any and abort
+ isJsonInput := util.CheckIfBothJsonAndFlagAreSetForCommand(validator.cmd, validator.jsonData, isStandardInputAvailable)
+
+ if isJsonInput {
+ if len(validator.jsonData) == 0 {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Json), internalconstant.ExitStatusCode2)
+ }
+
+ if validator.jsonData != nil {
+ util.ByteArrayToStruct(validator.cmd, validator.jsonData, &testSuite)
+ }
+ } else {
+ // validate name flag check.
+ validator.AddTestSuiteNameFlagCheck(name)
+
+ // validate propertyVersion usage.
+ validator.PropertyAndVersionFlagCheck(propertyId, propName, propVersion, true)
+ }
+}
+
+func (validator Validator) ValidateUpdateTestSuiteFields(testSuite *model.TestSuite, isStandardInputAvailable bool, id,
+ propertyId, propertyName, propertyVersion string, locked, unlocked, stateful, stateless, removeProperty bool) {
+
+ // throw invalid or missing errors if any and abort
+ isJsonInput := util.CheckIfBothJsonAndFlagAreSetForCommand(validator.cmd, validator.jsonData, isStandardInputAvailable)
+
+ if isJsonInput {
+ validator.ValidateManageFields(testSuite)
+ } else {
+ // validate id flag check.
+ validator.EditTestSuiteIdFlagCheck(id)
+
+ // validate propertyVersion usage.
+ validator.PropertyAndVersionFlagCheck(propertyId, propertyName, propertyVersion, true)
+
+ //Remove config flag check
+ validator.RemoveConfigFlagCheck(propertyName, removeProperty)
+ validator.LockedAndStatefulFlagCheck(locked, unlocked, stateful, stateless)
+ }
+}
+
+func (validator Validator) RemoveConfigFlagCheck(propertyName string, removeProperty bool) {
+ if removeProperty && propertyName != internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.RemoveProperty), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateImportFields(testSuitesImport *model.TestSuite) {
+
+ if len(validator.jsonData) == 0 {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Json), internalconstant.ExitStatusCode2)
+ }
+
+ if validator.jsonData != nil {
+ util.ByteArrayToStruct(validator.cmd, validator.jsonData, &testSuitesImport)
+ return
+ }
+}
+
+func (validator Validator) ValidateManageFields(testSuitesManage *model.TestSuite) {
+
+ if len(validator.jsonData) == 0 {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Json), internalconstant.ExitStatusCode2)
+ }
+
+ if validator.jsonData != nil {
+ util.ByteArrayToStruct(validator.cmd, validator.jsonData, &testSuitesManage)
+ testSuiteId := strconv.Itoa(testSuitesManage.TestSuiteId)
+ if testSuiteId == "0" {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.TestSuiteId), internalconstant.ExitStatusCode2)
+ }
+ return
+ }
+}
+
+func (validator Validator) ValidateDefaultTestSuiteFields(propertyId, propertyName, propertyVersion string, urls []string, jsonData []byte,
+ defaultTestSuite *model.DefaultTestSuiteRequest, isStandardInputAvailable bool) {
+ // throw invalid or missing errors if any and abort
+ isJsonInput := util.CheckIfBothJsonAndFlagAreSetForCommand(validator.cmd, jsonData, isStandardInputAvailable)
+
+ if isJsonInput {
+ log.Debug("Generating default test suite with input json data!!!!")
+ util.ByteArrayToStruct(validator.cmd, validator.jsonData, defaultTestSuite)
+ // the below returned values are not used anywhere for now as JSON payload is passed directly to the api
+ } else {
+ log.Debug("Generating default test suite with flags!!!!")
+ // validate configVersion usage.
+ validator.PropertyAndVersionFlagCheck(propertyId, propertyName, propertyVersion, false)
+ validator.UrlsFlagCheck(urls)
+ }
+}
+
+func (validator Validator) LockedAndStatefulFlagCheck(locked bool, unlocked bool, stateful bool, stateless bool) {
+ if locked && unlocked {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.LockedUnlocked), internalconstant.ExitStatusCode2)
+ }
+ if stateful && stateless {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.StatefulStateless), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) UrlsFlagCheck(urls []string) {
+
+ if len(urls) < 1 {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, externalconstant.FlagUrl), internalconstant.ExitStatusCode2)
+ }
+
+ for _, fullUrl := range urls {
+
+ u, err := url.Parse(fullUrl)
+ if err != nil {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, externalconstant.FlagUrl), internalconstant.ExitStatusCode2)
+ }
+
+ proto := u.Scheme
+ hn := u.Host
+ if proto == internalconstant.Empty || hn == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, externalconstant.FlagUrl), internalconstant.ExitStatusCode2)
+ }
+ }
+}
+
+func (validator Validator) GroupByFlagCheck(groupBy string) {
+
+ if groupBy != internalconstant.Empty && !util.ContainsInArray([]string{internalconstant.GroupByTestRequest, internalconstant.GroupByCondition, internalconstant.GroupByClientProfile}, groupBy) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.GroupBy), internalconstant.ExitStatusCode2)
+ }
+}
diff --git a/internal/validator/validator.go b/internal/validator/validator.go
new file mode 100644
index 0000000..8f831c2
--- /dev/null
+++ b/internal/validator/validator.go
@@ -0,0 +1,151 @@
+package validator
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "strconv"
+ "strings"
+
+ "github.com/spf13/cobra"
+)
+
+type Validator struct {
+ cmd *cobra.Command
+ jsonData []byte
+}
+
+// This validator class will have generic validation methods.
+
+func NewValidator(cmd *cobra.Command, jsonData []byte) *Validator {
+ return &Validator{cmd, jsonData}
+}
+
+func ipVersionFlagCheck(cmd *cobra.Command, ipVersion string) {
+
+ if ipVersion != internalconstant.Empty && !(ipVersion == "v6" || ipVersion == "v4" || ipVersion == "V6" || ipVersion == "V4") {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, "ipVersion"), internalconstant.ExitStatusCode2)
+ }
+}
+
+func clientTypeFlagCheck(cmd *cobra.Command, client string) {
+ if client != internalconstant.Empty && !(client == internalconstant.Chrome || client == internalconstant.Curl) {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, externalconstant.FlagClient), internalconstant.ExitStatusCode2)
+ }
+}
+
+func methodFlagCheck(cmd *cobra.Command, method string, client string) {
+ if method != internalconstant.Empty && !(method == internalconstant.GetRequestMethod || method == internalconstant.HeadRequestMethod || method == internalconstant.PostRequestMethod) {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, util.GetJsonKeyForFlag(externalconstant.FlagRequestMethod)), internalconstant.ExitStatusCode2)
+ }
+
+ if client == internalconstant.Chrome && (method == internalconstant.HeadRequestMethod || method == internalconstant.PostRequestMethod) {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, internalconstant.RequestMethodWithClient), internalconstant.ExitStatusCode2)
+ }
+}
+
+func requestBodyFlagCheck(cmd *cobra.Command, requestBody string, method string, client string) {
+ if requestBody != internalconstant.Empty && method != internalconstant.PostRequestMethod && client != internalconstant.Curl {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, util.GetJsonKeyForFlag(externalconstant.FlagRequestBody)), internalconstant.ExitStatusCode2)
+ }
+}
+
+func encodeRequestBodyFlagCheck(cmd *cobra.Command, encodeRequestBody bool, method string, client string) {
+ if encodeRequestBody == true && (method != internalconstant.PostRequestMethod || client != internalconstant.Curl) {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, util.GetJsonKeyForFlag(externalconstant.FlagEncodeRequestBody)), internalconstant.ExitStatusCode2)
+ }
+}
+
+func headerFlagCheck(cmd *cobra.Command, addHeader, modifyHeader []string) {
+
+ if len(addHeader) > 0 {
+ for _, header := range addHeader {
+ headerComponents := strings.Split(header, externalconstant.Colon)
+ if len(headerComponents) < 2 {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, internalconstant.AddHeader), internalconstant.ExitStatusCode2)
+ }
+ }
+ }
+
+ if len(modifyHeader) > 0 {
+ for _, header := range modifyHeader {
+ headerComponents := strings.Split(header, externalconstant.Colon)
+ if len(headerComponents) < 2 {
+ util.AbortWithUsageAndMessageAndCode(cmd, util.GetErrorMessageForFlag(cmd, internalconstant.Invalid, internalconstant.ModifyHeader), internalconstant.ExitStatusCode2)
+ }
+ }
+ }
+}
+
+func (validator Validator) PropertyAndVersionFlagCheck(propertyId string, propertyString string, versionString string, isOptional bool) {
+
+ if propertyId != internalconstant.Empty && propertyString != internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.PropertyCombinationErrorKey), internalconstant.ExitStatusCode2)
+ }
+
+ if propertyId != internalconstant.Empty && versionString == internalconstant.Empty && propertyString == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.MissingVersionWithId), internalconstant.ExitStatusCode2)
+ }
+
+ if propertyString != internalconstant.Empty && versionString == internalconstant.Empty && propertyId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.MissingVersionWithName), internalconstant.ExitStatusCode2)
+ }
+
+ if versionString != internalconstant.Empty && propertyId == internalconstant.Empty && propertyString == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.MissingIdOrNameWithVersion), internalconstant.ExitStatusCode2)
+ }
+
+ if propertyId != internalconstant.Empty || propertyString != internalconstant.Empty {
+ if propertyId != internalconstant.Empty {
+ _, err := strconv.Atoi(propertyId)
+ if err != nil {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.PropertyIdErrorKey), internalconstant.ExitStatusCode2)
+ }
+ }
+
+ _, err := strconv.Atoi(versionString)
+ if err != nil {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.PropertyVersionErrorKey), internalconstant.ExitStatusCode2)
+ }
+
+ // return if everything is valid and property flags are optional.
+ return
+ }
+
+ if !isOptional {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.PropertyVersionKey), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) EditTestSuiteIdFlagCheck(testSuiteId string) {
+
+ if testSuiteId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testSuiteId)
+ if err != nil || id == 0 {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateGetTestSuiteWithChildObjectsFlags(testSuiteId, testSuiteName, groupBy string) {
+
+ validator.TestSuiteIdAndNameFlagCheck(testSuiteId, testSuiteName)
+
+ // validate if group by flag value is - condition, test-request, client-profile only
+ validator.GroupByFlagCheck(groupBy)
+}
+
+func (validator Validator) TestSuiteIdAndNameFlagCheck(testSuiteId, testSuiteName string) {
+
+ if testSuiteName == internalconstant.Empty && testSuiteId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Any), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testSuiteId)
+ if testSuiteId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+}
diff --git a/internal/validator/variable_validator.go b/internal/validator/variable_validator.go
new file mode 100644
index 0000000..e51e210
--- /dev/null
+++ b/internal/validator/variable_validator.go
@@ -0,0 +1,88 @@
+package validator
+
+import (
+ internalconstant "github.com/akamai/cli-test-center/internal/constant"
+ "github.com/akamai/cli-test-center/internal/util"
+ externalconstant "github.com/akamai/cli-test-center/user/constant"
+ "strconv"
+ "strings"
+)
+
+//This validator class will have the variables related validate methods.
+
+func (validator Validator) ValidateVariableCreateFlagCheck(testSuiteId, name, value string, group []string) {
+
+ if testSuiteId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testSuiteId)
+ if testSuiteId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+ if name == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.VariableName), internalconstant.ExitStatusCode2)
+ }
+
+ if value == internalconstant.Empty && group == nil {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Any), internalconstant.ExitStatusCode2)
+ }
+
+ if group != nil {
+ for _, groupString := range group {
+ parts := strings.Split(groupString, externalconstant.Colon)
+ if len(parts) != 2 {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.VariableGroup), internalconstant.ExitStatusCode2)
+ }
+ }
+ }
+}
+
+func (validator Validator) ValidateVariablesListFlagCheck(testSuiteId string) {
+
+ if testSuiteId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testSuiteId)
+ if testSuiteId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+}
+
+func (validator Validator) ValidateVariableFlagCheck(testSuiteId, variableId string) {
+
+ if testSuiteId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+ id, err := strconv.Atoi(testSuiteId)
+ if testSuiteId != internalconstant.Empty && (err != nil || id == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.Id), internalconstant.ExitStatusCode2)
+ }
+
+ if variableId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.VariableId), internalconstant.ExitStatusCode2)
+ }
+
+ varId, err := strconv.Atoi(variableId)
+ if variableId != internalconstant.Empty && (err != nil || varId == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.VariableId), internalconstant.ExitStatusCode2)
+ }
+}
+
+func (validator Validator) ValidateVariableEditFlagCheck(testSuiteId, name, value, variableId string, group []string) {
+
+ validator.ValidateVariableCreateFlagCheck(testSuiteId, name, value, group)
+
+ if variableId == internalconstant.Empty {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Missing, internalconstant.VariableId), internalconstant.ExitStatusCode2)
+ }
+
+ varId, err := strconv.Atoi(variableId)
+ if variableId != internalconstant.Empty && (err != nil || varId == 0) {
+ util.AbortWithUsageAndMessageAndCode(validator.cmd, util.GetErrorMessageForFlag(validator.cmd, internalconstant.Invalid, internalconstant.VariableId), internalconstant.ExitStatusCode2)
+ }
+}
diff --git a/internal/logging.go b/logger/logging.go
similarity index 98%
rename from internal/logging.go
rename to logger/logging.go
index 4aa27ec..c60960c 100644
--- a/internal/logging.go
+++ b/logger/logging.go
@@ -1,4 +1,4 @@
-package internal
+package logger
import (
"os"
diff --git a/main.go b/main.go
index 7c287de..f7e7f78 100644
--- a/main.go
+++ b/main.go
@@ -2,14 +2,12 @@ package main
import (
"github.com/akamai/cli-test-center/cmd"
- "github.com/akamai/cli-test-center/internal"
+ "github.com/akamai/cli-test-center/logger"
)
-var (
- VERSION string = "0.2.0"
-)
+var VERSION = "1.0.0"
func main() {
- internal.InitLoggingConfig()
+ logger.InitLoggingConfig()
cmd.Execute(VERSION)
}
diff --git a/user/constant/user_visible_template.go b/user/constant/user_visible_template.go
new file mode 100644
index 0000000..b8df310
--- /dev/null
+++ b/user/constant/user_visible_template.go
@@ -0,0 +1,57 @@
+package constant
+
+/**
+This class will be used for all output print templates. Do not modify spaces/newlines for existing templates unless
+there is a requirement.
+Blogs foe templates:
+https://blog.logrocket.com/using-golang-templates/
+https://pkg.go.dev/text/template
+*/
+
+var GroupByTestRequest = "{{ $count := 1 }}" +
+ "{{ $trMapLength := len . }}{{ $trMapLength = dec $trMapLength }}" +
+ "{{ range $index, $mapValue := . }}" +
+ "{{ range $key, $value := $mapValue.Value }}" +
+ "{{if eq $key 0}}|-- {{ bold \"TR\" }}{{ bold $count }} {{ bold $value.TestRequest.RequestMethod }} {{ printRequestURL $value.TestRequest }}" +
+ "{{ $length := len $value.TestRequest.Tags }}{{ if ne $length 0 }}\n| Keywords: {{ join $value.TestRequest.Tags }}{{ end }}" +
+ "{{ $length := len $value.TestRequest.RequestHeaders }}{{ if ne $length 0 }}{{ $length = dec $length }}\n| Customized headers: {{ range $headerIndex, $header := $value.TestRequest.RequestHeaders }}{{ printHeader $header }}{{if ne $headerIndex $length }}\n| {{ end }}{{ end }}{{ end }}" +
+ "{{ if eq $value.TestRequest.RequestMethod \"POST\" }}\n| Request body: {{ printRequestBody $value.TestRequest }}{{ end }}" +
+ "{{ if eq $value.TestRequest.RequestMethod \"POST\" }}\n| URL encode: {{ $value.TestRequest.EncodeRequestBody }}{{ end }}{{ end }}" +
+ "{{ if ne $value.ParentOrder 0 }}\n| |-- {{ bold $value.ParentOrder }}.{{ bold $value.Order }} {{ else }}\n| |-- {{ bold $value.Order }} {{ end }}" +
+ "{{ printCondition $value.Condition }} | {{$ipVersion := printClientProfile $value.ClientProfile }}{{ bold $ipVersion }}" +
+ "{{ if ne $value.ParentOrder 0 }}{{ $length := len $value.SetVariables }}{{ if ne $length 0 }}{{ $length = dec $length }}\n| Set variables: {{ range $variableIndex, $variable := $value.SetVariables }}{{printSetVariables $variable }}{{if ne $variableIndex $length }}\n| {{end}}{{end}}{{end}}{{end}}" +
+ "{{ if eq $value.ParentOrder 0 }}{{ $length := len $value.SetVariables }}{{ if ne $length 0 }}{{ $length = dec $length }}\n| Set variables: {{ range $variableIndex, $variable := $value.SetVariables }}{{printSetVariables $variable }}{{if ne $variableIndex $length }}\n| {{end}}{{end}}{{end}}{{end}}" +
+ "{{ end }}{{if ne $index $trMapLength }}\n|\n{{ end }}" +
+ "{{ $count = inc $count }}{{end}}"
+
+var GroupByCondition = "{{ $condLength := len . }}{{ $condLength = dec $condLength }}" +
+ "{{ $count := 1 }}" +
+ "{{ range $index, $mapValue := . }}" +
+ "|-- {{ bold \"C\" }}{{ bold $count }} {{$mapValue.Key}}" +
+ "{{ $tcLength := len $mapValue.Value }}{{ $tcLength = dec $tcLength }}" +
+ "{{ range $tc_index, $value := $mapValue.Value }}" +
+ "{{ if ne $value.ParentOrder 0 }}\n| |-- {{ bold $value.ParentOrder }}.{{ bold $value.Order }} {{ else }}\n| |-- {{ bold $value.Order }} {{ end }}" +
+ " {{ bold $value.TestRequest.RequestMethod }} {{ printRequestURL $value.TestRequest }}" +
+ "{{ $length := len $value.TestRequest.Tags }}{{ if ne $length 0 }}\n| Keywords: {{ join $value.TestRequest.Tags }}{{ end }}" +
+ "{{ $length := len $value.TestRequest.RequestHeaders }}{{ if ne $length 0 }}{{ $length = dec $length }}\n| Customized headers: {{ range $headerIndex, $header := $value.TestRequest.RequestHeaders }}{{ printHeader $header }}{{if ne $headerIndex $length }}\n| {{ end }}{{ end }}{{ end }}" +
+ "{{ if eq $value.TestRequest.RequestMethod \"POST\" }}\n| Request body: {{ printRequestBody $value.TestRequest }}{{ end }}" +
+ "{{ if eq $value.TestRequest.RequestMethod \"POST\" }}\n| URL encode: {{ $value.TestRequest.EncodeRequestBody }}{{ end }}" +
+ "{{ $length := len $value.SetVariables }}{{ if ne $length 0 }}{{ $length = dec $length }}\n| Set variables: {{ range $variableIndex, $variable := $value.SetVariables }}{{printSetVariables $variable }}{{if ne $variableIndex $length }}\n| {{end}}{{end}}{{end}}" +
+ "\n| Client profile: {{$ipVersion := printClientProfile $value.ClientProfile }}{{ bold $ipVersion }} {{if ne $tc_index $tcLength }}\n|{{ end }}" +
+ "{{ end }}{{if ne $index $condLength }}\n|\n{{ end }}" +
+ "{{ $count = inc $count }}{{ end }}"
+
+var GroupByClientProfile = "{{ $cpLength := len . }}{{ $cpLength = dec $cpLength }}" +
+ "{{ range $index, $mapValue := . }}" +
+ "|-- {{ bold $mapValue.Key }}" +
+ "{{ $tcLength := len $mapValue.Value }}{{ $tcLength = dec $tcLength }}" +
+ "{{ range $tc_index, $value := $mapValue.Value }}" +
+ "{{ if ne $value.ParentOrder 0 }}\n| |-- {{ bold $value.ParentOrder }}.{{ bold $value.Order }} {{ else }}\n| |-- {{ bold $value.Order }} {{ end }}" +
+ "{{ bold $value.TestRequest.RequestMethod }} {{ printRequestURL $value.TestRequest }}" +
+ "{{ $length := len $value.TestRequest.Tags }}{{ if ne $length 0 }}\n| Keywords: {{ join $value.TestRequest.Tags }}{{ end }}" +
+ "{{ $length := len $value.TestRequest.RequestHeaders }}{{ if ne $length 0 }}{{ $length = dec $length }}\n| Customized headers: {{ range $headerIndex, $header := $value.TestRequest.RequestHeaders }}{{ printHeader $header }}{{if ne $headerIndex $length }}\n| {{ end }}{{ end }}{{ end }}" +
+ "{{ if eq $value.TestRequest.RequestMethod \"POST\" }}\n| Request body: {{ printRequestBody $value.TestRequest }}{{ end }}" +
+ "{{ if eq $value.TestRequest.RequestMethod \"POST\" }}\n| URL encode: {{ $value.TestRequest.EncodeRequestBody }}{{ end }}" +
+ "{{ $length := len $value.SetVariables }}{{ if ne $length 0 }}{{ $length = dec $length }}\n| Set variables: {{ range $variableIndex, $variable := $value.SetVariables }}{{printSetVariables $variable }}{{if ne $variableIndex $length }}\n| {{end}}{{end}}{{end}}" +
+ "\n| Condition: {{ printCondition $value.Condition }}{{if ne $tc_index $tcLength }}\n|{{ end }}" +
+ "{{ end }}{{if ne $index $cpLength }}\n|\n{{ end }}{{end}}"
diff --git a/user/constant/user_visible_text.go b/user/constant/user_visible_text.go
new file mode 100644
index 0000000..b2b822b
--- /dev/null
+++ b/user/constant/user_visible_text.go
@@ -0,0 +1,367 @@
+package constant
+
+// command usage and example
+const (
+ RootCommandUse = "test-center"
+
+ TestUse = "test"
+ TestCommandAlias = "t"
+
+ TestRunUse = `run [--test-suite-id ID] |
+ [--test-suite-name 'NAME'] |
+ [--property-name 'PROPERTY NAME' --property-version 'PROPERTY VERSION'] |
+ [--property-id ID --property-version 'PROPERTY VERSION'] |
+ [-u URL -c CONDITION --ip-version V4|V6 [--add-header 'name: value' ...] [--modify-header 'name: value' ...] [--filter-header name ...]]
+ --env STAGING|PRODUCTION`
+ TestRunExample = ` $ akamai test-center test run --test-suite-id 2500
+ $ akamai test-center test run --test-suite-name 'Regression test cases for example.com'
+ $ akamai test-center test run --property-name 'example.com' --property-version '26'
+ $ akamai test-center test run --property-id '438285' --property-version '26'
+ $ akamai test-center test run --url 'https://example.com/' --condition 'Response code is one of "200"' --ip-version 'V6' --modify-header 'Accept: application/json'
+ $ akamai test-center t run -u 'https://example.com/' -c 'Response code is one of "200"' --ip-version 'V6' -m 'Accept: application/json'
+ $ akamai test-center test run < {FILE_PATH}/FILE_NAME.json
+ $ echo '{"functional":{"testSuiteExecutions":[{"testSuiteId":123}]},"targetEnvironment":"STAGING","purgeOnStaging":false,"note":"Testing 1 test suites on staging.","sendEmailOnCompletion":false}' | akamai test-center test run
+ $ echo '{"functional":{"propertyManagerExecution":{"propertyId":4567,"propertyVersion":1}},"targetEnvironment":"STAGING","purgeOnStaging":true,"sendEmailOnCompletion":true,"note":"Testing the example.com v1 property"}' | akamai test-center test run
+ $ echo '{"functional":{"propertyManagerExecution":{"propertyName":"example.com","propertyVersion":1}},"targetEnvironment":"STAGING","purgeOnStaging":true,"sendEmailOnCompletion":true,"note":"Testing the example.com v1 property"}' | akamai test-center test run
+ $ echo '{"functional":{"testCaseExecution":{"testRequest":{"testRequestUrl":"https://example.com.com","requestHeaders":[{"headerName":"Accept","headerValue":"application/json","headerAction":"ADD"}],"requestBody":"{\"name\": \"akamai\"}","encodeRequestBody":true,"requestMethod":"POST"},"condition":{"conditionExpression":"Response code is one of \"200\""},"clientProfile":{"ipVersion":"IPV4","client":"CURL","geoLocation":"US"}}},"targetEnvironment":"STAGING","purgeOnStaging":true,"note":"Testing a simple test case on staging.","sendEmailOnCompletion":true}' | akamai test-center test run`
+
+ TestListUse = "list"
+ TestListAlias = "ls"
+ TestListExample = ` $ akamai test-center test list`
+
+ TestGetUse = "get"
+ TestGetAlias = "view"
+ TestGetExample = ` $ akamai test-center test get --test-run-id 1
+ $ akamai test-center test get -i 1`
+
+ TestSuiteUse = "test-suite"
+ TestSuiteCommandAlias = "ts"
+
+ TestSuiteAddUse = "create --test-suite-name NAME [--description DESCRIPTION] [--unlocked] [--stateful] [--property-name 'PROPERTY NAME' --property-version 'PROPERTY VERSION'] "
+ TestSuiteAddExample = ` $ akamai test-center test-suite create --test-suite-name 'Example TS'
+ $ akamai test-center test-suite create --test-suite-name 'Example TS' --description 'TS for example.com' --unlocked --stateful --property-name 'example.com' --property-version '4'
+ $ akamai test-center ts add -n 'Example TS' -d 'TS for example.com' --unlocked --stateful -p 'example.com' -v '4'
+ $ akamai test-center test-suite create < {filepath}/filename.json`
+
+ TestSuiteAddCommandAlias = "add"
+
+ TestSuiteGenerateDefaultUse = "generate-default --property-name 'PROPERTY NAME' --property-version 'PROPERTY VERSION' --url URL ... "
+ TestSuiteGenerateDefaultExample = ` $ akamai test-center test-suite generate-default --property-name 'example.com' --property-version '4' --url "https://www.example.com/" -u "https://www.example.com/index/"
+ $ akamai test-center ts template -p 'example.com' -v '4' -u "https://www.example.com/" -u "https://www.example.com/index/"
+ $ echo '{"configs":{"propertyManager":{"propertyName":"atc_test_config","propertyVersion":1}},"testRequestUrls":["http://www.example.com/"]}' | akamai test-center test-suite generate-default
+ $ akamai test-center test-suite generate-default < {filepath}/filename.json`
+ TestSuiteGenerateDefaultCommandAlias = "gd"
+
+ TestSuiteEditUse = "update --test-suite-id ID [--test-suite-name NAME] [--description DESCRIPTION] [--unlocked | --locked] [--stateful | --stateless] [--property-name 'PROPERTY NAME' --property-version 'PROPERTY VERSION' | --remove-property]"
+ TestSuiteEditExample = ` $ akamai test-center test-suite update --test-suite-id 1001 --test-suite-name 'Updated Example TS'
+ $ akamai test-center test-suite update --test-suite-id 1001 --test-suite-name 'Updated Example TS' --description 'TS for example.com' --property-name 'example.com' --property-version '4' --unlocked
+ $ akamai test-center test-suite update --test-suite-id 1001 --stateful --remove-property
+ $ akamai test-center test-suite update -i 1001 --stateful
+ $ akamai test-center test-suite update < {filepath}/filename.json`
+ TestSuiteEditCommandAlias = "edit"
+
+ TestSuiteCreateWithChildObjects = "create-with-child-objects"
+ TestSuiteCreateWithChildObjectsExample = ` $ akamai test-center test-suite create-with-child-objects < {FILE_PATH}/FILE_NAME.json
+ $ echo '{"testSuiteName":"ts1","testSuiteDescription":"ts1 description.","isLocked":true,"isStateful":false,"configs":{"propertyManager":{"propertyId":4567,"propertyVersion":1}},"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite import`
+ TestSuiteCreateWithChildObjectsCommandAlias = "import"
+
+ TestSuiteListUse = "list [--property-name 'PROPERTY NAME'] [--property-version 'PROPERTY VERSION'] [-u 'USERNAME'] [--search 'SEARCH STRING']"
+ TestSuiteListExample = ` $ akamai test-center test-suite list
+ $ akamai test-center test-suite list --property-name 'example.com' --property-version '4'
+ $ akamai test-center test-suite list -u 'johndoe' --search 'regression'`
+ TestSuiteListCommandAlias = "ls"
+
+ TestSuiteUpdateWithChildObjectsUse = "update-with-child-objects"
+ TestSuiteUpdateWithChildObjectsExample = ` $ akamai test-center test-suite manage < {FILE_PATH}/FILE_NAME.json
+ $ echo '{"testSuiteId":1,"testSuiteName":"ts1","testSuiteDescription":"ts1 description.","isLocked":true,"isStateful":false,"configs":{"propertyManager":{"propertyId":4567,"propertyVersion":1}},"variables":[{"variableName":"host","variableValue":"www.akamai.com"}],"testCases":[]}' | akamai test-center test-suite manage`
+ TestSuiteUpdateWithChildObjectsCommandAlias = "manage"
+
+ TestSuiteRemoveUse = "remove [--test-suite-id ID | --test-suite-name NAME]"
+ TestSuiteRemoveExample = ` $ akamai test-center test-suite remove --test-suite-name "Test suite name"
+ $ akamai test-center test-suite remove --test-suite-id 12345`
+
+ TestSuiteRestoreUse = "restore [--test-suite-id ID | --test-suite-name NAME]"
+ TestSuiteRestoreExample = ` $ akamai test-center test-suite restore --test-suite-name "Test suite name"
+ $ akamai test-center test-suite restore --test-suite-id 12345`
+
+ TestSuiteGetUse = "get [--test-suite-id ID | --test-suite-name NAME]"
+ TestSuiteGetExample = ` $ akamai test-center test-suite get --test-suite-id 1001
+ $ akamai test-center test-suite get --test-suite-name 'Example TS'`
+ TestSuiteGetCommandAliases = "view"
+
+ TestSuiteGetWithChildObjectsUse = "get-with-child-objects [--test-suite-id ID | --test-suite-name NAME] [--group-by test-request | condition | client-profile]"
+ TestSuiteGetWithChildObjectsExample = ` $ akamai test-center test-suite get-with-child-objects --test-suite-id 1001
+ $ akamai test-center test-suite get-with-child-objects --test-suite-name 'Example TS' --group-by test-request`
+ TestSuiteGetWithChildObjectsCommandAliases = "export"
+
+ ConditionUse = "condition"
+ ConditionCommandAliases = "c"
+
+ ConditionTemplateUse = "template"
+ ConditionTemplateExample = ` $ akamai test-center condition template`
+
+ ConditionListUse = "list"
+ ConditionListExample = ` $ akamai test-center condition list`
+ ConditionListCommandAliases = "ls"
+
+ TestRequestUse = "test-request"
+ TestRequestCommandAliases = "tr"
+
+ TestRequestListUse = "list"
+ TestRequestListExample = ` $ akamai test-center test-request list`
+ TestRequestListCommandAliases = "ls"
+
+ TestCaseUse = "test-case"
+ TestCaseCommandAlias = "tc"
+
+ CreateTestCaseCommandAlias = "add"
+ CreateTestCaseUse = "create [--test-suite-id ID | --test-suite-name NAME] -u URL -c CONDITION [--ip-version V4|V6] [-a header ...] [-m header ...] [-f header ...] [-C client ...] [-M request-method ...] [-E -encode-request-body] [-b request-body ...] [-S set-variables ...]"
+ CreateTestCaseExample = ` $ akamai test-center test-case create --test-suite-id 1001 --url 'https://example.com/' --condition 'Response code is one of "200,201"'
+ $ akamai test-center test-case create --test-suite-id 1001 -u 'https://example.com/' -c 'Response code is one of "200"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language' -C curl -M POST -S 'varName: varValue'
+ $ akamai test-center test-case create --test-suite-id 1001 -u 'https://example.com/' -c 'Response code is one of "{{variableName}}"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language' -C curl -M POST -S 'varName: varValue' -E`
+ ListTestCasesExample = ` $ akamai test-center test-case list --test-suite-id 1001 --resolve-variables --group-by test-request
+ $ akamai test-center test-case list --test-suite-id 1001 --resolve-variables --group-by condition
+ $ akamai test-center test-case list --test-suite-id 1001 --resolve-variables --group-by client-profile
+ $ akamai test-center test-case ls -i 1001 --resolve-variables -g test-request`
+ ListTestCasesUse = "list [--test-suite-id ID | --test-suite-name name] --resolve-variables [--group-by ...]"
+ ListTestCasesCommandAlias = "ls"
+
+ GetTestCaseExample = ` $ akamai test-center test-case get --test-suite-id 1001 --test-case-id 101 --resolve-variables`
+ GetTestCaseUse = "get [--test-suite-id ID | --test-suite-name name] [--test-case-id TEST_CASE_ID] --resolve-variables"
+ GetTestCaseCommandAlias = "view"
+
+ RemoveTestCaseUse = "remove --test-suite-id ID [--order-num ORDER_NUMBER | --test-case-id TEST_CASE_ID]"
+ RemoveTestCaseExample = ` $ akamai test-center test-case remove --test-suite-id 1001 --order-num 6
+ $ akamai test-center test-case remove --test-suite-id 1001 --test-case-id 101`
+
+ UpdateTestCaseCommandAlias = "edit"
+ UpdateTestCaseUse = "update [--test-suite-id ID | --test-suite-name NAME] [--test-case-id TEST_CASE_ID] -u URL -c CONDITION [--ip-version V4|V6] [-a header ...] [-m header ...] [-f header ...] [-C client ...] [-M request-method ...] [-E -encode-request-body] [-b request-body ...] [-S set-variables ...]"
+ UpdateTestCaseExample = ` $ akamai test-center test-case update --test-suite-id 1001 --test-case-id 101 --url 'https://example.com/' --condition 'Response code is one of "200,201"'
+ $ akamai test-center test-case update --test-suite-id 1001 --test-case-id 101 -u 'https://example.com/' -c 'Response code is one of "200"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language' -C curl -M POST -S 'varName: varValue'
+ $ akamai test-center test-case update --test-suite-id 1001 --test-case-id 101 -u 'https://example.com/' -c 'Response code is one of "{{variableName}}"' -a 'Accept: text/html' -a 'X-Custom: 123' -m 'User-Agent: Mozilla' -f 'Accept-Language' -C curl -M POST -S 'varName: varValue' -E`
+
+ VariableUse = "variable"
+ VariableCommandAliases = "var"
+
+ VariableCreateUse = "create --test-suite-id ID --name NAME [--value VALUE | --group-value H1: value1, value2 --group-value H2: value3, value4]"
+ VariableCreateExample = ` $ akamai test-center variable create --test-suite-id 1001 --name url --value 'https://example.com/'
+ $ akamai test-center variable create --test-suite-id 1001 --name url --group-value hostName: https://example.com/,https://example.com/123 --group-value ResponseCodes: 200,300`
+ VariableCreateCommandAliases = "add"
+
+ VariablesListUse = "list --test-suite-id ID"
+ VariablesListExample = " $ akamai test-center variable list --test-suite-id 1"
+ VariablesListCommandAliases = "ls"
+
+ VariableGetUse = "get --test-suite-id ID --variable-id VARIABLE_ID"
+ VariableGetExample = " $ akamai test-center variable get --test-suite-id 1 --variable-id 1"
+ VariableGetCommandAliases = "view"
+
+ VariableUpdateUse = "update --test-suite-id ID --variable-id VARIABLE_ID --name NAME [--value VALUE | --group-value H1: value1, value2 --group-value H2: value3, value4]"
+ VariableUpdateExample = ` $ akamai test-center variable update --test-suite-id 1001 --variable-id 1 --name url --value 'https://example.com/'
+ $ akamai test-center variable update --test-suite-id 1001 --name url --variable-id 1 --group-value hostName: https://example.com/,https://example.com/123 --group-value ResponseCodes: 200,300`
+ VariableUpdateCommandAliases = "edit"
+
+ VariableRemoveUse = "remove --test-suite-id ID --variable-id VARIABLE_ID"
+ VariableRemoveExample = " $ akamai test-center variable remove --test-suite-id 1 --variable-id 1"
+
+ FunctionUse = "function"
+ FunctionAliases = "fn"
+
+ TryItFunctionUse = "try-it"
+ TryItFunctionAliases = "try"
+ TryItFunctionExample = ` $ akamai test-center function try-it < {filepath}/filename.json
+ $ echo '{"functionExpression": "fn_getResponseHeaderValue(headerName, regex)","responseData": {"response": {"status": 200,"statusText": "OK","httpVersion": "HTTP/1.1","headers": [{"name": "server", "value":"Apache/2.2.15 (CentOS)"}]}}}' | akamai test-center function try-it`
+
+ TestRawReqResUse = "raw-request-response [--test-run-id ID | --tcx-id ID]"
+ TestRawReqResExampleUse = ` $ akamai test-center test raw-request-response --test-run-id 1
+ $ akamai test-center test raw-request-response --tcx-id 2`
+ TestRawReqResCommandAliases = "rr"
+
+ TestLogLinesUse = "log-lines --tcx-id 1"
+ TestLogLinesExampleUse = " $ akamai test-center test log-lines --tcx-id 1"
+ TestLogLinesCommandAliases = "ll"
+)
+
+// Flag Names
+const (
+ FlagEdgerc = "edgerc"
+ FlagSection = "section"
+ FlagAccountKey = "account-key"
+ FlagJson = "json"
+ FlagForceColor = "force-color"
+ FlagPropertyId = "property-id"
+ FlagPropertyName = "property-name"
+ FlagPropertyVersion = "property-version"
+ FlagUrl = "url"
+ FlagEnv = "env"
+ FlagAddHeader = "add-header"
+ FlagModifyHeader = "modify-header"
+ FlagFilterHeader = "filter-header"
+ FlagTestSuiteId = "test-suite-id"
+ FlagTestRunId = "test-run-id"
+ FlagTestSuiteName = "test-suite-name"
+ FlagIpVersion = "ip-version"
+ FlagCondition = "condition"
+ FlagDescription = "description"
+ FlagStateFul = "stateful"
+ FlagUnlocked = "unlocked"
+ FlagStateless = "stateless"
+ FlagLocked = "locked"
+ FlagRemoveProperty = "remove-property"
+ FlagUser = "user"
+ FlagSearch = "search"
+ FlagOrderNumber = "order-num"
+ FlagGroupBy = "group-by"
+ FlagHelp = "help"
+ FlagVersion = "version"
+ FlagVariableName = "name"
+ FlagVariableValue = "value"
+ FlagVarGroupValue = "group-value"
+ FlagVariableId = "variable-id"
+ FlagTestCaseExecId = "tcx-id"
+
+ // FlagClient etc...( new test run flags, can be used in test case as well.)
+ FlagClient = "client"
+ FlagLocation = "location"
+ FlagRequestMethod = "request-method"
+ FlagEncodeRequestBody = "encode-request-body"
+ FlagRequestBody = "request-body"
+ FlagSetVariables = "set-variables"
+ FlagTestCaseId = "test-case-id"
+ FlagResolveVariables = "resolve-variables"
+)
+
+const (
+ FlagUrlShortHand = "u"
+ FlagUserShortHand = "u"
+ FlagSectionShortHand = "s"
+ FlagEdgercShortHand = "e"
+ FlagAddHeaderShortHand = "a"
+ FlagModifyHeaderShortHand = "m"
+ FlagFilterHeaderShortHand = "f"
+ FlagConditionShortHand = "c"
+ FlagHelpShortHand = "h"
+ FlagTestSuiteIdShortHand = "i"
+ FlagTestRunIdShortHand = "i"
+ FlagTestSuiteNameShortHand = "n"
+ FlagDescriptionShortHand = "d"
+ FlagOrderNumberShortHand = "o"
+ FlagGroupShortHand = "g"
+ FlagPropertyShortHand = "p"
+ FlagPropertyVersionShortHand = "v"
+ FlagVariableNameShortHand = "n"
+ FlagVariableValueShortHand = "v"
+ FlagVariableGroupShortHand = "g"
+ FlagTestCaseExecShortHand = "x"
+
+ // FlagClientShortHand etc ... (new test run flag short hands, can be used in test case as well.)
+ FlagClientShortHand = "C"
+ FlagRequestMethodShortHand = "M"
+ FlagEncodeRequestBodyShortHand = "E"
+ FlagRequestBodyShortHand = "b"
+ FlagSetVariablesShortHand = "S"
+ FlagTestCaseIdShortHand = "I"
+)
+
+const (
+ LabelId = "ID"
+ LabelName = "Name"
+ LabelDescription = "Description"
+ LabelStateful = "Stateful"
+ LabelLocked = "Locked"
+ LabelAssociatedProperty = "Associated property version"
+ LabelCreated = "Created"
+ LabelLastModified = "Last modified"
+ LabelDeleted = "Deleted"
+ LabelExpected = "Expected"
+ LabelTestCaseExecutionId = "Test case execution id"
+ LabelRequestHeaders = "Customized headers"
+ LabelRequestBody = "Request body"
+ LabelEncodeRequestBody = "URL encode"
+ LabelNotRunError = "Not run - Error: "
+ LabelPassed = "Passed"
+ LabelInProgress = "In Progress"
+ LabelInconclusive = "Inconclusive"
+ LabelFailed = "Failed"
+ LabelActual = "Actual"
+ LabelIsReevaluationInProgress = "Reevaluation In Progress"
+ LabelIsReevaluationCompleted = "Reevaluation Completed"
+ LabelNotFound = "None found"
+ LabelTotalItem = "Total items"
+ LabelStatus = "Status"
+ LabelTargetEnvironment = "Target Environment"
+ LabelPropertyVersion = "Property version"
+ LabelIPv4 = "IPv4"
+ LabelIPv6 = "IPv6"
+ LabelTSDeleteState = "Test suites with the '*' prefix in their names are in the deleted state. You can restore them for 30 days since their removal."
+ LabelOrder = "Order"
+ LabelTRUrl = "URL"
+ LabelRequestMethod = "Method"
+ LabelSetVariables = "Set variables"
+ LabelCondition = "Condition"
+ LabelTags = "Keywords"
+ VariableId = "Id"
+ VariableName = "Name"
+ VariableValue = "Value"
+ TestCaseExecutionIds = "Raw request response for test case execution ids"
+ Request = "Request"
+ Response = "Response"
+ LabelFunctionExpression = "Function expression"
+ LabelFunctionResult = "Result for expression"
+ LabelClientProfile = "Client Profile"
+)
+
+const (
+ SeparatePipe = " | "
+ Dot = "."
+ Colon = ":"
+ PlusSign = " + "
+ SeparateLine = "======================================================================================================================================================"
+ SeparateBy = " by "
+ Star = "*"
+ Quote = "\""
+ Comma = ","
+ Equals = "="
+ SeparateLineStar = "**********************************************************************************************************************************************"
+ IndentationSpace = " "
+)
+
+// API CLinet Error Messages
+const (
+ ApiErrorAutoGeneratePostCall = "Failed to generate the test suite. Try again later."
+ ApiErrorConditionTemplateGetCall = "Failed to get the condition list. Try again later."
+ ApiErrorRemoveTestCasesPostCall = "Failed to remove test cases from the test suite. Try again later."
+ ApiErrorSubmitTestRunPostCall = "Failed to submit the test run. Try again later."
+ ApiErrorTestRunGetCall = "Failed to get the test run. Try again later."
+ ApiErrorTestRunsGetCall = "Failed to get test runs. Try again later."
+ ApiErrorTestRunContextGetCall = "Failed to get test run context. Try again later."
+ ApiErrorTestSuiteV3GetCall = "Failed to get test suites. Try again later."
+ ApiErrorTestSuiteV3PostCall = "Failed to create the test suite. Try again later."
+ ApiErrorEditTestSuiteV3PostCall = "Failed to edit the test suite. Try again later."
+ ApiErrorImportTestSuiteV3PostCall = "Failed to import the test suite. Try again later."
+ ApiErrorManageTestSuiteV3PutCall = "Failed to manage the test suite. Try again later."
+ ApiErrorRemoveTestSuiteDeleteCall = "Failed to remove test suite. Try again later."
+ ApiErrorRestoreTestSuitePostCall = "Failed to restore the test suite. Try again later."
+ ApiErrorTestSuiteWithChildObjectGetCall = "Failed to get test suites with child objects. Try again later."
+ ApiErrorTestCasesAssociatedForTestSuitGetCall = "Failed to get associated test cases for test suite. Try again later."
+ ApiErrorAddTestCasesToTestSuitPostCall = "Failed to add test cases to the test suite. Try again later."
+ ApiErrorGetConditions = "Failed to get Conditions. Try again later."
+ ApiErrorGetTestRequests = "Failed to get TestRequests. Try again later."
+ ApiErrorTestCaseForTestCaseGetCall = "Failed to get test case for test case ID. Try again later."
+ ApiErrorUpdateTestCasesToTestSuitPutCall = "Failed to update test cases of the test suite. Try again later."
+ ApiErrorVariablePostCall = "Failed to create the variable. Try again later"
+ ApiErrorVariablesGetCall = "Failed to get the variables. Try again later"
+ ApiErrorVariableGetCall = "Failed to get the variable. Try again later"
+ ApiErrorVariablePutCall = "Failed to update the variable. Try again later"
+ ApiErrorRemoveVariablePostCall = "Failed to remove variable from the test suite. Try again later."
+ ApiErrorTryFunctionPostCall = "Failed to evaluate the function expression. Try again later."
+ ApiErrorRawRequestResponseGetCall = "Failed to get the raw-request-response. Try again later."
+ ApiErrorTestLogLinesGetCall = "Failed to get the log lines. Try again later."
+)
+
+const (
+ CliErrorMessageTestRunStatus = "Failed to check the test run status. Try again later."
+ CliErrorMessageTemplateOutputError = "Output cannot be shown because of an internal CLI error. Try again later."
+)
+
+const TryFunctionEmptyResult = "No results to display. Modify the function or response sample and try again."