Skip to content

Samples

IlyaAI edited this page Apr 11, 2015 · 1 revision

Default Build Script

Performance Test on Last Good Build

Generating Release Notes

AnFake Building AnFake

Default Build Script

Below the trivial example which compiles and runs unit-tests (such script generated when you install AnFake into your solution):

.AnFake/build.fsx.tmpl

let out = ~~".out"               // ~~ operator converts string to FileSystemPath object
let productOut = out / "product" // FileSystemPath objects can be combined with operator /
let testsOut = out / "tests"
let tests = !!"*/*.Test.csproj"  // !! operator creates FileSet object from wildcarded path
let product = 
    !!"*/*.csproj"
    - tests                      // - operator excludes files from FileSet

// defining target 'Compile'
"Compile" => (fun _ ->
    MsBuild.BuildRelease(product, productOut) // run MSBuild for product projects
    MsBuild.BuildRelease(tests, testsOut)     // run MSBuild for test projects
)

// defining target 'Test'
"Test" => (fun _ -> 
    // run VSTest.Console on all *.Test.dll files from testsOut folder
    VsTest.Run(testsOut % "*.Test.dll")
)

// defining composition
"Build" <== ["Compile"; "Test"]     // 'Build' consists of 'Compile' and 'Test'

Performance Test on Last Good Build

A bit more complex example which looks up a last good build, takes its output, runs performance test, puts result into database, calculate statistical threshold over last 5 measurements and checks new result against this threshold:

Samples/perf-test.fsx

let out = ~~".out"
let binOut = out / "bin"

// declaring data contract for performance report
[<DataContract>]
type PerformanceReport () =
    [<DataMember>] member val ChangesetId: int = 0 with get, set
    [<DataMember>] member val ElapsedTime: double = 0.0 with get, set
    [<DataMember>] member val BytesProcessed: int64 = 0L with get, set

"Test.Performance" => (fun _ ->
    let buildDefName = MyBuild.GetProp("productBuild")  // gets externally passed parameter
    // looks up last build with quality 'Unit-Tests Passed' in Team Build
    let goodBuild = TfsBuild.QueryByQuality(buildDefName, "Unit-Tests Passed", 1).First()
    
    // copying goodBuild's output to local folder
    Files.Copy(goodBuild.GetDropLocationOf(ArtifactType.Deliverables) % "*", binOut)
    
    // building command line arguments for performance meter tool
    let reportPath = out / "PerfMeter.report"
    let args = 
        (new Args("--", " "))            
            .Option("threads", 4)
            .Option("report", reportPath)
            .ToString()

    // running performance meter tool
    Process.Run(fun p -> 
        p.FileName <- binOut / "PerfMeter.exe"
        p.Arguments <- args        
    ).FailIfExitCodeNonZero("PerfMeter.exe FAILED.") 
    |> ignore

    // loading performance report
    let report = Json.ReadAs<PerformanceReport>(reportPath.AsFile())
    report.ChangesetId <- VersionControl.CurrentChangesetId
    
    Nh.MapClass<PerformanceReport>()
    Nh.DoWork(fun uow ->
        // querying previous 5 measurements from DB
        let prevReports = 
            uow.Query("from PerformanceReport order by id desc")
                .SetMaxResults(5)
                .List<PerformanceReport>()
        
        // saving new result
        uow.Save(report)
        uow.Commit()

        // calculating and checking threshold
        if prevReports.Count = 5 then        
            let prevSpeeds = prevReports.Select(fun rep -> (double)rep.BytesProcessed / rep.ElapsedTime)
            let avg = prevSpeeds.Average()
            let sig2 = prevSpeeds.Average(fun x -> (x - avg)*(x - avg))

            let speed = (double)report.BytesProcessed / report.ElapsedTime
            let threshold = avg - Math.Sqrt(sig2);
            if speed < threshold then
                MyBuild.Failed(
                    "The last reported speed {0:F2} KB/s is under threshold {1:F2} KB/s.", 
                    speed / 1024.0, threshold / 1024.0
                )
    )
)

Generating Release Notes

Samples/tfs-releasenotes.fsx

AnFake Building AnFake

Of course, AnFake is built by itself – take a look on real-life example of build.fsx or build.csx

Clone this wiki locally