Skip to content

Commit

Permalink
- Add ServiceExtensions.GetPartition and SetPartition for alexmar…
Browse files Browse the repository at this point in the history
…shall132.
  • Loading branch information
LoekD authored and loekd committed Oct 27, 2018
1 parent 1dfa2ed commit aa324d4
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 41 deletions.
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -23,6 +23,9 @@ The VSTS Agent lagged behind in Service Fabric SDK version, this caused runtime

## Release notes

- 3.4.1
- Add `ServiceExtensions.GetPartition` and `SetPartition` for alexmarshall132.

- 3.4.0
- Fix issue 70. Racing for a lock could result in incorrect timeout. Thanks shushengli & likevi-MSFT.

Expand Down
61 changes: 61 additions & 0 deletions src/ServiceFabric.Mocks/MockStatefulServicePartition.cs
@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Fabric;
using System.Fabric.Health;

namespace ServiceFabric.Mocks
{
/// <inheritdoc />
public class MockStatefulServicePartition : IStatefulServicePartition
{
/// <inheritdoc />
public PartitionAccessStatus ReadStatus { get; set; }

/// <inheritdoc />
public PartitionAccessStatus WriteStatus { get; set; }

/// <inheritdoc />
public ServicePartitionInformation PartitionInfo { get; set; }

/// <inheritdoc />
public void ReportLoad(IEnumerable<LoadMetric> metrics)
{
}

/// <inheritdoc />
public void ReportFault(FaultType faultType)
{
}

/// <inheritdoc />
public void ReportMoveCost(MoveCost moveCost)
{
}

/// <inheritdoc />
public void ReportPartitionHealth(HealthInformation healthInfo)
{
}

/// <inheritdoc />
public void ReportPartitionHealth(HealthInformation healthInfo, HealthReportSendOptions sendOptions)
{
}

/// <inheritdoc />
public FabricReplicator CreateReplicator(IStateProvider stateProvider, ReplicatorSettings replicatorSettings)
{
return null;
}

/// <inheritdoc />
public void ReportReplicaHealth(HealthInformation healthInfo)
{
}

/// <inheritdoc />
public void ReportReplicaHealth(HealthInformation healthInfo, HealthReportSendOptions sendOptions)
{
}

}
}
48 changes: 48 additions & 0 deletions src/ServiceFabric.Mocks/MockStatelessServicePartition.cs
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Fabric;
using System.Fabric.Health;

namespace ServiceFabric.Mocks
{
/// <inheritdoc />
public class MockStatelessServicePartition : IStatelessServicePartition
{
/// <inheritdoc />
public void ReportLoad(IEnumerable<LoadMetric> metrics)
{
}

/// <inheritdoc />
public void ReportFault(FaultType faultType)
{
}

/// <inheritdoc />
public void ReportMoveCost(MoveCost moveCost)
{
}

/// <inheritdoc />
public void ReportPartitionHealth(HealthInformation healthInfo)
{
}

/// <inheritdoc />
public void ReportPartitionHealth(HealthInformation healthInfo, HealthReportSendOptions sendOptions)
{
}

/// <inheritdoc />
public ServicePartitionInformation PartitionInfo { get; set; }

/// <inheritdoc />
public void ReportInstanceHealth(HealthInformation healthInfo)
{
}

/// <inheritdoc />
public void ReportInstanceHealth(HealthInformation healthInfo, HealthReportSendOptions sendOptions)
{
}
}
}
61 changes: 58 additions & 3 deletions src/ServiceFabric.Mocks/ServiceExtensions.cs
@@ -1,11 +1,12 @@
using System;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;
using System;
using System.Collections.Generic;
using System.Fabric;
using System.Globalization;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;

namespace ServiceFabric.Mocks
{
Expand Down Expand Up @@ -144,6 +145,60 @@ public static IEnumerable<ServiceInstanceListener> InvokeCreateServiceInstanceLi
return (IEnumerable<ServiceInstanceListener>)method.Invoke(service, null);
}

/// <summary>
/// Gets the partition info of the provided <paramref name="service"/>.
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
public static IStatefulServicePartition GetPartition(this StatefulServiceBase service)
{
if (service == null) throw new ArgumentNullException(nameof(service));
//protected IStatefulServicePartition Partition { get; private set; }
var propertyInfo = typeof(StatefulServiceBase).GetProperty("Partition", BindingFlags.Instance | BindingFlags.NonPublic);
return (IStatefulServicePartition)propertyInfo?.GetValue(service, BindingFlags.Instance | BindingFlags.NonPublic, null, null, CultureInfo.InvariantCulture);
}

