From dcf84cfd4e75683dd1e4c38aaf2ae8e92ac7e1b0 Mon Sep 17 00:00:00 2001 From: Stas Date: Sat, 7 May 2022 13:02:43 -0700 Subject: [PATCH] Pool operations test hooks (#1909) Co-authored-by: stas --- .../ApiService/OneFuzzTypes/Model.cs | 20 ++++---- .../ApiService/OneFuzzTypes/ReturnTypes.cs | 7 ++- .../ApiService/TestHooks/EventsTestHooks.cs | 12 +++++ .../TestHooks/PoolOperationsTestHooks.cs | 46 +++++++++++++++++++ .../ApiService/onefuzzlib/PoolOperations.cs | 14 +++--- 5 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 src/ApiService/ApiService/TestHooks/PoolOperationsTestHooks.cs diff --git a/src/ApiService/ApiService/OneFuzzTypes/Model.cs b/src/ApiService/ApiService/OneFuzzTypes/Model.cs index 6b08b3a37..9781dd73b 100644 --- a/src/ApiService/ApiService/OneFuzzTypes/Model.cs +++ b/src/ApiService/ApiService/OneFuzzTypes/Model.cs @@ -494,19 +494,19 @@ public record ReproConfig( // Skipping AutoScaleConfig because it's not used anymore public record Pool( - DateTimeOffset Timestamp, - PoolName Name, - Guid PoolId, + [PartitionKey] PoolName Name, + [RowKey] Guid PoolId, Os Os, bool Managed, - Architecture Architecture, + Architecture Arch, PoolState State, - Guid? ClientId, - List? Nodes, - AgentConfig? Config, - List? WorkQueue, - List? ScalesetSummary -) : StatefulEntityBase(State); + Guid? ClientId +) : StatefulEntityBase(State) { + public List? Nodes { get; set; } + public AgentConfig? Config { get; set; } + public List? WorkQueue { get; set; } + public List? ScalesetSummary { get; set; } +} public record ClientCredentials diff --git a/src/ApiService/ApiService/OneFuzzTypes/ReturnTypes.cs b/src/ApiService/ApiService/OneFuzzTypes/ReturnTypes.cs index 36abcdec5..03d2e67c0 100644 --- a/src/ApiService/ApiService/OneFuzzTypes/ReturnTypes.cs +++ b/src/ApiService/ApiService/OneFuzzTypes/ReturnTypes.cs @@ -8,8 +8,7 @@ readonly bool isOk; public ResultVoid() => (error, isOk) = (default, true); - - public ResultVoid(T_Error error) => (this.error, isOk) = (error, false); + private ResultVoid(T_Error error) => (this.error, isOk) = (error, false); public bool IsOk => isOk; @@ -25,9 +24,9 @@ readonly T_Error? error; readonly bool isOk; - public Result(T_Ok ok) => (this.ok, error, isOk) = (ok, default, true); + private Result(T_Ok ok) => (this.ok, error, isOk) = (ok, default, true); - public Result(T_Error error) => (this.error, ok, isOk) = (error, default, false); + private Result(T_Error error) => (this.error, ok, isOk) = (error, default, false); public bool IsOk => isOk; diff --git a/src/ApiService/ApiService/TestHooks/EventsTestHooks.cs b/src/ApiService/ApiService/TestHooks/EventsTestHooks.cs index 09bf8307a..87a71934b 100644 --- a/src/ApiService/ApiService/TestHooks/EventsTestHooks.cs +++ b/src/ApiService/ApiService/TestHooks/EventsTestHooks.cs @@ -30,6 +30,18 @@ namespace ApiService.TestHooks { var resp = req.CreateResponse(HttpStatusCode.OK); return resp; } + + + [Function("SendEventTestHook")] + public async Task SendEvent([HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "testhooks/events/sendEvent")] HttpRequestData req) { + _log.Info("Send event"); + + var s = await req.ReadAsStringAsync(); + var msg = JsonSerializer.Deserialize(s!, EntityConverter.GetJsonSerializerOptions()); + await _events.SendEvent(msg!.Event); + var resp = req.CreateResponse(HttpStatusCode.OK); + return resp; + } } } diff --git a/src/ApiService/ApiService/TestHooks/PoolOperationsTestHooks.cs b/src/ApiService/ApiService/TestHooks/PoolOperationsTestHooks.cs new file mode 100644 index 000000000..b23c630f4 --- /dev/null +++ b/src/ApiService/ApiService/TestHooks/PoolOperationsTestHooks.cs @@ -0,0 +1,46 @@ +using System.Net; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.OneFuzz.Service; +using Microsoft.OneFuzz.Service.OneFuzzLib.Orm; + +#if DEBUG +namespace ApiService.TestHooks { + public class PoolOperationsTestHooks { + private readonly ILogTracer _log; + private readonly IConfigOperations _configOps; + private readonly IPoolOperations _poolOps; + + public PoolOperationsTestHooks(ILogTracer log, IConfigOperations configOps, IPoolOperations poolOps) { + _log = log.WithTag("TestHooks", nameof(PoolOperationsTestHooks)); + _configOps = configOps; ; + _poolOps = poolOps; + } + + + [Function("GetPoolTestHook")] + public async Task GetNsg([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "testhooks/poolOperations/pool")] HttpRequestData req) { + _log.Info("get pool"); + + var query = UriExtension.GetQueryComponents(req.Url); + var poolRes = await _poolOps.GetByName(query["name"]); + + if (poolRes.IsOk) { + var resp = req.CreateResponse(HttpStatusCode.OK); + var data = poolRes.OkV; + var msg = JsonSerializer.Serialize(data, EntityConverter.GetJsonSerializerOptions()); + await resp.WriteStringAsync(msg); + return resp; + } else { + var resp = req.CreateResponse(HttpStatusCode.BadRequest); + var msg = JsonSerializer.Serialize(poolRes.ErrorV, EntityConverter.GetJsonSerializerOptions()); + await resp.WriteStringAsync(msg); + return resp; + } + } + } +} + +#endif diff --git a/src/ApiService/ApiService/onefuzzlib/PoolOperations.cs b/src/ApiService/ApiService/onefuzzlib/PoolOperations.cs index a8089b773..7e0ae1bee 100644 --- a/src/ApiService/ApiService/onefuzzlib/PoolOperations.cs +++ b/src/ApiService/ApiService/onefuzzlib/PoolOperations.cs @@ -4,7 +4,7 @@ using ApiService.OneFuzzLib.Orm; namespace Microsoft.OneFuzz.Service; public interface IPoolOperations { - public Async.Task> GetByName(string poolName); + public Async.Task> GetByName(string poolName); Task ScheduleWorkset(Pool pool, WorkSet workSet); } @@ -15,18 +15,18 @@ public class PoolOperations : StatefulOrm, IPoolOperations { } - public async Async.Task> GetByName(string poolName) { - var pools = QueryAsync(filter: $"name eq '{poolName}'"); + public async Async.Task> GetByName(string poolName) { + var pools = QueryAsync(filter: $"PartitionKey eq '{poolName}'"); - if (pools == null) { - return new Result(new Error(ErrorCode.INVALID_REQUEST, new[] { "unable to find pool" })); + if (pools == null || await pools.CountAsync() == 0) { + return OneFuzzResult.Error(ErrorCode.INVALID_REQUEST, "unable to find pool"); } if (await pools.CountAsync() != 1) { - return new Result(new Error(ErrorCode.INVALID_REQUEST, new[] { "error identifying pool" })); + return OneFuzzResult.Error(ErrorCode.INVALID_REQUEST, "error identifying pool"); } - return new Result(await pools.SingleAsync()); + return OneFuzzResult.Ok(await pools.SingleAsync()); } public async Task ScheduleWorkset(Pool pool, WorkSet workSet) {