Setting up Jenkins for UWP App Project

Setting up Jenkins is always hard, especially for UWP Project which is still lacking in term of toolings. In this article, I will share my (in)experience on integrating Jenkins within a UWP Application Development Project.

I am using a demo application project to demonstrate the setup. You can get it from here. The project (or rather the solution) contains four projects:

solution

  • AnagramCheckerApp, is a UWP application project. I use Template 10 as the starting point. The App it self is a simple application to check whether two words are anagram.

app

  • AnagramCheckerAppTest, is an Application Unit Test project. It contains testing for AnagramCheckerApp’s  MainPageViewModel in MainPageViewModelTest class.
  • Library, is a portable class library project containing the business logic (AnagramChecker class) used by AnagramCheckerApp.
  • LibraryTest, is a normal MSTest project to test the Library project, specifically testing implemenation of AnagramChecker in AnagramCheckerTest class.

The build actions included in Jenkins job are: building the AnagramCheckerApp project, running both AnagramcheckerAppTest and LibraryTest, and then publishing the result to a Slack channel. To achieve these following steps are done:

Install & Prepare Jenkins

Download Jenkins from here. Complete the setup but don’t start Jenkins directly. In Windows machine, by default Jenkins will be started as a Windows Service, we don’t want that because it doesn’t have the capability to launch UI application (or any process that has interactive mode) which is required when running test in AnagramCheckerAppTest.

I stopped and disabled the Jenkins’s Service from Windows’s “Services” manager application.

jenkins-disabled

And then launch Jenkins from the command line.

java -jar "C:\Program Files (x86)\Jenkins\jenkins.war"

Access Jenkins from localhost and complete the initial setup.

Install & Configure Required Plugins

There are 5 plugins used in this setup:

1. MSBuild Plugin

This plugin is used to integrate Jenkins with MSBuild for building the project/solution.

2. VSTest Runner Plugin

This plugin is used to integrate Jenkins with VSTest runner which is used to run tests in both AnagramCheckerAppTest project and LibraryTest. You might need to use other test runner plugin for other testing frameworks such as xUnit or NUnit.

3. MSTest Plugin

This plugin is used to convert the test result generated from VSTest Runner (usually it’s a *.trx file) into JUnit XML reports so it can be read/published by Jenkins.

4. Github Plugin

Since I use Github to host the sample code then I need this plugin. There is also other version control system plugin available such as Mercurial, or SVN.

5. Slack Notification Plugin

This plugin allows posting build notifications to a Slack channel which is useful to keep team member up to date with the status of repository.

Install and configure all of these plugins. Additionally, I use Nuget command line application for restoring the project’s dependency. Instead of using Jenkin’s Nuget Plugin (which I haven’t configured successfully), I call the Nuget executable directly as a batch command in one of the build action.

Create Build Job & Setup Build Actions

Create a new build job using Freestyle Project template. The build job contains following main build actions:

  1. Fetch code from the repository.
  2. Restore project’s dependencies.
  3. Create AnagramCheckerApp’s App Package.
  4. Run test from AnagramCheckerAppTest & LibraryTest project.
  5. Publish Test Result & Send Notification to a Slack channel.

Let’s dive in!

1. Fetch code from repository

Specify the source control management that you use, configure the URL of your repository and credential to access it. If necessary, you can also set which branch to be used.

repo

2. Restore Project’s Dependencies

NuGet is used to restore project’s dependency. In my case, there are 2 build actions for this. The first action is to set the proxy used by NuGet (since I sit behind company’s firewall)

[folder containing nuget.exe]/nuget.exe config -set http_proxy=[proxy]

and second action is the dependency restore process. Note that you can use %WORKSPACE% Jenkins’s environment variable to location your solution file.

[folder containing nuget.exe]/nuget.exe restore [path to solution file]

dependency

3. Create AnagramCheckerApp’s App Package