/// <summary>
/// Sets the partition info of the provided <paramref name="service"/>.
/// </summary>
/// <param name="partition">partition to set</param>
/// <param name="service"></param>
/// <returns></returns>
public static void SetPartition(this StatefulServiceBase service, IStatefulServicePartition partition)
{
if (service == null) throw new ArgumentNullException(nameof(service));
//protected IStatefulServicePartition Partition { get; private set; }
var propertyInfo = typeof(StatefulServiceBase).GetProperty("Partition", BindingFlags.Instance | BindingFlags.NonPublic);
propertyInfo?.SetValue(service, partition, BindingFlags.Instance | BindingFlags.NonPublic, null, null, CultureInfo.InvariantCulture);
}

/// <summary>
/// Gets the partition info of the provided <paramref name="service"/>.
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
public static IStatelessServicePartition GetPartition(this StatelessService service)
{
if (service == null) throw new ArgumentNullException(nameof(service));
//protected IStatelessServicePartition Partition { get; private set; }
var propertyInfo = typeof(StatelessService).GetProperty("Partition", BindingFlags.Instance | BindingFlags.NonPublic);
return (IStatelessServicePartition)propertyInfo?.GetValue(service, BindingFlags.Instance | BindingFlags.NonPublic, null, null, CultureInfo.InvariantCulture);
}

/// <summary>
/// Sets the partition info of the provided <paramref name="service"/>.
/// </summary>
/// <param name="service"></param>
/// <param name="partition">partition to set</param>
/// <returns></returns>
public static void SetPartition(this StatelessService service, IStatelessServicePartition partition)
{
if (service == null) throw new ArgumentNullException(nameof(service));
//protected IStatelessServicePartition Partition { get; private set; }
var propertyInfo = typeof(StatelessService).GetProperty("Partition", BindingFlags.Instance | BindingFlags.NonPublic);
propertyInfo?.SetValue(service, partition, BindingFlags.Instance | BindingFlags.NonPublic, null, null, CultureInfo.InvariantCulture);
}

/// <summary>
/// Finds non private instance method on <paramref name="service"/> by name.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceFabric.Mocks/ServiceFabric.Mocks.csproj
Expand Up @@ -4,7 +4,7 @@
<Description>ServiceFabric.Mocks contains many mocks and helper classes to facilitate and simplify unit testing of your Service Fabric Actor and Service projects.</Description>
<Copyright>2018</Copyright>
<AssemblyTitle>ServiceFabric.Mocks</AssemblyTitle>
<VersionPrefix>3.4.0</VersionPrefix>
<VersionPrefix>3.4.1</VersionPrefix>
<Authors>Loek Duys</Authors>
<TargetFrameworks>net452;net46;netstandard2.0</TargetFrameworks>
<PlatformTarget>x64</PlatformTarget>
Expand Down
@@ -1,40 +1,41 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Fabric;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ServiceFabric.Mocks.Tests.Services;

