Skip to content

Commit 40a2a1b

Browse files
committed
Add integration tests for update_enging with D-Bus
This commit adds testing docker-compose configuration with D-Bus daemon running, which we execute unit tests against. This allows mocking update_engine and testing our interactions with D-Bus. Closes flatcar#59 Signed-off-by: Mateusz Gozdek <[email protected]>
1 parent 9e0ae7e commit 40a2a1b

File tree

6 files changed

+173
-1
lines changed

6 files changed

+173
-1
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
./bin
2+
./test/test_bus_socket

Makefile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ clean: ## Cleans build artifacts.
5151
rm -rf bin
5252

5353
.PHONY: ci
54-
ci: check-generate check-vendor check-tidy build test ## Runs checks performed by CI without external dependencies required (e.g. golangci-lint).
54+
ci: check-generate check-vendor check-tidy build test test-integration ## Runs checks performed by CI without external dependencies required (e.g. golangci-lint).
5555

5656
.PHONY: check-working-tree-clean
5757
check-working-tree-clean: ## Checks if working directory is clean.
@@ -93,6 +93,20 @@ codespell: ## Runs spell checking.
9393
which $(CODESPELL_BIN) >/dev/null 2>&1 || (echo "$(CODESPELL_BIN) binary not found, skipping spell checking"; exit 0)
9494
$(CODESPELL_BIN) --skip $(CODESPELL_SKIP) --ignore-words .codespell.ignorewords --check-filenames --check-hidden
9595

96+
.PHONY: test-up
97+
test-up: ## Starts testing D-Bus instance in Docker container using docker-compose.
98+
env UID=$$(id -u) docker-compose -f test/docker-compose.yml up -d
99+
100+
.PHONY: test-down
101+
test-down: ## Tears down testing D-Bus instance created by 'test-up'.
102+
docker-compose -f test/docker-compose.yml down
103+
104+
.PHONY: test-integration
105+
test-integration: test-up
106+
test-integration: ## Runs integration tests using D-Bus running in Docker container.
107+
FLUO_TEST_DBUS_SOCKET=$$(realpath ./test/test_bus_socket) go test -mod=vendor -count 1 ./...
108+
make test-down
109+
96110
.PHONY: help
97111
help: ## Prints help message.
98112
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

