github.com/netdata/go.d.plugin@v0.58.1/modules/isc_dhcpd/isc_dhcpd_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package isc_dhcpd
     4  
     5  import (
     6  	"testing"
     7  
     8  	"github.com/netdata/go.d.plugin/agent/module"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestNew(t *testing.T) {
    15  	assert.Implements(t, (*module.Module)(nil), New())
    16  }
    17  
    18  func TestDHCPd_Cleanup(t *testing.T) {
    19  	assert.NotPanics(t, New().Cleanup)
    20  }
    21  
    22  func TestDHCPd_Init(t *testing.T) {
    23  	tests := map[string]struct {
    24  		config   Config
    25  		wantFail bool
    26  	}{
    27  		"default": {
    28  			wantFail: true,
    29  			config:   New().Config,
    30  		},
    31  		"'leases_path' not set": {
    32  			wantFail: true,
    33  			config: Config{
    34  				LeasesPath: "",
    35  				Pools: []PoolConfig{
    36  					{Name: "test", Networks: "10.220.252.0/24"},
    37  				},
    38  			},
    39  		},
    40  		"'pools' not set": {
    41  			wantFail: true,
    42  			config: Config{
    43  				LeasesPath: "testdata/dhcpd.leases_ipv4",
    44  			},
    45  		},
    46  		"'pools->pool.networks' invalid syntax": {
    47  			wantFail: true,
    48  			config: Config{
    49  				LeasesPath: "testdata/dhcpd.leases_ipv4",
    50  				Pools: []PoolConfig{
    51  					{Name: "test", Networks: "10.220.252./24"},
    52  				},
    53  			}},
    54  		"ok config ('leases_path' and 'pools' are set)": {
    55  			config: Config{
    56  				LeasesPath: "testdata/dhcpd.leases_ipv4",
    57  				Pools: []PoolConfig{
    58  					{Name: "test", Networks: "10.220.252.0/24"},
    59  				},
    60  			},
    61  		},
    62  	}
    63  
    64  	for name, test := range tests {
    65  		t.Run(name, func(t *testing.T) {
    66  			dhcpd := New()
    67  			dhcpd.Config = test.config
    68  
    69  			if test.wantFail {
    70  				assert.False(t, dhcpd.Init())
    71  			} else {
    72  				assert.True(t, dhcpd.Init())
    73  			}
    74  		})
    75  	}
    76  }
    77  
    78  func TestDHCPd_Check(t *testing.T) {
    79  	tests := map[string]struct {
    80  		prepare  func() *DHCPd
    81  		wantFail bool
    82  	}{
    83  		"lease db not exists":                     {prepare: prepareDHCPdLeasesNotExists, wantFail: true},
    84  		"lease db is an empty file":               {prepare: prepareDHCPdLeasesEmpty},
    85  		"lease db ipv4":                           {prepare: prepareDHCPdLeasesIPv4},
    86  		"lease db ipv4 with only inactive leases": {prepare: prepareDHCPdLeasesIPv4Inactive},
    87  		"lease db ipv4 with backup leases":        {prepare: prepareDHCPdLeasesIPv4Backup},
    88  		"lease db ipv6":                           {prepare: prepareDHCPdLeasesIPv6},
    89  	}
    90  
    91  	for name, test := range tests {
    92  		t.Run(name, func(t *testing.T) {
    93  			dhcpd := test.prepare()
    94  			require.True(t, dhcpd.Init())
    95  
    96  			if test.wantFail {
    97  				assert.False(t, dhcpd.Check())
    98  			} else {
    99  				assert.True(t, dhcpd.Check())
   100  			}
   101  		})
   102  	}
   103  }
   104  
   105  func TestDHCPd_Charts(t *testing.T) {
   106  	dhcpd := New()
   107  	dhcpd.LeasesPath = "leases_path"
   108  	dhcpd.Pools = []PoolConfig{
   109  		{Name: "name", Networks: "192.0.2.0/24"},
   110  	}
   111  	require.True(t, dhcpd.Init())
   112  
   113  	assert.NotNil(t, dhcpd.Charts())
   114  }
   115  
   116  func TestDHCPd_Collect(t *testing.T) {
   117  	tests := map[string]struct {
   118  		prepare       func() *DHCPd
   119  		wantCollected map[string]int64
   120  	}{
   121  		"lease db not exists": {
   122  			prepare:       prepareDHCPdLeasesNotExists,
   123  			wantCollected: nil,
   124  		},
   125  		"lease db is an empty file": {
   126  			prepare: prepareDHCPdLeasesEmpty,
   127  			wantCollected: map[string]int64{
   128  				"active_leases_total":     0,
   129  				"pool_net1_active_leases": 0,
   130  				"pool_net1_utilization":   0,
   131  				"pool_net2_active_leases": 0,
   132  				"pool_net2_utilization":   0,
   133  				"pool_net3_active_leases": 0,
   134  				"pool_net3_utilization":   0,
   135  				"pool_net4_active_leases": 0,
   136  				"pool_net4_utilization":   0,
   137  				"pool_net5_active_leases": 0,
   138  				"pool_net5_utilization":   0,
   139  				"pool_net6_active_leases": 0,
   140  				"pool_net6_utilization":   0,
   141  			},
   142  		},
   143  		"lease db ipv4": {
   144  			prepare: prepareDHCPdLeasesIPv4,
   145  			wantCollected: map[string]int64{
   146  				"active_leases_total":     5,
   147  				"pool_net1_active_leases": 2,
   148  				"pool_net1_utilization":   158,
   149  				"pool_net2_active_leases": 1,
   150  				"pool_net2_utilization":   39,
   151  				"pool_net3_active_leases": 0,
   152  				"pool_net3_utilization":   0,
   153  				"pool_net4_active_leases": 1,
   154  				"pool_net4_utilization":   79,
   155  				"pool_net5_active_leases": 0,
   156  				"pool_net5_utilization":   0,
   157  				"pool_net6_active_leases": 1,
   158  				"pool_net6_utilization":   39,
   159  			},
   160  		},
   161  		"lease db ipv4 with only inactive leases": {
   162  			prepare: prepareDHCPdLeasesIPv4Inactive,
   163  			wantCollected: map[string]int64{
   164  				"active_leases_total":     0,
   165  				"pool_net1_active_leases": 0,
   166  				"pool_net1_utilization":   0,
   167  				"pool_net2_active_leases": 0,
   168  				"pool_net2_utilization":   0,
   169  				"pool_net3_active_leases": 0,
   170  				"pool_net3_utilization":   0,
   171  				"pool_net4_active_leases": 0,
   172  				"pool_net4_utilization":   0,
   173  				"pool_net5_active_leases": 0,
   174  				"pool_net5_utilization":   0,
   175  				"pool_net6_active_leases": 0,
   176  				"pool_net6_utilization":   0,
   177  			},
   178  		},
   179  		"lease db ipv4 with backup leases": {
   180  			prepare: prepareDHCPdLeasesIPv4Backup,
   181  			wantCollected: map[string]int64{
   182  				"active_leases_total":     2,
   183  				"pool_net1_active_leases": 1,
   184  				"pool_net1_utilization":   79,
   185  				"pool_net2_active_leases": 0,
   186  				"pool_net2_utilization":   0,
   187  				"pool_net3_active_leases": 0,
   188  				"pool_net3_utilization":   0,
   189  				"pool_net4_active_leases": 1,
   190  				"pool_net4_utilization":   79,
   191  				"pool_net5_active_leases": 0,
   192  				"pool_net5_utilization":   0,
   193  				"pool_net6_active_leases": 0,
   194  				"pool_net6_utilization":   0,
   195  			},
   196  		},
   197  		"lease db ipv6": {
   198  			prepare: prepareDHCPdLeasesIPv6,
   199  			wantCollected: map[string]int64{
   200  				"active_leases_total":     6,
   201  				"pool_net1_active_leases": 6,
   202  				"pool_net1_utilization":   5454,
   203  				"pool_net2_active_leases": 0,
   204  				"pool_net2_utilization":   0,
   205  			},
   206  		},
   207  	}
   208  
   209  	for name, test := range tests {
   210  		t.Run(name, func(t *testing.T) {
   211  			dhcpd := test.prepare()
   212  			require.True(t, dhcpd.Init())
   213  
   214  			collected := dhcpd.Collect()
   215  
   216  			assert.Equal(t, test.wantCollected, collected)
   217  			if len(collected) > 0 {
   218  				ensureCollectedHasAllChartsDimsVarsIDs(t, dhcpd, collected)
   219  			}
   220  		})
   221  	}
   222  }
   223  
   224  func ensureCollectedHasAllChartsDimsVarsIDs(t *testing.T, dhcpd *DHCPd, collected map[string]int64) {
   225  	for _, chart := range *dhcpd.Charts() {
   226  		if chart.Obsolete {
   227  			continue
   228  		}
   229  		for _, dim := range chart.Dims {
   230  			_, ok := collected[dim.ID]
   231  			assert.Truef(t, ok, "collected metrics has no data for dim '%s' chart '%s'", dim.ID, chart.ID)
   232  		}
   233  		for _, v := range chart.Vars {
   234  			_, ok := collected[v.ID]
   235  			assert.Truef(t, ok, "collected metrics has no data for var '%s' chart '%s'", v.ID, chart.ID)
   236  		}
   237  	}
   238  }
   239  
   240  func prepareDHCPdLeasesNotExists() *DHCPd {
   241  	dhcpd := New()
   242  	dhcpd.Config = Config{
   243  		LeasesPath: "testdata/dhcpd.leases_not_exists",
   244  		Pools: []PoolConfig{
   245  			{Name: "net1", Networks: "192.168.3.0/25"},
   246  			{Name: "net2", Networks: "10.254.251.0/24"},
   247  			{Name: "net3", Networks: "10.254.252.0/24"},
   248  			{Name: "net4", Networks: "10.254.253.0/25"},
   249  			{Name: "net5", Networks: "10.254.254.0/25"},
   250  			{Name: "net6", Networks: "10.254.255.0/24"},
   251  		},
   252  	}
   253  	return dhcpd
   254  }
   255  
   256  func prepareDHCPdLeasesEmpty() *DHCPd {
   257  	dhcpd := New()
   258  	dhcpd.Config = Config{
   259  		LeasesPath: "testdata/dhcpd.leases_empty",
   260  		Pools: []PoolConfig{
   261  			{Name: "net1", Networks: "192.168.3.0/25"},
   262  			{Name: "net2", Networks: "10.254.251.0/24"},
   263  			{Name: "net3", Networks: "10.254.252.0/24"},
   264  			{Name: "net4", Networks: "10.254.253.0/25"},
   265  			{Name: "net5", Networks: "10.254.254.0/25"},
   266  			{Name: "net6", Networks: "10.254.255.0/24"},
   267  		},
   268  	}
   269  	return dhcpd
   270  }
   271  
   272  func prepareDHCPdLeasesIPv4() *DHCPd {
   273  	dhcpd := New()
   274  	dhcpd.Config = Config{
   275  		LeasesPath: "testdata/dhcpd.leases_ipv4",
   276  		Pools: []PoolConfig{
   277  			{Name: "net1", Networks: "192.168.3.0/25"},
   278  			{Name: "net2", Networks: "10.254.251.0/24"},
   279  			{Name: "net3", Networks: "10.254.252.0/24"},
   280  			{Name: "net4", Networks: "10.254.253.0/25"},
   281  			{Name: "net5", Networks: "10.254.254.0/25"},
   282  			{Name: "net6", Networks: "10.254.255.0/24"},
   283  		},
   284  	}
   285  	return dhcpd
   286  }
   287  
   288  func prepareDHCPdLeasesIPv4Backup() *DHCPd {
   289  	dhcpd := New()
   290  	dhcpd.Config = Config{
   291  		LeasesPath: "testdata/dhcpd.leases_ipv4_backup",
   292  		Pools: []PoolConfig{
   293  			{Name: "net1", Networks: "192.168.3.0/25"},
   294  			{Name: "net2", Networks: "10.254.251.0/24"},
   295  			{Name: "net3", Networks: "10.254.252.0/24"},
   296  			{Name: "net4", Networks: "10.254.253.0/25"},
   297  			{Name: "net5", Networks: "10.254.254.0/25"},
   298  			{Name: "net6", Networks: "10.254.255.0/24"},
   299  		},
   300  	}
   301  	return dhcpd
   302  }
   303  
   304  func prepareDHCPdLeasesIPv4Inactive() *DHCPd {
   305  	dhcpd := New()
   306  	dhcpd.Config = Config{
   307  		LeasesPath: "testdata/dhcpd.leases_ipv4_inactive",
   308  		Pools: []PoolConfig{
   309  			{Name: "net1", Networks: "192.168.3.0/25"},
   310  			{Name: "net2", Networks: "10.254.251.0/24"},
   311  			{Name: "net3", Networks: "10.254.252.0/24"},
   312  			{Name: "net4", Networks: "10.254.253.0/25"},
   313  			{Name: "net5", Networks: "10.254.254.0/25"},
   314  			{Name: "net6", Networks: "10.254.255.0/24"},
   315  		},
   316  	}
   317  	return dhcpd
   318  }
   319  
   320  func prepareDHCPdLeasesIPv6() *DHCPd {
   321  	dhcpd := New()
   322  	dhcpd.Config = Config{
   323  		LeasesPath: "testdata/dhcpd.leases_ipv6",
   324  		Pools: []PoolConfig{
   325  			{Name: "net1", Networks: "2001:db8::-2001:db8::a"},
   326  			{Name: "net2", Networks: "2001:db8:0:1::-2001:db8:0:1::a"},
   327  		},
   328  	}
   329  	return dhcpd
   330  }