Skip to content
This repository was archived by the owner on Mar 27, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ integ-test:
$(GOBUILD) -ldflags "-X main.version=1.0.0-dev" github.com/arduino/arduino-connector
cd ./test && ./upload_dev_artifacts_on_s3.sh
cd ./test && vagrant provision
source ./test/setup_host_test_env.sh && $(GOTEST) ./... -timeout $(GOTEST_TIMEOUT)
source ./test/setup_host_test_env.sh && $(GOTEST) --tags=integration ./... -timeout $(GOTEST_TIMEOUT)

teardown-test:
cd ./test && ./teardown_iot_device.sh
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ See [API](./API.md)
This type of tests are executed all locally and you need to configure a dedicated docker container:
- `docker pull guerra1994/go-mqtt-docker-env`
- follow the steps [here](https://hub.docker.com/r/guerra1994/go-mqtt-docker-env) to run it
- run mosquitto broker in background mode using `mosquitto &`
- then run your test, for example `go test -v --run="TestDockerPsApi"`
- run mosquitto broker in background mode using `mosquitto > /dev/null 2>&1 &`
- then run your test, for example `go test -v --tags=functional --run="TestDockerPsApi"`


## Integration tests disclaimer
Expand Down
75 changes: 75 additions & 0 deletions handlers_containers_functional_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// +build functional

package main

import (
"encoding/json"
"os"
"os/exec"
"strings"
"testing"
"time"

"github.com/docker/docker/api/types"
docker "github.com/docker/docker/client"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/stretchr/testify/assert"
)

type testStatus struct {
appStatus *Status
ui *MqttTestClient
}

var ts testStatus

func TestMain(m *testing.M) {
os.Exit(setupAndRun(m))
}

func setupAndRun(m *testing.M) int {
ts.ui = NewMqttTestClientLocal()
defer ts.ui.Close()

ts.appStatus = NewStatus(program{}.Config, nil, nil, "")
ts.appStatus.dockerClient, _ = docker.NewClientWithOpts(docker.WithVersion("1.38"))
ts.appStatus.mqttClient = mqtt.NewClient(mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID("arduino-connector"))

defer ts.appStatus.mqttClient.Disconnect(100)

return m.Run()
}

func TestDockerPsApi(t *testing.T) {
if token := ts.appStatus.mqttClient.Connect(); token.Wait() && token.Error() != nil {
t.Fatal(token.Error())
}

subscribeTopic(ts.appStatus.mqttClient, "0", "/containers/ps/post", ts.appStatus, ts.appStatus.ContainersPsEvent, false)
resp := ts.ui.MqttSendAndReceiveTimeout(t, "/containers/ps", "{}", 50*time.Millisecond)

// ask Docker about containers effectively running
cmd := exec.Command("bash", "-c", "docker ps -a")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatal(err)
}

lines := strings.Split(string(out), "\n")
// Remove the first line (command output header) and the last line (empty line)
lines = lines[1 : len(lines)-1]

// Take json without INFO tag
resp = strings.TrimPrefix(resp, "INFO: ")
resp = strings.TrimSuffix(resp, "\n\n")
var result []types.Container
if err := json.Unmarshal([]byte(resp), &result); err != nil {
t.Fatal(err)
}

assert.Equal(t, len(result), len(lines))
for i, line := range lines {
containerId := strings.Fields(line)[0]
assert.True(t, strings.HasPrefix(result[i].ID, containerId))
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build integration

//
// This file is part of arduino-connector
//
Expand All @@ -22,63 +24,15 @@ import (
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
"testing"
"time"

"github.com/docker/docker/api/types"
docker "github.com/docker/docker/client"
mqtt "github.com/eclipse/paho.mqtt.golang"

"github.com/stretchr/testify/assert"
)

func TestDockerPsApi(t *testing.T) {
ui := NewMqttTestClientLocal()
defer ui.Close()

status := NewStatus(program{}.Config, nil, nil, "")
status.dockerClient, _ = docker.NewClientWithOpts(docker.WithVersion("1.38"))
acOptions := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID("arduino-connector")
status.mqttClient = mqtt.NewClient(acOptions)

if token := status.mqttClient.Connect(); token.Wait() && token.Error() != nil {
t.Fatal(token.Error())
}

subscribeTopic(status.mqttClient, "0", "/containers/ps/post", status, status.ContainersPsEvent, false)

resp := ui.MqttSendAndReceiveTimeout(t, "/containers/ps", "{}", 50*time.Millisecond)

// ask Docker about containers effectively running
cmd := exec.Command("bash", "-c", "docker ps -a")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatal(err)
}

lines := strings.Split(string(out), "\n")
// Remove the first line (command output header) and the last line (empty line)
lines = lines[1 : len(lines)-1]

// Take json without INFO tag
resp = strings.TrimPrefix(resp, "INFO: ")
resp = strings.TrimSuffix(resp, "\n\n")
var result []types.Container
if err := json.Unmarshal([]byte(resp), &result); err != nil {
t.Fatal(err)
}

assert.Equal(t, len(result), len(lines))
for i, line := range lines {
containerId := strings.Fields(line)[0]
assert.True(t, strings.HasPrefix(result[i].ID, containerId))
}

status.mqttClient.Disconnect(100)
}

func TestConnectorProcessIsRunning(t *testing.T) {
outputMessage, err := ExecAsVagrantSshCmd("systemctl status ArduinoConnector | grep running")
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion scripts/functional-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ set -euo pipefail
trap 'kill "$(pidof mosquitto)"' EXIT

mosquitto > /dev/null &
go test -v --run="TestDockerPsApi"
go test -v --tags=functional --run="TestDockerPsApi"