Exploring cross-platform development using .NET

This is a follow up post on Getting started with .NET on Linux.
In this post I’ll explore the new cross-platform .NET framework to see if it’s possible to develop on e.g. Windows while have unit tests executed on a Linux machine every time the source code is changed.

The idea is to have a file watcher on the Linux machine that triggers the unit tests and presents the results whenever code changes are made in the source folder on Windows. Or that’s how it should’ve worked if Linux supported file event notifications on mounted network drives which it doesn’t. Instead the files will be watched by a file watcher on the Windows side and then notify the Linux side via Web API which will then execute the tests.
So:
1. Create an application with tests on Windows
2. Create a file watcher on Windows that sends a http request to (3) whenever a file is modified in (1).
3. Create an application in a Linux VM (using Vagrant) that uses Web API to run the tests for (1) when there is a request from (2).
The source code used in this post is available here.

Creating a DNX application with tests

So let’s start installing the stuff needed to create a DNX application which are DNVM (DotNet Version Manager), the DNX (DotNet execution environment) and DNU (DNX utility) for managing packages. DNVM can be installed by installing Visual Studio 2015 or running this PowerShell script from the command line:

Restart the command window, and then run dnvm upgrade which install the latest version of the runtime. You now have the tools to build a DNX-application!

For the purpose of this setup we just need the simplest thing possible which is a Hello World console app and the bare minimum to do this is to create a project.json file and a Program.cs file. The project.json file contains information about the project’s dependencies, used run-time version, what commands it supports etc. Here’s what it looks like for our console app:

The Program.cs file contains this:

Now just run dnu restore to fetch packages specified in the project.json file and then dnx . run to execute the application.
Now to be able to test to application, install xunit and the xunit runner through the following commands:
dnu install xunit
dnu install xunit.runner.dnx
dnu restore
Also, add a test command to the project file pointing to the xunit runner:

Now the tests can be executed with dnx . test. But of course we need some testable code and some tests. Lets add this non-contrived, real world, enterprisey property in our Program class that we put under test:

and a test class:

Creating a file watcher

Now we’ll need a file watcher application that triggers the tests each time the application is changed so let’s create a an application for it and put it in a dnxFileWatcher folder together with its accompanying project.json:

When a file is modified in the application, the file watcher makes a get request to the test runner which will run the tests (see below).

Let’s arrange the code in a structure like this:
-dnxApplication
-project.json
-Application
-Program.cs
-Tests
-Tests.cs
-dnxFileWatcher
-Program.cs
-project.json
-dnxTestRunner
-Startup.cs
-TestRunnerController.cs
-project.json

Creating a test runner

What’s missing from the previous description is the dnxTestRunner code which is the application running on the Ubuntu VM. It’s a Web API application that invokes the tests when ever it receives a call to its only end-point action method:

The feature to make this work is the ability to share ports and folders between the host (Windows) and the guest (Ubuntu). The vagrantfile has settings that makes this possible (see below). The dnxApplication folder is shared between the machines which lets Ubuntu execute the tests and the Windows developer write the code. The port 5004 will be forwarded from the host to the guest meaning that all traffic through this port on Windows will be forwarded to the Ubuntu machine’s port 5004.

Installing a Linux on Windows

To install a Linux VM on Windows you might want to check out my previous post or tl;dr: Install VirtualBox, install Vagrant. Open git bash and cd into the dnxTestRunner folder. Download this vagrantfile and put it in the dnxTestRunner folder. This folder will be shared between Windows and the Linux VM.
Now run vagrant up which will download the machine and start it according to the vagrantfile specification.
When the installation and provisioning of the VM is ready ssh into it using vagrant ssh

Now go to the shared folder, i.e. the dnxTestRunner folder, by cd /vagrant
To start the test runner you need to run these commands:
dnvm upgrade
dnu restore
dnx . kestrel

On the Windows machine, go to the dnxFileWatcher folder and start the application using dnu restore and then dnx . run.
Now in dnxApplication/Application, make a change to the Program.cs content should trigger a test run on the Ubuntu machine and print out the result.

Conclusion

In this post I’ve shown you how you can take advantage of its cross-platform feature to build a system for developing on Windows and running unit tests on Linux. While it might not be as seamless as one could’ve wished for (due to limitations in Linux) it does show that Microsoft is well on the way of making .NET a first class citizen on all major platforms. It will be very exciting to follow the progression of .NET’s path forward!

Leave a Reply

Close Menu