Unit Tests with Rust Tutorial 101

Writing unit tests is heavily integrated into rust without additional dependencies or external test runners. You can write unit tests inside the file that has the testable code or use a separate tests directory, let’s see how we do that.

You don’t need to have any prior rust knowledge, but you will have to have rust installed, which most easily is done by using rustup.

Writing Your First Test

When creating a rust project with cargo new and we’ll need a function that takes arguments and returns something, so let’s go for a simple sum function in main.rs:

fn sum(a: i32, b: i32) -> i32 {
    return a + b;
}

fn main(){
    println!("12 + 1 is {}", sum(12,1));
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn sum_test() {
        assert_eq!(345+5, sum(345, 5));
    }
}

Now for the interesting parts in the bottom of the file

  • #[cfg(test)] <- the test section attribute (see conditional compilation)
  • #[test] <- the test attribute for the individual test
  • assert_eq! macro to compare the two values

This is the simplest way to implement a unit test in rust, the next step is to look at how to move your functions and tests into another separate file.

Running cargo test should output something like:

    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running target/debug/deps/rust_test_101-e2cf395340fbef91

running 1 test
test tests::sum_test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Adding the following has the correct types, but it would cause the return value to be larger than i32 allows:

#[test]
#[should_panic]
fn greater_than_i32() {
    sum(2147483647,1); // this would be bigger than i32 allows
}

By using #[should_panic] we tell the test run to expect the following function to fail. This catches errors that usually crop up with:

thread 'main' panicked at 'attempt to add with overflow', src/main.rs:2:12

Now this is the easiest possible way to get started with writing tests in Rust, let me know if you want to know more in future posts! Don’t forget to check out the Rust Book Chapter on Testing as well.

What is an Interface?

An interface is something I first stumbled upon when I started learning compiled languages. I had read the term a couple of times before, but really only with C, Java and lately Go an interface actually means something to me that I can remember.

I’ve used the abbreviation API about one thousand times in my life, which stands for Application programming interface, usually I mean web APIs, where I get some JSON to feed it to my frontend or something, but that’s already a very specific use case.

As with many words in computer science, interface can mean many things, but depending on context it means a very specific thing. To quote wikipedia:

In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information.

and more specifically regarding programming:

the term interface is used to define an abstract type that contains no data but defines behaviours as method signatures.

So an interface is a bit like a puzzle piece. You can’t just attach your code or your function anywhere, but you need to find the right part that’s sticking out.

Implementing / Satisfying Intefaces

To implement or to satisfy an interface means to comply with the rules set by the blueprint. In object oriented languages such as C# or Java, interfaces are abstract classes, that just set some requirements for which functions must be included and which types they can receive or return.

Since Golang is not an object oriented language, there are no classes to implement, but we can still satisfy an interface with our type and it will be checked automatically by the compiler. Let’s pretend we are programming a series of vending machines and instead of a <Product> type, they’re supposed to return a string:

package main

import "fmt"

type VendingMachine interface {
    ReturnItem() string
}

type Cola struct {
}

func (d Cola) ReturnItem() string {
    return "you get a cooled cola"
}

func main() {
    var vend1 VendingMachine
    vend1 = Cola{}
    fmt.Println(vend1.ReturnItem())
}

You can see that type VendingMachine interface creates the first blueprint interface and the Cola struct now will need to satisfy the interface by also having a ReturnItem function.

We test this by creating a variable vend1 of type VendingMachine and assign a Cola{} struct to it.

The expected output is: you get a cooled cola

If we remove the following code:

func (d Cola) ReturnItem() string {
    return "you get a cooled cola"
}

We get the error:

# command-line-arguments
./main.go:21:8: cannot use Cola literal (type Cola) as type VendingMachine in assignment:
        Cola does not implement VendingMachine (missing ReturnItem method)

Thanks Go! Helpful! This way we can’t forget the essential ReturnItem function in our VendingMachine and make our customers really angry at us, because no products come out after they payed.

Similarly, if we change the return type of the Cola ReturnItem to int:

