Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added CustomLabeller with tests #253

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions project/UnitTests/Core/Label/CustomLabellerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using Exortech.NetReflector;
using NUnit.Framework;
using ThoughtWorks.CruiseControl.Core.Label;

namespace ThoughtWorks.CruiseControl.UnitTests.Core.Label
{
[TestFixture]
public class CustomLabellerTest : IntegrationFixture
{
private CustomLabeller labeller;

private string exampleCode = @"

if (
integrationResult != null
&& integrationResult.LastIntegration != null
&& !integrationResult.LastIntegration.IsInitial()
)
{
if (integrationResult.LastIntegration.Status == ThoughtWorks.CruiseControl.Remote.IntegrationStatus.Success)
{
System.Version lastVersion = System.Version.Parse(integrationResult.LastIntegration.Label);
System.Version nextVersion = new System.Version(lastVersion.Major, lastVersion.Minor, lastVersion.Build, lastVersion.Revision + 1);
ret = nextVersion.ToString();
}
else
{
ret = integrationResult.LastIntegration.Label;
}
}
else
{
ret = new System.Version(1, 1, 1, 1).ToString();
}


";

[SetUp]
public void SetUp()
{
labeller = new CustomLabeller();
}

[Test]
public void GenerateInitialLabelWoCode()
{
Assert.AreEqual("0.0.0.0", labeller.Generate(InitialIntegrationResult()));
}

[Test]
public void GenerateLabelWoCode()
{
Assert.AreEqual("0.0.0.0", labeller.Generate(SuccessfulResult("35")));
}

[Test]
public void GenerateNextLabel()
{
labeller.CsCode = @"ret = ""somelabel"";";
Assert.AreEqual("somelabel", labeller.Generate(SuccessfulResult("previouslabel")));
}

[Test]
public void GenerateInitialLabel()
{
labeller.CsCode = @"ret = ""somelabel"";";
Assert.AreEqual("somelabel", labeller.Generate(SuccessfulResult("previouslabel")));
}

[Test]
public void GenerateInitialLabelWithExampleCode()
{
labeller.CsCode = exampleCode;
Assert.AreEqual("1.1.1.1", labeller.Generate(InitialIntegrationResult()));
}

[Test]
public void GenerateNextLabelWithExampleCode()
{
labeller.CsCode = exampleCode;
Assert.AreEqual("1.2.3.5", labeller.Generate(SuccessfulResult("1.2.3.4")));
}

[Test]
public void GenerateSameLabelWithExampleCode()
{
labeller.CsCode = exampleCode;
Assert.AreEqual("1.2.3.4", labeller.Generate(FailedResult("1.2.3.4")));
}
}
}
1 change: 1 addition & 0 deletions project/UnitTests/UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@
<Compile Include="Core\Extensions\IntegrationPerformanceCountersExtensionTests.cs" />
<Compile Include="Core\Extensions\DiskSpaceMonitorExtensionTests.cs" />
<Compile Include="Core\Extensions\IntegrationRequestThrottleExtensionTests.cs" />
<Compile Include="Core\Label\CustomLabellerTest.cs" />
<Compile Include="Core\Publishers\ConditionalPublisherTests.cs" />
<Compile Include="Core\Publishers\ManifestGeneratorTests.cs" />
<Compile Include="Core\Publishers\ManifestImporterTests.cs" />
Expand Down
1 change: 1 addition & 0 deletions project/core/core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@
<Compile Include="label\DateLabeller.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="label\CustomLabeller.cs" />
<Compile Include="label\DefaultLabeller.cs">
<SubType>Code</SubType>
</Compile>
Expand Down
135 changes: 135 additions & 0 deletions project/core/label/CustomLabeller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Remote;
using System.Globalization;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;

namespace ThoughtWorks.CruiseControl.Core.Label
{
/// <summary>
/// <para>
/// Allows CCNet create custom code-generated labels
/// </para>
/// <para>
/// You can do this by specifying your own configuration of the default labeller in your project.
/// </para>
/// </summary>
/// <title>Custom Labeller</title>
/// <version>1.0</version>
/// <example>
/// <code>
/// &lt;labeller type="customlabeller"&gt;
/// &lt;cscode&gt;1&lt;/cscode&gt;
/// &lt;/labeller&gt;
/// </code>
/// </example>
[ReflectorType("customlabeller")]
public class CustomLabeller
: LabellerBase
{
/// <summary>
/// Generates the specified integration result.
/// </summary>
/// <param name="integrationResult">The integration result.</param>
/// <returns></returns>
/// <remarks></remarks>
public override string Generate(IIntegrationResult integrationResult)
{
MethodInfo method = this.CreateFunction(this.CsCode);
string ret = (string)method.Invoke(null, new object[1] { integrationResult });
return ret;
}

[ReflectorProperty("usings", Required = false)]
public string Usings { get; set; }

[ReflectorProperty("referencedassemblies", Required = false)]
public string ReferencedAssemblies { get; set; }

[ReflectorProperty("cscode", Required = true)]
public string CsCode { get; set; }

private string CSCodeWrapper
{
get
{
return @"

using System;
using ThoughtWorks.CruiseControl.Core;
using ThoughtWorks.CruiseControl.Remote;

namespace CustomLabelerGeneratorUserFunctions
{
public class CustomLabelerGenerator
{
public static string Generate(ThoughtWorks.CruiseControl.Core.IIntegrationResult integrationResult)
{
string ret = ""0.0.0.0"";
<customCodeForReplace>
return ret;
}
}
}
";
}
}

public MethodInfo CreateFunction(string function)
{
System.Text.StringBuilder usings = new System.Text.StringBuilder();
if (!string.IsNullOrWhiteSpace(this.Usings))
{
foreach (var each in this.Usings.Split(';'))
{
if (!string.IsNullOrWhiteSpace(each))
{
usings.AppendFormat("using {0};", each);
usings.AppendLine();
}
}
}

string finalCode = usings.ToString() + CSCodeWrapper.Replace("<customCodeForReplace>", function);

CSharpCodeProvider provider = new CSharpCodeProvider();
var parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
parameters.ReferencedAssemblies.Add(typeof(ThoughtWorks.CruiseControl.Remote.IntegrationStatus).Assembly.Location);
if (!string.IsNullOrWhiteSpace(this.ReferencedAssemblies))
{
foreach (var each in this.ReferencedAssemblies.Split(';'))
{
if (!string.IsNullOrWhiteSpace(each))
{
parameters.ReferencedAssemblies.Add(each);
}
}
}

parameters.GenerateInMemory = true;
parameters.GenerateExecutable = false;
parameters.IncludeDebugInformation = false;
CompilerResults results = provider.CompileAssemblyFromSource(parameters, finalCode);
if (results.Errors != null && results.Errors.Count > 0)
{
var path = System.IO.Path.GetTempFileName();
System.IO.File.WriteAllText(path, finalCode);
foreach (var each in results.Errors)
{
Console.WriteLine("ERROR in {0}: {1}", path, each);
}

throw new ApplicationException("There are compilation errors. Please see " + path);
}


Type binaryFunction = results.CompiledAssembly.GetType("CustomLabelerGeneratorUserFunctions.CustomLabelerGenerator");
return binaryFunction.GetMethod("Generate");
}
}
}