pkg/updateengine/client_test.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package updateengine_test
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
dbus "github.com/godbus/dbus/v5"
9+
10+
"github.com/kinvolk/flatcar-linux-update-operator/pkg/updateengine"
11+
)
12+
13+
//nolint:paralleltest // Test uses environment variables, which are global.
14+
func Test_Connecting_to_non_existing_system_bus_fails(t *testing.T) {
15+
if err := os.Setenv("DBUS_SYSTEM_BUS_ADDRESS", "foo"); err != nil {
16+
t.Fatalf("Setting systemd bus address: %v", err)
17+
}
18+
19+
if _, err := updateengine.New(); err == nil {
20+
t.Fatalf("Creating client should fail when unable to connect to system bus")
21+
}
22+
}
23+
24+
//nolint:funlen,tparallel // Test uses environment variables, which are global.
25+
func Test_Emitted_status_parses(t *testing.T) {
26+
var (
27+
lastCheckedTime int64 = 10
28+
progress float64 = 20
29+
currentOperation = updateengine.UpdateStatusVerifying
30+
newVersion = "1.2.3"
31+
newSize int64 = 30
32+
)
33+
34+
withMockGetStatus(t, func(message dbus.Message) (int64, float64, string, string, int64, *dbus.Error) {
35+
return lastCheckedTime, progress, currentOperation, newVersion, newSize, nil
36+
})
37+
38+
c, err := updateengine.New()
39+
if err != nil {
40+
t.Fatalf("Creating client should succeed, got: %v", err)
41+
}
42+
43+
stop := make(chan struct{})
44+
ch := make(chan updateengine.Status, 1)
45+
46+
go c.ReceiveStatuses(ch, stop)
47+
48+
status := <-ch
49+
50+
t.Run("first_value_as_last_checked_time", func(t *testing.T) {
51+
t.Parallel()
52+
53+
if status.LastCheckedTime != lastCheckedTime {
54+
t.Errorf("Expected %v, got %v", lastCheckedTime, status.LastCheckedTime)
55+
}
56+
})
57+
58+
t.Run("second_value_as_progress", func(t *testing.T) {
59+
t.Parallel()
60+
61+
if status.Progress != progress {
62+
t.Errorf("Expected %v, got %v", progress, status.Progress)
63+
}
64+
})
65+
66+
t.Run("third_value_as_current_operation", func(t *testing.T) {
67+
t.Parallel()
68+
69+
if status.CurrentOperation != currentOperation {
70+
t.Errorf("Expected %q, got %q", currentOperation, status.CurrentOperation)
71+
}
72+
})
73+
74+
t.Run("forth_value_as_new_version", func(t *testing.T) {
75+
t.Parallel()
76+
77+
if status.NewVersion != newVersion {
78+
t.Errorf("Expected %q, got %q", newVersion, status.NewVersion)
79+
}
80+
})
81+
82+
t.Run("fifth_value_as_new_size", func(t *testing.T) {
83+
t.Parallel()
84+
85+
if status.NewSize != newSize {
86+
t.Errorf("Expected %v, got %v", newSize, status.NewSize)
87+
}
88+
})
89+
}
90+
91+
const (
92+
testDbusSocketEnv = "FLUO_TEST_DBUS_SOCKET"
93+
)
94+
95+
func testSystemConnection(t *testing.T) *dbus.Conn {
96+
t.Helper()
97+
98+
socket := os.Getenv(testDbusSocketEnv)
99+
if socket == "" {
100+
t.Skipf("%q environment variable empty", testDbusSocketEnv)
101+
}
102+
103+
if err := os.Setenv("DBUS_SYSTEM_BUS_ADDRESS", fmt.Sprintf("unix:path=%s", socket)); err != nil {
104+
t.Fatalf("Setting systemd bus address: %v", err)
105+
}
106+
107+
conn, err := dbus.SystemBus()
108+
if err != nil {
109+
t.Fatalf("Opening private connection to system bus: %v", err)
110+
}
111+
112+
return conn
113+
}
114+
115+
func withMockGetStatus(t *testing.T, fn interface{}) {
116+
t.Helper()
117+
118+
conn := testSystemConnection(t)
119+
120+
if _, err := conn.RequestName("com.coreos.update1", 0); err != nil {
121+
t.Fatalf("Requesting name: %v", err)
122+
}
123+
124+
tbl := map[string]interface{}{
125+
"GetStatus": fn,
126+
}
127+
128+
if err := conn.ExportMethodTable(tbl, "/com/coreos/update1", "com.coreos.update1.Manager"); err != nil {
129+
t.Fatalf("Exporting method table: %v", err)
130+
}
131+
}

test/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM alpine:3.13
2+
3+
RUN apk add -U dbus

test/docker-compose.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: "3.8"
2+
services:
3+
dbus:
4+
build: .
5+
command:
6+
- dbus-daemon
7+
- --nofork
8+
- --config-file=/var/run/dbus/testing.conf
9+
- --nosyslog
10+
user: "${UID}"
11+
volumes:
12+
- ./:/var/run/dbus
13+
- /etc/passwd:/etc/passwd

test/testing.conf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
2+
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
3+
<busconfig>
4+
<listen>unix:path=/var/run/dbus/test_bus_socket</listen>
5+
<policy context="default">
6+
<allow send_destination="*"/>
7+
<allow receive_sender="*"/>
8+
<allow own="*"/>
9+
</policy>
10+
</busconfig>

0 commit comments

Comments
 (0)