diff --git a/Test/TaskHubStressTest/.nuget/NuGet.Config b/Test/TaskHubStressTest/.nuget/NuGet.Config new file mode 100644 index 000000000..67f8ea046 --- /dev/null +++ b/Test/TaskHubStressTest/.nuget/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Test/TaskHubStressTest/.nuget/NuGet.targets b/Test/TaskHubStressTest/.nuget/NuGet.targets new file mode 100644 index 000000000..83fe90601 --- /dev/null +++ b/Test/TaskHubStressTest/.nuget/NuGet.targets @@ -0,0 +1,136 @@ + + + + $(MSBuildProjectDirectory)\..\ + + + false + + + false + + + true + + + false + + + + + + + + + + + $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) + $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) + + + + + $(SolutionDir).nuget + packages.config + + + + + $(NuGetToolsPath)\NuGet.exe + @(PackageSource) + + "$(NuGetExePath)" + mono --runtime=v4.0.30319 $(NuGetExePath) + + $(TargetDir.Trim('\\')) + + -RequireConsent + -NonInteractive + + "$(SolutionDir) " + "$(SolutionDir)" + + + $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) + $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols + + + + RestorePackages; + $(BuildDependsOn); + + + + + $(BuildDependsOn); + BuildPackage; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Test/TaskHubStressTest/TaskHubStressTest.sln b/Test/TaskHubStressTest/TaskHubStressTest.sln new file mode 100644 index 000000000..8c48c00d7 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest.sln @@ -0,0 +1,33 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaskHubStressTest", "TaskHubStressTest\TaskHubStressTest.csproj", "{96980359-8003-4500-B97B-949A7FE01F31}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{3EB529F2-51AE-42CE-9560-706DB5B2C178}" + ProjectSection(SolutionItems) = preProject + .nuget\NuGet.Config = .nuget\NuGet.Config + .nuget\NuGet.exe = .nuget\NuGet.exe + .nuget\NuGet.targets = .nuget\NuGet.targets + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Framework", "..\..\Framework\Framework.csproj", "{6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {96980359-8003-4500-B97B-949A7FE01F31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96980359-8003-4500-B97B-949A7FE01F31}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96980359-8003-4500-B97B-949A7FE01F31}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96980359-8003-4500-B97B-949A7FE01F31}.Release|Any CPU.Build.0 = Release|Any CPU + {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Test/TaskHubStressTest/TaskHubStressTest/App.config b/Test/TaskHubStressTest/TaskHubStressTest/App.config new file mode 100644 index 000000000..9a4e3d923 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/App.config @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestration.cs b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestration.cs new file mode 100644 index 000000000..290462516 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestration.cs @@ -0,0 +1,33 @@ +namespace TaskHubStressTest +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using DurableTask; + + public class DriverOrchestration : TaskOrchestration + { + public override async Task RunTask(OrchestrationContext context, DriverOrchestrationData data) + { + int result = 0; + List> results = new List>(); + int i = 0; + for (; i < data.NumberOfParallelTasks; i++) + { + results.Add(context.CreateSubOrchestrationInstance(typeof(TestOrchestration), data.SubOrchestrationData)); + } + + int[] counters = await Task.WhenAll(results.ToArray()); + result = counters.Max(); + + if (data.NumberOfIteration > 0) + { + data.NumberOfIteration--; + context.ContinueAsNew(data); + } + + return result; + } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestrationData.cs b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestrationData.cs new file mode 100644 index 000000000..ecf8dfc91 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestrationData.cs @@ -0,0 +1,9 @@ +namespace TaskHubStressTest +{ + public class DriverOrchestrationData + { + public int NumberOfParallelTasks { get; set; } + public int NumberOfIteration { get; set; } + public TestOrchestrationData SubOrchestrationData { get; set; } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/Options.cs b/Test/TaskHubStressTest/TaskHubStressTest/Options.cs new file mode 100644 index 000000000..c611d15d0 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/Options.cs @@ -0,0 +1,40 @@ +namespace TaskHubStressTest +{ + using CommandLine; + using CommandLine.Text; + using System.Text; + + class Options + { + [Option('c', "create-hub", DefaultValue = false, + HelpText = "Create Orchestration Hub.")] + public bool CreateHub { get; set; } + + [Option('s', "start-instance", DefaultValue = null, + HelpText = "Start Driver Instance")] + public string StartInstance { get; set; } + + [Option('i', "instance-id", + HelpText = "Instance id for new orchestration instance.")] + public string InstanceId { get; set; } + + [HelpOption] + public string GetUsage() + { + // this without using CommandLine.Text + // or using HelpText.AutoBuild + + var help = new HelpText + { + Heading = new HeadingInfo("TaskHubStressTest", "1.0"), + AdditionalNewLineAfterOption = true, + AddDashesToOption = true + }; + help.AddPreOptionsLine("Usage: TaskHubStressTest.exe -c"); + help.AddPreOptionsLine("Usage: TaskHubStressTest.exe -c -s "); + help.AddPreOptionsLine("Usage: TaskHubStressTest.exe -i "); + help.AddOptions(this); + return help; + } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationConsoleTraceListener.cs b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationConsoleTraceListener.cs new file mode 100644 index 000000000..60360eac5 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationConsoleTraceListener.cs @@ -0,0 +1,38 @@ +namespace TaskHubStressTest +{ + using System; + using System.Linq; + using System.Diagnostics; + + class OrchestrationConsoleTraceListener : ConsoleTraceListener + { + public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) + { + try + { + var dict = message.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) + .Select(part => part.Split('=')) + .ToDictionary(split => split[0], split => split[1]); + string iid; + if (dict.TryGetValue("iid", out iid)) + { + string toWrite = string.Format("[{0} {1}] {2}", DateTime.Now, iid, dict["msg"]); + Console.WriteLine(toWrite); + Debug.WriteLine(toWrite); + } + else + { + string toWrite = string.Format("[{0}] {1}", DateTime.Now, dict["msg"]); + Console.WriteLine(toWrite); + Debug.WriteLine(toWrite); + } + } + catch (Exception exception) + { + string toWrite = string.Format("Exception while parsing trace: {0}\n\t", exception.Message, exception.StackTrace); + Console.WriteLine(toWrite); + Debug.WriteLine(toWrite); + } + } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationFileTraceListener.cs b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationFileTraceListener.cs new file mode 100644 index 000000000..af6068a52 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationFileTraceListener.cs @@ -0,0 +1,63 @@ +namespace TaskHubStressTest +{ + using System; + using System.Linq; + using System.Diagnostics; + + class OrchestrationFileTraceListener : TextWriterTraceListener + { + public OrchestrationFileTraceListener(string file) + : base(file) + { + } + + public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id) + { + base.TraceEvent(eventCache, source, eventType, id); + } + + public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) + { + string message = format; + try + { + if (args != null && args.Length > 0) + { + message = string.Format(format, args); + } + } + catch (Exception ex) + { + message = "msg=Cannot format message"; + } + + this.TraceEvent(eventCache, source, eventType, id, message); + } + + public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) + { + try + { + var dict = message.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) + .Select(part => part.Split('=')) + .ToDictionary(split => split[0], split => split[1]); + string iid; + if (dict.TryGetValue("iid", out iid)) + { + string toWrite = string.Format("[{0} {1}] {2}", DateTime.Now, iid, dict["msg"]); + base.WriteLine(toWrite); + } + else + { + string toWrite = string.Format("[{0}] {1}", DateTime.Now, dict["msg"]); + base.WriteLine(toWrite); + } + } + catch (Exception exception) + { + string toWrite = string.Format("Exception while parsing trace: {0}\n\t", exception.Message, exception.StackTrace); + base.WriteLine(toWrite); + } + } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/Program.cs b/Test/TaskHubStressTest/TaskHubStressTest/Program.cs new file mode 100644 index 000000000..f9946d9e9 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/Program.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DurableTask; + +namespace TaskHubStressTest +{ + class Program + { + static Options options = new Options(); + + static void Main(string[] args) + { + string tableConnectionString = ConfigurationManager.AppSettings["StorageConnectionString"]; + if (CommandLine.Parser.Default.ParseArgumentsStrict(args, options)) + { + string connectionString = ConfigurationManager.ConnectionStrings["Microsoft.ServiceBus.ConnectionString"].ConnectionString; + string taskHubName = ConfigurationManager.AppSettings["TaskHubName"]; + + TaskHubClient taskHubClient = new TaskHubClient(taskHubName, connectionString, tableConnectionString); + TaskHubWorkerSettings settings = new TaskHubWorkerSettings(); + settings.TaskOrchestrationDispatcherSettings.CompressOrchestrationState = bool.Parse(ConfigurationManager.AppSettings["CompressOrchestrationState"]); + settings.TaskActivityDispatcherSettings.MaxConcurrentActivities = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentActivities"]); + settings.TaskOrchestrationDispatcherSettings.MaxConcurrentOrchestrations = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentOrchestrations"]); + TaskHubWorker taskHub = new TaskHubWorker(taskHubName, connectionString, tableConnectionString, settings); + + if (options.CreateHub) + { + taskHub.CreateHub(); + } + + OrchestrationInstance instance = null; + string instanceId = options.StartInstance; + + if (!string.IsNullOrWhiteSpace(instanceId)) + { + instance = taskHubClient.CreateOrchestrationInstance(typeof(DriverOrchestration), instanceId, new DriverOrchestrationData + { + NumberOfIteration = int.Parse(ConfigurationManager.AppSettings["DriverOrchestrationIterations"]), + NumberOfParallelTasks = int.Parse(ConfigurationManager.AppSettings["DriverOrchestrationParallelTasks"]), + SubOrchestrationData = new TestOrchestrationData + { + NumberOfParallelTasks = int.Parse(ConfigurationManager.AppSettings["ChildOrchestrationParallelTasks"]), + NumberOfSerialTasks = int.Parse(ConfigurationManager.AppSettings["ChildOrchestrationSerialTasks"]), + MaxDelayInSeconds = int.Parse(ConfigurationManager.AppSettings["TestTaskMaxDelayInMinutes"]), + }, + }); + } + else + { + instance = new OrchestrationInstance { InstanceId = options.InstanceId }; + } + + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + + TestTask testTask = new TestTask(); + taskHub.AddTaskActivities(testTask); + taskHub.AddTaskOrchestrations(typeof(DriverOrchestration)); + taskHub.AddTaskOrchestrations(typeof(TestOrchestration)); + taskHub.Start(); + + int testTimeoutInSeconds = int.Parse(ConfigurationManager.AppSettings["TestTimeoutInSeconds"]); + OrchestrationState state = WaitForInstance(taskHubClient, instance, testTimeoutInSeconds); + stopWatch.Stop(); + Console.WriteLine("Orchestration Status: " + state.OrchestrationStatus.ToString()); + Console.WriteLine("Orchestration Result: " + state.Output); + Console.WriteLine("Counter: " + testTask.counter); + + TimeSpan totalTime = stopWatch.Elapsed; + string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", + totalTime.Hours, totalTime.Minutes, totalTime.Seconds, + totalTime.Milliseconds / 10); + Console.WriteLine("Total Time: " + elapsedTime); + + taskHub.Stop(); + } + + } + + public static OrchestrationState WaitForInstance(TaskHubClient taskHubClient, OrchestrationInstance instance, int timeoutSeconds) + { + OrchestrationStatus status = OrchestrationStatus.Running; + if (instance == null || string.IsNullOrWhiteSpace(instance.InstanceId)) + { + throw new ArgumentException("instance"); + } + + int sleepForSeconds = 30; + while (timeoutSeconds > 0) + { + try + { + var state = taskHubClient.GetOrchestrationState(instance.InstanceId); + if (state != null) status = state.OrchestrationStatus; + if (status == OrchestrationStatus.Running) + { + System.Threading.Thread.Sleep(sleepForSeconds * 1000); + timeoutSeconds -= sleepForSeconds; + } + else + { + // Session state deleted after completion + return state; + } + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Error retrieving state for instance [instanceId: '{0}', executionId: '{1}'].", instance.InstanceId, instance.ExecutionId)); + Console.WriteLine(ex.ToString()); + } + } + + throw new TimeoutException("Timeout expired: " + timeoutSeconds.ToString()); + } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/Properties/AssemblyInfo.cs b/Test/TaskHubStressTest/TaskHubStressTest/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..afe71842a --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TaskHubStressTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TaskHubStressTest")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d66d425c-6748-467d-83d1-b44945cc38c8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TaskHubStressTest.csproj b/Test/TaskHubStressTest/TaskHubStressTest/TaskHubStressTest.csproj new file mode 100644 index 000000000..17dbee575 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/TaskHubStressTest.csproj @@ -0,0 +1,111 @@ + + + + + Debug + AnyCPU + {96980359-8003-4500-B97B-949A7FE01F31} + Exe + Properties + TaskHubStressTest + TaskHubStressTest + v4.5 + 512 + ..\ + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll + + + ..\packages\ImpromptuInterface.6.2.2\lib\net40\ImpromptuInterface.dll + + + ..\packages\Microsoft.Data.Edm.5.2.0\lib\net40\Microsoft.Data.Edm.dll + + + ..\packages\Microsoft.Data.OData.5.2.0\lib\net40\Microsoft.Data.OData.dll + + + ..\packages\WindowsAzure.ServiceBus.2.2.4.0\lib\net40-full\Microsoft.ServiceBus.dll + + + ..\packages\Microsoft.WindowsAzure.ConfigurationManager.2.0.3\lib\net40\Microsoft.WindowsAzure.Configuration.dll + + + False + ..\packages\WindowsAzure.Storage.2.1.0.4\lib\net40\Microsoft.WindowsAzure.Storage.dll + + + ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll + + + + + + + + + ..\packages\System.Spatial.5.2.0\lib\net40\System.Spatial.dll + + + + + + + + {6f5d2ead-726d-4fe5-a575-aeb96d1cce37} + Microsoft.ServiceBus.DurableTask + + + + + + + + + + + + + + + + + + Designer + + + Designer + + + + + + \ No newline at end of file diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestration.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestration.cs new file mode 100644 index 000000000..11e7cff95 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestration.cs @@ -0,0 +1,43 @@ + +namespace TaskHubStressTest +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using DurableTask; + + public class TestOrchestration : TaskOrchestration + { + public override async Task RunTask(OrchestrationContext context, TestOrchestrationData data) + { + int result = 0; + List> results = new List>(); + int i = 0; + int j = 0; + for (; i < data.NumberOfParallelTasks; i++) + { + results.Add(context.ScheduleTask(typeof(TestTask), new TestTaskData + { + TaskId = "ParallelTask: " + i.ToString(), + MaxDelayInMinutes = data.MaxDelayInSeconds, + })); + } + + int[] counters = await Task.WhenAll(results.ToArray()); + result = counters.Max(); + + for (; j < data.NumberOfSerialTasks; j++) + { + int c = await context.ScheduleTask(typeof(TestTask), new TestTaskData + { + TaskId = "SerialTask" + (i + j).ToString(), + MaxDelayInMinutes = data.MaxDelayInSeconds, + }); + result = Math.Max(result, c); + } + + return result; + } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestrationData.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestrationData.cs new file mode 100644 index 000000000..98ae386ef --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestrationData.cs @@ -0,0 +1,9 @@ +namespace TaskHubStressTest +{ + public class TestOrchestrationData + { + public int NumberOfParallelTasks { get; set; } + public int NumberOfSerialTasks { get; set; } + public int MaxDelayInSeconds { get; set; } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestTask.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestTask.cs new file mode 100644 index 000000000..48997a560 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/TestTask.cs @@ -0,0 +1,32 @@ +namespace TaskHubStressTest +{ + using System; + using System.Threading; + using System.Threading.Tasks; + using DurableTask; + + public sealed class TestTask : AsyncTaskActivity + { + public int counter = 0; + + public TestTask() + { + } + + protected override async Task ExecuteAsync(TaskContext context, TestTaskData input) + { + int c = Interlocked.Increment(ref this.counter); + OrchestrationInstance instance = context.OrchestrationInstance; + Random random = new Random(); + int minutesToSleep = random.Next(0, input.MaxDelayInMinutes); + + Console.WriteLine(string.Format("[InstanceId: {0}, ExecutionId: {1}, TaskId: {2}, Counter: {3}] ---> Sleeping for '{4}'", + instance.InstanceId, instance.ExecutionId, input.TaskId, c, minutesToSleep)); + + await Task.Delay(TimeSpan.FromMinutes(minutesToSleep)); + + return c; + } + + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestTaskData.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestTaskData.cs new file mode 100644 index 000000000..86ef6210f --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/TestTaskData.cs @@ -0,0 +1,8 @@ +namespace TaskHubStressTest +{ + public class TestTaskData + { + public string TaskId { get; set; } + public int MaxDelayInMinutes { get; set; } + } +} diff --git a/Test/TaskHubStressTest/TaskHubStressTest/packages.config b/Test/TaskHubStressTest/TaskHubStressTest/packages.config new file mode 100644 index 000000000..485fd5596 --- /dev/null +++ b/Test/TaskHubStressTest/TaskHubStressTest/packages.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file