//go:build linux package fingerprint import ( "fmt" "testing" "github.com/hashicorp/nomad/ci" "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" "github.com/stretchr/testify/require" ) // A fake mount point detector that returns an empty path type MountPointDetectorNoMountPoint struct{} func (m *MountPointDetectorNoMountPoint) MountPoint() (string, error) { return "", nil } // A fake mount point detector that returns an error type MountPointDetectorMountPointFail struct{} func (m *MountPointDetectorMountPointFail) MountPoint() (string, error) { return "", fmt.Errorf("cgroup mountpoint discovery failed") } // A fake mount point detector that returns a valid path type MountPointDetectorValidMountPoint struct{} func (m *MountPointDetectorValidMountPoint) MountPoint() (string, error) { return "/sys/fs/cgroup", nil } // A fake mount point detector that returns an empty path type MountPointDetectorEmptyMountPoint struct{} func (m *MountPointDetectorEmptyMountPoint) MountPoint() (string, error) { return "", nil } // A fake version detector that returns the set version. type FakeVersionDetector struct { version string } func (f *FakeVersionDetector) CgroupVersion() string { return f.version } func newRequest(node *structs.Node) *FingerprintRequest { return &FingerprintRequest{ Config: new(config.Config), Node: node, } } func newNode() *structs.Node { return &structs.Node{ Attributes: make(map[string]string), } } func TestCgroup_MountPoint(t *testing.T) { ci.Parallel(t) t.Run("mount-point fail", func(t *testing.T) { f := &CGroupFingerprint{ logger: testlog.HCLogger(t), lastState: cgroupUnavailable, mountPointDetector: new(MountPointDetectorMountPointFail), versionDetector: new(DefaultCgroupVersionDetector), } request := newRequest(newNode()) var response FingerprintResponse err := f.Fingerprint(request, &response) require.EqualError(t, err, "failed to discover cgroup mount point: cgroup mountpoint discovery failed") require.Empty(t, response.Attributes[cgroupMountPointAttribute]) }) t.Run("mount-point available", func(t *testing.T) { f := &CGroupFingerprint{ logger: testlog.HCLogger(t), lastState: cgroupUnavailable, mountPointDetector: new(MountPointDetectorValidMountPoint), versionDetector: new(DefaultCgroupVersionDetector), } request := newRequest(newNode()) var response FingerprintResponse err := f.Fingerprint(request, &response) require.NoError(t, err) require.Equal(t, "/sys/fs/cgroup", response.Attributes[cgroupMountPointAttribute]) }) t.Run("mount-point empty", func(t *testing.T) { f := &CGroupFingerprint{ logger: testlog.HCLogger(t), lastState: cgroupUnavailable, mountPointDetector: new(MountPointDetectorEmptyMountPoint), versionDetector: new(DefaultCgroupVersionDetector), } var response FingerprintResponse err := f.Fingerprint(newRequest(newNode()), &response) require.NoError(t, err) require.Empty(t, response.Attributes[cgroupMountPointAttribute]) }) t.Run("mount-point already present", func(t *testing.T) { f := &CGroupFingerprint{ logger: testlog.HCLogger(t), lastState: cgroupAvailable, mountPointDetector: new(MountPointDetectorValidMountPoint), versionDetector: new(DefaultCgroupVersionDetector), } var response FingerprintResponse err := f.Fingerprint(newRequest(newNode()), &response) require.NoError(t, err) require.Equal(t, "/sys/fs/cgroup", response.Attributes[cgroupMountPointAttribute]) }) } func TestCgroup_Version(t *testing.T) { t.Run("version v1", func(t *testing.T) { f := &CGroupFingerprint{ logger: testlog.HCLogger(t), lastState: cgroupUnavailable, mountPointDetector: new(MountPointDetectorValidMountPoint), versionDetector: &FakeVersionDetector{version: "v1"}, } var response FingerprintResponse err := f.Fingerprint(newRequest(newNode()), &response) require.NoError(t, err) require.Equal(t, "v1", response.Attributes[cgroupVersionAttribute]) }) t.Run("without mount-point", func(t *testing.T) { f := &CGroupFingerprint{ logger: testlog.HCLogger(t), lastState: cgroupUnavailable, mountPointDetector: new(MountPointDetectorEmptyMountPoint), versionDetector: &FakeVersionDetector{version: "v1"}, } var response FingerprintResponse err := f.Fingerprint(newRequest(newNode()), &response) require.NoError(t, err) require.Empty(t, response.Attributes[cgroupMountPointAttribute]) }) }