SlideShare ist ein Scribd-Unternehmen logo
1 von 61
© IBM Corporation1
Presented by:
How to set up an ASP.NET 5
Continuous Delivery Pipeline using
IBM Bluemix DevOps Services
Richard Johansson
Linus Karlsson
Fredrik Lindahl
Olof Kindblad
DevOps Interns, Bluemix Garage, IBM Malmö
2016-03-16
© IBM Corporation2
Introduction
This presentation is a result of an applied project internship carried out during the spring of 2016 by four Information Systems
students from Lund University School of Economics and Management for IBM Bluemix Garage in Malmö, Sweden. The project’s
purpose was to assess the current capabilities, opportunities and pain points in using the ASP.NET 5 runtime with Bluemix and the
DevOps Services, and based on that provide recommendations to IBM on how they can enhance that experience and thus
motivate more .NET developers to choose Bluemix, DevOps Services and the Bluemix Garage Method as their Continuous
Delivery and DevOps enablers.
The result of the assessment showed that the Bluemix and .NET experience is not bad at all, although one pain point was that there
is no built-in support for a .NET runtime environment in the DevOps Services Delivery Pipeline – which is not surprising since
ASP.NET 5 is so far only tagged as an experimental runtime in Bluemix. A .NET supportive runtime environment is however
possible to install manually, as the Delivery Pipeline offers its users to specify their own manual build scripts. How to do this is
explained in this presentation. Altogether, we can conclude that Bluemix and the DevOps Services is most definitely a full-worthy
option to other popular hybrid cloud solutions for .NET developers.
In this presentation we will explain how to set up a complete IBM native tool chain for Continuous Delivery by using the IBM
DevOps Services Build & Deploy function, also known as the Delivery Pipeline. We will develop, build, (autonomously) unit test,
integration test, load test and deploy an ASP.NET 5 application with a Cloudant NoSQL database to Bluemix.
© IBM Corporation3
Orientation
This guide picks up and extends the Getting started with ASP.NET 5 in Bluemix guide, which shows how to create a simple
HelloWorld ASP.NET 5 application and deploy it to Bluemix. That guide briefly mentions the ASP.NET 5 + Cloudant Starter
App boilerplate, which can be used to generate a pre-built ASP.NET 5 application with basic CRUD functionality using a
Cloudant NoSQL database. That is the boilerplate we used as a starting point for this guide. Our own application extends that
one with automated unit tests, automated integration tests and the required project dependencies for building and testing in
the DevOps Services Delivery Pipeline.
The Getting started with ASP.NET 5 in Bluemix guide:
https://developer.ibm.com/bluemix/2015/05/18/getting-started-asp-net-5-bluemix
The ASP.NET 5 + Cloudant Starter App boilerplate that we started from is available here:
https://github.com/IBM-Bluemix/asp.net5-cloudant
Our finished application that was created during the making of this guide is available here:
https://github.com/FredrikLindahl/ASP.NET-5-Cloudant-for-Bluemix-Delivery-Pipeline
© IBM Corporation4
The Delivery Pipeline
Our Delivery Pipeline was configured in four stages.
– The Build stage has two jobs: one Build job that builds
the application and the runtime in the Delivery Pipeline
server environment, and one Unit Test job that first builds
and then executes some basic unit tests.
– If the first stage is passed, the Test stage is triggered.
This stage has one job: an Integration Test job that runs
some basic CRUD tests against the Cloudant database.
– If the second stage is passed, the Staging stage is
triggered. This stage has two jobs: a Deployment job that
deploys the build to a “pre-production” test environment
in the Bluemix cloud, which is accessed through
myApplication-PreProd.eu-gb.mybluemix.net. The stage
also has a Load Test job that runs some performance
tests using the third party tool Load Impact that is
available as a Bluemix Service and API.
– If the third stage is passed, the Production stage is
triggered. This stage only has one job: a Deployment job
that deploys the build to a live production environment in
the Bluemix cloud, accessible via myApplication.eu-
gb.mybluemix.net.
The Toolchain
IDE: Visual Studio Code
SCM: DevOps Services JazzHub
CI & CD: DevOps Services Delivery Pipeline
Unit Testing: xUnit
Integration Testing: xUnit
Load Testing: Load Impact
© IBM Corporation5
text
Overview of the Delivery Pipeline Setup Process
© IBM Corporation6© IBM Corporation6
The Guide
Created and verified in March 2016
© IBM Corporation7© IBM Corporation7
Start Main Process
Delivery Pipeline
© IBM Corporation8© IBM Corporation8
Start Main Process
Delivery Pipeline
© IBM Corporation9
Delivery Pipeline
1. Create Application from Boilerplate
• Go to https://github.com/IBM-Bluemix/asp.net5-cloudant
• Click Deploy to Bluemix
• When finished, click EDIT CODE
1. Create Application from Boilerplate
© IBM Corporation10
Delivery Pipeline
2. Develop Code
• Make some code changes, i.e. change the title of the page to “HelloWorldIBM”
3. Commit and Push Code
• Commit and push code changes to your JazzHub git repository.
4. Trigger Delivery Pipeline
This step is done automatically each time a code change is pushed to the
JazzHub git repository.
2. Develop Code
3. Commit and Push Code
4. Trigger Delivery Pipeline
© IBM Corporation11
Delivery Pipeline
5. Add Build Stage
This one-time-step is automatically done by the Delivery Pipeline as part of
setting up the structure.
6. Add Build Job
This one-time-step is automatically done by the Delivery Pipeline as part of
setting up the structure.
7. Add Unit Test Job
This one-time step needs to be manually done as part of setting up the
structure of the Delivery Pipeline.
• Click on Configure Stage in the Build Stage
• Go to the tab Jobs
• Add a new Test job and name it "Unit Test"
• Select Tester Type: Simple
• Make sure that the Unit Test Job is sequentially positioned after the Build
Job in the Build Stage
8. Deploy to Build Stage
This continuous-delivery-step is automatically done each time the Delivery
Pipeline is triggered.
5. Add Build Stage
6. Add Build Job
7. Add Unit Test Job
8. Deploy to Build Stage
© IBM Corporation12© IBM Corporation12
Start Sub-Process
Delivery Pipeline: Build
© IBM Corporation13© IBM Corporation13
Start Sub-Process
Delivery Pipeline: Build
© IBM Corporation14
Overview Sub-Process
Delivery Pipeline: Build
© IBM Corporation15
Delivery Pipeline: Build
9. Configure Builder Type to Shell Script
10. Add ASP.NET 5 Manual Build Script
9. Configure Builder Type to Shell Script
• In the Delivery Pipeline, select Configure on the Build Stage
• Go to the tab Jobs
• Set Builder Type to Shell Script
10. Add ASP.NET Manual Build Script
• Insert the manual build script below. Further explanation of what the script does is
available in appendix A1.
• Make sure to replace the project path with your own in cd src/your-project-path
#!/bin/bash
echo --- UPDATING DEPENDENCIES! ---
sudo apt-get update
echo --- DOWNLOADING PACKAGES! ---
sudo apt-get -y install libunwind8 gettext libssl-dev libcurl3-dev zlib1g
libcurl4-openssl-dev libicu-dev uuid-dev
echo --- DOWNLOADING DNVM! ---
curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh |
DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh
echo --- INSTALLING DNVM! ---
dnvm install 1.0.0-rc1-final -r coreclr -a x64
echo --- EXECUTING RESTORE! ---
cd src/your-project-path
dnu restore
echo --- EXECUTING BUILD! ---
dnu build
© IBM Corporation16
Delivery Pipeline: Build
11. Run Build Script
12. Upload Artifact
11. Run Build Script
This step is automated when triggering the Delivery Pipeline. To manually run it, click Run
Stage on the Build Stage.
12. Upload Artifact
The Build Job in the Build Stage is automatically run and the build artifact is automatically
uploaded.
© IBM Corporation17© IBM Corporation17
End Sub-Process
Delivery Pipeline: Build
© IBM Corporation18© IBM Corporation18
Start Sub-Process
Delivery Pipeline: Unit Test
© IBM Corporation19© IBM Corporation19
Start Sub-Process
Delivery Pipeline: Unit Test
© IBM Corporation20
Overview Sub-Process
Delivery Pipeline: Unit Test
© IBM Corporation21
Delivery Pipeline: Unit Test
13. Add xUnit Dependencies to project.json
13. Add xUnit Dependencies to project.json
• Navigate to the project.json file of your application and add the following dependencies:
"xunit": "2.1.0"
"xunit.runner.dnx": "2.1.0-rc1-build204“
The project.json file should look something like this:
{
"version": "1.0.0-*",
"dependencies": {
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
"Newtonsoft.Json": "7.0.1",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
"Microsoft.AspNet.WebApi.Client": "5.2.3",
"System.Net.Http": "4.0.0",
"System.Runtime.Serialization.Xml": "4.0.10",
"xunit": "2.1.0",
"xunit.runner.dnx": "2.1.0-rc1-build204"
},
"commands": {
"kestrel": "Microsoft.AspNet.Hosting --server
Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5004"
},
"frameworks": {
"dnxcore50": { }
},
"exclude": [
"wwwroot",
"node_modules"
],
"publishExclude": [
"**.user",
"**.vspscc"
]
}
© IBM Corporation22
Delivery Pipeline: Unit Test
14. Add xUnit Command to project.json
14. Add xUnit Command to project.json
• Navigate to the project.json file of your application and add the following command:
test": "xunit.runner.dnx"
The project.json file should look something like this:
{
"version": "1.0.0-*",
"dependencies": {
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
"Newtonsoft.Json": "7.0.1",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
"Microsoft.AspNet.WebApi.Client": "5.2.3",
"System.Net.Http": "4.0.0",
"System.Runtime.Serialization.Xml": "4.0.10",
"xunit": "2.1.0",
"xunit.runner.dnx": "2.1.0-rc1-build204"
},
"commands": {
"kestrel": "Microsoft.AspNet.Hosting --server
Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5004",
"test": "xunit.runner.dnx"
},
"frameworks": {
"dnxcore50": { }
},
"exclude": [
"wwwroot",
"node_modules"
],
"publishExclude": [
"**.user",
"**.vspscc"
]
}
© IBM Corporation23
Delivery Pipeline: Unit Test
15. Create Unit Test Class
16. Write Unit Test(s)
15. Create Unit Test Class
• In Visual Studio, navigate to your project folder
• Add a new folder in src called "Tests"
• Create a new file in the Tests folder called "UnitTests.cs“
16. Write Unit Test(s)
• Open the UnitTests class and write some unit tests.
• Make sure to import the Xunit package at the top of the class (using Xunit;) and to specify the
correct namespace/folder that the class lies in (namespace your-project-path.Tests).
• An example of a class that has a few basic unit tests can be found in appendix A2.
© IBM Corporation24
Delivery Pipeline: Unit Test
17. Insert ASP.NET 5 Manual Build Script
18. Remove DNU Build From Script
19. Insert Unit Test Call Script
20. Run Unit Tests
17. Insert ASP.NET 5 Manual Build Script
• In the Delivery Pipeline, navigate to the Unit Test Job in the Build Stage
• Insert the manual build script in the Test Command console
18. Remove DNU Build From Script
• Delete the following lines from the manual build Shell Script:
echo --- EXECUTING BUILD! ---
dnu build
19. Insert Unit Test Call Script
• Call the xUnit unit test(s) by adding the below command at the end of the Shell Script:
dnx test -class path-to-unittest-class
• Example:
dnx test -class dotnetCloudantWebstarter.Tests.UnitTests
20. Run Unit Tests
• This step is automatically run when committing code changes and thus triggering the Build
Stage and its Build Job and Unit Test Job.
• (For manual triggering, click Run Stage in the Build Stage).
© IBM Corporation25© IBM Corporation25
End Sub-Process
Delivery Pipeline: Unit Test
© IBM Corporation26© IBM Corporation26
Continue Main Process
Delivery Pipeline
© IBM Corporation27© IBM Corporation27
Continue Main Process
Delivery Pipeline
© IBM Corporation28
Delivery Pipeline
21. Add Test Stage
This one-time step needs to be manually done as part of setting up the structure
of the Delivery Pipeline.
• In the Delivery Pipeline, select ADD STAGE
• Name the stage "Test"
• Input Type: Build Artifacts
• Stage: Build
• Job: Build
• State Trigger: Run jobs when the previous stage is completed
• Make sure that the Test Stage is positioned after the Build Stage in the
Delivery Pipeline
22. Add Integration Test Job
This one-time step needs to be manually done as part of setting up the structure
of the Delivery Pipeline.
• Click on Configure Stage in the Test Stage
• Go to the tab Jobs
• Add a new Test job and name it "Integration Test"
• Select Tester Type: Simple
23. Deploy to Test Stage
This continuous-delivery-step can be set to be triggered either manually or
automatically, by changing the State Trigger settings in the Test Stage.
21. Add Test Stage
22. Add Integration Test Job
23. Deploy to Test Stage
© IBM Corporation29© IBM Corporation29
Start Sub-Process
Delivery Pipeline: Integration Test
© IBM Corporation30© IBM Corporation30
Start Sub-Process
Delivery Pipeline: Integration Test
© IBM Corporation31
Overview Sub-Process
Delivery Pipeline: Integration Test
© IBM Corporation32
Delivery Pipeline: Integration Test
24. Add xUnit Dependencies to project.json
25. Add xUnit Command to project.json
24. Add xUnit Dependencies to project.json
Note: This step has already been described as part of the Unit Testing setup manual. It can
thus be omitted if the xUnit dependencies and command is already configured.
25. Add xUnit Command to project.json
Note: This step has already been described as part of the Unit Testing setup manual. It can
thus be omitted if the xUnit dependencies and command is already configured.
© IBM Corporation33
Delivery Pipeline: Integration Test
26. Create Integration Test Class
27. Write Integration Test(s)
26. Create Integration Test Class
• In Visual Studio, navigate to your project folder
• If not done already, add a new folder in src called "Tests"
• Create a new file in the Tests folder called “IntegrationTests.cs“
27. Write Integration Test(s)
• Open the IntegrationTests class and write some integration tests.
• Make sure to import the Xunit package at the top of the class (using Xunit;) and to specify the
correct namespace/folder that the class lies in (namespace your-project-path.Tests).
• An example of a class that has a few basic integration tests can be found in appendix A3.
© IBM Corporation34
Delivery Pipeline: Integration Test
28. Add VCAP_SERVICES
28. Add VCAP_SERVICES
This step establishes the connection between the database and
the Delivery Pipeline.
• Retrieve VCAP_SERVICES from the Cloudant DB Service
• Navigate to the Application Overview via the Bluemix
Dashboard
• Select the Show Credentials arrow button from the
Cloudant DB Service
• Copy the VCAP_SERVICES credentials.
• Add VCAP_SERVICES to the Delivery Pipeline Test Job
• Click on Configure Stage in the Test Stage
• Go to the tab ENVIRONMENT PROPERTIES
• Add a new Text Area Property
• Name: VCAP_SERVICES
• Value: Paste the previously copied
VCAP_SERVICES credentials
© IBM Corporation35
Delivery Pipeline: Integration Test
29. Insert ASP.NET 5 Manual Build Script
30. Remove DNU Build From Script
31. Insert Integration Test Call Script
32. Run Integration Tests
29. Insert ASP.NET 5 Manual Build Script
• In the Delivery Pipeline, navigate to the Integration Test Job in the Test Stage
• Insert the manual build script in the Test Command console
30. Remove DNU Build From Script
• Delete the following lines from the manual build Shell Script:
echo --- EXECUTING BUILD! ---
dnu build
31. Insert Integration Test Call Script
• Call the xUnit integration test(s) by adding the below command at the end of the Shell Script:
dnx test -class path-to-integrationtest-class
• Example:
dnx test -class dotnetCloudantWebstarter.Tests.IntegrationTests
32. Run Integration Tests
• This stage can be set to be triggered manually or automatically by changing the State Trigger settings
in the Test Stage. If automatic, this step is automatically triggered when the Build Stage is passed.
• (For manual triggering, click Run Stage in the Test Stage).
© IBM Corporation36© IBM Corporation36
End Sub-Process
Delivery Pipeline: Integration Test
© IBM Corporation37© IBM Corporation37
Continue Main Process
Delivery Pipeline
© IBM Corporation38© IBM Corporation38
Continue Main Process
Delivery Pipeline
© IBM Corporation39
Delivery Pipeline
33. Add Staging Stage
This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline.
• In the Delivery Pipeline, select ADD STAGE
• Name the stage "Staging"
• Input Type: Build Artifacts
• Stage: Build
• Job: Build
• State Trigger: Run jobs when the previous stage is completed
• Make sure that the Staging Stage is positioned after the Test Stage in the Delivery Pipeline
34. Add Pre-Production Deployment Job
This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline.
• Click on Configure Stage in the Staging Stage
• Go to the tab Jobs
• Add a new Deploy job and name it "Deploy to Pre-Prod“
• In the Deploy Script command window, add the following script in order to create and route to a new
application which will act as our pre-production environment:
cf push "${CF_APP}"-PreProd -n "${CF_APP}"-PreProd
33. Add Staging Stage
34. Add Pre-Production Deployment Job
© IBM Corporation40
Delivery Pipeline
35. Add Load Impact Test Job
This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline.
• In the Delivery Pipeline, click Configure Stage in the Staging Stage
• Go to the tab Jobs
• Add a new Test job and name it "Load Test"
• Select Tester Type: Simple
• Include the following command (as-is) in the Test Command console:
curl -X POST "${LOAD_IMPACT_TEST_URL}" -u "${LOAD_IMPACT_API_TOKEN}:“
36. Deploy to Staging Stage
This continuous-delivery-step can be set to be triggered either manually or automatically, by changing the
State Trigger settings in the Staging Stage.
35. Add Load Impact Test Job
36. Deploy to Staging Stage
© IBM Corporation41© IBM Corporation41
Start Sub-Process
Delivery Pipeline: Load Test
© IBM Corporation42© IBM Corporation42
Start Sub-Process
Delivery Pipeline: Load Test
© IBM Corporation43
Overview Sub-Process
Delivery Pipeline: Load Test
© IBM Corporation44
Delivery Pipeline: Load Test
37. Add Load Impact as a Service
38. Open Load Impact Dashboard
39. Retrieve API Token
37. Add Load Impact as a Service
• In Bluemix, select the space to add the Load Impact service to
• Click ADD SERVICE OR API
• Find and click the Load Impact service
• Select the appropriate plan and name your service
• Click CREATE
This step can also be done using the Cloud Foundry CLI command:
$ cf create-service loadimpact lifree my-loadimpact-service
38. Open Load Impact Dashboard
• Navigate to the created Load Impact Service in Bluemix
• Click OPEN LOAD IMPACT DASHBOARD
• The Load Impact website is opened
39. Retrieve API Token
• On the Load Impact website, navigate to Integrations Menu
• Choose Load Impact API Token
• Click Generate token and then copy and save the API token that is generated
© IBM Corporation45
Delivery Pipeline: Load Test
40. Create Load Test
41. Run Load Test
42. Retrieve Load Impact Test ID
40. Create Load Test
• On the Load Impact website, navigate to Tests Menu
• Click Add user scenario
• Paste the Bluemix application's Pre-Production URL and click Add
• Set desirable VUs and duration
• Click Save changes
41. Run Load Test
• On the Load Impact website, in the Tests Menu, click Run test to create and run a simple load test
42. Retrieve Load Impact Test ID
• On the Load Impact website, on the Tests page, click the test that you just ran
• Select and copy the ID at the end of URL from your browser and save it
For example, if your test case URL is https://app.loadimpact.com/tests/1234567, the config ID
is 1234567. This ID, along with the API token, will be used when configuring your app to use Load
Impact.
© IBM Corporation46
Delivery Pipeline: Load Test
43. Set Environment Properties
44. Run Load Test in Delivery Pipeline
43. Set Environment Properties
This step establishes the link between the Load Impact test and the Delivery Pipeline.
• In the Delivery Pipeline's Staging Stage, click the Environment Properties tab
• Click Add Property
• Choose Text Property from the list and name it "LOAD_IMPACT_API_TOKEN"
• For the value of this property, enter the Load Impact API key that you generated earlier
• Click Add Property
• Add another Text Property and name it "LOAD_IMPACT_TEST_URL"
• For the value of this property, enter the following URL, replacing id with the config ID of the test case
your created earlier: https://api.loadimpact.com/v2/test-configs/id/start
44. Run Load Test in Delivery Pipeline
• This continuous-delivery-step can be set to be triggered either manually or automatically, by
changing the State Trigger settings in the Staging Stage. For manual triggering, click Run Stage in
the Staging Stage.
• The test progress and results can be observed on the Load Impact website.
© IBM Corporation47© IBM Corporation47
End Sub-Process
Delivery Pipeline: Load Test
© IBM Corporation48© IBM Corporation48
Continue Main Process
Delivery Pipeline
© IBM Corporation49© IBM Corporation49
Continue Main Process
Delivery Pipeline
© IBM Corporation50
Delivery Pipeline
45. Deploy to Production
45. Deploy to Production
This continuous-delivery-step can be set to be triggered either manually or automatically, by changing
the State Trigger settings in the Staging Stage.
© IBM Corporation51© IBM Corporation51
End Main Process
Delivery Pipeline
© IBM Corporation52© IBM Corporation52
Appendix
© IBM Corporation53
A1: Manual Build Script
• Update Package Lists
Updates the package lists to make sure that the latest
packages are downloaded.
echo --- UPDATING DEPENDENCIES! ---
sudo apt-get update
• Install Necessary Packages
Installs the below listed necessary runtime environment
packages.
• libunwind8
• gettext
• libssl-dev
• libcurl3-dev
• zlib1g
• libcurl4-openssl-dev
• libicu-dev
• uuid-dev
echo --- DOWNLOADING PACKAGES! ---
sudo apt-get -y install libunwind8 gettext
libssl-dev libcurl3-dev zlib1g libcurl4-
openssl-dev libicu-dev uuid-dev
• Download DNVM
Downloads DNVM (.NET Version Manager) so that we can
restore and build and publish. DNX (.NET Execution Manager)
and DNU (.NET Utilites) are included in DNVM.
echo --- DOWNLOADING DNVM! ---
curl -sSL
https://raw.githubusercontent.com/aspnet/Home/
dev/dnvminstall.sh | DNX_BRANCH=dev sh &&
source ~/.dnx/dnvm/dnvm.sh
• Install DNVM
Installs DNVM (.NET Version Manager).
Note: The DNVM version must correspond to the required
DNVM version listed in the application's project.json file.
echo --- INSTALLING DNVM! ---
dnvm install 1.0.0-rc1-final -r coreclr -a x64
• Change Directory to Project Folder
Changes the directory to the project source path where
the DNU commands are executed.
Note: Make sure to replace your-project-path with your
own project path.
cd src/your-project-path
• Restore DNU Dependencies
Restores the project dependencies.
echo --- EXECUTING RESTORE! ---
dnu restore
• Build Project with DNU
Builds the artifact.
echo --- EXECUTING BUILD! ---
dnu build
© IBM Corporation54
A2: Example Unit Test Class
using dotnetCloudantWebstarter.Models;
using CloudantDotNet.Controllers;
using Xunit;
namespace dotnetCloudantWebstarter.Tests {
public class UnitTests {
// Verifies ToDoItem constructor!
[Fact]
public void ToDoItem_ConstructorTest() {
ToDoItem item = new ToDoItem();
Assert.NotNull(item);
Assert.Null(item.id);
Assert.Null(item.rev);
Assert.Null(item.text);
}
// Verifies IntegrationTests constructor!
// NB! IntegrationTests_ConstructorTest()can only be run if an integration test class is setup accordingly! If no such class exists, disable the test.
[Fact]
public void IntegrationTests_ConstructorTest() {
IntegrationTests integrationTest = new IntegrationTests();
Assert.NotNull(integrationTest.cloudantCreds);
Assert.NotNull(integrationTest.createItem);
Assert.NotNull(integrationTest.updateItem);
Assert.NotNull(integrationTest.deleteItem);
}
}
}
© IBM Corporation55
A3-1: Example Integration Test Class
using System;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Microsoft.AspNet.Mvc;
using Newtonsoft.Json;
using Microsoft.Extensions.OptionsModel;
using dotnetCloudantWebstarter.Models;
using CloudantDotNet.Controllers;
using Xunit;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
namespace dotnetCloudantWebstarter.Tests {
public class IntegrationTests {
private static readonly string dbName = "todos";
public Creds cloudantCreds;
public ToDoItem createItem;
public ToDoItem updateItem;
public ToDoItem deleteItem;
public string createItemResponseID;
public string createItemResponseRev;
public string updateItemResponseID;
public string updateItemResponseRev;
public string deleteItemResponseID;
public string deleteItemResponseRev;
public bool createTestResult;
public bool updateTestResult;
public bool deleteTestResult;
// -----------------------------------------
© IBM Corporation56
A3-2: Example Integration Test Class (Continued)
public IntegrationTests() {
cloudantCreds = new Creds();
string vcapServices = System.Environment.GetEnvironmentVariable("VCAP_SERVICES");
if (vcapServices != null) {
dynamic json = JsonConvert.DeserializeObject(vcapServices);
foreach (dynamic obj in json.Children()) {
if (((string)obj.Name).ToLowerInvariant().Contains("cloudant")) {
dynamic credentials = (((JProperty)obj).Value[0] as dynamic).credentials;
if (credentials != null) {
cloudantCreds.host = credentials.host;
cloudantCreds.username = credentials.username;
cloudantCreds.password = credentials.password;
break;
}
}
}
}
createItem = new ToDoItem();
updateItem = new ToDoItem();
deleteItem = new ToDoItem();
}
// ------------------------------------------------
© IBM Corporation57
A3-3: Example Integration Test Class (Continued)
[Fact]
public async void testCreate() {
createTestResult = await create(JsonConvert.DeserializeObject<ToDoItem>("{ 'text': 'Sample 1' }"), "testCreate");
Assert.True(createTestResult);
}
[Fact]
public async void testUpdate() {
await create(JsonConvert.DeserializeObject<ToDoItem>("{ 'text': 'Sample 2' }"), "testUpdate");
updateItem.id = updateItemResponseID;
updateItem.rev = updateItemResponseRev;
updateItem.text = "TestUpdate";
updateTestResult = await update(updateItem, "testUpdate");
Assert.True(updateTestResult);
}
[Fact]
public async void testDelete() {
await create(JsonConvert.DeserializeObject<ToDoItem>("{ 'text': 'Sample 3' }"), "testDelete");
deleteItem.id = deleteItemResponseID;
deleteItem.rev = deleteItemResponseRev;
deleteTestResult = await delete(deleteItem, "testDelete");
Assert.True(deleteTestResult);
}
// ------------------------------------------------
© IBM Corporation58
A3-4: Example Integration Test Class (Continued)
[HttpPost]
public async Task<bool> create(ToDoItem item, string invoker) {
using (var client = cloudantClient()) {
var response = await client.PostAsJsonAsync(dbName, item);
if (response.IsSuccessStatusCode) {
var responseJson = await response.Content.ReadAsAsync<ToDoItem>();
if(invoker.Equals("testCreate")) {
this.createItemResponseID = responseJson.id;
this.createItemResponseRev = responseJson.rev;
} else if(invoker.Equals("testUpdate")) {
this.updateItemResponseID = responseJson.id;
this.updateItemResponseRev = responseJson.rev;
} else if(invoker.Equals("testDelete")) {
this.deleteItemResponseID = responseJson.id;
this.deleteItemResponseRev = responseJson.rev;
}
return true;
}
string msg = "Failure to POST. Invoked by: " + invoker + ". Status Code: " + response.StatusCode + ". Reason: " + response.ReasonPhrase;
Console.WriteLine(msg);
return false;
}
}
// ------------------------------------------------
© IBM Corporation59
A3-5: Example Integration Test Class (Continued)
[HttpPut]
public async Task<bool> update(ToDoItem item, string invoker) {
using (var client = cloudantClient()) {
var response = await client.PutAsJsonAsync(dbName + "/" + item.id + "?rev=" + item.rev, item);
if (response.IsSuccessStatusCode) {
var responseJson = await response.Content.ReadAsAsync<ToDoItem>();
Console.WriteLine("ITEM ID: " + responseJson.id + "ITEM REV: " + responseJson.rev);
return true;
}
string msg = "Failure to PUT. Invoked by: " + invoker + ". Status Code: " + response.StatusCode + ". Reason: " + response.ReasonPhrase;
Console.WriteLine(msg);
return false;
}
}
// --------------------------------------------------
[HttpDelete]
public async Task<bool> delete(ToDoItem item, string invoker) {
using (var client = cloudantClient()) {
var response = await client.DeleteAsync(dbName + "/" + item.id + "?rev=" + item.rev);
if (response.IsSuccessStatusCode) {
return true;
}
string msg = "Failure to POST. Invoked by: " + invoker + ". Status Code: " + response.StatusCode + ". Reason: " + response.ReasonPhrase;
Console.WriteLine(msg);
return false;
}
}
// ------------------------------------------------
© IBM Corporation60
A3-5: Example Integration Test Class (Continued)
private HttpClient cloudantClient() {
if (cloudantCreds.username == null || cloudantCreds.password == null || cloudantCreds.host == null) {
throw new Exception("Missing Cloudant NoSQL DB service credentials");
}
var auth = Convert.ToBase64String(Encoding.ASCII.GetBytes(cloudantCreds.username + ":" + cloudantCreds.password));
HttpClient client = HttpClientFactory.Create(new LoggingHandler());
client.BaseAddress = new Uri("https://" + cloudantCreds.host);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth);
return client;
}
} // END IntegrationTests CLASS!
// ------------------------------------------------
public class Creds {
public string username { get; set; }
public string password { get; set; }
public string host { get; set; }
}
class LoggingHandler : DelegatingHandler {
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
Console.WriteLine("{0}t{1}", request.Method, request.RequestUri);
var response = await base.SendAsync(request, cancellationToken);
Console.WriteLine(response.StatusCode);
return response;
}
}
}
© IBM Corporation61
Presented by:
How to set up an ASP.NET 5 Continuous Delivery
Pipeline using IBM Bluemix DevOps Services
Richard Johansson
Linus Karlsson
Fredrik Lindahl
Olof Kindblad
DevOps Interns, Bluemix Garage, IBM Malmö
2016-03-16
The End

Weitere ähnliche Inhalte

Was ist angesagt?

JavaOne 2016 - Pipeline as code
JavaOne 2016 - Pipeline as codeJavaOne 2016 - Pipeline as code
JavaOne 2016 - Pipeline as codeBert Jan Schrijver
 
OpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgart
OpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgartOpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgart
OpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgartTobias Schneck
 
Pipeline based deployments on Jenkins
Pipeline based deployments  on JenkinsPipeline based deployments  on Jenkins
Pipeline based deployments on JenkinsKnoldus Inc.
 
Jenkins Pipeline @ Scale. Building Automation Frameworks for Systems Integration
Jenkins Pipeline @ Scale. Building Automation Frameworks for Systems IntegrationJenkins Pipeline @ Scale. Building Automation Frameworks for Systems Integration
Jenkins Pipeline @ Scale. Building Automation Frameworks for Systems IntegrationOleg Nenashev
 
Jenkins days workshop pipelines - Eric Long
Jenkins days workshop  pipelines - Eric LongJenkins days workshop  pipelines - Eric Long
Jenkins days workshop pipelines - Eric Longericlongtx
 
Pipeline as code - new feature in Jenkins 2
Pipeline as code - new feature in Jenkins 2Pipeline as code - new feature in Jenkins 2
Pipeline as code - new feature in Jenkins 2Michal Ziarnik
 
7 Habits of Highly Effective Jenkins Users
7 Habits of Highly Effective Jenkins Users7 Habits of Highly Effective Jenkins Users
7 Habits of Highly Effective Jenkins UsersJules Pierre-Louis
 
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...Evgeniy Kuzmin
 
Brujug Jenkins pipeline scalability
Brujug Jenkins pipeline scalabilityBrujug Jenkins pipeline scalability
Brujug Jenkins pipeline scalabilityDamien Coraboeuf
 
Continuous Deployment of your Application - SpringOne Tour Dallas
Continuous Deployment of your Application - SpringOne Tour DallasContinuous Deployment of your Application - SpringOne Tour Dallas
Continuous Deployment of your Application - SpringOne Tour DallasVMware Tanzu
 
Product Overview: The New IBM UrbanCode Deploy 6.0
Product Overview: The New IBM UrbanCode Deploy 6.0Product Overview: The New IBM UrbanCode Deploy 6.0
Product Overview: The New IBM UrbanCode Deploy 6.0IBM UrbanCode Products
 
Automated acceptance test
Automated acceptance testAutomated acceptance test
Automated acceptance testBryan Liu
 
Ci For The Web 2.0 Guy Or Gal
Ci For The Web 2.0 Guy Or GalCi For The Web 2.0 Guy Or Gal
Ci For The Web 2.0 Guy Or GalChad Woolley
 
OpenShift Build Pipelines @ Lightweight Java User Group Meetup
OpenShift Build Pipelines @ Lightweight Java User Group MeetupOpenShift Build Pipelines @ Lightweight Java User Group Meetup
OpenShift Build Pipelines @ Lightweight Java User Group MeetupTobias Schneck
 
Continuous Delivery - Pipeline as-code
Continuous Delivery - Pipeline as-codeContinuous Delivery - Pipeline as-code
Continuous Delivery - Pipeline as-codeMike van Vendeloo
 
Jenkins Declarative Pipelines 101
Jenkins Declarative Pipelines 101Jenkins Declarative Pipelines 101
Jenkins Declarative Pipelines 101Malcolm Groves
 
Continuous Testing using Shippable and Docker
Continuous Testing using Shippable and DockerContinuous Testing using Shippable and Docker
Continuous Testing using Shippable and DockerMukta Aphale
 
Effective Platform Building with Kubernetes. Is K8S new Linux?
Effective Platform Building with Kubernetes. Is K8S new Linux?Effective Platform Building with Kubernetes. Is K8S new Linux?
Effective Platform Building with Kubernetes. Is K8S new Linux?Wojciech Barczyński
 

Was ist angesagt? (20)

JavaOne 2016 - Pipeline as code
JavaOne 2016 - Pipeline as codeJavaOne 2016 - Pipeline as code
JavaOne 2016 - Pipeline as code
 
OpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgart
OpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgartOpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgart
OpenShift-Build-Pipelines: Build -> Test -> Run! @JavaForumStuttgart
 
Pipeline based deployments on Jenkins
Pipeline based deployments  on JenkinsPipeline based deployments  on Jenkins
Pipeline based deployments on Jenkins
 
Jenkins Pipeline @ Scale. Building Automation Frameworks for Systems Integration
Jenkins Pipeline @ Scale. Building Automation Frameworks for Systems IntegrationJenkins Pipeline @ Scale. Building Automation Frameworks for Systems Integration
Jenkins Pipeline @ Scale. Building Automation Frameworks for Systems Integration
 
Jenkins days workshop pipelines - Eric Long
Jenkins days workshop  pipelines - Eric LongJenkins days workshop  pipelines - Eric Long
Jenkins days workshop pipelines - Eric Long
 
Pipeline as code - new feature in Jenkins 2
Pipeline as code - new feature in Jenkins 2Pipeline as code - new feature in Jenkins 2
Pipeline as code - new feature in Jenkins 2
 
7 Habits of Highly Effective Jenkins Users
7 Habits of Highly Effective Jenkins Users7 Habits of Highly Effective Jenkins Users
7 Habits of Highly Effective Jenkins Users
 
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
 
Overview
OverviewOverview
Overview
 
Brujug Jenkins pipeline scalability
Brujug Jenkins pipeline scalabilityBrujug Jenkins pipeline scalability
Brujug Jenkins pipeline scalability
 
Continuous Deployment of your Application - SpringOne Tour Dallas
Continuous Deployment of your Application - SpringOne Tour DallasContinuous Deployment of your Application - SpringOne Tour Dallas
Continuous Deployment of your Application - SpringOne Tour Dallas
 
Product Overview: The New IBM UrbanCode Deploy 6.0
Product Overview: The New IBM UrbanCode Deploy 6.0Product Overview: The New IBM UrbanCode Deploy 6.0
Product Overview: The New IBM UrbanCode Deploy 6.0
 
Automated acceptance test
Automated acceptance testAutomated acceptance test
Automated acceptance test
 
Ci For The Web 2.0 Guy Or Gal
Ci For The Web 2.0 Guy Or GalCi For The Web 2.0 Guy Or Gal
Ci For The Web 2.0 Guy Or Gal
 
sed.pdf
sed.pdfsed.pdf
sed.pdf
 
OpenShift Build Pipelines @ Lightweight Java User Group Meetup
OpenShift Build Pipelines @ Lightweight Java User Group MeetupOpenShift Build Pipelines @ Lightweight Java User Group Meetup
OpenShift Build Pipelines @ Lightweight Java User Group Meetup
 
Continuous Delivery - Pipeline as-code
Continuous Delivery - Pipeline as-codeContinuous Delivery - Pipeline as-code
Continuous Delivery - Pipeline as-code
 
Jenkins Declarative Pipelines 101
Jenkins Declarative Pipelines 101Jenkins Declarative Pipelines 101
Jenkins Declarative Pipelines 101
 
Continuous Testing using Shippable and Docker
Continuous Testing using Shippable and DockerContinuous Testing using Shippable and Docker
Continuous Testing using Shippable and Docker
 
