Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Ignore regression update when the work item is in some states #3532

Merged
merged 16 commits into from
Oct 2, 2023
24 changes: 13 additions & 11 deletions src/ApiService/ApiService/Functions/QueueFileChanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,22 @@ private async Async.Task RequeueMessage(string msg, TimeSpan? visibilityTimeout
newCustomDequeueCount = json["data"]!["customDequeueCount"]!.GetValue<int>();
}

var queueName = QueueFileChangesQueueName;
if (newCustomDequeueCount > MAX_DEQUEUE_COUNT) {
_log.LogWarning("Message retried more than {MAX_DEQUEUE_COUNT} times with no success: {msg}", MAX_DEQUEUE_COUNT, msg);
queueName = QueueFileChangesPoisonQueueName;
await _context.Queue.QueueObject(
QueueFileChangesPoisonQueueName,
json,
StorageType.Config)
.IgnoreResult();
} else {
json!["data"]!["customDequeueCount"] = newCustomDequeueCount + 1;
await _context.Queue.QueueObject(
QueueFileChangesQueueName,
json,
StorageType.Config,
visibilityTimeout ?? CalculateExponentialBackoff(newCustomDequeueCount))
.IgnoreResult();
}

json!["data"]!["customDequeueCount"] = newCustomDequeueCount + 1;

await _context.Queue.QueueObject(
queueName,
json,
StorageType.Config,
visibilityTimeout ?? CalculateExponentialBackoff(newCustomDequeueCount))
.IgnoreResult();
}

// Possible return values:
Expand Down
8 changes: 7 additions & 1 deletion src/ApiService/ApiService/OneFuzzTypes/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,10 @@ public record ADODuplicateTemplate(
List<Dictionary<string, string>>? Unless = null
);

public record ADORegressionTemplate(
List<string> IgnoreStates
) { }

