Skip to content

Commit

Permalink
More deamon tests leveraging netwatcher
Browse files Browse the repository at this point in the history
I made a separate test function with a single case for
the expected scenario where there is no WSL adapter
until it eventually shows up.
The test is not a perfect mimic, but it proves a new
.address file is written after the emulated system signal
is delivered.

It's setup is a bit more involving and distinct from
other cases found in TestServeWSLIP, thus I preferred
to make it in its own test function.
  • Loading branch information
CarlosNihelton committed Sep 4, 2024
1 parent 6d61a53 commit 314de17
Showing 1 changed file with 64 additions and 3 deletions.
67 changes: 64 additions & 3 deletions windows-agent/internal/daemon/daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package daemon_test

import (
"context"
"errors"
"io/fs"
"net"
"os"
Expand All @@ -14,6 +15,7 @@ import (
"github.com/canonical/ubuntu-pro-for-wsl/windows-agent/internal/daemon"
"github.com/canonical/ubuntu-pro-for-wsl/windows-agent/internal/daemon/daemontestutils"
"github.com/canonical/ubuntu-pro-for-wsl/windows-agent/internal/daemon/testdata/grpctestservice"
"github.com/canonical/ubuntu-pro-for-wsl/windows-agent/internal/netwatcher"
"github.com/canonical/ubuntu-pro-for-wsl/windows-agent/internal/netwatcher/netwatchertestutils"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
Expand Down Expand Up @@ -265,16 +267,16 @@ func TestRestart(t *testing.T) {
}
}

//nolint:tparallel // Cannot make test parallel because we play with the default netwatcher global options.

Check failure on line 270 in windows-agent/internal/daemon/daemon_test.go

View workflow job for this annotation

GitHub Actions / Go Quality checks (ubuntu, windows-agent)

directive `//nolint:tparallel // Cannot make test parallel because we play with the default netwatcher global options.` is unused for linter "tparallel" (nolintlint)

Check failure on line 270 in windows-agent/internal/daemon/daemon_test.go

View workflow job for this annotation

GitHub Actions / Go Quality checks (windows, windows-agent)

directive `//nolint:tparallel // Cannot make test parallel because we play with the default netwatcher global options.` is unused for linter "tparallel" (nolintlint)
func TestServeWSLIP(t *testing.T) {
t.Parallel()

registerer := func(context.Context, bool) *grpc.Server {
return grpc.NewServer()
}

testcases := map[string]struct {
netmode string
withAdapters daemontestutils.MockIPAdaptersState
subscribeErr error

wantErr bool
}{
Expand All @@ -288,11 +290,19 @@ func TestServeWSLIP(t *testing.T) {
"When listing adapters requires too much memory": {withAdapters: daemontestutils.RequiresTooMuchMem},
"When there is no Hyper-V adapter the list": {withAdapters: daemontestutils.NoHyperVAdapterInList},
"When retrieving adapters information fails": {withAdapters: daemontestutils.MockError},

// Should wantErr?
"When the WSL IP cannot be found and monitoring network fails": {withAdapters: daemontestutils.NoHyperVAdapterInList, subscribeErr: errors.New("mock error")},
}

//nolint:tparallel // Cannot make test parallel because we play with the default netwatcher global options.

Check failure on line 298 in windows-agent/internal/daemon/daemon_test.go

View workflow job for this annotation

GitHub Actions / Go Quality checks (ubuntu, windows-agent)

directive `//nolint:tparallel // Cannot make test parallel because we play with the default netwatcher global options.` is unused for linter "tparallel" (nolintlint)

Check failure on line 298 in windows-agent/internal/daemon/daemon_test.go

View workflow job for this annotation

GitHub Actions / Go Quality checks (windows, windows-agent)

directive `//nolint:tparallel // Cannot make test parallel because we play with the default netwatcher global options.` is unused for linter "tparallel" (nolintlint)
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
t.Parallel()
if tc.subscribeErr != nil {
netwatchertestutils.SetDefaultNetAdaptersAPIProviderToMock(t, func() (netwatcher.NetAdaptersAPI, error) {
return nil, tc.subscribeErr
})
}

addrDir := t.TempDir()
// Very lenient timeout because we either expect Serve to fail immediately or we stop it manually.
Expand Down Expand Up @@ -345,6 +355,57 @@ func TestServeWSLIP(t *testing.T) {
}
}

//nolint:parallel // Cannot make test parallel because we play with the default netwatcher global options.
func TestAddingWSLAdapterRestarts(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
addrDir := t.TempDir()

registerer := func(context.Context, bool) *grpc.Server {
server := grpc.NewServer()
var service testGRPCService
grpctestservice.RegisterTestServiceServer(server, service)
return server
}

d := daemon.New(ctx, registerer, addrDir)

systemNotification := make(chan error)
defer close(systemNotification)
netwatchertestutils.SetDefaultNetAdaptersAPIProviderToMock(t, netwatchertestutils.NetAdapterMockAPIWithAddedWSL(systemNotification))
mock := daemontestutils.NewHostIPConfigMock(daemontestutils.NoHyperVAdapterInList)

serveErr := make(chan error, 1)
go func() {
serveErr <- d.Serve(ctx, daemon.WithMockedGetAdapterAddresses(mock))
close(serveErr)
}()

addrPath := filepath.Join(addrDir, common.ListeningPortFileName)

var err error
requireWaitPathExists(t, addrPath, "Serve should create an address file")
addrSt, err := os.Stat(addrPath)
require.NoError(t, err, "Address file should be readable")

// Now we know the GRPC server has started serving. Let's emulate the OS triggering a notification.
systemNotification <- nil

// d.Serve() shouldn't have exitted with an error yet at this point.
select {
case err := <-serveErr:
require.NoError(t, err, "Restart should not have caused Serve() to exit with an error")
case <-time.After(200 * time.Millisecond):
// proceed.
}

requireWaitPathExists(t, addrPath, "Serve should create an address file")
// Contents could be the same without our control, thus best to check the file time.
newAddrSt, err := os.Stat(addrPath)
require.NoError(t, err, "Address file should be readable")
require.NotEqual(t, addrSt.ModTime(), newAddrSt.ModTime(), "Address file should be overwritten after Restart")
}

func TestServeError(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 314de17

Please sign in to comment.