./main.go:13:9: cannot use "you get a cooled cola" (type string) as type int in return argument
./main.go:25:8: cannot use Cola literal (type Cola) as type VendingMachine in assignment:
        Cola does not implement VendingMachine (wrong type for ReturnItem method)
                have ReturnItem() int
                want ReturnItem() string

This makes sure that we return the correct type as well, because the humans or possibly robots interfacing with our vending machine will expect strings, not integers to come out.

Lastly, when coming from other languages you might try to implement a go interface by using the interface to create a type instance, maybe like this:

vend1 := VendingMachine{Cola{}

However, since the implements checking is done by the compiler and abstracted away, you’ll only get an error about a composite literal:

./main.go:17:25: invalid type for composite literal: VendingMachine

Summary

Interfaces are handy tools to ensure that your application can have consistently grouped functionalities with different values, even in a non OOP language like Go.

Real world examples of interfaces are the Readers and Writers in Go are IO parts like the Writer or Reader which you can try out and extend for some simple file system operations if you’re interested.

Building law.photography

We built a website that lists photography related laws by country and also in multiple languages. We started it as an independent project to enable the community to contribute to the site and to keep the content open source on a public repository, in this case on github.

Building law.photography is something that happened over the last 4 months when ever we had time and energy for the undertaking, to learn the new skills and to mill through foreign legal texts and some (actually really great) Wikipedia summaries.

Since we’re both photographers interested in street photography, it wasn’t hard to find a starting point. We often witness similar discussions unfold in photography communities about what is legal, what is not, where different laws protect either the subject or the right of the photographer. Especially on facebook a lot of the posted content reflects only an opinion or only takes one of multiple laws that may be relevant into account.

We wanted to create easy to understand summaries and quote the relevant law texts so photographers could inform themselves relatively quickly. None of us studied law, but we’re hoping a lawyer or two (per country and language) will join our efforts in the future.

The content for the laws is publicly available on the content repository on github and the change history since the initial release can be traced and a “who wrote this line when” is always just a few clicks away. This transparency is probably a benefit in the long run, also considering that new privacy laws like the GDPR and other local implementations (and court cases) will further clarify some of the legal situations over the years.

User Journey

Search engine traffic will probably be the biggest driver to this site in the future, while somebody researches their rights or compares local laws to a travel destination’s laws. Possibly the individual articles will be used as a reference on forums or social media discussions.

Editing a page currently is a bit of a techie experience, but we hope it is possible while using the web interface, even for anyone who is not a developer. When the first contributions come in, we’ll try to reach out to the editors and ask how difficult it was to apply. In general, editing a text / markdown file is a low barrier of entry, but the versioning through git adds a bit of complexity.

Technology: Gatsby.js

The first version was actually done with hugo, but we decided to with a an approach that has similar speeds, but is component based and allows for more flexible template and asynchronous data handling. For that our considered options were next.js, nuxt.js and Gatsby.

Having little to no experience with all of them, the odds were pretty even in the beginning, but Gatsby won the race, because of the outstanding existing ecosystem including image loading, familiar react syntax and the frontmatter enhanced markdown support.

The GraphQL querying is still new to us, but has great ease of use for different content types and not having to think too much about what content could possibly come in the future, but just focusing on getting an early version out. We’re confident to be able to add example contracts for photographers like for weddings, events or general model release forms without doing too much restructuring.

Gatsby is great for speed, because the initial hit is server side rendered, further navigation just loads the difference between the current and the destination page.

This fits our primary expected use case of a large portion of search engine traffic well, as the initial load times are low and assets can be prioritised. Especially when looking up something on the go, we don’t want to keep users waiting for too many network requests or images in an unfit resolution.

Very helpful while optimising for speed, was the Google Lighthouse test through the respective browser plugin, even though Gatsby makes it very difficult to make anything slow.

Currently there isn’t too much content for every release and the site builds swiftly, if this stays as snappy for the future volume and the localisations remains to be seen.

For deployment we chose docker, since we already had a dokku server at our disposal that runs some other side projects and deploying containers to other services is becoming easier and more widely supported by the minute. Since Gatsby only requires the static files to be served, the Dockerfile basically installs node and Gatsby, clones the content repository and serves the build directory through nginx.

Summary

We built a static site with Gatsby trying to be an easy to understand and at times illustrated resource for everything that has to do with photography and the law. We’re not done and we hope the community will help us out on github. Maybe it’s a silly idea, but we’ll know that in a year or two.

Check it out at law.photography and give us a shout what you think about it!

Deploying a Nuxt.js App with Docker

Let’s check out how you can deploy your Nuxt.js app, including server side rendering, with Docker. You can also view this post as a video:

The versions at the time of writing are:

  • nuxt: 2.6
  • Docker 18.09.3

Nuxt.js installation

For this tutorial I’ll create a new nuxt app

npx create-nuxt-app my_app

Hitting ENTER will work for us, but you can customise your app as you wish.

? Project name my_app
? Project description My shining Nuxt.js project
? Use a custom server framework none
? Choose features to install Prettier, Axios
? Use a custom UI framework none
? Use a custom test framework none
? Choose rendering mode Universal
? Author name Jonathan M. Hethey
? Choose a package manager npm

  To get started:

    cd my_app
    npm run dev

  To build & start for production:

    cd my_app
    npm run build
    npm start

Now let’s verify that our app works with:

    cd my_app
    npm run dev

If we access http://localhost:3000 now we should see:

Which is exactly like it should be.

Nuxt.js Dockerfile

Next, we’re going to write the Dockerfile for your Nuxt.js app.

FROM node:11.13.0-alpine

# create destination directory
RUN mkdir -p /usr/src/nuxt-app
WORKDIR /usr/src/nuxt-app

# update and install dependency
RUN apk update && apk upgrade
RUN apk add git

# copy the app, note .dockerignore
COPY . /usr/src/nuxt-app/
RUN npm install

# build necessary, even if no static files are needed,
# since it builds the server as well
RUN npm run build

# expose 5000 on container
EXPOSE 5000

# set app serving to permissive / assigned
ENV NUXT_HOST=0.0.0.0
# set app port
ENV NUXT_PORT=5000

# start the app
CMD [ "npm", "start" ]

This Dockerfile is based on the node alpine Linux image and then moves on to install git, the npm dependencies and finally builds and starts the Nuxt project.

Note that the NUXT_HOST and NUXT_PORT are set to Bind to any IP at port 5000, this might change depending on how you deploy your docker container.

My .dockerignore file contains the following to prevent using my local dependencies and builds:

node_modules
npm-debug*
.nuxt

Building your docker container can be done with, while in the repository with the Dockerfile present:

docker build -t my_app .

The output should be something along the lines of:

Removing intermediate container 7e9f607fb06e
 ---> c5b57739f412
Step 9/12 : EXPOSE 5000
 ---> Running in a326b4f25052
Removing intermediate container a326b4f25052
 ---> 796e335481fb
Step 10/12 : ENV NUXT_HOST=0.0.0.0
 ---> Running in 9aa3b799df0b
Removing intermediate container 9aa3b799df0b
 ---> 12f905ccb574
Step 11/12 : ENV NUXT_PORT=5000
 ---> Running in d9e9e111a32c
Removing intermediate container d9e9e111a32c
 ---> 0eab950732ab
Step 12/12 : CMD [ "npm", "start" ]
 ---> Running in 211496606e04
Removing intermediate container 211496606e04
 ---> 54779de7e817
Successfully built 54779de7e817
Successfully tagged my_app:latest

Next, to run the container:

docker run -it -p 5000:5000 my_app

Which should show this or similar:

   ╭────────────────────────────────────────────╮
   │                                            │
   │   Nuxt.js v2.6.1                           │
   │   Running in production mode (universal)   │
   │   Memory usage: 20.8 MB (RSS: 54.9 MB)     │
   │                                            │
   │   Listening on: http://172.17.0.2:5000     │
   │                                            │
   ╰────────────────────────────────────────────╯

and also display the app again when accessing the stated listening URL.

Summary

Setting Nuxt.js up with a Dockerfile couldn’t be much easier than it is already, so you know you have a reliable way of distributing your app after writing it.

I’m still new to Nuxt.js, but I suggest you give it a shot, since it’s amazing.

Getting Started with Flutter on Linux for Android [Beginner Tutorial]

Flutter is a cross platform and performant native mobile app framework by Google and can target Android and iOS at the moment. The language that comes with it is Dart, which originally made it into Chrome Canary as a possible JavaScript replacement or alternative.

In this post we’re going to have a look at how to set up a development environment for Flutter and Android. At the end of this post, you’ll have a working development environment on Ubuntu, Linux Mint or similar, including your first Flutter app running in an emulator and device.

Installing Flutter and Android Studio

The Flutter Linux Installation Docs are the starting point and take you through downloading the appropriate file:

# adapted
cd ~/Downloads
wget https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.0.0-stable.tar.xz
tar xf ~/Downloads/flutter_linux_v1.0.0-stable.tar.xz

Now you can add the flutter binaries to your PATH, either by running this in your terminal:

export PATH="$PATH:/home/$USER/Downloads/flutter/bin"

or by adding it to the configuration file of your shell permanently. Depending on which shell you use, these will typically be:

  • ~/.bashrc for bash
  • ~/.zshrc for zsh

Open the respective file and add around the bottom.

export PATH="$PATH:/home/$USER/Downloads/flutter/bin"

You can reload your config by running:

  • source ~/.zshrc
  • source ~/.bashrc

or restart your terminal.

You can verify your flutter installation with flutter doctor, the output should be something like:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.0.0, on Linux, locale en_US.UTF-8)
[✗] Android toolchain - develop for Android devices
    ✗ ANDROID_HOME = /home/jonathan/Android/Sdk
      but Android SDK not found at this location.
