public async Async.Task WorkerDone_ForNonStartedTask_MarksTaskAsFailed() { await Context.InsertAll( new Node(_poolName, _machineId, _poolId, _poolVersion), // task state is scheduled, not running new Task(_jobId, _taskId, TaskState.Scheduled, Os.Linux, new TaskConfig(_jobId, null, new TaskDetails(TaskType.Coverage, 100)))); var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentEvents(Logger, auth, Context); var data = new NodeStateEnvelope( MachineId: _machineId, Event: new WorkerEvent(Done: new WorkerDoneEvent( TaskId: _taskId, ExitStatus: new ExitStatus(0, 0, true), "stderr", "stdout"))); var result = await func.Run(TestHttpRequestData.FromJson("POST", data)); Assert.Equal(HttpStatusCode.OK, result.StatusCode); var task = await Context.TaskOperations.SearchAll().SingleAsync(); // should be failed - it never started running Assert.Equal(TaskState.Stopping, task.State); Assert.Equal(ErrorCode.TASK_FAILED, task.Error?.Code); }
public async Async.Task Post_DeletesExistingNodeForMachineId() { await Context.InsertAll( new Node(PoolName.Parse("another-pool"), _machineId, _poolId, "1.0.0"), new Pool(_poolName, _poolId, Os.Linux, false, Architecture.x86_64, PoolState.Init, null)); var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentRegistration(Logger, auth, Context); var req = TestHttpRequestData.Empty("POST"); req.SetUrlParameter("machine_id", _machineId); req.SetUrlParameter("pool_name", _poolName); req.SetUrlParameter("scaleset_id", _scalesetId); var result = await func.Run(req); Assert.Equal(HttpStatusCode.OK, result.StatusCode); // there should only be one node, the old one with the same machineID was deleted var nodes = await Context.NodeOperations.SearchAll().ToListAsync(); var node = Assert.Single(nodes); Assert.Equal(_poolName, node.PoolName); }
public async Async.Task NodeStateUpdate_BecomingFree_StopsNode_IfMarkedForDeletion() { await Context.InsertAll( new Node(_poolName, _machineId, _poolId, _poolVersion, DeleteRequested : true)); var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentEvents(Logger, auth, Context); var data = new NodeStateEnvelope( MachineId: _machineId, Event: new NodeStateUpdate(NodeState.Free)); var result = await func.Run(TestHttpRequestData.FromJson("POST", data)); Assert.Equal(HttpStatusCode.OK, result.StatusCode); await Async.Task.WhenAll( Async.Task.Run(async() => { // the node should still be in init state: var node = await Context.NodeOperations.SearchAll().SingleAsync(); Assert.Equal(NodeState.Init, node.State); }), Async.Task.Run(async() => { // the node should be told to stop: var messages = await Context.NodeMessageOperations.SearchAll().ToListAsync(); Assert.Contains(messages, msg => msg.MachineId == _machineId && msg.Message.Stop == new StopNodeCommand()); })); }
public async Async.Task Post_SetsCorrectVersion() { await Context.InsertAll( new Pool(_poolName, _poolId, Os.Linux, false, Architecture.x86_64, PoolState.Init, null)); var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentRegistration(Logger, auth, Context); var req = TestHttpRequestData.Empty("POST"); req.SetUrlParameter("machine_id", _machineId); req.SetUrlParameter("pool_name", _poolName); req.SetUrlParameter("scaleset_id", _scalesetId); req.SetUrlParameter("version", "1.2.3"); var result = await func.Run(req); Assert.Equal(HttpStatusCode.OK, result.StatusCode); // should be one node with provided version var nodes = await Context.NodeOperations.SearchAll().ToListAsync(); var node = Assert.Single(nodes); Assert.Equal("1.2.3", node.Version); }
public async Async.Task RequiresAdmin(string method) { // config must be found await Context.InsertAll( new InstanceConfig(Context.ServiceConfiguration.OneFuzzInstanceName !)); // must be a user to auth var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); // override the found user credentials var userInfo = new UserInfo(ApplicationId: Guid.NewGuid(), ObjectId: Guid.NewGuid(), "upn"); Context.UserCredentials = new TestUserCredentials(Logger, Context.ConfigOperations, OneFuzzResult <UserInfo> .Ok(userInfo)); var req = new NodeGet(MachineId: _machineId); var func = new NodeFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.FromJson(method, req)); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); var err = BodyAs <Error>(result); Assert.Equal(ErrorCode.UNAUTHORIZED, err.Code); Assert.Contains("pool modification disabled", err.Errors?.Single()); }
public async Async.Task Download_RedirectsToResult_WithLocationHeader() { // set up a file to download var container = GetContainerClient("xxx"); await container.CreateAsync(); await container.UploadBlobAsync("yyy", new BinaryData("content")); var req = TestHttpRequestData.Empty("GET"); var url = new UriBuilder(req.Url) { Query = "container=xxx&filename=yyy" }.Uri; req.SetUrl(url); var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var func = new Download(auth, Context); var result = await func.Run(req); Assert.Equal(HttpStatusCode.Found, result.StatusCode); var location = Assert.Single(result.Headers.GetValues("Location")); // check that the SAS URI works using var client = new HttpClient(); var blobContent = await client.GetStringAsync(location); Assert.Equal("content", blobContent); }
public async Async.Task CanPost_New() { var meta = new Dictionary <string, string> { { "some", "value" } }; var containerName = "test"; var msg = TestHttpRequestData.FromJson("POST", new ContainerCreate(new Container(containerName), meta)); var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var func = new ContainersFunction(Logger, auth, Context); var result = await func.Run(msg); Assert.Equal(HttpStatusCode.OK, result.StatusCode); // container should be created with metadata: var client = GetContainerClient(containerName); Assert.True(await client.ExistsAsync()); var props = await client.GetPropertiesAsync(); Assert.Equal(meta, props.Value.Metadata); var response = BodyAs <ContainerInfo>(result); await AssertCanCRUD(response.SasUrl); }
public async Async.Task List_Existing() { var meta1 = new Dictionary <string, string> { { "key1", "value1" } }; var meta2 = new Dictionary <string, string> { { "key2", "value2" } }; await GetContainerClient("one").CreateIfNotExistsAsync(metadata: meta1); await GetContainerClient("two").CreateIfNotExistsAsync(metadata: meta2); var msg = TestHttpRequestData.Empty("GET"); // this means list all var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var func = new ContainersFunction(Logger, auth, Context); var result = await func.Run(msg); Assert.Equal(HttpStatusCode.OK, result.StatusCode); var list = BodyAs <ContainerInfoBase[]>(result); // other tests can run in parallel, so filter to just our containers: var cs = list.Where(ci => ci.Name.ContainerName.StartsWith(Context.ServiceConfiguration.OneFuzzStoragePrefix)).ToList(); Assert.Equal(2, cs.Count); // ensure correct metadata was returned. // these will be in order as "one"<"two" Assert.Equal(meta1, cs[0].Metadata); Assert.Equal(meta2, cs[1].Metadata); }
public async Async.Task Post_ChecksRequiredParameters(string parameterToSkip) { await Context.InsertAll( new Pool(_poolName, _poolId, Os.Linux, false, Architecture.x86_64, PoolState.Init, null)); var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentRegistration(Logger, auth, Context); var req = TestHttpRequestData.Empty("POST"); if (parameterToSkip != "machine_id") { req.SetUrlParameter("machine_id", _machineId); } if (parameterToSkip != "pool_name") { req.SetUrlParameter("pool_name", _poolName); } var result = await func.Run(req); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); var err = BodyAs <Error>(result); Assert.Equal(ErrorCode.INVALID_REQUEST, err.Code); Assert.Equal($"'{parameterToSkip}' query parameter must be provided", err.Errors?.Single()); }
public async Async.Task WorkerDone_WithSuccessfulResult_ForRunningTask_MarksTaskAsStopping() { await Context.InsertAll( new Node(_poolName, _machineId, _poolId, _poolVersion), // task state is running new Task(_jobId, _taskId, TaskState.Running, Os.Linux, new TaskConfig(_jobId, null, new TaskDetails(TaskType.Coverage, 100)))); var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentEvents(Logger, auth, Context); var data = new NodeStateEnvelope( MachineId: _machineId, Event: new WorkerEvent(Done: new WorkerDoneEvent( TaskId: _taskId, ExitStatus: new ExitStatus(Code: 0, Signal: 0, Success: true), "stderr", "stdout"))); var result = await func.Run(TestHttpRequestData.FromJson("POST", data)); Assert.Equal(HttpStatusCode.OK, result.StatusCode); var task = await Context.TaskOperations.SearchAll().SingleAsync(); // should have transitioned into stopping Assert.Equal(TaskState.Stopping, task.State); }
public async Async.Task UserAuthorization_IsRequired(string method, RequestType authType) { var auth = new TestEndpointAuthorization(authType, Logger, Context); var func = new ScalesetFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.Empty(method)); Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode); }
public async Async.Task TestInfo_WithAgentCredentials_IsRejected() { var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new Info(auth, Context); var result = await func.Run(TestHttpRequestData.Empty("GET")); Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode); }
public async Async.Task AgentAuthorization_IsAccepted() { var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentCommands(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.Empty("GET")); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); // BadRequest due to no body, not Unauthorized }
public async Async.Task AgentAuthorization_IsAccepted() { var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentRegistration(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.Empty("POST")); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); // BadRequest due to missing parameters, not Unauthorized }
public async Async.Task UserAuthorization_IsNotPermitted() { var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var func = new AgentCommands(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.Empty("GET")); Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode); }
public async Async.Task Authorization_IsRequired() { var auth = new TestEndpointAuthorization(RequestType.NoAuthorization, Logger, Context); var func = new AgentRegistration(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.Empty("POST")); Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode); }
public async Async.Task Search_SpecificPool_ByName_NotFound_ReturnsBadRequest() { var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var req = new PoolSearch(Name: _poolName); var func = new PoolFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.FromJson("GET", req)); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); }
public async Async.Task Get_Missing_Fails() { var msg = TestHttpRequestData.FromJson("GET", new ContainerGet(new Container("container"))); var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var func = new ContainersFunction(Logger, auth, Context); var result = await func.Run(msg); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); }
public async Async.Task Search_SpecificNode_NotFound_ReturnsNotFound() { var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var req = new NodeSearch(MachineId: _machineId); var func = new NodeFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.FromJson("GET", req)); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); }
public async Async.Task Search_AllScalesets_ReturnsEmptyIfNoneFound() { var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var req = new ScalesetSearch(); var func = new ScalesetFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.FromJson("GET", req)); Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal("[]", BodyAsString(result)); }
public async Async.Task Search_MultipleNodes_CanFindNone() { var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var req = new NodeSearch(); var func = new NodeFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.FromJson("GET", req)); Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal("[]", BodyAsString(result)); }
public async Async.Task Download_WithoutAuthorization_IsRejected() { var auth = new TestEndpointAuthorization(RequestType.NoAuthorization, Logger, Context); var func = new Download(auth, Context); var result = await func.Run(TestHttpRequestData.Empty("GET")); Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode); var err = BodyAs <Error>(result); Assert.Equal(ErrorCode.UNAUTHORIZED, err.Code); }
public async Async.Task Search_SpecificScaleset_ReturnsErrorIfNoneFound() { var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var req = new ScalesetSearch(ScalesetId: Guid.NewGuid()); var func = new ScalesetFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.FromJson("GET", req)); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); var err = BodyAs <Error>(result); Assert.Equal("unable to find scaleset", err.Errors?.Single()); }
public async Async.Task WithoutAuthorization_IsRejected(string method) { var auth = new TestEndpointAuthorization(RequestType.NoAuthorization, Logger, Context); var func = new ContainersFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.Empty(method)); Assert.Equal(HttpStatusCode.Unauthorized, result.StatusCode); var err = BodyAs <Error>(result); Assert.Equal(ErrorCode.UNAUTHORIZED, err.Code); }
public async Async.Task WorkerEventMustHaveDoneOrRunningSet() { var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentEvents(Logger, auth, Context); var data = new NodeStateEnvelope( MachineId: Guid.NewGuid(), Event: new WorkerEvent(null, null)); var result = await func.Run(TestHttpRequestData.FromJson("POST", data)); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); }
public async Async.Task Search_SpecificPool_ByState_NotFound_ReturnsEmptyResult() { var auth = new TestEndpointAuthorization(RequestType.User, Logger, Context); var req = new PoolSearch(State: new List <PoolState> { PoolState.Init }); var func = new PoolFunction(Logger, auth, Context); var result = await func.Run(TestHttpRequestData.FromJson("GET", req)); Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal("[]", BodyAsString(result)); }
public async Async.Task NodeStateUpdate_ForMissingNode_IgnoresEvent() { // nothing present in storage var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentEvents(Logger, auth, Context); var data = new NodeStateEnvelope( MachineId: _machineId, Event: new NodeStateUpdate(NodeState.Init)); var result = await func.Run(TestHttpRequestData.FromJson("POST", data)); Assert.Equal(HttpStatusCode.OK, result.StatusCode); }
public async Task ReadAsJsonAsync_SerializerOverload_AppliesSerializer() { FunctionContext context = CreateContext(); var body = "{\"jsonnetname\":\"Test\",\"jsonnetint\":42}"; var stream = new MemoryStream(Encoding.UTF8.GetBytes(body)); var request = new TestHttpRequestData(context, body: stream); RequestPoco result = await request.ReadFromJsonAsync <RequestPoco>(new NewtonsoftJsonObjectSerializer()); Assert.NotNull(result); Assert.Equal("Test", result.Name); Assert.Equal(42, result.SomeInt); }
public async Task ReadAsJsonAsync_SimpleOverload_AppliesDefaults() { FunctionContext context = CreateContext(); var body = "{\"textjsonname\":\"Test\",\"textjsonint\":42}"; var stream = new MemoryStream(Encoding.UTF8.GetBytes(body)); var request = new TestHttpRequestData(context, body: stream); RequestPoco result = await request.ReadFromJsonAsync <RequestPoco>(); Assert.NotNull(result); Assert.Equal("Test", result.Name); Assert.Equal(42, result.SomeInt); }
public async Async.Task Get_UrlParameterRequired() { var auth = new TestEndpointAuthorization(RequestType.Agent, Logger, Context); var func = new AgentRegistration(Logger, auth, Context); var req = TestHttpRequestData.Empty("GET"); var result = await func.Run(req); Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); var body = BodyAs <Error>(result); Assert.Equal(ErrorCode.INVALID_REQUEST, body.Code); Assert.Equal("'machine_id' query parameter must be provided", body.Errors?.Single()); }