github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/fingerprint/cgroup_test.go (about)

     1  //go:build linux
     2  
     3  package fingerprint
     4  
     5  import (
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/nomad/ci"
    10  	"github.com/hashicorp/nomad/client/config"
    11  	"github.com/hashicorp/nomad/helper/testlog"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  // A fake mount point detector that returns an empty path
    17  type MountPointDetectorNoMountPoint struct{}
    18  
    19  func (m *MountPointDetectorNoMountPoint) MountPoint() (string, error) {
    20  	return "", nil
    21  }
    22  
    23  // A fake mount point detector that returns an error
    24  type MountPointDetectorMountPointFail struct{}
    25  
    26  func (m *MountPointDetectorMountPointFail) MountPoint() (string, error) {
    27  	return "", fmt.Errorf("cgroup mountpoint discovery failed")
    28  }
    29  
    30  // A fake mount point detector that returns a valid path
    31  type MountPointDetectorValidMountPoint struct{}
    32  
    33  func (m *MountPointDetectorValidMountPoint) MountPoint() (string, error) {
    34  	return "/sys/fs/cgroup", nil
    35  }
    36  
    37  // A fake mount point detector that returns an empty path
    38  type MountPointDetectorEmptyMountPoint struct{}
    39  
    40  func (m *MountPointDetectorEmptyMountPoint) MountPoint() (string, error) {
    41  	return "", nil
    42  }
    43  
    44  // A fake version detector that returns the set version.
    45  type FakeVersionDetector struct {
    46  	version string
    47  }
    48  
    49  func (f *FakeVersionDetector) CgroupVersion() string {
    50  	return f.version
    51  }
    52  
    53  func newRequest(node *structs.Node) *FingerprintRequest {
    54  	return &FingerprintRequest{
    55  		Config: new(config.Config),
    56  		Node:   node,
    57  	}
    58  }
    59  
    60  func newNode() *structs.Node {
    61  	return &structs.Node{
    62  		Attributes: make(map[string]string),
    63  	}
    64  }
    65  
    66  func TestCgroup_MountPoint(t *testing.T) {
    67  	ci.Parallel(t)
    68  
    69  	t.Run("mount-point fail", func(t *testing.T) {
    70  		f := &CGroupFingerprint{
    71  			logger:             testlog.HCLogger(t),
    72  			lastState:          cgroupUnavailable,
    73  			mountPointDetector: new(MountPointDetectorMountPointFail),
    74  			versionDetector:    new(DefaultCgroupVersionDetector),
    75  		}
    76  
    77  		request := newRequest(newNode())
    78  		var response FingerprintResponse
    79  		err := f.Fingerprint(request, &response)
    80  		require.EqualError(t, err, "failed to discover cgroup mount point: cgroup mountpoint discovery failed")
    81  		require.Empty(t, response.Attributes[cgroupMountPointAttribute])
    82  	})
    83  
    84  	t.Run("mount-point available", func(t *testing.T) {
    85  		f := &CGroupFingerprint{
    86  			logger:             testlog.HCLogger(t),
    87  			lastState:          cgroupUnavailable,
    88  			mountPointDetector: new(MountPointDetectorValidMountPoint),
    89  			versionDetector:    new(DefaultCgroupVersionDetector),
    90  		}
    91  
    92  		request := newRequest(newNode())
    93  		var response FingerprintResponse
    94  		err := f.Fingerprint(request, &response)
    95  		require.NoError(t, err)
    96  		require.Equal(t, "/sys/fs/cgroup", response.Attributes[cgroupMountPointAttribute])
    97  	})
    98  
    99  	t.Run("mount-point empty", func(t *testing.T) {
   100  		f := &CGroupFingerprint{
   101  			logger:             testlog.HCLogger(t),
   102  			lastState:          cgroupUnavailable,
   103  			mountPointDetector: new(MountPointDetectorEmptyMountPoint),
   104  			versionDetector:    new(DefaultCgroupVersionDetector),
   105  		}
   106  
   107  		var response FingerprintResponse
   108  		err := f.Fingerprint(newRequest(newNode()), &response)
   109  		require.NoError(t, err)
   110  		require.Empty(t, response.Attributes[cgroupMountPointAttribute])
   111  	})
   112  
   113  	t.Run("mount-point already present", func(t *testing.T) {
   114  		f := &CGroupFingerprint{
   115  			logger:             testlog.HCLogger(t),
   116  			lastState:          cgroupAvailable,
   117  			mountPointDetector: new(MountPointDetectorValidMountPoint),
   118  			versionDetector:    new(DefaultCgroupVersionDetector),
   119  		}
   120  
   121  		var response FingerprintResponse
   122  		err := f.Fingerprint(newRequest(newNode()), &response)
   123  		require.NoError(t, err)
   124  		require.Equal(t, "/sys/fs/cgroup", response.Attributes[cgroupMountPointAttribute])
   125  	})
   126  }
   127  
   128  func TestCgroup_Version(t *testing.T) {
   129  	t.Run("version v1", func(t *testing.T) {
   130  		f := &CGroupFingerprint{
   131  			logger:             testlog.HCLogger(t),
   132  			lastState:          cgroupUnavailable,
   133  			mountPointDetector: new(MountPointDetectorValidMountPoint),
   134  			versionDetector:    &FakeVersionDetector{version: "v1"},
   135  		}
   136  
   137  		var response FingerprintResponse
   138  		err := f.Fingerprint(newRequest(newNode()), &response)
   139  		require.NoError(t, err)
   140  		require.Equal(t, "v1", response.Attributes[cgroupVersionAttribute])
   141  	})
   142  
   143  	t.Run("without mount-point", func(t *testing.T) {
   144  		f := &CGroupFingerprint{
   145  			logger:             testlog.HCLogger(t),
   146  			lastState:          cgroupUnavailable,
   147  			mountPointDetector: new(MountPointDetectorEmptyMountPoint),
   148  			versionDetector:    &FakeVersionDetector{version: "v1"},
   149  		}
   150  
   151  		var response FingerprintResponse
   152  		err := f.Fingerprint(newRequest(newNode()), &response)
   153  		require.NoError(t, err)
   154  		require.Empty(t, response.Attributes[cgroupMountPointAttribute])
   155  	})
   156  }