public record AdoTemplate(
Uri BaseUrl,
SecretData<string> AuthToken,
Expand All @@ -689,6 +693,7 @@ public record AdoTemplate(
List<string> UniqueFields,
Dictionary<string, string> AdoFields,
ADODuplicateTemplate OnDuplicate,
ADORegressionTemplate? OnRegression = null,
Dictionary<string, string>? AdoDuplicateFields = null,
string? Comment = null
) : NotificationTemplate {
Expand All @@ -705,9 +710,10 @@ public record RenderedAdoTemplate(
List<string> UniqueFields,
Dictionary<string, string> AdoFields,
ADODuplicateTemplate OnDuplicate,
ADORegressionTemplate? OnRegression = null,
Dictionary<string, string>? AdoDuplicateFields = null,
string? Comment = null
) : AdoTemplate(BaseUrl, AuthToken, Project, Type, UniqueFields, AdoFields, OnDuplicate, AdoDuplicateFields, Comment);
) : AdoTemplate(BaseUrl, AuthToken, Project, Type, UniqueFields, AdoFields, OnDuplicate, OnRegression, AdoDuplicateFields, Comment) { }

public record TeamsTemplate(SecretData<string> Url) : NotificationTemplate {
public Task<OneFuzzResultVoid> Validate() {
Expand Down
15 changes: 11 additions & 4 deletions src/ApiService/ApiService/onefuzzlib/notifications/Ado.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class Ado : NotificationsBase, IAdo {
// https://github.com/MicrosoftDocs/azure-devops-docs/issues/5890#issuecomment-539632059
private const int MAX_SYSTEM_TITLE_LENGTH = 128;
private const string TITLE_FIELD = "System.Title";
private static List<string> DEFAULT_REGRESSION_IGNORE_STATES = new() { "New", "Commited", "Active" };
tevoinea marked this conversation as resolved.
Show resolved Hide resolved

public Ado(ILogger<Ado> logTracer, IOnefuzzContext context) : base(logTracer, context) {
}
Expand Down Expand Up @@ -56,7 +57,7 @@ public async Async.Task<OneFuzzResultVoid> NotifyAdo(AdoTemplate config, Contain
_logTracer.LogEvent(adoEventType);

try {
await ProcessNotification(_context, container, filename, config, report, _logTracer, notificationInfo);
await ProcessNotification(_context, container, filename, config, report, _logTracer, notificationInfo, isRegression: reportable is RegressionReport);
} catch (Exception e)
when (e is VssUnauthorizedException || e is VssAuthenticationException || e is VssServiceException) {
if (config.AdoFields.TryGetValue("System.AssignedTo", out var assignedTo)) {
Expand Down Expand Up @@ -298,7 +299,7 @@ private static async Async.Task<Dictionary<string, WorkItemField2>> GetValidFiel
.ToDictionary(field => field.ReferenceName.ToLowerInvariant());
}

private static async Async.Task ProcessNotification(IOnefuzzContext context, Container container, string filename, AdoTemplate config, Report report, ILogger logTracer, IList<(string, string)> notificationInfo, Renderer? renderer = null) {
private static async Async.Task ProcessNotification(IOnefuzzContext context, Container container, string filename, AdoTemplate config, Report report, ILogger logTracer, IList<(string, string)> notificationInfo, Renderer? renderer = null, bool isRegression = false) {
if (!config.AdoFields.TryGetValue(TITLE_FIELD, out var issueTitle)) {
issueTitle = "{{ report.crash_site }} - {{ report.executable }}";
}
Expand All @@ -311,7 +312,7 @@ private static async Async.Task ProcessNotification(IOnefuzzContext context, Con

var renderedConfig = RenderAdoTemplate(logTracer, renderer, config, instanceUrl);
var ado = new AdoConnector(renderedConfig, project!, client, instanceUrl, logTracer, await GetValidFields(client, project));
await ado.Process(notificationInfo);
await ado.Process(notificationInfo, isRegression);
}

public static RenderedAdoTemplate RenderAdoTemplate(ILogger logTracer, Renderer renderer, AdoTemplate original, Uri instanceUrl) {
Expand Down Expand Up @@ -363,6 +364,7 @@ public static RenderedAdoTemplate RenderAdoTemplate(ILogger logTracer, Renderer
original.UniqueFields,
adoFields,
onDuplicate,
original.OnRegression,
original.AdoDuplicateFields,
original.Comment != null ? Render(renderer, original.Comment, instanceUrl, logTracer) : null
);
Expand Down Expand Up @@ -598,7 +600,7 @@ private async Async.Task<WorkItem> CreateNew() {
return (taskType, document);
}

public async Async.Task Process(IList<(string, string)> notificationInfo) {
public async Async.Task Process(IList<(string, string)> notificationInfo, bool isRegression) {
var updated = false;
WorkItem? oldestWorkItem = null;
await foreach (var workItem in ExistingWorkItems(notificationInfo)) {
Expand All @@ -612,6 +614,11 @@ public async Async.Task Process(IList<(string, string)> notificationInfo) {
continue;
}

var regressionStatesToIgnore = _config.OnRegression != null ? _config.OnRegression.IgnoreStates : DEFAULT_REGRESSION_IGNORE_STATES;
if (isRegression && regressionStatesToIgnore.Contains((string)workItem.Fields["System.State"], StringComparer.InvariantCultureIgnoreCase)) {
continue;
}

using (_logTracer.BeginScope("Non-duplicate work item")) {
_logTracer.AddTags(new List<(string, string)> { ("NonDuplicateWorkItemId", $"{workItem.Id}") });
_logTracer.LogInformation("Found matching non-duplicate work item");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public async Async.Task OptionalFieldsAreSupported() {
"{{ if org }} blah {{ end }}"
),
null,
null,
"{{ if org }} blah {{ end }}"
);

Expand Down Expand Up @@ -139,6 +140,7 @@ public async Async.Task All_ADO_Fields_Are_Migrated() {
"{% if org %} comment {% endif %}"
),
null,
null,
"{% if org %} comment {% endif %}"
);

Expand Down
2 changes: 2 additions & 0 deletions src/ApiService/Tests/OrmModelsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ from str in Arb.Generate<NonEmptyString>()
from fields in Arb.Generate<List<string>>()
from adoFields in Arb.Generate<Dictionary<string, string>>()
from adoDuplicateFields in Arb.Generate<Dictionary<string, string>>()
from onDuplicate in Arb.Generate<ADORegressionTemplate>()
from dupeTemplate in Arb.Generate<ADODuplicateTemplate>()
select new AdoTemplate(
baseUrl,
Expand All @@ -242,6 +243,7 @@ from dupeTemplate in Arb.Generate<ADODuplicateTemplate>()
fields,
adoFields,
dupeTemplate,
onDuplicate,
adoDuplicateFields,
str.Get));

Expand Down
3 changes: 3 additions & 0 deletions src/cli/onefuzz/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,9 @@ def create_ado(
ado_fields=on_dup_fields or {},
set_state=on_dup_set_state or {},
),
on_regression=models.ADORegressionTemplate(
ignore_states=[],
),
),
)
return self.create(container, entry)
Expand Down
5 changes: 5 additions & 0 deletions src/pytypes/onefuzztypes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ class ADODuplicateTemplate(BaseModel):
ado_fields: Dict[str, str]


class ADORegressionTemplate(BaseModel):
ignore_states: List[str]


class ADOTemplate(BaseModel):
base_url: str
auth_token: SecretData[str]
Expand All @@ -275,6 +279,7 @@ class ADOTemplate(BaseModel):
ado_fields: Dict[str, str]
ado_duplicate_fields: Optional[Dict[str, str]]
on_duplicate: ADODuplicateTemplate
on_regression: Optional[ADORegressionTemplate]

# validator needed to convert auth_token to SecretData
@validator("auth_token", pre=True, always=True)
Expand Down
Loading