notwork

package module
v1.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2024 License: Apache-2.0 Imports: 0 Imported by: 0

README

notwork

PkgGoDev GitHub build and test goroutines file descriptors Go Report Card Coverage

A tiny package to help with creating transient Linux virtual network elements for testing purposes, without having to deal with the tedious details of proper and robust cleanup.

notwork leverages the vishvananda/netlink module for RTNETLINK communication, as well as the Ginkgo testing framework with Gomega matchers.

Usage Example

Usually, you don't want to trash around in the host's network namespace. Instead, let's trash around in a ephemeral ("throw-away") network namespace, just created for testing purposes and removed at the end of the current test node.

In it, we create a transient MACVLAN-type network interface with a dummy-type parent network interface, also only for the duration of the current test (node):

import (
    "github.com/thediveo/notwork/dummy"
    "github.com/thediveo/notwork/macvlan"

    . "github.com/onsi/ginkgo/v2"
    . "github.com/onsi/gomega"
)

var _ = Describe("some testing", func() {

    It("creates a transient MACVLAN with a dummy parent in a throw-away network namespace", func() {
        defer netns.EnterTransient()() // !!! double ()()
        // current temporary network namespace will be remove automatically
        // at the end of this test.

        mcvlan := macvlan.NewTransient(dummy.NewTransient())
        // ...virtual network interface will be automatically removed
        // at the end of this test.
    })

})

[!IMPORTANT] Notice the double ()() when defer'ing netns.EnterTransient.

VETH Pair Ends in Different Network Namespaces

With the previous example under our black notwork belts, let's create a VETH pair of network interfaces that connect two transient network namespaces.

import (
  "github.com/notwork/netns"
  "github.com/notwork/veth"
)

var _ = Describe("some isolated testing", func() {

	It("connects two temporary network namespaces", func() {
		dupondNetns := netns.NewTransient() // create, but don't enter
		dupontNetns := netns.NewTransient() // create, but don't enter
		dupond, dupont := veth.NewTransient(InNamespace(dupondNetns), WithPeerNamespace(dupontNetns))
	})

})

As for the names of the VETH pair end variables, please refer to Dupond et Dupont.

Go Version Support

notwork supports versions of Go that are noted by the Go release policy, that is, major versions N and N-1 (where N is the current major version).

Make Targets

  • make: lists all targets.
  • make coverage: runs all tests with coverage and then updates the coverage badge in README.md.
  • make pkgsite: installs x/pkgsite, as well as the browser-sync and nodemon npm packages first, if not already done so. Then runs the pkgsite and hot reloads it whenever the documentation changes.
  • make report: installs @gojp/goreportcard if not yet done so and then runs it on the code base.
  • make test: runs all tests (as root), always.
  • make vuln: installs x/vuln/cmd/govulncheck and then runs it.

Copyright 2023–24 Harald Albrecht, licensed under the Apache License, Version 2.0.

Documentation

Overview

Package notwork is a tiny package that helps unit tests to create transient virtual network interfaces. It leverages vishvananda/netlink, as well as the Ginkgo testing framework with Gomega matchers.

Usage Example

To create a transient MACVLAN network interface with a dummy-type parent network interface for the duration of a test (node):

import (
    "github.com/thediveo/notwork/dummy"
    "github.com/thediveo/notwork/macvlan"

    . "github.com/onsi/ginkgo/v2"
    . "github.com/onsi/gomega"
)

var _ = Describe("some testing", func() {

    It("creates a transient MACVLAN with a dummy parent", func() {
        mcvlan := macvlan.NewTransient(dummy.NewTransient())
    })

})

The MACVLAN and dummy network interfaces will automatically removed at the end of the test (node) they are created in, regardless of success or failure.

If creating any of the virtual network interfaces fails, the test will immediately fail.

Using Throw-Away Network Namespaces

Even better, don't trash around the host network namespace, but instead use a throw-away network namespace that is separate from the host network namespace.

import (
    "github.com/thediveo/notwork/dummy"
    "github.com/thediveo/notwork/macvlan"
    "github.com/thediveo/notwork/netns"

    . "github.com/onsi/ginkgo/v2"
    . "github.com/onsi/gomega"
)

var _ = Describe("some isolated testing", func() {

    It("creates a transient MACVLAN with a dummy parent inside a throw-away netns", func() {
        defer netns.EnterTransient()()
        mcvlan := macvlan.NewTransient(dummy.NewTransient())
    })

})

Please pay attention to the double “()()” when deferring github.com/thediveo/notwork/netns.EnterTransient.

VETH Pair Ends in Different Network Namespaces

With the previous examples under our black notwork belts, let's create a VETH pair of network interfaces that connect two transient network namespaces.

import (
    "github.com/notwork/netns"
    "github.com/notwork/veth"
)

It("connects two temporary network namespaces", func() {
    dupondNetns := netns.NewTransient()
    dupontNetns := netns.NewTransient()
    var dupond, dupont netlink.Link
    netns.Execute(dupondNetns, func() {
        dupond, dupont = veth.NewTransient(WithPeerNamespace(dupontNetns))
    })
})

As for the names of the VETH pair end variables, please refer to Dupond et Dupont.

Testing /sys/class/net (Sysfs)

Sometimes, the (RT)NETLINK API isn't enough and you need to test production code that uses information inside “/sys/class/net”. Unfortunately, sysfs is peculiar in that its network view doesn't adapt to a viewer's current network namespace. Instead, sysfs freezes the network namespace to display when it gets mounted: from then on, it shows the mounter's network namespace that the caller was attached to when issuing the mount syscall.

This module thus supports creating transient mount namespaces and mounting a correct sysfs instance.

import (
	"github.com/notwork/mntns"
	"github.com/notwork/netns"
)

It("creates transient mount and network namespaces, mounts a sysfs", func() {
	defer netns.EnterTransient()()
	mntnsfd, procfsroot := mntns.NewTransient()
	mntns.Execute(mntnsfd, func() {
		mntns.MountSysfsRO()
	}
})

Known Limitations

This module suffers from overzealous sub-packaging.

Directories

Path Synopsis
Package dummy helps with creating transient dummy type virtual network interfaces for testing purposes.
Package dummy helps with creating transient dummy type virtual network interfaces for testing purposes.
Package link helps with creating transient virtual network interfaces of various types for testing purposes.
Package link helps with creating transient virtual network interfaces of various types for testing purposes.
internal/test/netlink
Package netlink contains general netlink behavioral tests (assertions) and documents gotchas in the github.com/vishvananda/netlink module.
Package netlink contains general netlink behavioral tests (assertions) and documents gotchas in the github.com/vishvananda/netlink module.
Package macvlan helps with creating transient MACVLAN network interfaces for testing purposes.
Package macvlan helps with creating transient MACVLAN network interfaces for testing purposes.
Package mntns supports running unit tests in separated transient mount namespaces.
Package mntns supports running unit tests in separated transient mount namespaces.
Package netdevsim helps with creating transient netdevsim type virtual network interfaces for testing purposes.
Package netdevsim helps with creating transient netdevsim type virtual network interfaces for testing purposes.
Package netns supports running unit tests in separated transient network namespaces.
Package netns supports running unit tests in separated transient network namespaces.
Package veth helps with creating transient virtual Ethernet network interfaces that always come in pairs.
Package veth helps with creating transient virtual Ethernet network interfaces that always come in pairs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL