Running tests on Gitlabs CI


#1

I have a small nerves project locally that I would like to write tests for. The tests won’t interact with hardware, they will test functions I wrote to handle data from sensors. Gitlab’s CI infrastructure is what I will be using, and I have other Elixir projects running on it successfully. That being said, I cannot get my nerves project to run. My .gitlab-ci.yml file and error is below. I did move the archive.install command around a bit to test out a theory, it yielded no results. It appears Nerves isn’t installed and trying to install it (or any mix commands) throws errors about it not being installed :102:

.gitlab-ci.yml

image: elixir:1.6

variables:
  MIX_ENV: "test"
  MIX_TARGET: "rpi3"

stages:
  - test

before_script:
  - apt-get -qq update && apt-get install -y ssh-askpass squashfs-tools git g++ libssl-dev libncurses5-dev bc m4 make unzip cmake python
  - mix local.hex --force
  - mix local.rebar --force
  - mix archive.install hex nerves_bootstrap
  - mix local.nerves
  - mix deps.get --only test

unit-testing:
  stage: test
  script:
    - mix test

Error

$ mix archive.install hex nerves_bootstrap
Mix environment
  MIX_TARGET:   rpi3
  MIX_ENV:      test

** (UndefinedFunctionError) function Nerves.Bootstrap.add_aliases/1 is undefined (module Nerves.Bootstrap is not available)
    Nerves.Bootstrap.add_aliases([])
    mix.exs:28: LakeEffect.MixProject.project/0
    (mix) lib/mix/project.ex:676: Mix.Project.get_project_config/1
    (mix) lib/mix/project.ex:111: Mix.Project.push/3
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
ERROR: Job failed: exit code 1

#2

Is this the error of running mix archive.install?


#3

It’s the error of any mix call, full output below. I moved the archive.install around to debug a bit, and still received the same error.

Running with gitlab-runner 10.4.0 (857480b6)
  on docker-auto-scale (72989761)
Using Docker executor with image elixir:1.6 ...
Using docker image sha256:9265efb4a4f4bc42c73e761b15ea3c0c901bf714f2262d7021c42e8e5ff41fdf for predefined container...
Pulling docker image elixir:1.6 ...
Using docker image elixir:1.6 ID=sha256:1fd3332a6393f092a8c40b608709399384f332b299a8ba8643bacb3c767b6efd for build container...
Running on runner-72989761-project-5357356-concurrent-0 via runner-72989761-srm-1517693488-dd826fb6...
Cloning repository...
Cloning into '/builds/fkumro/lake_effect'...
Checking out 8db9eec7 as sensors...
Skipping Git submodules setup
$ apt-get -qq update && apt-get install -y ssh-askpass squashfs-tools git g++ libssl-dev libncurses5-dev bc m4 make unzip cmake python
Reading package lists...
Building dependency tree...
Reading state information...
g++ is already the newest version.
git is already the newest version.
m4 is already the newest version.
m4 set to manually installed.
make is already the newest version.
libncurses5-dev is already the newest version.
libssl-dev is already the newest version.
python is already the newest version.
python set to manually installed.
The following extra packages will be installed:
  cmake-data libarchive13
Suggested packages:
  codeblocks eclipse ninja-build lrzip
The following NEW packages will be installed:
  bc cmake cmake-data libarchive13 squashfs-tools ssh-askpass unzip
0 upgraded, 7 newly installed, 0 to remove and 18 not upgraded.
Need to get 3980 kB of archives.
After this operation, 18.4 MB of additional disk space will be used.
Get:1 http://deb.debian.org/debian/ jessie/main cmake-data all 3.0.2-1+deb8u1 [929 kB]
Get:2 http://deb.debian.org/debian/ jessie/main libarchive13 amd64 3.1.2-11+deb8u3 [271 kB]
Get:3 http://deb.debian.org/debian/ jessie/main cmake amd64 3.0.2-1+deb8u1 [2385 kB]
Get:4 http://deb.debian.org/debian/ jessie/main bc amd64 1.06.95-9 [103 kB]
Get:5 http://deb.debian.org/debian/ jessie/main squashfs-tools amd64 1:4.2+20130409-2 [96.1 kB]
Get:6 http://deb.debian.org/debian/ jessie/main ssh-askpass amd64 1:1.2.4.1-9 [34.5 kB]
Get:7 http://deb.debian.org/debian/ jessie/main unzip amd64 6.0-16+deb8u3 [162 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 3980 kB in 0s (4490 kB/s)
Selecting previously unselected package cmake-data.
(Reading database ... 
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 22355 files and directories currently installed.)
Preparing to unpack .../cmake-data_3.0.2-1+deb8u1_all.deb ...
Unpacking cmake-data (3.0.2-1+deb8u1) ...
Selecting previously unselected package libarchive13:amd64.
Preparing to unpack .../libarchive13_3.1.2-11+deb8u3_amd64.deb ...
Unpacking libarchive13:amd64 (3.1.2-11+deb8u3) ...
Selecting previously unselected package cmake.
Preparing to unpack .../cmake_3.0.2-1+deb8u1_amd64.deb ...
Unpacking cmake (3.0.2-1+deb8u1) ...
Selecting previously unselected package bc.
Preparing to unpack .../bc_1.06.95-9_amd64.deb ...
Unpacking bc (1.06.95-9) ...
Selecting previously unselected package squashfs-tools.
Preparing to unpack .../squashfs-tools_1%3a4.2+20130409-2_amd64.deb ...
Unpacking squashfs-tools (1:4.2+20130409-2) ...
Selecting previously unselected package ssh-askpass.
Preparing to unpack .../ssh-askpass_1%3a1.2.4.1-9_amd64.deb ...
Unpacking ssh-askpass (1:1.2.4.1-9) ...
Selecting previously unselected package unzip.
Preparing to unpack .../unzip_6.0-16+deb8u3_amd64.deb ...
Unpacking unzip (6.0-16+deb8u3) ...
Processing triggers for mime-support (3.58) ...
Setting up cmake-data (3.0.2-1+deb8u1) ...
Setting up libarchive13:amd64 (3.1.2-11+deb8u3) ...
Setting up cmake (3.0.2-1+deb8u1) ...
Setting up bc (1.06.95-9) ...
Setting up squashfs-tools (1:4.2+20130409-2) ...
Setting up ssh-askpass (1:1.2.4.1-9) ...
update-alternatives: using /usr/lib/ssh/x11-ssh-askpass to provide /usr/bin/ssh-askpass (ssh-askpass) in auto mode
Setting up unzip (6.0-16+deb8u3) ...
Processing triggers for libc-bin (2.19-18+deb8u10) ...
$ mix archive.install hex nerves_bootstrap
Mix environment
  MIX_TARGET:   rpi3
  MIX_ENV:      test

** (UndefinedFunctionError) function Nerves.Bootstrap.add_aliases/1 is undefined (module Nerves.Bootstrap is not available)
    Nerves.Bootstrap.add_aliases([])
    mix.exs:28: LakeEffect.MixProject.project/0
    (mix) lib/mix/project.ex:676: Mix.Project.get_project_config/1
    (mix) lib/mix/project.ex:111: Mix.Project.push/3
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
ERROR: Job failed: exit code 1

#4

