Skip to content

Commit

Permalink
Fix #313: CometTask support (#315)
Browse files Browse the repository at this point in the history
* WIP

First implementation at DAL level

* Missing tests for CDP4ServicesDal

* Fix CometTaskRoute

* Unit tests using MockHttp

* Fix SQ code smells

* Session returns CometTask and not uses CDPMessageBus for CometTask
  • Loading branch information
antoineatstariongroup authored Mar 5, 2024
1 parent c021d7c commit 3146b82
Show file tree
Hide file tree
Showing 27 changed files with 1,976 additions and 89 deletions.
6 changes: 6 additions & 0 deletions CDP4-SDK.sln
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CDP4ServicesMessaging", "CD
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CDP4ServicesMessaging.Tests", "CDP4ServicesMessaging.Tests\CDP4ServicesMessaging.Tests.csproj", "{210B96F7-2695-4750-8808-D895C8C2E303}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CDP4DalCommon", "CDP4DalCommon\CDP4DalCommon.csproj", "{E7CDB217-8442-4FD4-8E87-F4A8BFE9622A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -203,6 +205,10 @@ Global
{210B96F7-2695-4750-8808-D895C8C2E303}.Debug|Any CPU.Build.0 = Debug|Any CPU
{210B96F7-2695-4750-8808-D895C8C2E303}.Release|Any CPU.ActiveCfg = Release|Any CPU
{210B96F7-2695-4750-8808-D895C8C2E303}.Release|Any CPU.Build.0 = Release|Any CPU
{E7CDB217-8442-4FD4-8E87-F4A8BFE9622A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7CDB217-8442-4FD4-8E87-F4A8BFE9622A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7CDB217-8442-4FD4-8E87-F4A8BFE9622A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7CDB217-8442-4FD4-8E87-F4A8BFE9622A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
82 changes: 82 additions & 0 deletions CDP4Dal.NetCore.Tests/DAL/DalTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace CDP4Dal.Tests.DAL
using CDP4Dal.Operations;
using CDP4Dal.DAL;

using CDP4DalCommon.Tasks;

using NUnit.Framework;

using Thing = CDP4Common.DTO.Thing;
Expand Down Expand Up @@ -339,6 +341,25 @@ public override Task<IEnumerable<Thing>> Write(OperationContainer operationConta
throw new System.NotImplementedException();
}

/// <summary>
/// Write all the <see cref="Operation"/>s from an <see cref="OperationContainer"/> asynchronously for a possible long running task.
/// </summary>
/// <param name="operationContainer">
/// The provided <see cref="OperationContainer"/> to write
/// </param>
/// <param name="waitTime">The maximum time that we allow the server before responding. If the write operation takes more time
/// than the provided <paramref name="waitTime"/>, a <see cref="CometTask"/></param>
/// <param name="files">
/// The path to the files that need to be uploaded. If <paramref name="files"/> is null, then no files are to be uploaded
/// </param>
/// <returns>
/// A list of <see cref="Thing"/>s that has been created or updated since the last Read or Write operation.
/// </returns>
public override Task<LongRunningTaskResult> Write(OperationContainer operationContainer, int waitTime, IEnumerable<string> files = null)
{
throw new System.NotImplementedException();
}

public override Task<IEnumerable<Thing>> Read<T>(T thing, CancellationToken token, IQueryAttributes attributes = null)
{
throw new System.NotImplementedException();
Expand All @@ -354,6 +375,27 @@ public override Task<IEnumerable<EngineeringModel>> Read(IEnumerable<Engineering
throw new NotImplementedException();
}

/// <summary>
/// Reads the <see cref="CometTask" /> identified by the provided <see cref="System.Guid" />
/// </summary>
/// <param name="id">The <see cref="CometTask" /> identifier</param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken" /></param>
/// <returns>The read <see cref="CometTask" /></returns>
public override Task<CometTask> ReadCometTask(Guid id, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

/// <summary>
/// Reads all <see cref="CometTask" /> available for the current logged <see cref="Person" />
/// </summary>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken" /></param>
/// <returns>All available <see cref="CometTask" /></returns>
public override Task<IEnumerable<CometTask>> ReadCometTasks(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

public override Task<byte[]> ReadFile(Thing localFile, CancellationToken cancellationToken)
{
throw new NotImplementedException();
Expand Down Expand Up @@ -419,6 +461,25 @@ public override Task<IEnumerable<Thing>> Write(OperationContainer operationConta
throw new NotImplementedException();
}

/// <summary>
/// Write all the <see cref="Operation"/>s from an <see cref="OperationContainer"/> asynchronously for a possible long running task.
/// </summary>
/// <param name="operationContainer">
/// The provided <see cref="OperationContainer"/> to write
/// </param>
/// <param name="waitTime">The maximum time that we allow the server before responding. If the write operation takes more time
/// than the provided <paramref name="waitTime"/>, a <see cref="CometTask"/></param>
/// <param name="files">
/// The path to the files that need to be uploaded. If <paramref name="files"/> is null, then no files are to be uploaded
/// </param>
/// <returns>
/// A list of <see cref="Thing"/>s that has been created or updated since the last Read or Write operation.
/// </returns>
public override Task<LongRunningTaskResult> Write(OperationContainer operationContainer, int waitTime, IEnumerable<string> files = null)
{
throw new System.NotImplementedException();
}

public override Task<IEnumerable<Thing>> Read<T>(T thing, CancellationToken token, IQueryAttributes attributes = null)
{
throw new NotImplementedException();
Expand All @@ -434,6 +495,27 @@ public override Task<IEnumerable<EngineeringModel>> Read(IEnumerable<Engineering
throw new NotImplementedException();
}

/// <summary>
/// Reads the <see cref="CometTask" /> identified by the provided <see cref="System.Guid" />
/// </summary>
/// <param name="id">The <see cref="CometTask" /> identifier</param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken" /></param>
/// <returns>The read <see cref="CometTask" /></returns>
public override Task<CometTask> ReadCometTask(Guid id, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

/// <summary>
/// Reads all <see cref="CometTask" /> available for the current logged <see cref="Person" />
/// </summary>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken" /></param>
/// <returns>All available <see cref="CometTask" /></returns>
public override Task<IEnumerable<CometTask>> ReadCometTasks(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

public override Task<byte[]> ReadFile(Thing localFile, CancellationToken cancellationToken)
{
throw new NotImplementedException();
Expand Down
181 changes: 181 additions & 0 deletions CDP4Dal.NetCore.Tests/SessionTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ namespace CDP4Dal.NetCore.Tests
using CDP4Dal.Operations;
using CDP4Dal.DAL;
using CDP4Dal.Events;
using CDP4Dal.Exceptions;

using CDP4DalCommon.Tasks;

using Moq;

Expand All @@ -48,9 +51,11 @@ namespace CDP4Dal.NetCore.Tests
using DomainOfExpertise = CDP4Common.SiteDirectoryData.DomainOfExpertise;
using EngineeringModelSetup = CDP4Common.DTO.EngineeringModelSetup;
using ModelReferenceDataLibrary = CDP4Common.SiteDirectoryData.ModelReferenceDataLibrary;
using Person = CDP4Common.SiteDirectoryData.Person;
using SiteDirectory = CDP4Common.DTO.SiteDirectory;
using SiteReferenceDataLibrary = CDP4Common.SiteDirectoryData.SiteReferenceDataLibrary;
using TelephoneNumber = CDP4Common.SiteDirectoryData.TelephoneNumber;
using TextParameterType = CDP4Common.DTO.TextParameterType;
using Thing = CDP4Common.DTO.Thing;

/// <summary>
Expand Down Expand Up @@ -685,12 +690,148 @@ public void VerifyThatCancelWriteWorks()

this.mockedDal.Verify(x => x.Write(It.IsAny<OperationContainer>(), It.IsAny<IEnumerable<string>>()), Times.Exactly(0));
}

[Test]
public async Task VerifyCanReadCometTask()
{
var cometTaskId = Guid.NewGuid();

Assert.Multiple(() =>
{
Assert.That(this.session.ActivePerson, Is.Null);
Assert.That(() => this.session.ReadCometTask(cometTaskId), Throws.InvalidOperationException);
});

this.AssignActivePerson();

var returnedCometTask = new CometTask()
{
Id = cometTaskId
};

this.mockedDal.Setup(x => x.ReadCometTask(cometTaskId, It.IsAny<CancellationToken>())).ReturnsAsync(returnedCometTask);

var cometTask = await this.session.ReadCometTask(cometTaskId);

Assert.Multiple(() =>
{
Assert.That(cometTask, Is.Not.Null);
Assert.That(cometTask, Is.EqualTo(returnedCometTask));
Assert.That(this.session.CometTasks[cometTaskId], Is.EqualTo(returnedCometTask));
});

this.mockedDal.Setup(x => x.ReadCometTask(cometTaskId, It.IsAny<CancellationToken>())).Throws<OperationCanceledException>();
cometTask = await this.session.ReadCometTask(cometTaskId);

Assert.Multiple(() =>
{
Assert.That(cometTask, Is.EqualTo((CometTask)default));
Assert.That(this.session.CometTasks[cometTaskId], Is.EqualTo(returnedCometTask));
});

this.mockedDal.Setup(x => x.ReadCometTask(cometTaskId, It.IsAny<CancellationToken>())).Throws<DalReadException>();
Assert.That(() => this.session.ReadCometTask(cometTaskId), Throws.Exception.TypeOf<DalReadException>());
}

[Test]
public async Task VerifyCanReadCometTasks()
{
Assert.Multiple(() =>
{
Assert.That(this.session.ActivePerson, Is.Null);
Assert.That(() => this.session.ReadCometTasks(), Throws.InvalidOperationException);
});

this.AssignActivePerson();

var returnedCometTasks = new List<CometTask>()
{
new ()
{
Id = Guid.NewGuid()
},
new ()
{
Id = Guid.NewGuid()
},
};

this.mockedDal.Setup(x => x.ReadCometTasks(It.IsAny<CancellationToken>())).ReturnsAsync(returnedCometTasks);

var cometTasks = await this.session.ReadCometTasks();

Assert.Multiple(() =>
{
Assert.That(cometTasks, Is.Not.Empty);
Assert.That(cometTasks, Is.EquivalentTo(returnedCometTasks));
Assert.That(this.session.CometTasks, Has.Count.EqualTo(returnedCometTasks.Count));
});

this.mockedDal.Setup(x => x.ReadCometTasks(It.IsAny<CancellationToken>())).Throws<OperationCanceledException>();
cometTasks = await this.session.ReadCometTasks();

Assert.Multiple(() =>
{
Assert.That(cometTasks, Is.Empty);
Assert.That(this.session.CometTasks, Has.Count.EqualTo(returnedCometTasks.Count));
});

this.mockedDal.Setup(x => x.ReadCometTasks(It.IsAny<CancellationToken>())).Throws<DalReadException>();
Assert.That(() => this.session.ReadCometTasks(), Throws.Exception.TypeOf<DalReadException>());
}

[Test]
public async Task VerifyWritePossibleLongRunningTask()
{
var context = $"/SiteDirectory/{Guid.NewGuid()}";
this.AssignActivePerson();

this.mockedDal.Setup(x => x.Write(It.IsAny<OperationContainer>(), It.IsAny<int>(), It.IsAny<IEnumerable<string>>()))
.ReturnsAsync(new LongRunningTaskResult(new CometTask() { Id = Guid.Empty }));

var cometTask = await this.session.Write(new OperationContainer(context), 1);

Assert.Multiple(() =>
{
Assert.That(cometTask.HasValue, Is.True);
Assert.That(this.session.CometTasks, Is.Not.Empty);
});

this.mockedDal.Setup(x => x.Write(It.IsAny<OperationContainer>(), It.IsAny<int>(), It.IsAny<IEnumerable<string>>()))
.ReturnsAsync(new LongRunningTaskResult(new List<Thing>()
{
new TextParameterType()
{
Iid = Guid.NewGuid()
}
}));

cometTask = await this.session.Write(new OperationContainer(context), 1);

Assert.Multiple(() =>
{
Assert.That(cometTask.HasValue, Is.False);
Assert.That(this.session.CometTasks, Is.Not.Empty);
});

this.mockedDal.Setup(x => x.Write(It.IsAny<OperationContainer>(), It.IsAny<int>(), It.IsAny<IEnumerable<string>>()))
.ThrowsAsync(new DalReadException());

Assert.That(() =>this.session.Write(new OperationContainer(context), 1), Throws.Exception.TypeOf<DalReadException>());
}

private void AssignActivePerson()
{
var johnDoe = new Person(this.person.Iid, this.session.Assembler.Cache, this.uri) { ShortName = "John" };
this.session.GetType().GetProperty("ActivePerson")?.SetValue(this.session, johnDoe, null);
}
}

[DalExport("test dal", "test dal description", "1.1.0", DalType.Web)]
internal class TestDal : IDal
{
public Version SupportedVersion { get {return new Version(1, 0, 0);} }

public Version DalVersion { get {return new Version("1.1.0");} }
public IMetaDataProvider MetaDataProvider { get {return new MetaDataProvider();} }

Expand Down Expand Up @@ -735,6 +876,25 @@ public Task<IEnumerable<Thing>> Write(OperationContainer operationContainer, IEn
throw new NotImplementedException();
}

/// <summary>
/// Write all the <see cref="Operation"/>s from an <see cref="OperationContainer"/> asynchronously for a possible long running task.
/// </summary>
/// <param name="operationContainer">
/// The provided <see cref="OperationContainer"/> to write
/// </param>
/// <param name="waitTime">The maximum time that we allow the server before responding. If the write operation takes more time
/// than the provided <paramref name="waitTime"/>, a <see cref="CometTask"/></param>
/// <param name="files">
/// The path to the files that need to be uploaded. If <paramref name="files"/> is null, then no files are to be uploaded
/// </param>
/// <returns>
/// A list of <see cref="Thing"/>s that has been created or updated since the last Read or Write operation.
/// </returns>
public Task<LongRunningTaskResult> Write(OperationContainer operationContainer, int waitTime, IEnumerable<string> files = null)
{
throw new System.NotImplementedException();
}

/// <summary>
/// Reads the data related to the provided <see cref="Thing"/> from the data-source
/// </summary>
Expand Down Expand Up @@ -805,6 +965,27 @@ public Task<IEnumerable<EngineeringModel>> Read(IEnumerable<EngineeringModel> en
throw new NotImplementedException();
}

/// <summary>
/// Reads the <see cref="CometTask" /> identified by the provided <see cref="System.Guid" />
/// </summary>
/// <param name="id">The <see cref="CometTask" /> identifier</param>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken" /></param>
/// <returns>The read <see cref="CometTask" /></returns>
public Task<CometTask> ReadCometTask(Guid id, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

/// <summary>
/// Reads all <see cref="CometTask" /> available for the current logged <see cref="CDP4Common.DTO.Person" />
/// </summary>
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken" /></param>
/// <returns>All available <see cref="CometTask" /></returns>
public Task<IEnumerable<CometTask>> ReadCometTasks(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

public Task<byte[]> ReadFile(Thing localFile, CancellationToken cancellationToken)
{
throw new NotImplementedException();
Expand Down
Loading

0 comments on commit 3146b82

Please sign in to comment.