We finally had time to perform some much needed upgrades to the code base for the qualitative and quantitative metrics produced by our addin to CruiseControl.net continuous integration system
Anyway here’s an idea of how the framework API is shaping up. Expect this to move dramatically toward’s Fowler’s fantastic coverage of ‘Expression Builder’.
We hope that this will evolve into a full Linq provider, and due to the XML foundation this is not all that unrealistic a goal.
namespace CCStatisticsTDD { using System; using System.Collections.Generic; using System.Linq; using CCStatistics.Domain.Api; using CCStatistics.Domain.Api.Interfaces; using NUnit.Framework; using Rhino.Mocks; using TDDViewOutputStatus; using ThoughtWorks.CruiseControl.Core; /// <summary> /// This is a monolitic 'Smoke Test'. There are many fine grained tests to be writtem! /// </summary> [TestFixture] public class MainTestFixtureBaselineSmokes : TestBase { /// <summary> /// Gets the mock list. /// </summary> /// <param name="mockBuildName">Name of the mock build.</param> /// <param name="repositoryBuildCount">The repository build count.</param> /// <returns></returns> /// Documentation Created 6/23/2008 private static List<string> GetMockList(string mockBuildName, int repositoryBuildCount) { // Add the build name to the array tht is expected to be available for ALL builds // from the repositoy. Here we use 10 return Enumerable.Repeat(mockBuildName + " {0}", repositoryBuildCount).Select( s => String.Format(s, DateTime.Now.TimeOfDay.TotalMilliseconds/1000)).ToList(); } protected override ICCStatsProject Prepare() { // We need a name for this project const String mockBuildName = "CCStatisticsBuildMock"; // Simulate 100 legacy build results const int repositoryBuildCount = 100; var repository = mocks.Stub<IIntegrationRepository>(); var buildNames = GetMockList(mockBuildName, repositoryBuildCount); // OK set this up to return our builds repository.Stub(x => x.GetBuildNames()).Return(buildNames.ToArray()); var currentProject = mocks.Stub<ICCStatsProject>(); currentProject.Stub(x => x.IntegrationRepository).Return(repository); currentProject.Stub(x => x.StatisticsForPublisher).Return(MockStats); currentProject.StubEx(x => x.Name, mockBuildName). StubEx(x => x.BuildLogDirectory, DefaultDirectory). StubEx(x => x.ArtifactDirectory, DefaultDirectory). StubEx(x => x.WorkingDirectory, DefaultDirectory). Stub(x => x.StatsPostPublisher).Return(InitializePublisher(currentProject)); return currentProject; } private IMetricPublisher InitializePublisher(ICCStatsProject project) { // OK now it's interesting.. We have our own IMetricPublisher which is a stand-in for the // StattisticsPublisher concrete class in CruiseControl. We need to add a new overload // and obviously make this behave in ways it was not intended to (as we are doing all the legacy builds) var _statisticsPublisher = mocks.Stub<IMetricPublisher>(); // Here we use the mock array of stats created above. This is a duplicate of StatisticsForPublisher // Need to look into consolodating that. _statisticsPublisher.Stub(x => x.ConfiguredStatistics).Return(MockStats); // Core Validation is Below _statisticsPublisher.Expect(x => x.ProcesLogFile(project.Name)). IgnoreArguments().Repeat.Times(project.BuildCount); return _statisticsPublisher; } /// <summary> /// NOTE: This is a FULL CYCLE Mock Smoke test. We need many more finely grained /// tests. This is just to ensure all is well in the application. Each subcomponent /// will need to have tests added as this evolves. In the mean time this works /// well to ensure we fundamentally work and this is called from OUR BuildServer /// (how META is that?) to ensure this is working. /// This should be your first stop to undersand this code /// </summary> [Test] public void ShouldSmokeTestProjectAPI() { using (mocks.Record()) Assert.IsTrue(ForStatistics.RefreshValues(MockTDDView.New, Prepare())); } } public static class MockExtensions { /// <summary> /// Stubs the type defined /// </summary> /// <typeparam name="TType">The type of the type.</typeparam> /// <param name="currentProject">The current project.</param> /// <param name="funcMock">The func mock.</param> /// <param name="returnString">The return string.</param> /// <returns></returns> /// Documentation Created 6/20/2008 public static TType StubEx<TType>(this TType currentProject, Func<TType, String> funcMock, String returnString) where TType : class, ICCStatsProject { currentProject.Expect(funcMock).Return(returnString).Repeat.Any(); return currentProject; } } }




