diff --git a/Tms.Adapter.Core/Client/ITmsClient.cs b/Tms.Adapter.Core/Client/ITmsClient.cs
index f35e2c9..75a0b45 100644
--- a/Tms.Adapter.Core/Client/ITmsClient.cs
+++ b/Tms.Adapter.Core/Client/ITmsClient.cs
@@ -1,3 +1,4 @@
+using TestIT.ApiClient.Model;
using Tms.Adapter.Core.Models;
namespace Tms.Adapter.Core.Client;
@@ -8,9 +9,12 @@ public interface ITmsClient
Task CreateAutotest(TestContainer result, ClassContainer container);
Task UpdateAutotest(TestContainer result, ClassContainer container);
Task UpdateAutotest(string externalId, List links);
- Task TryLinkAutoTestToWorkItems(string externalId, IEnumerable workItemIds);
+ Task LinkAutoTestToWorkItems(string autotestId, IEnumerable workItemIds);
+ Task DeleteAutoTestLinkFromWorkItem(string autotestId, string workItemId);
+ Task> GetWorkItemsLinkedToAutoTest(string autotestId);
Task SubmitTestCaseResult(TestContainer result, ClassContainer container);
Task UploadAttachment(string fileName, Stream content);
Task CreateTestRun();
Task CompleteTestRun();
+ Task GetAutotestByExternalId(string externalId);
}
\ No newline at end of file
diff --git a/Tms.Adapter.Core/Client/TmsClient.cs b/Tms.Adapter.Core/Client/TmsClient.cs
index 53fc999..0c00a33 100644
--- a/Tms.Adapter.Core/Client/TmsClient.cs
+++ b/Tms.Adapter.Core/Client/TmsClient.cs
@@ -15,6 +15,8 @@ public class TmsClient : ITmsClient
private readonly TestRunsApi _testRuns;
private readonly AttachmentsApi _attachments;
private readonly AutoTestsApi _autoTests;
+ private readonly int MAX_TRIES = 10;
+ private readonly int WAITING_TIME = 200;
public TmsClient(ILogger logger, TmsSettings settings)
{
@@ -102,45 +104,75 @@ public async Task UpdateAutotest(string externalId, List links)
_logger.LogDebug("Update autotest {ExternalId} is successfully", externalId);
}
- public async Task TryLinkAutoTestToWorkItems(string externalId, IEnumerable workItemIds)
+ public async Task LinkAutoTestToWorkItems(string autotestId, IEnumerable workItemIds)
{
- var autotest = await GetAutotestByExternalId(externalId);
-
- if (autotest == null)
- {
- _logger.LogError("Autotest with {ID} not found", externalId);
-
- return false;
- }
-
foreach (var workItemId in workItemIds)
{
_logger.LogDebug(
- "Linking autotest {AutotestId} to work item {WorkItemId}",
- autotest.Id,
+ "Linking autotest {AutotestId} to workitem {WorkitemId}",
+ autotestId,
workItemId);
+ for (var attempts = 0; attempts < MAX_TRIES; attempts++)
+ {
+ try
+ {
+ await _autoTests.LinkAutoTestToWorkItemAsync(autotestId, new LinkAutoTestToWorkItemRequest(workItemId ?? string.Empty)).ConfigureAwait(false);
+ _logger.LogDebug(
+ "Link autotest {AutotestId} to workitem {WorkitemId} is successfully",
+ autotestId,
+ workItemId);
+
+ return;
+ }
+ catch (ApiException e)
+ {
+ _logger.LogError(
+ "Cannot link autotest {AutotestId} to work item {WorkItemId}: work item does not exist",
+ autotestId,
+ workItemId);
+
+ Thread.Sleep(WAITING_TIME);
+ }
+ }
+ }
+
+ }
+
+ public async Task DeleteAutoTestLinkFromWorkItem(string autotestId, string workItemId)
+ {
+ _logger.LogDebug(
+ "Unlink autotest {AutotestId} from workitem {WorkitemId}",
+ autotestId,
+ workItemId);
+
+ for (var attempts = 0; attempts < MAX_TRIES; attempts++)
+ {
try
{
- await _autoTests.LinkAutoTestToWorkItemAsync(autotest.Id.ToString(), new LinkAutoTestToWorkItemRequest(workItemId));
+ await _autoTests.DeleteAutoTestLinkFromWorkItemAsync(autotestId, workItemId);
+ _logger.LogDebug(
+ "Unlink autotest {AutotestId} from workitem {WorkitemId} is successfully",
+ autotestId,
+ workItemId);
+
+ return;
}
- catch (ApiException e) when (e.Message.Contains("does not exist"))
+ catch (ApiException e)
{
_logger.LogError(
- "Cannot link autotest {AutotestId} to work item {WorkItemId}: work item does not exist",
- autotest.Id,
+ "Cannot link autotest {AutotestId} to work item {WorkitemId}",
+ autotestId,
workItemId);
- return false;
+ Thread.Sleep(WAITING_TIME);
}
-
- _logger.LogDebug(
- "Link autotest {AutotestId} to work item {WorkItemId} is successfully",
- autotest.Id,
- workItemId);
}
+ }
- return true;
+ public async Task> GetWorkItemsLinkedToAutoTest(string autotestId)
+ {
+ return await _autoTests.GetWorkItemsLinkedToAutoTestAsync(autotestId);
}
public async Task SubmitTestCaseResult(TestContainer result, ClassContainer container)
@@ -212,7 +244,7 @@ public async Task CompleteTestRun()
_logger.LogDebug("Complete test run is successfully");
}
- private async Task GetAutotestByExternalId(string externalId)
+ public async Task GetAutotestByExternalId(string externalId)
{
_logger.LogDebug("Getting autotest by external id {Id}", externalId);
diff --git a/Tms.Adapter.Core/Configurator/Configurator.cs b/Tms.Adapter.Core/Configurator/Configurator.cs
index 3d55deb..769c79d 100644
--- a/Tms.Adapter.Core/Configurator/Configurator.cs
+++ b/Tms.Adapter.Core/Configurator/Configurator.cs
@@ -13,6 +13,7 @@ public static class Configurator
private const string TmsTestRunId = "TMS_TEST_RUN_ID";
private const string TmsTestRunName = "TMS_TEST_RUN_NAME";
private const string TmsAutomaticCreationTestCases = "TMS_AUTOMATIC_CREATION_TEST_CASES";
+ private const string TmsAutomaticUpdationLinksToTestCases = "TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES";
private const string TmsCertValidation = "TMS_CERT_VALIDATION";
private const string ConfigFile = "TMS_CONFIG_FILE";
private static readonly JsonSerializerOptions SerializerOptions = new() { PropertyNameCaseInsensitive = true };
@@ -22,6 +23,7 @@ public static TmsSettings GetConfig()
var config = new TmsSettings
{
AutomaticCreationTestCases = false,
+ AutomaticUpdationLinksToTestCases = false,
CertValidation = true
};
@@ -98,6 +100,12 @@ private static void ApplyEnv(TmsSettings settings)
settings.AutomaticCreationTestCases = value;
}
+ var updateLinksToTestCase = Environment.GetEnvironmentVariable(TmsAutomaticUpdationLinksToTestCases);
+ if (bool.TryParse(updateLinksToTestCase, out var updateLinks) && updateLinks)
+ {
+ settings.AutomaticUpdationLinksToTestCases = updateLinks;
+ }
+
if (bool.TryParse(Environment.GetEnvironmentVariable(TmsCertValidation), out var validCert) && !validCert)
{
settings.CertValidation = false;
diff --git a/Tms.Adapter.Core/Configurator/TmsSettings.cs b/Tms.Adapter.Core/Configurator/TmsSettings.cs
index eeacfeb..71cfb66 100644
--- a/Tms.Adapter.Core/Configurator/TmsSettings.cs
+++ b/Tms.Adapter.Core/Configurator/TmsSettings.cs
@@ -16,6 +16,7 @@ public string Url
public string TestRunId { get; set; }
public string TestRunName { get; set; }
public bool AutomaticCreationTestCases { get; set; }
+ public bool AutomaticUpdationLinksToTestCases { get; set; }
public bool CertValidation { get; set; }
public bool IsDebug { get; set; }
}
\ No newline at end of file
diff --git a/Tms.Adapter.Core/Service/AdapterManager.cs b/Tms.Adapter.Core/Service/AdapterManager.cs
index f5713cb..601a20f 100644
--- a/Tms.Adapter.Core/Service/AdapterManager.cs
+++ b/Tms.Adapter.Core/Service/AdapterManager.cs
@@ -48,7 +48,7 @@ public AdapterManager()
_logger = logger.CreateLogger();
_client = new TmsClient(logger.CreateLogger(), config);
_storage = new ResultStorage();
- _writer = new Writer.Writer(logger.CreateLogger(), _client);
+ _writer = new Writer.Writer(logger.CreateLogger(), _client, config);
}
public virtual AdapterManager StartTestContainer(ClassContainer container)
diff --git a/Tms.Adapter.Core/Tms.Adapter.Core.csproj b/Tms.Adapter.Core/Tms.Adapter.Core.csproj
index 9197f7a..2931336 100644
--- a/Tms.Adapter.Core/Tms.Adapter.Core.csproj
+++ b/Tms.Adapter.Core/Tms.Adapter.Core.csproj
@@ -1,7 +1,7 @@
- 1.6.0
+ 1.6.1netstandard2.1enabletrue
diff --git a/Tms.Adapter.Core/Writer/Writer.cs b/Tms.Adapter.Core/Writer/Writer.cs
index 238f370..db11e39 100644
--- a/Tms.Adapter.Core/Writer/Writer.cs
+++ b/Tms.Adapter.Core/Writer/Writer.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
+using Tms.Adapter.Core.Configurator;
using Tms.Adapter.Core.Client;
using Tms.Adapter.Core.Models;
@@ -8,11 +9,13 @@ public class Writer : IWriter
{
private readonly ILogger _logger;
private readonly ITmsClient _client;
+ private readonly TmsSettings _tmsSettings;
- public Writer(ILogger logger, ITmsClient client)
+ public Writer(ILogger logger, ITmsClient client, TmsSettings tmsSettings)
{
_logger = logger;
_client = client;
+ _tmsSettings = tmsSettings;
}
public async Task Write(TestContainer result, ClassContainer container)
@@ -44,10 +47,7 @@ public async Task Write(TestContainer result, ClassContainer container)
if (result.WorkItemIds.Count > 0)
{
- if (!await _client.TryLinkAutoTestToWorkItems(result.ExternalId, result.WorkItemIds))
- {
- return;
- }
+ await UpdateTestLinkToWorkItems(result.ExternalId, result.WorkItemIds);
}
await _client.SubmitTestCaseResult(result, container);
@@ -59,4 +59,38 @@ public async Task Write(TestContainer result, ClassContainer container)
_logger.LogError(e, "Can not write autotest with ID {ID}", result.ExternalId);
}
}
+
+ private async Task UpdateTestLinkToWorkItems(string externalId, List workItemIds)
+ {
+ var autotest = await _client.GetAutotestByExternalId(externalId);
+
+ if (autotest == null)
+ {
+ _logger.LogError("Autotest with {ID} not found", externalId);
+ return;
+ }
+
+ var autotestId = autotest.Id.ToString();
+
+ var linkedWorkItems = await _client.GetWorkItemsLinkedToAutoTest(autotestId);
+
+ foreach (var linkedWorkItem in linkedWorkItems)
+ {
+ var linkedWorkItemId = linkedWorkItem.GlobalId.ToString();
+
+ if (workItemIds.Contains(linkedWorkItemId))
+ {
+ workItemIds.Remove(linkedWorkItemId);
+
+ continue;
+ }
+
+ if (_tmsSettings.AutomaticUpdationLinksToTestCases)
+ {
+ await _client.DeleteAutoTestLinkFromWorkItem(autotestId, linkedWorkItemId);
+ }
+ }
+
+ await _client.LinkAutoTestToWorkItems(autotestId, workItemIds);
+ }
}
\ No newline at end of file
diff --git a/Tms.Adapter.SpecFlowPlugin/README.md b/Tms.Adapter.SpecFlowPlugin/README.md
index f0c3b0b..aa2e35a 100644
--- a/Tms.Adapter.SpecFlowPlugin/README.md
+++ b/Tms.Adapter.SpecFlowPlugin/README.md
@@ -32,17 +32,18 @@ Also you need to add following lines to `specflow.json`:
### 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. If you don't provide a test run ID, the adapter will automatically create one. | testRunId | TMS_TEST_RUN_ID |
-| Parameter for specifying the name of test run in TMS instance (**It's optional**). If it is not provided, it is created automatically | testRunName | TMS_TEST_RUN_NAME |
-| 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 | - |
+| 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. If you don't provide a test run ID, the adapter will automatically create one. | testRunId | TMS_TEST_RUN_ID |
+| Parameter for specifying the name of test run in TMS instance (**It's optional**). If it is not provided, it is created automatically | testRunName | TMS_TEST_RUN_NAME |
+| 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 | - |
#### File
@@ -57,6 +58,7 @@ Create **Tms.config.json** file in the project directory:
"testRunId": "TEST_RUN_ID",
"testRunName": "TEST_RUN_NAME",
"automaticCreationTestCases": false,
+ "automaticUpdationLinksToTestCases": false,
"certValidation": true,
"isDebug": true
}
diff --git a/Tms.Adapter.SpecFlowPlugin/Tms.Adapter.SpecFlowPlugin.csproj b/Tms.Adapter.SpecFlowPlugin/Tms.Adapter.SpecFlowPlugin.csproj
index 1c195db..a070bcb 100644
--- a/Tms.Adapter.SpecFlowPlugin/Tms.Adapter.SpecFlowPlugin.csproj
+++ b/Tms.Adapter.SpecFlowPlugin/Tms.Adapter.SpecFlowPlugin.csproj
@@ -1,7 +1,7 @@
- 1.6.0
+ 1.6.1netstandard2.1enabletrue
diff --git a/Tms.Adapter.XUnit/README.md b/Tms.Adapter.XUnit/README.md
index 26c093f..30ae41a 100644
--- a/Tms.Adapter.XUnit/README.md
+++ b/Tms.Adapter.XUnit/README.md
@@ -22,16 +22,17 @@ dotnet package add TestIT.Adapter.Core
### 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 |
-| 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 | - |
+| 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. If you don't provide a test run ID, the adapter will automatically create one. | testRunId | TMS_TEST_RUN_ID |
+| 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 | - |
#### File
@@ -39,14 +40,15 @@ Create **Tms.config.json** file in the project directory:
```json
{
- "url": "URL",
- "privateToken": "USER_PRIVATE_TOKEN",
- "projectId": "PROJECT_ID",
- "configurationId": "CONFIGURATION_ID",
- "testRunId": "TEST_RUN_ID",
- "automaticCreationTestCases": false,
- "certValidation": true,
- "isDebug": true
+ "url": "URL",
+ "privateToken": "USER_PRIVATE_TOKEN",
+ "projectId": "PROJECT_ID",
+ "configurationId": "CONFIGURATION_ID",
+ "testRunId": "TEST_RUN_ID",
+ "automaticCreationTestCases": false,
+ "automaticUpdationLinksToTestCases": false,
+ "certValidation": true,
+ "isDebug": true
}
```
diff --git a/Tms.Adapter.XUnit/Tms.Adapter.XUnit.csproj b/Tms.Adapter.XUnit/Tms.Adapter.XUnit.csproj
index 96b95fc..a6b6063 100644
--- a/Tms.Adapter.XUnit/Tms.Adapter.XUnit.csproj
+++ b/Tms.Adapter.XUnit/Tms.Adapter.XUnit.csproj
@@ -1,7 +1,7 @@
- 1.6.0
+ 1.6.1netstandard2.1enabletrue
diff --git a/Tms.Adapter/README.md b/Tms.Adapter/README.md
index 316d553..a550575 100644
--- a/Tms.Adapter/README.md
+++ b/Tms.Adapter/README.md
@@ -27,18 +27,19 @@ dotnet package add TestIt.Adapter
### Configuration
-| Description | File property | Environment variable | CLI argument |
-|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-----------------------------------|-------------------------------|
-| Location of the TMS instance | url | TMS_URL | tmsUrl |
-| API secret key [How to getting API secret key?](https://github.com/testit-tms/.github/tree/main/configuration#privatetoken) | privateToken | TMS_PRIVATE_TOKEN | tmsPrivateToken |
-| 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 | tmsProjectId |
-| 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 | tmsConfigurationId |
-| ID of the created test run in TMS instance. It's necessary for **adapterMode** 0 or 1 | testRunId | TMS_TEST_RUN_ID | tmsTestRunId |
-| Parameter for specifying the name of test run in TMS instance (**It's optional**). If it is not provided, it is created automatically | testRunName | TMS_TEST_RUN_NAME | tmsTestRunName |
-| 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 | tmsCertValidation |
-| 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 | tmsAutomaticCreationTestCases |
-| List of labels for filtering tests (**Optional**). It will only work with adapter mode 2. | - | - | tmsLabelsOfTestsToRun |
+| Description | File property | Environment variable | CLI argument |
+|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|--------------------------------------------|--------------------------------------|
+| Location of the TMS instance | url | TMS_URL | tmsUrl |
+| API secret key [How to getting API secret key?](https://github.com/testit-tms/.github/tree/main/configuration#privatetoken) | privateToken | TMS_PRIVATE_TOKEN | tmsPrivateToken |
+| 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 | tmsProjectId |
+| 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 | tmsConfigurationId |
+| ID of the created test run in TMS instance. It's necessary for **adapterMode** 0 or 1 | testRunId | TMS_TEST_RUN_ID | tmsTestRunId |
+| Parameter for specifying the name of test run in TMS instance (**It's optional**). If it is not provided, it is created automatically | testRunName | TMS_TEST_RUN_NAME | tmsTestRunName |
+| 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 | tmsCertValidation |
+| 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 | tmsAutomaticCreationTestCases |
+| 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 | tmsAutomaticUpdationLinksToTestCases |
+| List of labels for filtering tests (**Optional**). It will only work with adapter mode 2. | - | - | tmsLabelsOfTestsToRun |
#### File
@@ -54,6 +55,7 @@ Create **Tms.config.json** file in the project directory:
"testRunName": "TEST_RUN_NAME",
"adapterMode": ADAPTER_MODE,
"automaticCreationTestCases": AUTOMATIC_CREATION_TEST_CASES,
+ "automaticUpdationLinksToTestCases": AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES,
"certValidation": CERT_VALIDATION
}
```
@@ -64,7 +66,7 @@ Create **Tms.config.json** file in the project directory:
```
TmsRunner --runner "/usr/local/share/dotnet/sdk/6.0.302/vstest.console.dll" --testassembly "/tests/MsTest.dll" --tmsUrl=http://localhost:8080 --tmsPrivateToken=Token --tmsProjectId=f5da5bab-380a-4382-b36f-600083fdd795 --tmsConfigurationId=3a14fa45-b54e-4859-9998-cc502d4cc8c6
--tmsAdapterMode=0 --tmsTestRunId=a17269da-bc65-4671-90dd-d3e3da92af80 --tmsTestRunName=Regress --tmsAutomaticCreationTestCases=true --tmsCertValidation=true --tmsLabelsOfTestsToRun smoke,regress --debug
+-tmsAdapterMode=0 --tmsTestRunId=a17269da-bc65-4671-90dd-d3e3da92af80 --tmsTestRunName=Regress --tmsAutomaticCreationTestCases=true --tmsAutomaticUpdationLinksToTestCases=true --tmsCertValidation=true --tmsLabelsOfTestsToRun smoke,regress --debug
```
* `runner` - path to vstest.console.dll or vstest.console.exe
diff --git a/Tms.Adapter/Tms.Adapter.csproj b/Tms.Adapter/Tms.Adapter.csproj
index cf3d0d3..1cdb862 100644
--- a/Tms.Adapter/Tms.Adapter.csproj
+++ b/Tms.Adapter/Tms.Adapter.csproj
@@ -1,7 +1,7 @@
- 1.6.0
+ 1.6.1netstandard2.1enabletrue
diff --git a/TmsRunner/Entities/Configuration/AdapterConfig.cs b/TmsRunner/Entities/Configuration/AdapterConfig.cs
index 62003e7..3b1e74a 100644
--- a/TmsRunner/Entities/Configuration/AdapterConfig.cs
+++ b/TmsRunner/Entities/Configuration/AdapterConfig.cs
@@ -72,6 +72,9 @@ public string? LoggerPath
[Option("tmsAutomaticCreationTestCases", Required = false, HelpText = "Set automatic creation test cases.")]
public string? TmsAutomaticCreationTestCases { get; init; }
+ [Option("TmsAutomaticUpdationLinksToTestCases", Required = false, HelpText = "Set automatic updation links to test cases.")]
+ public string? TmsAutomaticUpdationLinksToTestCases { get; init; }
+
[Option("tmsCertValidation", Default = "true", Required = false, HelpText = "Set certificate validation.")]
public string? TmsCertValidation { get; init; }
@@ -89,8 +92,10 @@ public Config ToInternalConfig()
TmsConfigFile = TmsConfigFile,
TmsRunSettings = TmsRunSettings,
TmsAutomaticCreationTestCases = TmsAutomaticCreationTestCases,
+ TmsAutomaticUpdationLinksToTestCases = TmsAutomaticUpdationLinksToTestCases,
TmsCertValidation = TmsCertValidation,
TmsLabelsOfTestsToRun = TmsLabelsOfTestsToRun
+
};
}
diff --git a/TmsRunner/Entities/Configuration/ClassConfigurationProvider.cs b/TmsRunner/Entities/Configuration/ClassConfigurationProvider.cs
index 0346743..5b913f0 100644
--- a/TmsRunner/Entities/Configuration/ClassConfigurationProvider.cs
+++ b/TmsRunner/Entities/Configuration/ClassConfigurationProvider.cs
@@ -18,6 +18,7 @@ public override void Load()
{ "ConfigFile", config.TmsConfigFile },
{ "RunSettings", config.TmsRunSettings },
{ "AutomaticCreationTestCases", config.TmsAutomaticCreationTestCases },
+ { "AutomaticUpdationLinksToTestCases", config.TmsAutomaticUpdationLinksToTestCases },
{ "CertValidation", config.TmsCertValidation }
};
diff --git a/TmsRunner/Entities/Configuration/Config.cs b/TmsRunner/Entities/Configuration/Config.cs
index 95d278a..fc2bd1e 100644
--- a/TmsRunner/Entities/Configuration/Config.cs
+++ b/TmsRunner/Entities/Configuration/Config.cs
@@ -12,6 +12,7 @@ public sealed record Config
public string? TmsConfigFile;
public string? TmsRunSettings;
public string? TmsAutomaticCreationTestCases;
+ public string? TmsAutomaticUpdationLinksToTestCases;
public string? TmsCertValidation;
public string? TmsLabelsOfTestsToRun;
-}
\ No newline at end of file
+}
diff --git a/TmsRunner/Entities/Configuration/EnvConfigurationProvider.cs b/TmsRunner/Entities/Configuration/EnvConfigurationProvider.cs
index 5d92200..dd16682 100644
--- a/TmsRunner/Entities/Configuration/EnvConfigurationProvider.cs
+++ b/TmsRunner/Entities/Configuration/EnvConfigurationProvider.cs
@@ -13,6 +13,7 @@ public sealed class EnvConfigurationProvider : ConfigurationProvider
private const string EnvTmsAdapterMode = "TMS_ADAPTER_MODE";
private const string EnvTmsRunSettings = "TMS_RUN_SETTINGS";
private const string EnvTmsAutomaticCreationTestCases = "TMS_AUTOMATIC_CREATION_TEST_CASES";
+ private const string EnvTmsAutomaticUpdationLinksToTestCases = "TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES";
private const string EnvTmsCertValidation = "TMS_CERT_VALIDATION";
public override void Load()
@@ -28,6 +29,7 @@ public override void Load()
{ "AdapterMode", Environment.GetEnvironmentVariable(EnvTmsAdapterMode) },
{ "RunSettings", Environment.GetEnvironmentVariable(EnvTmsRunSettings) },
{ "AutomaticCreationTestCases", Environment.GetEnvironmentVariable(EnvTmsAutomaticCreationTestCases) },
+ { "AutomaticUpdationLinksToTestCases", Environment.GetEnvironmentVariable(EnvTmsAutomaticUpdationLinksToTestCases) },
{ "CertValidation", Environment.GetEnvironmentVariable(EnvTmsCertValidation) },
};
diff --git a/TmsRunner/Entities/TmsSettings.cs b/TmsRunner/Entities/TmsSettings.cs
index 4df7b22..d3132aa 100644
--- a/TmsRunner/Entities/TmsSettings.cs
+++ b/TmsRunner/Entities/TmsSettings.cs
@@ -18,5 +18,6 @@ public string? Url
public int AdapterMode { get; set; }
public string? RunSettings { get; set; }
public bool AutomaticCreationTestCases { get; set; }
+ public bool AutomaticUpdationLinksToTestCases { get; set; }
public bool CertValidation { get; set; }
}
\ No newline at end of file
diff --git a/TmsRunner/Managers/TmsManager.cs b/TmsRunner/Managers/TmsManager.cs
index 49e9204..2183057 100644
--- a/TmsRunner/Managers/TmsManager.cs
+++ b/TmsRunner/Managers/TmsManager.cs
@@ -14,6 +14,9 @@ public sealed class TmsManager(ILogger logger,
ITestRunsApiAsync testRunsApi,
TmsSettings settings)
{
+ private readonly int MAX_TRIES = 10;
+ private readonly int WAITING_TIME = 200;
+
public async Task CreateTestRunAsync()
{
var createTestRunRequestBody = new CreateEmptyRequest
@@ -120,7 +123,7 @@ public async Task UpdateAutotestAsync(AutoTest dto)
logger.LogDebug("Update autotest {@Autotest} is successfully", model);
}
- public async Task TryLinkAutoTestToWorkItemAsync(string autotestId, IEnumerable workItemIds)
+ public async Task LinkAutoTestToWorkItemAsync(string autotestId, IEnumerable workItemIds)
{
foreach (var workItemId in workItemIds)
{
@@ -129,26 +132,65 @@ public async Task TryLinkAutoTestToWorkItemAsync(string autotestId, IEnume
autotestId,
workItemId);
+ for (var attempts = 0; attempts < MAX_TRIES; attempts++)
+ {
+ try
+ {
+ await autoTestsApi.LinkAutoTestToWorkItemAsync(autotestId, new LinkAutoTestToWorkItemRequest(workItemId ?? string.Empty)).ConfigureAwait(false);
+ logger.LogDebug(
+ "Link autotest {AutotestId} to workitem {WorkitemId} is successfully",
+ autotestId,
+ workItemId);
+
+ return;
+ }
+ catch (ApiException e)
+ {
+ logger.LogError(
+ "Cannot link autotest {AutotestId} to work item {WorkItemId}",
+ autotestId,
+ workItemId);
+
+ Thread.Sleep(WAITING_TIME);
+ }
+ }
+ }
+
+ }
+
+ public async Task DeleteAutoTestLinkFromWorkItemAsync(string autotestId, string workItemId)
+ {
+ logger.LogDebug(
+ "Unlink autotest {AutotestId} from workitem {WorkitemId}",
+ autotestId,
+ workItemId);
+
+ for (var attempts = 0; attempts < MAX_TRIES; attempts++)
+ {
try
{
- await autoTestsApi.LinkAutoTestToWorkItemAsync(autotestId, new LinkAutoTestToWorkItemRequest(workItemId ?? string.Empty)).ConfigureAwait(false);
+ await autoTestsApi.DeleteAutoTestLinkFromWorkItemAsync(autotestId, workItemId);
+ logger.LogDebug(
+ "Unlink autotest {AutotestId} from workitem {WorkitemId} is successfully",
+ autotestId,
+ workItemId);
+
+ return;
}
- catch (ApiException e) when (e.Message.Contains("does not exist"))
+ catch (ApiException e)
{
logger.LogError(
- "Cannot link autotest {AutotestId} to work item {WorkItemId}: work item does not exist",
- autotestId,
- workItemId);
+ "Cannot link autotest {AutotestId} to work item {WorkitemId}",
+ autotestId,
+ workItemId);
- return false;
+ Thread.Sleep(WAITING_TIME);
}
-
- logger.LogDebug(
- "Link autotest {AutotestId} to workitem {WorkitemId} is successfully",
- autotestId,
- workItemId);
}
+ }
- return true;
+ public async Task> GetWorkItemsLinkedToAutoTestAsync(string autotestId)
+ {
+ return await autoTestsApi.GetWorkItemsLinkedToAutoTestAsync(autotestId);
}
-}
\ No newline at end of file
+}
diff --git a/TmsRunner/Program.cs b/TmsRunner/Program.cs
index d2c6914..13dbc88 100644
--- a/TmsRunner/Program.cs
+++ b/TmsRunner/Program.cs
@@ -55,7 +55,10 @@ private static AdapterConfig GetAdapterConfiguration(IEnumerable args)
TmsTestRunName = ac.TmsTestRunName,
TmsAdapterMode = ac.TmsAdapterMode,
TmsConfigFile = ac.TmsConfigFile,
- TmsLabelsOfTestsToRun = ac.TmsLabelsOfTestsToRun
+ TmsLabelsOfTestsToRun = ac.TmsLabelsOfTestsToRun,
+ TmsAutomaticCreationTestCases = ac.TmsAutomaticCreationTestCases,
+ TmsAutomaticUpdationLinksToTestCases = ac.TmsAutomaticUpdationLinksToTestCases,
+ TmsCertValidation = ac.TmsCertValidation
};
});
diff --git a/TmsRunner/Services/ProcessorService.cs b/TmsRunner/Services/ProcessorService.cs
index 111fb3e..382bb6b 100644
--- a/TmsRunner/Services/ProcessorService.cs
+++ b/TmsRunner/Services/ProcessorService.cs
@@ -203,10 +203,7 @@ public async Task ProcessAutoTestAsync(TestResult testResult)
if (autoTest.WorkItemIds.Count > 0)
{
- if (!await apiClient.TryLinkAutoTestToWorkItemAsync(existAutotest.Id.ToString(), autoTest.WorkItemIds).ConfigureAwait(false))
- {
- return;
- }
+ await UpdateTestLinkToWorkItems(existAutotest.Id.ToString(), autoTest.WorkItemIds);
}
if (!string.IsNullOrEmpty(testResult.ErrorMessage))
@@ -220,6 +217,27 @@ public async Task ProcessAutoTestAsync(TestResult testResult)
await apiClient.SubmitResultToTestRunAsync(tmsSettings.TestRunId, autoTestResultRequestBody).ConfigureAwait(false);
}
+ private async Task UpdateTestLinkToWorkItems(string autoTestId, List workItemIds)
+ {
+ var linkedWorkItems = await apiClient.GetWorkItemsLinkedToAutoTestAsync(autoTestId);
+
+ foreach (var linkedWorkItem in linkedWorkItems) {
+ var linkedWorkItemId = linkedWorkItem.GlobalId.ToString();
+
+ if (workItemIds.Contains(linkedWorkItemId)) {
+ workItemIds.Remove(linkedWorkItemId);
+
+ continue;
+ }
+
+ if (tmsSettings.AutomaticUpdationLinksToTestCases) {
+ await apiClient.DeleteAutoTestLinkFromWorkItemAsync(autoTestId, linkedWorkItemId);
+ }
+ }
+
+ await apiClient.LinkAutoTestToWorkItemAsync(autoTestId, workItemIds);
+ }
+
private static AutoTestResult GetAutoTestResultsForTestRunModel(AutoTest autoTest,
TestResult testResult,
string traceJson,
diff --git a/TmsRunner/TmsRunner.csproj b/TmsRunner/TmsRunner.csproj
index 7a3d99c..ed29087 100644
--- a/TmsRunner/TmsRunner.csproj
+++ b/TmsRunner/TmsRunner.csproj
@@ -1,7 +1,7 @@
- 1.6.0
+ 1.6.1Exeenableenable