NuGet Perf, The Final Part – Load Testing – Setup
So, after talking so long about the perf issues, here is the final part of this series. In which we actually take this for a spin using Load Testing.
I built a Web API application to serve as the test bed. It has a RavenController, which looks like this:
public class RavenController : ApiController { private static IDocumentStore documentStore; public static IDocumentStore DocumentStore { get { if (documentStore == null) { lock (typeof (RavenController)) { if (documentStore != null) return documentStore; documentStore = new DocumentStore { Url = "http://localhost:8080", DefaultDatabase = "Nuget" }.Initialize(); IndexCreation.CreateIndexes(typeof (Packages_Search).Assembly, documentStore); } } return documentStore; } } public IDocumentSession DocumentSession { get; set; } public override async Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) { using (DocumentSession = DocumentStore.OpenSession()) { HttpResponseMessage result = await base.ExecuteAsync(controllerContext, cancellationToken); DocumentSession.SaveChanges(); return result; } } }
And now we have the following controllers:
public class PackagesController : RavenController { public IEnumerable<Packages_Search.ReduceResult> Get(int page = 0) { return DocumentSession.Query<Packages_Search.ReduceResult, Packages_Search>() .Where(x=>x.IsPrerelease == false) .OrderByDescending(x=>x.DownloadCount) .ThenBy(x=>x.Created) .Skip(page*30) .Take(30) .ToList(); } } public class SearchController : RavenController { public IEnumerable<Packages_Search.ReduceResult> Get(string q, int page = 0) { return DocumentSession.Query<Packages_Search.ReduceResult, Packages_Search>() .Search(x => x.Query, q) .Where(x => x.IsPrerelease == false) .OrderByDescending(x => x.DownloadCount) .ThenBy(x => x.Created) .Skip(page * 30) .Take(30) .ToList(); } }
And, just for completeness sake, the Packages_Search index looks like this:
public class Packages_Search : AbstractIndexCreationTask<Package, Packages_Search.ReduceResult> { public class ReduceResult { public DateTime Created { get; set; } public int DownloadCount { get; set; } public string PackageId { get; set; } public bool IsPrerelease { get; set; } public object[] Query { get; set; } } public Packages_Search() { Map = packages => from p in packages select new { p.Created, DownloadCount = p.VersionDownloadCount, p.PackageId, p.IsPrerelease, Query = new object[] { p.Tags, p.Title, p.PackageId} }; Reduce = results => from result in results group result by new {result.PackageId, result.IsPrerelease} into g select new { g.Key.PackageId, g.Key.IsPrerelease, DownloadCount = g.Sum(x => x.DownloadCount), Created = g.Select(x => x.Created).OrderBy(x => x).First(), Query = g.SelectMany(x=>x.Query).Distinct() }; Store(x=>x.Query, FieldStorage.No); } }
That is enough setup, in the next post, I’ll discuss the actual structure of the load tests.

Comments
Comment preview