Effective Platform Building with Kubernetes. Is K8S new Linux?
Effective Platform Building with Kubernetes. Is K8S new Linux?Effective Platform Building with Kubernetes. Is K8S new Linux?
Effective Platform Building with Kubernetes. Is K8S new Linux?
 

Ähnlich wie How to set up an ASP.NET 5 Continuous Delivery Pipeline using IBM Bluemix DevOps Services

Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...
Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...
Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...VMware Tanzu
 
UrbanCode Deploy course and product overview slides
UrbanCode Deploy course and product overview slidesUrbanCode Deploy course and product overview slides
UrbanCode Deploy course and product overview slidesIBM Rational software
 
IBM Pulse session 2727: Continuous delivery -accelerated with DevOps
IBM Pulse session 2727: Continuous delivery -accelerated with DevOpsIBM Pulse session 2727: Continuous delivery -accelerated with DevOps
IBM Pulse session 2727: Continuous delivery -accelerated with DevOpsSanjeev Sharma
 
Deploying Mule Applications with Jenkins, Azure and BitBucket (1).pptx
Deploying Mule Applications with Jenkins, Azure and BitBucket (1).pptxDeploying Mule Applications with Jenkins, Azure and BitBucket (1).pptx
Deploying Mule Applications with Jenkins, Azure and BitBucket (1).pptxPankaj Goyal
 
Simplified DevOps Bliss -with OpenAI API
Simplified DevOps Bliss -with OpenAI APISimplified DevOps Bliss -with OpenAI API
Simplified DevOps Bliss -with OpenAI APIVictorSzoltysek
 
Twelve-Factor App: Software Application Architecture
Twelve-Factor App: Software Application ArchitectureTwelve-Factor App: Software Application Architecture
Twelve-Factor App: Software Application ArchitectureSigfred Balatan Jr.
 
Práticas, Técnicas e Ferramentas para Continuous Delivery com ALM
Práticas, Técnicas e Ferramentas para Continuous Delivery com ALMPráticas, Técnicas e Ferramentas para Continuous Delivery com ALM
Práticas, Técnicas e Ferramentas para Continuous Delivery com ALMMarcelo Sousa Ancelmo
 
Get Mapped: Using Value Stream Mapping to Create a DevOps Adoption Roadmap
Get Mapped: Using Value Stream Mapping to Create a DevOps Adoption RoadmapGet Mapped: Using Value Stream Mapping to Create a DevOps Adoption Roadmap
Get Mapped: Using Value Stream Mapping to Create a DevOps Adoption RoadmapIBM UrbanCode Products
 
Automated CI with AEM Cloud service
Automated CI with AEM Cloud serviceAutomated CI with AEM Cloud service
Automated CI with AEM Cloud serviceJakub Wadolowski
 
Agile Bodensee - Testautomation & Continuous Delivery Workshop
Agile Bodensee - Testautomation & Continuous Delivery WorkshopAgile Bodensee - Testautomation & Continuous Delivery Workshop
Agile Bodensee - Testautomation & Continuous Delivery WorkshopMichael Palotas
 
Turnkey Continuous Delivery
Turnkey Continuous DeliveryTurnkey Continuous Delivery
Turnkey Continuous DeliveryGianni Bombelli
 
Why it's dangerous to turn off automatic updates and here's how to do it
Why it's dangerous to turn off automatic updates and here's how to do itWhy it's dangerous to turn off automatic updates and here's how to do it
Why it's dangerous to turn off automatic updates and here's how to do itOnni Hakala
 
Scaffolding for Serverless: lightning talk for AWS Arlington Meetup
Scaffolding for Serverless: lightning talk for AWS Arlington MeetupScaffolding for Serverless: lightning talk for AWS Arlington Meetup
Scaffolding for Serverless: lightning talk for AWS Arlington MeetupChris Shenton
 
Developing MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack RoutersDeveloping MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack RoutersBGA Cyber Security
 
Continuous Deployment of your Application @SpringOne
Continuous Deployment of your Application @SpringOneContinuous Deployment of your Application @SpringOne
Continuous Deployment of your Application @SpringOneciberkleid
 
Continuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CIContinuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CIDavid Hahn
 
CICD Pipeline - AWS Azure
CICD Pipeline - AWS AzureCICD Pipeline - AWS Azure
CICD Pipeline - AWS AzureRatan Das
 
DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...
DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...
DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...Amazon Web Services
 

Ähnlich wie How to set up an ASP.NET 5 Continuous Delivery Pipeline using IBM Bluemix DevOps Services (20)

Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...
Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...
Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gat...
 
UrbanCode Deploy course and product overview slides
UrbanCode Deploy course and product overview slidesUrbanCode Deploy course and product overview slides
UrbanCode Deploy course and product overview slides
 
IBM Pulse session 2727: Continuous delivery -accelerated with DevOps
IBM Pulse session 2727: Continuous delivery -accelerated with DevOpsIBM Pulse session 2727: Continuous delivery -accelerated with DevOps
IBM Pulse session 2727: Continuous delivery -accelerated with DevOps
 
Deploying Mule Applications with Jenkins, Azure and BitBucket (1).pptx
Deploying Mule Applications with Jenkins, Azure and BitBucket (1).pptxDeploying Mule Applications with Jenkins, Azure and BitBucket (1).pptx
Deploying Mule Applications with Jenkins, Azure and BitBucket (1).pptx
 
Simplified DevOps Bliss -with OpenAI API
Simplified DevOps Bliss -with OpenAI APISimplified DevOps Bliss -with OpenAI API
Simplified DevOps Bliss -with OpenAI API
 
Twelve-Factor App: Software Application Architecture
Twelve-Factor App: Software Application ArchitectureTwelve-Factor App: Software Application Architecture
Twelve-Factor App: Software Application Architecture
 
Práticas, Técnicas e Ferramentas para Continuous Delivery com ALM
Práticas, Técnicas e Ferramentas para Continuous Delivery com ALMPráticas, Técnicas e Ferramentas para Continuous Delivery com ALM
Práticas, Técnicas e Ferramentas para Continuous Delivery com ALM
 
Get Mapped: Using Value Stream Mapping to Create a DevOps Adoption Roadmap
Get Mapped: Using Value Stream Mapping to Create a DevOps Adoption RoadmapGet Mapped: Using Value Stream Mapping to Create a DevOps Adoption Roadmap
Get Mapped: Using Value Stream Mapping to Create a DevOps Adoption Roadmap
 
CI/CD with Github Actions
CI/CD with Github ActionsCI/CD with Github Actions
CI/CD with Github Actions
 
Automated CI with AEM Cloud service
Automated CI with AEM Cloud serviceAutomated CI with AEM Cloud service
Automated CI with AEM Cloud service
 
Agile Bodensee - Testautomation & Continuous Delivery Workshop
Agile Bodensee - Testautomation & Continuous Delivery WorkshopAgile Bodensee - Testautomation & Continuous Delivery Workshop
Agile Bodensee - Testautomation & Continuous Delivery Workshop
 
Homestead demo
Homestead demoHomestead demo
Homestead demo
 
Turnkey Continuous Delivery
Turnkey Continuous DeliveryTurnkey Continuous Delivery
Turnkey Continuous Delivery
 
Why it's dangerous to turn off automatic updates and here's how to do it
Why it's dangerous to turn off automatic updates and here's how to do itWhy it's dangerous to turn off automatic updates and here's how to do it
Why it's dangerous to turn off automatic updates and here's how to do it
 
Scaffolding for Serverless: lightning talk for AWS Arlington Meetup
Scaffolding for Serverless: lightning talk for AWS Arlington MeetupScaffolding for Serverless: lightning talk for AWS Arlington Meetup
Scaffolding for Serverless: lightning talk for AWS Arlington Meetup
 
Developing MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack RoutersDeveloping MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack Routers
 
Continuous Deployment of your Application @SpringOne
Continuous Deployment of your Application @SpringOneContinuous Deployment of your Application @SpringOne
Continuous Deployment of your Application @SpringOne
 
Continuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CIContinuous Integration/Deployment with Gitlab CI
Continuous Integration/Deployment with Gitlab CI
 
CICD Pipeline - AWS Azure
CICD Pipeline - AWS AzureCICD Pipeline - AWS Azure
CICD Pipeline - AWS Azure
 
DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...
DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...
DevOps on Windows: How to Deploy Complex Windows Workloads | AWS Public Secto...
 

Kürzlich hochgeladen

Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 

Kürzlich hochgeladen (20)

Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 