This build action is to ensure that we could create a UWP Application package (*.appx/*appxbundle) from the source code in the repository. The build action comes from MSBuild plugin and you need to configure the App’s project location and the build arguments.

apppackage

4. Run test from AnagramCheckerAppTest & LibraryTest project.

There are several build action to achieve this step. First we have to build both AnagramCheckerApp and LibraryTest project. For AnagramCheckerAppTest project, the build process will produce an App package which contains the Application Unit tests, on the other hand, LibraryTest project produces a *.dll file containing the test.

build test.png

Running test from AnagramCheckerAppTest is slightly more complicated. You’ll have to install the code signing certificate of the test app into the local machine’s TrustedPeople certificate storage. This is due to the fact that AnagramCheckerAppTest itself is a UWP Apps and running the test inside it requires the application to be installed. The certificate file is located in the same folder as the app package. In my case it is located in “%WORKSPACE%\ApplicationTest\AppPackages\AnagramCheckerAppTest_1.0.0.0_x86_Test\AnagramCheckerAppTest_1.0.0.0_x86.cer

I use certmgr tool to install the certificate. Note that the certmgr tool must be run as Administrator since we are trying to install the certificate on the local machine.

"C:\Program Files (x86)\Windows Kits\10\bin\x64\certmgr.exe" /add "%WORKSPACE%\ApplicationTest\AppPackages\AnagramCheckerAppTest_1.0.0.0_x86_Test\AnagramCheckerAppTest_1.0.0.0_x86.cer" /s /r localMachine trustedPeople

Once done, we are ready to run both tests from AnagramCheckerAppTest  and LibraryTest (we don’t need to configure extra stuff for LibraryTest project). The build action for running the test is available from VSTest Runner plugin. Create a separate build action for each test and specify the “Test Files” target accordingly. For AnagramCheckerAppTest, the test file is the application package located in “ApplicationTest\AppPackages\AnagramCheckerAppTest_1.0.0.0_x86_Test\AnagramCheckerAppTest_1.0.0.0_x86.appx” and for LibraryTest the test file is “LibraryTest\bin\Release\LibraryTest.dll” (name and path may differ based on their corresponding build parameter you specified in previous build action).

run test.png

5. Publish Test Result & Send Notification to a Slack channel.

The last step is to publish the test result using MSTest plugin. This plugin will convert the *.trx file produced by test runner into *.xml file that is compatible with Jenkins. The only thing that you need to configure is the location of *.trx file.

Additionally, I use Slack to receive notification of the build result. See this for the integration guide.post build.png

Everything is ready now and you could try the configuration by triggering it manually to see the result. Once completed, the project’s dashboard will display build & test result.

dashboard.png

And you’ll get a concise information in Slack.

slack

Feel free to try and add suggestion!

Advertisements

Testing Pre-Install Task on UWP Apps

Microsoft provides an entry point to execute UWP app’s code even before the application is opened by the user. The entry point is available through background task component which can be triggered during deployment task. There are two deployments task types available to UWP: PreInstallConfigTask and UpdateTask.

In this article I will guide you on how to incorporate and test PreInstallConfigTask in your application. Note that PreInstallConfigTask is only available for pre-installed application.

Clone https://github.com/pradithya/UwpSamplePreInstalledApp for the sample code.

I created a background task (Windows Runtime Component) with name BackgroundTask.PreInstalledTask. The background task will only display a toast notification with pre-defined text information.

namespace BackgroundTask
{
    public sealed class PreInstalledTask : IBackgroundTask
    {
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            ToastHelper.PopToast("Pre-Install Task", "Pre install task is running", "OK");
        }
    }
}

Add pre-installed task capability to the main application’s app manifest and hook it to the background task.

preinstall

Now the application is ready and we can test it.
Create application package for testing (see how).
Once the app package is created, open PowerShell as Administrator and enter the following command.

Add-AppxProvisionedPackage -Online -PackagePath [*appx / *appxbundle path] -SkipLicense

This command will use DISM to include the application into current Windows image. In the same time, the deployment of the application for the current user will be done and the pre-install task will also be triggered. In this application context, the task will display toast notification as shown below.

preinstall

As the application become the part of Windows image, every time you create a new user the application will be available as a pre-installed app. To revert this behavior you’ll need to remove all of the application instances in each user and execute following command in Powershell.

Remove-AppxProvisionedPackage -online -packagename TestPreInstalledApp_1.0.0.0_neutral_~_yzekw4x8qxe1g

source:
https://docs.microsoft.com/en-us/windows-hardware/customize/preinstall/preinstall-tasks
https://docs.microsoft.com/en-us/windows/uwp/publish/generate-preinstall-packages-for-oems
https://technet.microsoft.com/library/dn376490(v=wps.620).aspx

Macro Expansion

This bug made me spent half of my day. I have a macro to read a 32-bit data from either a virtual memory or RAM, depending on the address passed to a macro. More or less the code is as follow


#define read_u32(addr)    (if (is_addr_in_virtual(addr))?read_virtual_u32(addr):(*((u32 *) addr )) )

Did you see what is wrong?

Normally the macro works fine, let say we have a “ram_addr” which is an address in RAM and we pass it to the macro


var = read_u32(ram_addr)

//read_u32(ram_addr) will return 
var = (*((u32 *) ram_addr))


The problem happen when parameter passed is some short of operation like “base_addr + offset” where the macro expansion leads to a different behavior than expected.


var = read_u32(ram_addr + offset)

//read_u32(ram_addr + offset) will return
var = (*((u32 *) ram_addr + offset)

Let’s say that ram_addr is 0x0000A00 and offset is 2. What I want the macro to return is the u32 data in address 0x0000A02. But the expansion above, will return address 0x0000A08 since “ram_addr” is casted to (u32 *) before adding to “offset”.

The problem lies on the presence of parenthesis surrounding the macro parameter. The corrected version is as follow.

 
#define read_u32(addr)    (if (is_addr_in_virtual(addr))?read_virtual_u32(addr):(*((u32 *) (addr) )) ) 

This way, if I pass “ram_addr + offset” to the macro, the addition will take place first before the address is casted to (u32 *), and thus will return correct value.

Debugging Android Application Database using Terminal, ADB, and SQLite3

Following are the steps to debug android application database using terminal and adb.

1. Open Terminal to start debugging your application database.

2. Goto your platform-tools folder under sdk.

Screen Shot 2014-02-08 at 7.55.32 pm

3. Connect to device using adb

I use emulator in this tutorial. To connect to the device, type command “./adb -s <device-name> shell”. You’ll be redirected to the root folder of your device.

Screen Shot 2014-02-08 at 8.00.25 pm

4. Navigate to your database folder.

go to the folder where your database located. The location is in  “data/data/<package-name>/databases/”

Screen Shot 2014-02-08 at 8.13.13 pm

5. Call sqlite3

execute “sqlite3 <database-name>” to launch sqlite3 service

Screen Shot 2014-02-08 at 8.12.07 pm

6. Start playing with your database

You will be able to issue  command to your database using sqlite3. One thing to be noted is that the foreign key restriction is not activated here, so that you are able to add any row to any table.

Screen Shot 2014-02-08 at 8.19.40 pm

9 patch Image

Building Android Application introduced me to 9-patch image format. While studying it, I feel 9 patch is poorly documented. After using it for sometimes, I can understand why 9patch is so powerful for building a nice Android UI. In this writing, I will introduce 9patch image and how 9patch works.

Nine patch is basically png image file. However, it has special properties that make it very good for scalable image. To differentiate from ordinary png, the file name of nine patch image has extra “.9” string after its name, for example “beautiful_button.9.png”. Nine patch is not firstly used in Android, it is also used in Web Design using CSS .

As its name suggest, 9 patch is composed of 9 parts.  Each part is separated by a guide which can be found in the outer most part of 9patch image. The guide is a straight black  line (RGB #000000) with exactly 1 pixel wide.

There are two separate nine-slices in 9-patch image. The first 9 slices determine its scalable property. These slices are separated by top and left guide (see image below). Area 2 and 8 determine area that will be stretched if 9 patch image is scaled horizontally. Area 4 and 6 determine area that will be stretched if it is scaled vertically. Area 5 is stretched if  the image is scaled either vertically or horizontally.  And area 1,3,7 and 9 will maintain its size even when 9 patch image is scaled.

scalable property
Scalable property of 9patch determined by top and left border

The second 9 slices determine fill property of 9 patch image. These slices are separated by guide located at right and bottom of image. The most important area is area 5, which will enclose the content of of your image. The other slices will act as border.

Fill/Content Property of 9patch
Fill/Content property determined by right and bottom border

Nine patch acts nicely if it is scaled up, however it is not so good in scaling down. Thus, when generating 9patch image, it is better to start from the smallest size while maintaining image style.

Resulting Scalable Image
Resulting Scalable Image

Hello World!

 

“There are only two mistakes one can make along the road to truth: not going all the way, and not starting” – Budha

 

I take the plunge to start this website of my own. I am planning to write post related to my hobby which are: technology, robotics, and some science stuff. It probably contains my experience, small research, or any tips as well.

This is a part of my 2013 year’s resolution: to create a website and update it frequently (once a week is my target). I hope I can achieve the target and get benefit from it.