You are calling into nerves bootstrap from your mix file? That means you have to install bootstrap before mix file is available (in case of emergency just move a dirlevel up for installing the archive.

pushd .. && mix archive.install nerves_bootstrap && popd

Should do the trick


#5

Thanks, you were spot on! Getting close, trying to get past the compiler error now. build-essential and erlang-dev packages are being installed. Updated gitlab-ci.yml file and error below.

gitlab-ci.yml


image: elixir:1.6

variables:
  MIX_ENV: "test"
  MIX_TARGET: "rpi3"

stages:
  - test

before_script:
  - 'echo `pwd`'
  - apt-get -qq update && apt-get install -y ssh-askpass squashfs-tools git g++ libssl-dev libncurses5-dev bc m4 make unzip cmake python build-essential erlang-dev
  - cd /srv && mix local.hex --force
  - cd /srv && mix local.rebar --force
  - cd /srv && mix archive.install --force hex nerves_bootstrap
#  - mix local.nerves --force
  - 'cd $CI_PROJECT_DIR && mix deps.get --only test'

unit-testing:
  stage: test
  script:
    - mix test

Error

==> nerves_runtime
mkdir -p priv
/root/.nerves/artifacts/nerves_toolchain_arm_unknown_linux_gnueabihf-linux_x86_64-0.13.0/bin/arm-unknown-linux-gnueabihf-gcc -c -I/root/.nerves/artifacts/nerves_system_rpi3-portable-0.20.0/staging/usr/lib/erlang/erts-9.2/include -I/root/.nerves/artifacts/nerves_system_rpi3-portable-0.20.0/staging/usr/lib/erlang/lib/erl_interface-3.10.1/include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -pipe -Os -I/root/.nerves/artifacts/nerves_system_rpi3-portable-0.20.0/staging/usr/include -std=gnu99 -o src/uevent.o src/uevent.c
/root/.nerves/artifacts/nerves_toolchain_arm_unknown_linux_gnueabihf-linux_x86_64-0.13.0/bin/arm-unknown-linux-gnueabihf-gcc: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /root/.nerves/artifacts/nerves_toolchain_arm_unknown_linux_gnueabihf-linux_x86_64-0.13.0/bin/arm-unknown-linux-gnueabihf-gcc)
Makefile:66: recipe for target 'src/uevent.o' failed
make: *** [src/uevent.o] Error 1
could not compile dependency :nerves_runtime, "mix compile" failed. You can recompile this dependency with "mix deps.compile nerves_runtime", update it with "mix deps.update nerves_runtime" or clean it with "mix deps.clean nerves_runtime"
==> lake_effect
** (Mix) Could not compile with "make" (exit status: 2).
Depending on your OS, make sure to follow these instructions:

  * Mac OS X: You need to have gcc and make installed. Try running the
    commands "gcc --version" and / or "make --version". If these programs
    are not installed, you will be prompted to install them.

  * Linux: You need to have gcc and make installed. If you are using
    Ubuntu or any other Debian-based system, install the packages
    "build-essential". Also install "erlang-dev" package if not
    included in your Erlang/OTP version. If you're on Fedora, run
    "dnf group install 'Development Tools'".

ERROR: Job failed: exit code 1

#6

One thing I notice is that you have MIX_TARGET set to rpi3, which will end up cross-compiling things to run on Raspberry Pi 3 (ARM CPU). Unless your goal is to build firmware in CI, this probably isn’t what you want because your CI server won’t be able to run the tests.


#7

Thanks for pointing that out Greg, I copied over the local config I had and didn’t think about the proper target. After looking through the target docs, x86_64 is the correct target. Digging into the compiler issues, and it seems to be related to version issues at the distro level, still need to dig more.


#8

Ah sorry, I should have clarified. I think you should set MIX_TARGET to host, which should disable all the Nerves magic and allow you to just test the modules you want to. You’ll need to check your mix.exs to make sure that you’re not loading any dependencies in host mode that depend on real hardware being there.


#9

No worries, I appreciate the help! I really do need to sit down and read all the documentation instead of picking and choosing based on my current needs.


#10

Greg…you rock!!

$ mix test
Mix environment
  MIX_TARGET:   host
  MIX_ENV:      test

==> distillery
Compiling 19 files (.ex)
Generated distillery app
==> nerves
Compiling 31 files (.ex)
Generated nerves app
==> lake_effect
Compiling 7 files (.ex)
Generated lake_effect app
.

Finished in 0.03 seconds
1 test, 0 failures

Randomized with seed 121236
Job succeeded

Also thank you NobbZ !


#11

Figured I would post the final .gitlab-ci.yml file for others. The pages section generates and deploys the ExDocs to Gitlab pages.

image: elixir:1.6

variables:
  MIX_ENV: "test"
  MIX_TARGET: "host"

stages:
  - test
  - deploy

before_script:
  - apt-get -qq update && apt-get install -y ssh-askpass squashfs-tools git libssl-dev libncurses5-dev bc m4 make unzip cmake python # erlang-dev build-essential
  - cd /srv && mix local.hex --force
  - mix local.rebar --force
  - mix archive.install --force hex nerves_bootstrap
  - mix local.nerves --force
  - 'cd $CI_PROJECT_DIR && mix deps.get --only test'

unit-testing:
  stage: test
  script:
    - mix test

pages:
  stage: deploy
  script:
  - mix docs
  - cp -r doc/* public
  - rm -rf doc
  artifacts:
    paths:
    - public
  only:
  - master


#12

Neat, thanks for sharing!