namespace ServiceFabric.Mocks.Tests.MocksTests
{
[TestClass]
[TestClass]
public class MockStatefulServiceContextFactoryTests
{
[TestMethod]
public void TestDefaultServiceUri()
{
var instance = MockStatefulServiceContextFactory.Default;
[TestMethod]
public void TestDefaultServiceUri()
{
var instance = MockStatefulServiceContextFactory.Default;

Assert.IsInstanceOfType(instance, typeof(StatefulServiceContext));
Assert.AreEqual(new Uri(MockStatefulServiceContextFactory.ServiceName), instance.ServiceName);
Assert.AreEqual(MockStatefulServiceContextFactory.ServiceTypeName, instance.ServiceTypeName);
}
Assert.IsInstanceOfType(instance, typeof(StatefulServiceContext));
Assert.AreEqual(new Uri(MockStatefulServiceContextFactory.ServiceName), instance.ServiceName);
Assert.AreEqual(MockStatefulServiceContextFactory.ServiceTypeName, instance.ServiceTypeName);
}

[TestMethod]
public void TestCustom()
{
var newUri = new Uri("fabric:/MockApp/OtherMockStatefulService");
var serviceTypeName = "OtherMockServiceType";
var partitionId = Guid.NewGuid();
var replicaId = long.MaxValue;
var context = new MockCodePackageActivationContext("fabric:/MyApp", "MyAppType", "Code", "Ver", "Context", "Log", "Temp", "Work", "Man", "ManVer");
[TestMethod]
public void TestCustom()
{
var newUri = new Uri("fabric:/MockApp/OtherMockStatefulService");
var serviceTypeName = "OtherMockServiceType";
var partitionId = Guid.NewGuid();
var replicaId = long.MaxValue;
var context = new MockCodePackageActivationContext("fabric:/MyApp", "MyAppType", "Code", "Ver", "Context", "Log", "Temp", "Work", "Man", "ManVer");

var instance = MockStatefulServiceContextFactory.Create(context, serviceTypeName, newUri, partitionId, replicaId);
var instance = MockStatefulServiceContextFactory.Create(context, serviceTypeName, newUri, partitionId, replicaId);

Assert.IsInstanceOfType(instance, typeof(StatefulServiceContext));
Assert.AreEqual(context, instance.CodePackageActivationContext);
Assert.AreEqual(newUri, instance.ServiceName);
Assert.AreEqual(serviceTypeName, instance.ServiceTypeName);
Assert.AreEqual(partitionId, instance.PartitionId);
Assert.AreEqual(replicaId, instance.ReplicaId);
Assert.AreEqual(replicaId, instance.ReplicaOrInstanceId);
}
}
Assert.IsInstanceOfType(instance, typeof(StatefulServiceContext));
Assert.AreEqual(context, instance.CodePackageActivationContext);
Assert.AreEqual(newUri, instance.ServiceName);
Assert.AreEqual(serviceTypeName, instance.ServiceTypeName);
Assert.AreEqual(partitionId, instance.PartitionId);
Assert.AreEqual(replicaId, instance.ReplicaId);
Assert.AreEqual(replicaId, instance.ReplicaOrInstanceId);
}
}
}
Expand Up @@ -85,7 +85,33 @@ public void TestInvokeInvokeCreateServiceReplicaListeners()
Assert.IsInstanceOfType(result, typeof(ServiceReplicaListener[]));
}

[TestMethod]
public void TestStatefulServiceWithMockPartition()
{
var partition = new MockStatefulServicePartition();
var partitionInfo = MockQueryPartitionFactory.CreateIntPartitonInfo();
partition.PartitionInfo = partitionInfo;
var statefulServiceContext = MockStatefulServiceContextFactory.Default;

var sut = new NestedStatefulService(statefulServiceContext);
sut.SetPartition(partition);

Assert.AreEqual(partitionInfo, sut.GetPartition().PartitionInfo);
}

[TestMethod]
public void TestStatelessServiceWithMockPartition()
{
var partition = new MockStatelessServicePartition();
var partitionInfo = MockQueryPartitionFactory.CreateSingletonPartitonInfo();
partition.PartitionInfo = partitionInfo;
var statelessServiceContext = MockStatelessServiceContextFactory.Default;

var sut = new NestedStatelessService(statelessServiceContext);
sut.SetPartition(partition);

Assert.AreEqual(partitionInfo, sut.GetPartition().PartitionInfo);
}
private class NestedStatelessService : StatelessService
{
public bool OnOpenCalled { get; private set; }
Expand Down
15 changes: 7 additions & 8 deletions test/ServiceFabric.Mocks.Tests/Services/MyStatefulService.cs
@@ -1,13 +1,12 @@
using System.Fabric;
using System.Threading.Tasks;
using Microsoft.ServiceFabric.Data;
using Microsoft.ServiceFabric.Data;
using Microsoft.ServiceFabric.Data.Collections;
using Microsoft.ServiceFabric.Services.Runtime;
using Microsoft.ServiceFabric.Data.Notifications;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading;
using System.Collections.Generic;
using System.Fabric;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ServiceFabric.Mocks.Tests.Services
{
Expand Down Expand Up @@ -116,8 +115,8 @@ protected override async Task RunAsync(CancellationToken cancellationToken)
var item = new KeyValuePair<string, Payload>(enumerator.Current.Key, new Payload(enumerator.Current.Value.Content));
_cache.AddOrUpdate(item.Key, item.Value, (k, v) => item.Value);
}
}
}
}
}
}
else
{
Expand Down

0 comments on commit aa324d4

Please sign in to comment.