[!] Android Studio (not installed)
[!] Connected device
    ! No devices available

! Doctor found issues in 3 categories.

Installing Android Studio and Flutter Plugins

First, we’ll need to download Android Studio and unpack this into our Downloads or home folder. I have placed my unpacked version in /home/jonathan/android-studio. To start it I can run:

cd /home/jonathan/android-studio/bin
./studio.sh

This will open the IntelliJ based IDE for Android Studio and start off with a splash screen. After the IDE has started, just create a new Android project, because we want to head into the Tools menu and open the SDK Manager.

Inside the SDK Manager we want to navigate to the Plugins menu and press the Browse Repositories… In the following dialogue you can now search for Flutter and hit install, which should prompt you to install the Dart plugin as well.

Adding the Android Studio Home to your PATH

Now that we have the Android Studio installed, it should have created a directory in our home folder called Android, to add the tools and platform-tools that come with it, we need to add something like the following to our .zshrc or .bashrc. Remember to change the paths if you’re not called Jonathan 😉

export ANDROID_HOME="/home/jonathan/Android/Sdk"
export PATH="/home/jonathan/scripts:/home/jonathan/projects/go/bin:/home/jonathan/Downloads/flutter/bin:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH"

Remember to reload your shell config with source ~/[config name here].

Now to verify that we have installed the Android SDK correctly, let’s run flutter doctor again:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.0.0, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
[✓] Android Studio (version 3.2)
[!] Connected device
    ! No devices available

