using System;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using System.IO;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Hosting;
// see https://github.com/Shazwazza/UmbracoScripts/tree/master/src/LoadTesting
namespace Umbraco.TestData
{
public class LoadTestController : Controller
{
public LoadTestController(
ServiceContext serviceContext,
IShortStringHelper shortStringHelper,
IHostingEnvironment hostingEnvironment)
{
_serviceContext = serviceContext;
_shortStringHelper = shortStringHelper;
_hostingEnvironment = hostingEnvironment;
}
private static readonly Random _random = new Random();
private static readonly object _locko = new object();
private static volatile int _containerId = -1;
private const string _containerAlias = "LoadTestContainer";
private const string _contentAlias = "LoadTestContent";
private const int _textboxDefinitionId = -88;
private const int _maxCreate = 1000;
private static readonly string HeadHtml = @"
LoadTest
" + System.Configuration.ConfigurationManager.AppSettings["umbracoConfigurationStatus"] + @"
";
private const string FootHtml = @"
";
private static readonly string _containerTemplateText = @"
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@{
Layout = null;
var container = Umbraco.ContentAtRoot().OfTypes(""" + _containerAlias + @""").FirstOrDefault();
var contents = container.Children().ToArray();
var groups = contents.GroupBy(x => x.Value(""origin""));
var id = contents.Length > 0 ? contents[0].Id : -1;
var wurl = Request.QueryString[""u""] == ""1"";
var missing = contents.Length > 0 && contents[contents.Length - 1].Id - contents[0].Id >= contents.Length;
}
" + HeadHtml + @"
@contents.Length items
@foreach (var group in groups)
{
- @group.Key: @group.Count()
}
@foreach (var content in contents)
{
while (content.Id > id)
{
@id :: MISSING
id++;
}
if (wurl)
{
@content.Id :: @content.Name :: @content.Url
}
else
{
@content.Id :: @content.Name
} id++;
}
" + FootHtml;
private readonly ServiceContext _serviceContext;
private readonly IShortStringHelper _shortStringHelper;
private readonly IHostingEnvironment _hostingEnvironment;
private ActionResult ContentHtml(string s)
{
return Content(HeadHtml + s + FootHtml);
}
public ActionResult Index()
{
var res = EnsureInitialize();
if (res != null) return res;
var html = @"Welcome. You can:
";
return ContentHtml(html);
}
private ActionResult EnsureInitialize()
{
if (_containerId > 0) return null;
lock (_locko)
{
if (_containerId > 0) return null;
var contentTypeService = _serviceContext.ContentTypeService;
var contentType = contentTypeService.Get(_contentAlias);
if (contentType == null)
return ContentHtml("Not installed, first you must install.");
var containerType = contentTypeService.Get(_containerAlias);
if (containerType == null)
return ContentHtml("Panic! Container type is missing.");
var contentService = _serviceContext.ContentService;
var container = contentService.GetPagedOfType(containerType.Id, 0, 100, out _, null).FirstOrDefault();
if (container == null)
return ContentHtml("Panic! Container is missing.");
_containerId = container.Id;
return null;
}
}
public ActionResult Install()
{
var dataTypeService = _serviceContext.DataTypeService;
//var dataType = dataTypeService.GetAll(Constants.DataTypes.DefaultContentListView);
//if (!dict.ContainsKey("pageSize")) dict["pageSize"] = new PreValue("10");
//dict["pageSize"].Value = "200";
//dataTypeService.SavePreValues(dataType, dict);
var contentTypeService = _serviceContext.ContentTypeService;
var contentType = new ContentType(_shortStringHelper, -1)
{
Alias = _contentAlias,
Name = "LoadTest Content",
Description = "Content for LoadTest",
Icon = "icon-document"
};
var def = _serviceContext.DataTypeService.GetDataType(_textboxDefinitionId);
contentType.AddPropertyType(new PropertyType(_shortStringHelper, def)
{
Name = "Origin",
Alias = "origin",
Description = "The origin of the content.",
});
contentTypeService.Save(contentType);
var containerTemplate = ImportTemplate(_serviceContext, _shortStringHelper,
"LoadTestContainer", "LoadTestContainer", _containerTemplateText);
var containerType = new ContentType(_shortStringHelper, -1)
{
Alias = _containerAlias,
Name = "LoadTest Container",
Description = "Container for LoadTest content",
Icon = "icon-document",
AllowedAsRoot = true,
IsContainer = true
};
containerType.AllowedContentTypes = containerType.AllowedContentTypes.Union(new[]
{
new ContentTypeSort(new Lazy(() => contentType.Id), 0, contentType.Alias),
});
containerType.AllowedTemplates = containerType.AllowedTemplates.Union(new[] { containerTemplate });
containerType.SetDefaultTemplate(containerTemplate);
contentTypeService.Save(containerType);
var contentService = _serviceContext.ContentService;
var content = contentService.Create("LoadTestContainer", -1, _containerAlias);
contentService.SaveAndPublish(content);
return ContentHtml("Installed.");
}
public ActionResult Create(int n = 1, int r = 0, string o = null)
{
var res = EnsureInitialize();
if (res != null) return res;
if (r < 0) r = 0;
if (r > 100) r = 100;
var restart = GetRandom(0, 100) > (100 - r);
var contentService = _serviceContext.ContentService;
if (n < 1) n = 1;
if (n > _maxCreate) n = _maxCreate;
for (int i = 0; i < n; i++)
{
var name = Guid.NewGuid().ToString("N").ToUpper() + "-" + (restart ? "R" : "X") + "-" + o;
var content = contentService.Create(name, _containerId, _contentAlias);
content.SetValue("origin", o);
contentService.SaveAndPublish(content);
}
if (restart)
DoRestart();
return ContentHtml("Created " + n + " content"
+ (restart ? ", and restarted" : "")
+ ".");
}
private int GetRandom(int minValue, int maxValue)
{
lock (_locko)
{
return _random.Next(minValue, maxValue);
}
}
public ActionResult Clear()
{
var res = EnsureInitialize();
if (res != null) return res;
var contentType = _serviceContext.ContentTypeService.Get(_contentAlias);
_serviceContext.ContentService.DeleteOfType(contentType.Id);
return ContentHtml("Cleared.");
}
private void DoRestart()
{
HttpContext.User = null;
System.Web.HttpContext.Current.User = null;
Thread.CurrentPrincipal = null;
HttpRuntime.UnloadAppDomain();
}
public ActionResult ColdBootRestart()
{
Directory.Delete(_hostingEnvironment.MapPathContentRoot(Path.Combine(Constants.SystemDirectories.TempData,"DistCache")), true);
DoRestart();
return Content("Cold Boot Restarted.");
}
public ActionResult Restart()
{
DoRestart();
return ContentHtml("Restarted.");
}
public ActionResult Die()
{
var timer = new System.Threading.Timer(_ =>
{
throw new Exception("die!");
});
timer.Change(100, 0);
return ContentHtml("Dying.");
}
public ActionResult Domains()
{
var currentDomain = AppDomain.CurrentDomain;
var currentName = currentDomain.FriendlyName;
var pos = currentName.IndexOf('-');
if (pos > 0) currentName = currentName.Substring(0, pos);
var text = new System.Text.StringBuilder();
text.Append("Process ID: " + Process.GetCurrentProcess().Id + "
");
text.Append("");
text.Append("
IIS Site: " + HostingEnvironment.ApplicationHost.GetSiteName() + "
");
text.Append("
App ID: " + currentName + "
");
//text.Append("
AppPool: " + Zbu.WebManagement.AppPoolHelper.GetCurrentApplicationPoolName() + "
");
text.Append("
");
text.Append("Domains:
");
text.Append("- Not implemented.
");
/*
foreach (var domain in Zbu.WebManagement.AppDomainHelper.GetAppDomains().OrderBy(x => x.Id))
{
var name = domain.FriendlyName;
pos = name.IndexOf('-');
if (pos > 0) name = name.Substring(0, pos);
text.Append("- "
+"[" + domain.Id + "] " + name
+ (domain.IsDefaultAppDomain() ? " (default)" : "")
+ (domain.Id == currentDomain.Id ? " (current)" : "")
+ "
");
}
*/
text.Append("
");
return ContentHtml(text.ToString());
}
public ActionResult Recycle()
{
return ContentHtml("Not implemented—please use IIS console.");
}
private static Template ImportTemplate(ServiceContext svces, IShortStringHelper shortStringHelper, string name, string alias, string text, ITemplate master = null)
{
var t = new Template(shortStringHelper, name, alias) { Content = text };
if (master != null)
t.SetMasterTemplate(master);
svces.FileService.SaveTemplate(t);
return t;
}
}
public class TestComponent : IComponent
{
public void Initialize()
{
if (ConfigurationManager.AppSettings["Umbraco.TestData.Enabled"] != "true")
return;
RouteTable.Routes.MapRoute(
name: "LoadTest",
url: "LoadTest/{action}",
defaults: new
{
controller = "LoadTest",
action = "Index"
},
namespaces: new[] { "Umbraco.TestData" }
);
}
public void Terminate()
{
}
}
public class TestComposer : ComponentComposer, IUserComposer
{
public override void Compose(IUmbracoBuilder builder)
{
base.Compose(builder);
if (ConfigurationManager.AppSettings["Umbraco.TestData.Enabled"] != "true")
return;
builder.Services.AddScoped(typeof(LoadTestController));
}
}
}