How to set up an ASP.NET 5 Continuous Delivery Pipeline using IBM Bluemix DevOps Services

  • 1. © IBM Corporation1 Presented by: How to set up an ASP.NET 5 Continuous Delivery Pipeline using IBM Bluemix DevOps Services Richard Johansson Linus Karlsson Fredrik Lindahl Olof Kindblad DevOps Interns, Bluemix Garage, IBM Malmö 2016-03-16
  • 2. © IBM Corporation2 Introduction This presentation is a result of an applied project internship carried out during the spring of 2016 by four Information Systems students from Lund University School of Economics and Management for IBM Bluemix Garage in Malmö, Sweden. The project’s purpose was to assess the current capabilities, opportunities and pain points in using the ASP.NET 5 runtime with Bluemix and the DevOps Services, and based on that provide recommendations to IBM on how they can enhance that experience and thus motivate more .NET developers to choose Bluemix, DevOps Services and the Bluemix Garage Method as their Continuous Delivery and DevOps enablers. The result of the assessment showed that the Bluemix and .NET experience is not bad at all, although one pain point was that there is no built-in support for a .NET runtime environment in the DevOps Services Delivery Pipeline – which is not surprising since ASP.NET 5 is so far only tagged as an experimental runtime in Bluemix. A .NET supportive runtime environment is however possible to install manually, as the Delivery Pipeline offers its users to specify their own manual build scripts. How to do this is explained in this presentation. Altogether, we can conclude that Bluemix and the DevOps Services is most definitely a full-worthy option to other popular hybrid cloud solutions for .NET developers. In this presentation we will explain how to set up a complete IBM native tool chain for Continuous Delivery by using the IBM DevOps Services Build & Deploy function, also known as the Delivery Pipeline. We will develop, build, (autonomously) unit test, integration test, load test and deploy an ASP.NET 5 application with a Cloudant NoSQL database to Bluemix.
  • 3. © IBM Corporation3 Orientation This guide picks up and extends the Getting started with ASP.NET 5 in Bluemix guide, which shows how to create a simple HelloWorld ASP.NET 5 application and deploy it to Bluemix. That guide briefly mentions the ASP.NET 5 + Cloudant Starter App boilerplate, which can be used to generate a pre-built ASP.NET 5 application with basic CRUD functionality using a Cloudant NoSQL database. That is the boilerplate we used as a starting point for this guide. Our own application extends that one with automated unit tests, automated integration tests and the required project dependencies for building and testing in the DevOps Services Delivery Pipeline. The Getting started with ASP.NET 5 in Bluemix guide: https://developer.ibm.com/bluemix/2015/05/18/getting-started-asp-net-5-bluemix The ASP.NET 5 + Cloudant Starter App boilerplate that we started from is available here: https://github.com/IBM-Bluemix/asp.net5-cloudant Our finished application that was created during the making of this guide is available here: https://github.com/FredrikLindahl/ASP.NET-5-Cloudant-for-Bluemix-Delivery-Pipeline
  • 4. © IBM Corporation4 The Delivery Pipeline Our Delivery Pipeline was configured in four stages. – The Build stage has two jobs: one Build job that builds the application and the runtime in the Delivery Pipeline server environment, and one Unit Test job that first builds and then executes some basic unit tests. – If the first stage is passed, the Test stage is triggered. This stage has one job: an Integration Test job that runs some basic CRUD tests against the Cloudant database. – If the second stage is passed, the Staging stage is triggered. This stage has two jobs: a Deployment job that deploys the build to a “pre-production” test environment in the Bluemix cloud, which is accessed through myApplication-PreProd.eu-gb.mybluemix.net. The stage also has a Load Test job that runs some performance tests using the third party tool Load Impact that is available as a Bluemix Service and API. – If the third stage is passed, the Production stage is triggered. This stage only has one job: a Deployment job that deploys the build to a live production environment in the Bluemix cloud, accessible via myApplication.eu- gb.mybluemix.net. The Toolchain IDE: Visual Studio Code SCM: DevOps Services JazzHub CI & CD: DevOps Services Delivery Pipeline Unit Testing: xUnit Integration Testing: xUnit Load Testing: Load Impact
  • 5. © IBM Corporation5 text Overview of the Delivery Pipeline Setup Process
  • 6. © IBM Corporation6© IBM Corporation6 The Guide Created and verified in March 2016
  • 7. © IBM Corporation7© IBM Corporation7 Start Main Process Delivery Pipeline
  • 8. © IBM Corporation8© IBM Corporation8 Start Main Process Delivery Pipeline
  • 9. © IBM Corporation9 Delivery Pipeline 1. Create Application from Boilerplate • Go to https://github.com/IBM-Bluemix/asp.net5-cloudant • Click Deploy to Bluemix • When finished, click EDIT CODE 1. Create Application from Boilerplate
  • 10. © IBM Corporation10 Delivery Pipeline 2. Develop Code • Make some code changes, i.e. change the title of the page to “HelloWorldIBM” 3. Commit and Push Code • Commit and push code changes to your JazzHub git repository. 4. Trigger Delivery Pipeline This step is done automatically each time a code change is pushed to the JazzHub git repository. 2. Develop Code 3. Commit and Push Code 4. Trigger Delivery Pipeline
  • 11. © IBM Corporation11 Delivery Pipeline 5. Add Build Stage This one-time-step is automatically done by the Delivery Pipeline as part of setting up the structure. 6. Add Build Job This one-time-step is automatically done by the Delivery Pipeline as part of setting up the structure. 7. Add Unit Test Job This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline. • Click on Configure Stage in the Build Stage • Go to the tab Jobs • Add a new Test job and name it "Unit Test" • Select Tester Type: Simple • Make sure that the Unit Test Job is sequentially positioned after the Build Job in the Build Stage 8. Deploy to Build Stage This continuous-delivery-step is automatically done each time the Delivery Pipeline is triggered. 5. Add Build Stage 6. Add Build Job 7. Add Unit Test Job 8. Deploy to Build Stage
  • 12. © IBM Corporation12© IBM Corporation12 Start Sub-Process Delivery Pipeline: Build
  • 13. © IBM Corporation13© IBM Corporation13 Start Sub-Process Delivery Pipeline: Build
  • 14. © IBM Corporation14 Overview Sub-Process Delivery Pipeline: Build
  • 15. © IBM Corporation15 Delivery Pipeline: Build 9. Configure Builder Type to Shell Script 10. Add ASP.NET 5 Manual Build Script 9. Configure Builder Type to Shell Script • In the Delivery Pipeline, select Configure on the Build Stage • Go to the tab Jobs • Set Builder Type to Shell Script 10. Add ASP.NET Manual Build Script • Insert the manual build script below. Further explanation of what the script does is available in appendix A1. • Make sure to replace the project path with your own in cd src/your-project-path #!/bin/bash echo --- UPDATING DEPENDENCIES! --- sudo apt-get update echo --- DOWNLOADING PACKAGES! --- sudo apt-get -y install libunwind8 gettext libssl-dev libcurl3-dev zlib1g libcurl4-openssl-dev libicu-dev uuid-dev echo --- DOWNLOADING DNVM! --- curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh echo --- INSTALLING DNVM! --- dnvm install 1.0.0-rc1-final -r coreclr -a x64 echo --- EXECUTING RESTORE! --- cd src/your-project-path dnu restore echo --- EXECUTING BUILD! --- dnu build
  • 16. © IBM Corporation16 Delivery Pipeline: Build 11. Run Build Script 12. Upload Artifact 11. Run Build Script This step is automated when triggering the Delivery Pipeline. To manually run it, click Run Stage on the Build Stage. 12. Upload Artifact The Build Job in the Build Stage is automatically run and the build artifact is automatically uploaded.
  • 17. © IBM Corporation17© IBM Corporation17 End Sub-Process Delivery Pipeline: Build
  • 18. © IBM Corporation18© IBM Corporation18 Start Sub-Process Delivery Pipeline: Unit Test
  • 19. © IBM Corporation19© IBM Corporation19 Start Sub-Process Delivery Pipeline: Unit Test
  • 20. © IBM Corporation20 Overview Sub-Process Delivery Pipeline: Unit Test
  • 21. © IBM Corporation21 Delivery Pipeline: Unit Test 13. Add xUnit Dependencies to project.json 13. Add xUnit Dependencies to project.json • Navigate to the project.json file of your application and add the following dependencies: "xunit": "2.1.0" "xunit.runner.dnx": "2.1.0-rc1-build204“ The project.json file should look something like this: { "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final", "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "Newtonsoft.Json": "7.0.1", "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", "Microsoft.AspNet.WebApi.Client": "5.2.3", "System.Net.Http": "4.0.0", "System.Runtime.Serialization.Xml": "4.0.10", "xunit": "2.1.0", "xunit.runner.dnx": "2.1.0-rc1-build204" }, "commands": { "kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5004" }, "frameworks": { "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
  • 22. © IBM Corporation22 Delivery Pipeline: Unit Test 14. Add xUnit Command to project.json 14. Add xUnit Command to project.json • Navigate to the project.json file of your application and add the following command: test": "xunit.runner.dnx" The project.json file should look something like this: { "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final", "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "Newtonsoft.Json": "7.0.1", "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", "Microsoft.AspNet.WebApi.Client": "5.2.3", "System.Net.Http": "4.0.0", "System.Runtime.Serialization.Xml": "4.0.10", "xunit": "2.1.0", "xunit.runner.dnx": "2.1.0-rc1-build204" }, "commands": { "kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5004", "test": "xunit.runner.dnx" }, "frameworks": { "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
  • 23. © IBM Corporation23 Delivery Pipeline: Unit Test 15. Create Unit Test Class 16. Write Unit Test(s) 15. Create Unit Test Class • In Visual Studio, navigate to your project folder • Add a new folder in src called "Tests" • Create a new file in the Tests folder called "UnitTests.cs“ 16. Write Unit Test(s) • Open the UnitTests class and write some unit tests. • Make sure to import the Xunit package at the top of the class (using Xunit;) and to specify the correct namespace/folder that the class lies in (namespace your-project-path.Tests). • An example of a class that has a few basic unit tests can be found in appendix A2.
  • 24. © IBM Corporation24 Delivery Pipeline: Unit Test 17. Insert ASP.NET 5 Manual Build Script 18. Remove DNU Build From Script 19. Insert Unit Test Call Script 20. Run Unit Tests 17. Insert ASP.NET 5 Manual Build Script • In the Delivery Pipeline, navigate to the Unit Test Job in the Build Stage • Insert the manual build script in the Test Command console 18. Remove DNU Build From Script • Delete the following lines from the manual build Shell Script: echo --- EXECUTING BUILD! --- dnu build 19. Insert Unit Test Call Script • Call the xUnit unit test(s) by adding the below command at the end of the Shell Script: dnx test -class path-to-unittest-class • Example: dnx test -class dotnetCloudantWebstarter.Tests.UnitTests 20. Run Unit Tests • This step is automatically run when committing code changes and thus triggering the Build Stage and its Build Job and Unit Test Job. • (For manual triggering, click Run Stage in the Build Stage).
  • 25. © IBM Corporation25© IBM Corporation25 End Sub-Process Delivery Pipeline: Unit Test
  • 26. © IBM Corporation26© IBM Corporation26 Continue Main Process Delivery Pipeline
  • 27. © IBM Corporation27© IBM Corporation27 Continue Main Process Delivery Pipeline
  • 28. © IBM Corporation28 Delivery Pipeline 21. Add Test Stage This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline. • In the Delivery Pipeline, select ADD STAGE • Name the stage "Test" • Input Type: Build Artifacts • Stage: Build • Job: Build • State Trigger: Run jobs when the previous stage is completed • Make sure that the Test Stage is positioned after the Build Stage in the Delivery Pipeline 22. Add Integration Test Job This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline. • Click on Configure Stage in the Test Stage • Go to the tab Jobs • Add a new Test job and name it "Integration Test" • Select Tester Type: Simple 23. Deploy to Test Stage This continuous-delivery-step can be set to be triggered either manually or automatically, by changing the State Trigger settings in the Test Stage. 21. Add Test Stage 22. Add Integration Test Job 23. Deploy to Test Stage
  • 29. © IBM Corporation29© IBM Corporation29 Start Sub-Process Delivery Pipeline: Integration Test
  • 30. © IBM Corporation30© IBM Corporation30 Start Sub-Process Delivery Pipeline: Integration Test
  • 31. © IBM Corporation31 Overview Sub-Process Delivery Pipeline: Integration Test
  • 32. © IBM Corporation32 Delivery Pipeline: Integration Test 24. Add xUnit Dependencies to project.json 25. Add xUnit Command to project.json 24. Add xUnit Dependencies to project.json Note: This step has already been described as part of the Unit Testing setup manual. It can thus be omitted if the xUnit dependencies and command is already configured. 25. Add xUnit Command to project.json Note: This step has already been described as part of the Unit Testing setup manual. It can thus be omitted if the xUnit dependencies and command is already configured.
  • 33. © IBM Corporation33 Delivery Pipeline: Integration Test 26. Create Integration Test Class 27. Write Integration Test(s) 26. Create Integration Test Class • In Visual Studio, navigate to your project folder • If not done already, add a new folder in src called "Tests" • Create a new file in the Tests folder called “IntegrationTests.cs“ 27. Write Integration Test(s) • Open the IntegrationTests class and write some integration tests. • Make sure to import the Xunit package at the top of the class (using Xunit;) and to specify the correct namespace/folder that the class lies in (namespace your-project-path.Tests). • An example of a class that has a few basic integration tests can be found in appendix A3.
  • 34. © IBM Corporation34 Delivery Pipeline: Integration Test 28. Add VCAP_SERVICES 28. Add VCAP_SERVICES This step establishes the connection between the database and the Delivery Pipeline. • Retrieve VCAP_SERVICES from the Cloudant DB Service • Navigate to the Application Overview via the Bluemix Dashboard • Select the Show Credentials arrow button from the Cloudant DB Service • Copy the VCAP_SERVICES credentials. • Add VCAP_SERVICES to the Delivery Pipeline Test Job • Click on Configure Stage in the Test Stage • Go to the tab ENVIRONMENT PROPERTIES • Add a new Text Area Property • Name: VCAP_SERVICES • Value: Paste the previously copied VCAP_SERVICES credentials
  • 35. © IBM Corporation35 Delivery Pipeline: Integration Test 29. Insert ASP.NET 5 Manual Build Script 30. Remove DNU Build From Script 31. Insert Integration Test Call Script 32. Run Integration Tests 29. Insert ASP.NET 5 Manual Build Script • In the Delivery Pipeline, navigate to the Integration Test Job in the Test Stage • Insert the manual build script in the Test Command console 30. Remove DNU Build From Script • Delete the following lines from the manual build Shell Script: echo --- EXECUTING BUILD! --- dnu build 31. Insert Integration Test Call Script • Call the xUnit integration test(s) by adding the below command at the end of the Shell Script: dnx test -class path-to-integrationtest-class • Example: dnx test -class dotnetCloudantWebstarter.Tests.IntegrationTests 32. Run Integration Tests • This stage can be set to be triggered manually or automatically by changing the State Trigger settings in the Test Stage. If automatic, this step is automatically triggered when the Build Stage is passed. • (For manual triggering, click Run Stage in the Test Stage).
  • 36. © IBM Corporation36© IBM Corporation36 End Sub-Process Delivery Pipeline: Integration Test
  • 37. © IBM Corporation37© IBM Corporation37 Continue Main Process Delivery Pipeline
  • 38. © IBM Corporation38© IBM Corporation38 Continue Main Process Delivery Pipeline
  • 39. © IBM Corporation39 Delivery Pipeline 33. Add Staging Stage This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline. • In the Delivery Pipeline, select ADD STAGE • Name the stage "Staging" • Input Type: Build Artifacts • Stage: Build • Job: Build • State Trigger: Run jobs when the previous stage is completed • Make sure that the Staging Stage is positioned after the Test Stage in the Delivery Pipeline 34. Add Pre-Production Deployment Job This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline. • Click on Configure Stage in the Staging Stage • Go to the tab Jobs • Add a new Deploy job and name it "Deploy to Pre-Prod“ • In the Deploy Script command window, add the following script in order to create and route to a new application which will act as our pre-production environment: cf push "${CF_APP}"-PreProd -n "${CF_APP}"-PreProd 33. Add Staging Stage 34. Add Pre-Production Deployment Job
  • 40. © IBM Corporation40 Delivery Pipeline 35. Add Load Impact Test Job This one-time step needs to be manually done as part of setting up the structure of the Delivery Pipeline. • In the Delivery Pipeline, click Configure Stage in the Staging Stage • Go to the tab Jobs • Add a new Test job and name it "Load Test" • Select Tester Type: Simple • Include the following command (as-is) in the Test Command console: curl -X POST "${LOAD_IMPACT_TEST_URL}" -u "${LOAD_IMPACT_API_TOKEN}:“ 36. Deploy to Staging Stage This continuous-delivery-step can be set to be triggered either manually or automatically, by changing the State Trigger settings in the Staging Stage. 35. Add Load Impact Test Job 36. Deploy to Staging Stage
  • 41. © IBM Corporation41© IBM Corporation41 Start Sub-Process Delivery Pipeline: Load Test
  • 42. © IBM Corporation42© IBM Corporation42 Start Sub-Process Delivery Pipeline: Load Test
  • 43. © IBM Corporation43 Overview Sub-Process Delivery Pipeline: Load Test
  • 44. © IBM Corporation44 Delivery Pipeline: Load Test 37. Add Load Impact as a Service 38. Open Load Impact Dashboard 39. Retrieve API Token 37. Add Load Impact as a Service • In Bluemix, select the space to add the Load Impact service to • Click ADD SERVICE OR API • Find and click the Load Impact service • Select the appropriate plan and name your service • Click CREATE This step can also be done using the Cloud Foundry CLI command: $ cf create-service loadimpact lifree my-loadimpact-service 38. Open Load Impact Dashboard • Navigate to the created Load Impact Service in Bluemix • Click OPEN LOAD IMPACT DASHBOARD • The Load Impact website is opened 39. Retrieve API Token • On the Load Impact website, navigate to Integrations Menu • Choose Load Impact API Token • Click Generate token and then copy and save the API token that is generated
  • 45. © IBM Corporation45 Delivery Pipeline: Load Test 40. Create Load Test 41. Run Load Test 42. Retrieve Load Impact Test ID 40. Create Load Test • On the Load Impact website, navigate to Tests Menu • Click Add user scenario • Paste the Bluemix application's Pre-Production URL and click Add • Set desirable VUs and duration • Click Save changes 41. Run Load Test • On the Load Impact website, in the Tests Menu, click Run test to create and run a simple load test 42. Retrieve Load Impact Test ID • On the Load Impact website, on the Tests page, click the test that you just ran • Select and copy the ID at the end of URL from your browser and save it For example, if your test case URL is https://app.loadimpact.com/tests/1234567, the config ID is 1234567. This ID, along with the API token, will be used when configuring your app to use Load Impact.
  • 46. © IBM Corporation46 Delivery Pipeline: Load Test 43. Set Environment Properties 44. Run Load Test in Delivery Pipeline 43. Set Environment Properties This step establishes the link between the Load Impact test and the Delivery Pipeline. • In the Delivery Pipeline's Staging Stage, click the Environment Properties tab • Click Add Property • Choose Text Property from the list and name it "LOAD_IMPACT_API_TOKEN" • For the value of this property, enter the Load Impact API key that you generated earlier • Click Add Property • Add another Text Property and name it "LOAD_IMPACT_TEST_URL" • For the value of this property, enter the following URL, replacing id with the config ID of the test case your created earlier: https://api.loadimpact.com/v2/test-configs/id/start 44. Run Load Test in Delivery Pipeline • This continuous-delivery-step can be set to be triggered either manually or automatically, by changing the State Trigger settings in the Staging Stage. For manual triggering, click Run Stage in the Staging Stage. • The test progress and results can be observed on the Load Impact website.
  • 47. © IBM Corporation47© IBM Corporation47 End Sub-Process Delivery Pipeline: Load Test
  • 48. © IBM Corporation48© IBM Corporation48 Continue Main Process Delivery Pipeline
  • 49. © IBM Corporation49© IBM Corporation49 Continue Main Process Delivery Pipeline
  • 50. © IBM Corporation50 Delivery Pipeline 45. Deploy to Production 45. Deploy to Production This continuous-delivery-step can be set to be triggered either manually or automatically, by changing the State Trigger settings in the Staging Stage.
  • 51. © IBM Corporation51© IBM Corporation51 End Main Process Delivery Pipeline
  • 52. © IBM Corporation52© IBM Corporation52 Appendix
  • 53. © IBM Corporation53 A1: Manual Build Script • Update Package Lists Updates the package lists to make sure that the latest packages are downloaded. echo --- UPDATING DEPENDENCIES! --- sudo apt-get update • Install Necessary Packages Installs the below listed necessary runtime environment packages. • libunwind8 • gettext • libssl-dev • libcurl3-dev • zlib1g • libcurl4-openssl-dev • libicu-dev • uuid-dev echo --- DOWNLOADING PACKAGES! --- sudo apt-get -y install libunwind8 gettext libssl-dev libcurl3-dev zlib1g libcurl4- openssl-dev libicu-dev uuid-dev • Download DNVM Downloads DNVM (.NET Version Manager) so that we can restore and build and publish. DNX (.NET Execution Manager) and DNU (.NET Utilites) are included in DNVM. echo --- DOWNLOADING DNVM! --- curl -sSL https://raw.githubusercontent.com/aspnet/Home/ dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh • Install DNVM Installs DNVM (.NET Version Manager). Note: The DNVM version must correspond to the required DNVM version listed in the application's project.json file. echo --- INSTALLING DNVM! --- dnvm install 1.0.0-rc1-final -r coreclr -a x64 • Change Directory to Project Folder Changes the directory to the project source path where the DNU commands are executed. Note: Make sure to replace your-project-path with your own project path. cd src/your-project-path • Restore DNU Dependencies Restores the project dependencies. echo --- EXECUTING RESTORE! --- dnu restore • Build Project with DNU Builds the artifact. echo --- EXECUTING BUILD! --- dnu build
  • 54. © IBM Corporation54 A2: Example Unit Test Class using dotnetCloudantWebstarter.Models; using CloudantDotNet.Controllers; using Xunit; namespace dotnetCloudantWebstarter.Tests { public class UnitTests { // Verifies ToDoItem constructor! [Fact] public void ToDoItem_ConstructorTest() { ToDoItem item = new ToDoItem(); Assert.NotNull(item); Assert.Null(item.id); Assert.Null(item.rev); Assert.Null(item.text); } // Verifies IntegrationTests constructor! // NB! IntegrationTests_ConstructorTest()can only be run if an integration test class is setup accordingly! If no such class exists, disable the test. [Fact] public void IntegrationTests_ConstructorTest() { IntegrationTests integrationTest = new IntegrationTests(); Assert.NotNull(integrationTest.cloudantCreds); Assert.NotNull(integrationTest.createItem); Assert.NotNull(integrationTest.updateItem); Assert.NotNull(integrationTest.deleteItem); } } }
  • 55. © IBM Corporation55 A3-1: Example Integration Test Class using System; using System.Threading.Tasks; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using Microsoft.AspNet.Mvc; using Newtonsoft.Json; using Microsoft.Extensions.OptionsModel; using dotnetCloudantWebstarter.Models; using CloudantDotNet.Controllers; using Xunit; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Configuration; using Newtonsoft.Json.Linq; namespace dotnetCloudantWebstarter.Tests { public class IntegrationTests { private static readonly string dbName = "todos"; public Creds cloudantCreds; public ToDoItem createItem; public ToDoItem updateItem; public ToDoItem deleteItem; public string createItemResponseID; public string createItemResponseRev; public string updateItemResponseID; public string updateItemResponseRev; public string deleteItemResponseID; public string deleteItemResponseRev; public bool createTestResult; public bool updateTestResult; public bool deleteTestResult; // -----------------------------------------
  • 56. © IBM Corporation56 A3-2: Example Integration Test Class (Continued) public IntegrationTests() { cloudantCreds = new Creds(); string vcapServices = System.Environment.GetEnvironmentVariable("VCAP_SERVICES"); if (vcapServices != null) { dynamic json = JsonConvert.DeserializeObject(vcapServices); foreach (dynamic obj in json.Children()) { if (((string)obj.Name).ToLowerInvariant().Contains("cloudant")) { dynamic credentials = (((JProperty)obj).Value[0] as dynamic).credentials; if (credentials != null) { cloudantCreds.host = credentials.host; cloudantCreds.username = credentials.username; cloudantCreds.password = credentials.password; break; } } } } createItem = new ToDoItem(); updateItem = new ToDoItem(); deleteItem = new ToDoItem(); } // ------------------------------------------------
  • 57. © IBM Corporation57 A3-3: Example Integration Test Class (Continued) [Fact] public async void testCreate() { createTestResult = await create(JsonConvert.DeserializeObject<ToDoItem>("{ 'text': 'Sample 1' }"), "testCreate"); Assert.True(createTestResult); } [Fact] public async void testUpdate() { await create(JsonConvert.DeserializeObject<ToDoItem>("{ 'text': 'Sample 2' }"), "testUpdate"); updateItem.id = updateItemResponseID; updateItem.rev = updateItemResponseRev; updateItem.text = "TestUpdate"; updateTestResult = await update(updateItem, "testUpdate"); Assert.True(updateTestResult); } [Fact] public async void testDelete() { await create(JsonConvert.DeserializeObject<ToDoItem>("{ 'text': 'Sample 3' }"), "testDelete"); deleteItem.id = deleteItemResponseID; deleteItem.rev = deleteItemResponseRev; deleteTestResult = await delete(deleteItem, "testDelete"); Assert.True(deleteTestResult); } // ------------------------------------------------
  • 58. © IBM Corporation58 A3-4: Example Integration Test Class (Continued) [HttpPost] public async Task<bool> create(ToDoItem item, string invoker) { using (var client = cloudantClient()) { var response = await client.PostAsJsonAsync(dbName, item); if (response.IsSuccessStatusCode) { var responseJson = await response.Content.ReadAsAsync<ToDoItem>(); if(invoker.Equals("testCreate")) { this.createItemResponseID = responseJson.id; this.createItemResponseRev = responseJson.rev; } else if(invoker.Equals("testUpdate")) { this.updateItemResponseID = responseJson.id; this.updateItemResponseRev = responseJson.rev; } else if(invoker.Equals("testDelete")) { this.deleteItemResponseID = responseJson.id; this.deleteItemResponseRev = responseJson.rev; } return true; } string msg = "Failure to POST. Invoked by: " + invoker + ". Status Code: " + response.StatusCode + ". Reason: " + response.ReasonPhrase; Console.WriteLine(msg); return false; } } // ------------------------------------------------
  • 59. © IBM Corporation59 A3-5: Example Integration Test Class (Continued) [HttpPut] public async Task<bool> update(ToDoItem item, string invoker) { using (var client = cloudantClient()) { var response = await client.PutAsJsonAsync(dbName + "/" + item.id + "?rev=" + item.rev, item); if (response.IsSuccessStatusCode) { var responseJson = await response.Content.ReadAsAsync<ToDoItem>(); Console.WriteLine("ITEM ID: " + responseJson.id + "ITEM REV: " + responseJson.rev); return true; } string msg = "Failure to PUT. Invoked by: " + invoker + ". Status Code: " + response.StatusCode + ". Reason: " + response.ReasonPhrase; Console.WriteLine(msg); return false; } } // -------------------------------------------------- [HttpDelete] public async Task<bool> delete(ToDoItem item, string invoker) { using (var client = cloudantClient()) { var response = await client.DeleteAsync(dbName + "/" + item.id + "?rev=" + item.rev); if (response.IsSuccessStatusCode) { return true; } string msg = "Failure to POST. Invoked by: " + invoker + ". Status Code: " + response.StatusCode + ". Reason: " + response.ReasonPhrase; Console.WriteLine(msg); return false; } } // ------------------------------------------------
  • 60. © IBM Corporation60 A3-5: Example Integration Test Class (Continued) private HttpClient cloudantClient() { if (cloudantCreds.username == null || cloudantCreds.password == null || cloudantCreds.host == null) { throw new Exception("Missing Cloudant NoSQL DB service credentials"); } var auth = Convert.ToBase64String(Encoding.ASCII.GetBytes(cloudantCreds.username + ":" + cloudantCreds.password)); HttpClient client = HttpClientFactory.Create(new LoggingHandler()); client.BaseAddress = new Uri("https://" + cloudantCreds.host); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); return client; } } // END IntegrationTests CLASS! // ------------------------------------------------ public class Creds { public string username { get; set; } public string password { get; set; } public string host { get; set; } } class LoggingHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { Console.WriteLine("{0}t{1}", request.Method, request.RequestUri); var response = await base.SendAsync(request, cancellationToken); Console.WriteLine(response.StatusCode); return response; } } }
  • 61. © IBM Corporation61 Presented by: How to set up an ASP.NET 5 Continuous Delivery Pipeline using IBM Bluemix DevOps Services Richard Johansson Linus Karlsson Fredrik Lindahl Olof Kindblad DevOps Interns, Bluemix Garage, IBM Malmö 2016-03-16 The End