! Doctor found issues in 1 category.

After installing the Android SDK, you’ll have to agree to some license agreements via the CLI. Now we still have No devices available, let’s fix that with an Android Emulator.

Adding an Android Emulator

In Android Studio, head to Tools and then AVD Manager (Android Virtual Devices) and add a new emulator. This should be straight forward.

After you have gone through this process and started your emulator, you should no longer receive the warning that no devices are present by flutter doctor.

Troubleshooting the AVD

If you can’t add an AVD due to errors regarding /dev/kvm permission denied on Linux, you can try to install some additional dependencies and adding your user to the kvm group:

sudo apt install qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager
sudo adduser $USER kvm

NOTE: after running the adduser command you should restart your machine.

If you’re still facing trouble, there may be a BIOS setting which is not set correctly, for the most common BIOS versions you can see how to change it here: fedora wiki: BIOS setting for virtualisation

For GIGABYTE mainboards this setting is slightly hidden within Advanced CPU Core Settings and called SVM mode which needs to be enabled.

Enabling your Android Phone for Development

To set your phone up for app development, you’ll need to enable some developer settings, like explained by the Google Android Docs.

After this, if your phone is the target device for flutter and attached to your computer, it will automatically install the app and launch it when you use flutter run.

Creating your first Flutter App

