diff --git a/README.md b/README.md index b72d447..1f9b915 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,18 @@ go get github.com/testit-tms/adapters-go/pkg/tms ### Configuration -| Description | File property | Environment variable | -|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-----------------------------------| -| Location of the TMS instance | url | TMS_URL | -| API secret key [How to getting API secret key?](https://github.com/testit-tms/.github/tree/main/configuration#privatetoken) | privateToken | TMS_PRIVATE_TOKEN | -| ID of project in TMS instance [How to getting project ID?](https://github.com/testit-tms/.github/tree/main/configuration#projectid) | projectId | TMS_PROJECT_ID | -| ID of configuration in TMS instance [How to getting configuration ID?](https://github.com/testit-tms/.github/tree/main/configuration#configurationid) | configurationId | TMS_CONFIGURATION_ID | -| ID of the created test run in TMS instance. | testRunId | TMS_TEST_RUN_ID | -| Adapter mode. Default value - 0. The adapter supports following modes:
0 - in this mode, the adapter filters tests by test run ID and configuration ID, and sends the results to the test run
1 - in this mode, the adapter sends all results to the test run without filtering
2 - in this mode, the adapter creates a new test run and sends results to the new test run | adapterMode | TMS_ADAPTER_MODE | tmsAdapterMode | -| It enables/disables certificate validation (**It's optional**). Default value - true | certValidation | TMS_CERT_VALIDATION | -| Mode of automatic creation test cases (**It's optional**). Default value - false. The adapter supports following modes:
true - in this mode, the adapter will create a test case linked to the created autotest (not to the updated autotest)
false - in this mode, the adapter will not create a test case | automaticCreationTestCases | TMS_AUTOMATIC_CREATION_TEST_CASES | -| Enable debug logs (**It's optional**). Default value - false | isDebug | TMS_IS_DEBUG | +| Description | File property | Environment variable | +|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|--------------------------------------------| +| Location of the TMS instance | url | TMS_URL | +| API secret key [How to getting API secret key?](https://github.com/testit-tms/.github/tree/main/configuration#privatetoken) | privateToken | TMS_PRIVATE_TOKEN | +| ID of project in TMS instance [How to getting project ID?](https://github.com/testit-tms/.github/tree/main/configuration#projectid) | projectId | TMS_PROJECT_ID | +| ID of configuration in TMS instance [How to getting configuration ID?](https://github.com/testit-tms/.github/tree/main/configuration#configurationid) | configurationId | TMS_CONFIGURATION_ID | +| ID of the created test run in TMS instance. | testRunId | TMS_TEST_RUN_ID | +| Adapter mode. Default value - 0. The adapter supports following modes:
0 - in this mode, the adapter filters tests by test run ID and configuration ID, and sends the results to the test run
1 - in this mode, the adapter sends all results to the test run without filtering
2 - in this mode, the adapter creates a new test run and sends results to the new test run | adapterMode | TMS_ADAPTER_MODE | +| It enables/disables certificate validation (**It's optional**). Default value - true | certValidation | TMS_CERT_VALIDATION | +| Mode of automatic creation test cases (**It's optional**). Default value - false. The adapter supports following modes:
true - in this mode, the adapter will create a test case linked to the created autotest (not to the updated autotest)
false - in this mode, the adapter will not create a test case | automaticCreationTestCases | TMS_AUTOMATIC_CREATION_TEST_CASES | +| Mode of automatic updation links to test cases (**It's optional**). Default value - false. The adapter supports following modes:
true - in this mode, the adapter will update links to test cases
false - in this mode, the adapter will not update link to test cases | automaticUpdationLinksToTestCases | TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES | +| Enable debug logs (**It's optional**). Default value - false | isDebug | TMS_IS_DEBUG | #### File @@ -36,8 +37,9 @@ Create **tms.config.json** file in the project directory: "configurationId": "CONFIGURATION_ID", "testRunId": "TEST_RUN_ID", "automaticCreationTestCases": false, + "automaticUpdationLinksToTestCases": false, "certValidation": true, - "adapterMode": 0, + "adapterMode": 1, "isDebug": true } ``` diff --git a/go.mod b/go.mod index 2b7b43e..9a6de1e 100644 --- a/go.mod +++ b/go.mod @@ -2,27 +2,25 @@ module github.com/testit-tms/adapters-go go 1.20 -require ( - github.com/ilyakaznacheev/cleanenv v1.5.0 - github.com/testit-tms/api-client-golang v1.1.2 -) +require github.com/testit-tms/adapters-go/pkg/tms v0.0.0-20240405083110-bea9bf588d07 replace github.com/testit-tms/adapters-go/pkg/tms => ./pkg/tms require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/ilyakaznacheev/cleanenv v1.5.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/testit-tms/adapters-go/pkg/tms v0.0.0-20240405083110-bea9bf588d07 // indirect + github.com/testit-tms/api-client-golang v1.1.2 // indirect golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect ) require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/joho/godotenv v1.5.1 // indirect - github.com/jtolds/gls v4.20.0+incompatible - github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.8.4 + github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/stretchr/testify v1.8.4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect ) diff --git a/pkg/tms/client.go b/pkg/tms/client.go index f4a12ea..f26fd73 100644 --- a/pkg/tms/client.go +++ b/pkg/tms/client.go @@ -7,13 +7,20 @@ import ( "io" "net/http" "os" + "strconv" "strings" + "time" "github.com/testit-tms/adapters-go/pkg/tms/config" tmsclient "github.com/testit-tms/api-client-golang" "golang.org/x/exp/slog" ) +const ( + maxTries = 10 + waitingTime = 100 +) + type tmsClient struct { cfg config.Config client *tmsclient.APIClient @@ -97,16 +104,54 @@ func (c *tmsClient) writeTest(test testResult) (string, error) { } if len(test.workItemIds) != 0 { + var linkedWorkItems []tmsclient.WorkItemIdentifierModel + linkedWorkItems, r, err = c.client.AutoTestsApi.GetWorkItemsLinkedToAutoTest(ctx, autotestID). + Execute() + + if err != nil { + logger.Error("failed to get linked workitems to autotest", "error", err, slog.String("response", respToString(r.Body)), slog.String("op", op)) + } + + for _, v := range linkedWorkItems { + var linkedWorkItemId string = strconv.Itoa(int(v.GetGlobalId())) + var index int = getIndex(test.workItemIds, linkedWorkItemId) + + if index != -1 { + test.workItemIds = remove(test.workItemIds, index) + + continue + } + + if c.cfg.AutomaticUpdationLinksToTestCases { + for i := 0; i < maxTries; i++ { + r, err = c.client.AutoTestsApi.DeleteAutoTestLinkFromWorkItem(ctx, autotestID). + WorkItemId(linkedWorkItemId). + Execute() + if err != nil { + logger.Error("failed to unlink autotest from workitem", "error", err, slog.String("response", respToString(r.Body)), slog.String("op", op)) + time.Sleep(waitingTime * time.Millisecond) + } else { + break + } + } + } + } + for _, v := range test.workItemIds { logger.Debug("link autotest to workitem", "workItemId", v, "autotestId", autotestID) - r, err = c.client.AutoTestsApi.LinkAutoTestToWorkItem(ctx, autotestID). - LinkAutoTestToWorkItemRequest(tmsclient.LinkAutoTestToWorkItemRequest{ - Id: v, - }). - Execute() - } - if err != nil { - logger.Error("failed to link autotest to workitem", "error", err, slog.String("response", respToString(r.Body)), slog.String("op", op)) + for i := 0; i < maxTries; i++ { + r, err = c.client.AutoTestsApi.LinkAutoTestToWorkItem(ctx, autotestID). + LinkAutoTestToWorkItemRequest(tmsclient.LinkAutoTestToWorkItemRequest{ + Id: v, + }). + Execute() + if err != nil { + logger.Error("failed to link autotest to workitem", "error", err, slog.String("response", respToString(r.Body)), slog.String("op", op)) + time.Sleep(waitingTime * time.Millisecond) + } else { + break + } + } } } @@ -179,6 +224,19 @@ func respToString(r io.ReadCloser) string { return string(respBytes) } +func getIndex(list []string, item string) int { + for i := 0; i < len(list); i++ { + if item == list[i] { + return i + } + } + return -1 +} + +func remove(slice []string, s int) []string { + return append(slice[:s], slice[s+1:]...) +} + func (c *tmsClient) updateTest(test testResult) error { const op = "tmsClient.updateTest" logger := logger.With("op", op) diff --git a/pkg/tms/config/config.go b/pkg/tms/config/config.go index 51501be..7b67ddc 100644 --- a/pkg/tms/config/config.go +++ b/pkg/tms/config/config.go @@ -1,12 +1,13 @@ package config import ( - "github.com/ilyakaznacheev/cleanenv" "log" "net/url" "os" "regexp" "strconv" + + "github.com/ilyakaznacheev/cleanenv" ) const ( @@ -14,15 +15,16 @@ const ( ) type Config struct { - Url string `json:"url" env-required:"true" env:"TMS_URL"` - Token string `json:"privateToken" env-required:"true" env:"TMS_PRIVATE_TOKEN"` - ProjectId string `json:"projectId" env-required:"true" env:"TMS_PROJECT_ID"` - ConfigurationId string `json:"configurationId" env-required:"true" env:"TMS_CONFIGURATION_ID"` - TestRunId string `json:"testRunId" env-required:"true" env:"TMS_TEST_RUN_ID"` - AdapterMode string `json:"adapterMode" env:"TMS_ADAPTER_MODE" env-default:"0"` - IsDebug bool `json:"isDebug" env:"TMS_IS_DEBUG" env-default:"false"` - AutomaticCreationTestCases bool `json:"automaticCreationTestCases" env:"TMS_AUTOMATIC_CREATION_TEST_CASES" env-default:"false"` - CertValidation bool `json:"certValidation" env:"TMS_CERT_VALIDATION" env-default:"true"` + Url string `json:"url" env-required:"true" env:"TMS_URL"` + Token string `json:"privateToken" env-required:"true" env:"TMS_PRIVATE_TOKEN"` + ProjectId string `json:"projectId" env-required:"true" env:"TMS_PROJECT_ID"` + ConfigurationId string `json:"configurationId" env-required:"true" env:"TMS_CONFIGURATION_ID"` + TestRunId string `json:"testRunId" env-required:"true" env:"TMS_TEST_RUN_ID"` + AdapterMode string `json:"adapterMode" env:"TMS_ADAPTER_MODE" env-default:"0"` + IsDebug bool `json:"isDebug" env:"TMS_IS_DEBUG" env-default:"false"` + AutomaticCreationTestCases bool `json:"automaticCreationTestCases" env:"TMS_AUTOMATIC_CREATION_TEST_CASES" env-default:"false"` + AutomaticUpdationLinksToTestCases bool `json:"automaticUpdationLinksToTestCases" env:"TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES" env-default:"false"` + CertValidation bool `json:"certValidation" env:"TMS_CERT_VALIDATION" env-default:"true"` } func MustLoad() *Config {