For the next step you can either use Visual Studio Code or the Android Studio, as you wish. I’ll use vscode in the example:

  1. I create a directory where my flutter projects will live with cd ~/projects && mkdir flutter && cd flutter
  2. I create a new flutter project with flutter create test1
  3. I follow the instructions and run cd test 1 and flutter run
  4. The app should now appear in your AVD

To open your project with Visual Studio Code, change to your project directory with cd ~/projects/flutter/test1 && code .

Now you will be able to edit the flutter app and change the text labels or counter behaviour (try adding 3 at a time!).

If you want to integrate VSCode more closely with Flutter, make sure to install the Dart and Flutter plugins, which will enable you to create new projects or run your app from within Visual Studio Code.

That’s it! You’re now up and running with Flutter development for Android! Happy coding and remember to share your first app results!

PS: Thanks to some sub-reddits and Thomas for the review!

Rust Nightly or Stable with Rustup and “may not be used” error

When writing one of my pet projects or rather, a very simple automation matter in Rust, I fell into many pits. Usually full of snakes (of my own lack of knowledge of rust), but this one struck me as relatively interesting.

The stable compiler does not allow you to use unstable APIs/features. You have to use the nightly release branch.

If you know node, this is probably the equivalent of having to run V8 with harmony flags.

Rustup easily enables you to install the nightly branch of rust and to use it by default:

Continue reading “Rust Nightly or Stable with Rustup and “may not be used” error”

Upgrading XMR-Stak Miners for the Monero7 Protocol Update

If you’re mining Monero, you might have heard of the currency getting some bad press because several botnets pushed miners out to their clients. This is one of the reasons why the core team decided to upgrade the protocol. You can find their official statement on getmonero.org.

Continue reading “Upgrading XMR-Stak Miners for the Monero7 Protocol Update”

Goroutines, Channels and awaiting Asynchronously Operations in Go

Golang has fantastic support for actions that are supposed to happen concurrently (at the same time) without blocking the thread, they are called goroutines and are used by simply putting go in front of a function.

The functions prefixed with go will run “on their own” and the rest of your code will continue to run.

In order to gather results or returns from the functions, you commonly make use of a channel. Channels are the collecting “buckets” that will receive what your goroutines write to them.

Continue reading “Goroutines, Channels and awaiting Asynchronously Operations in Go”

WordPress Filters Example for Beginners

WordPress comes with a lot of built in amazingness, one of those are filters. You can filter a lot of different things that WordPress outputs into your theme or from your plugin that originate from another place.

That means you can add or remove something to all titles, category names or widgets. That might not seem incredibly useful at first, but if you for example want to add a text at the end of a blog post or page while using an already existing theme, it can be very nifty.

Continue reading “WordPress Filters Example for Beginners”

How To: Detect Ad Blockers (adblock, uBlock, etc)

As a blogger or any other kind of publisher, you might be interested in if the user accessing your page right now is using an ad blocker or not. You might want to do that to display a box that encourages them to disable their ad blocker, because you’re trying to make a living off of blogging or to make more conscious decisions about how you’re going to layout your page.

If a user has an adblocker installed, you don’t have to reserve the space in your layout for the ad units, so you might as well get rid of them, so in this post we’re going to have a look at how we can determine if a user has installed an ad blocker like Adblock, Adblock Plus or uBlock.

Continue reading “How To: Detect Ad Blockers (adblock, uBlock, etc)”