github.com/netdata/go.d.plugin@v0.58.1/modules/openvpn_status_log/openvpn_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package openvpn_status_log
     4  
     5  import (
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/netdata/go.d.plugin/pkg/matcher"
    13  )
    14  
    15  const (
    16  	pathNonExistentFile         = "testdata/v2.5.1/non-existent.txt"
    17  	pathEmptyFile               = "testdata/v2.5.1/empty.txt"
    18  	pathStaticKey               = "testdata/v2.5.1/static-key.txt"
    19  	pathStatusVersion1          = "testdata/v2.5.1/version1.txt"
    20  	pathStatusVersion1NoClients = "testdata/v2.5.1/version1-no-clients.txt"
    21  	pathStatusVersion2          = "testdata/v2.5.1/version2.txt"
    22  	pathStatusVersion2NoClients = "testdata/v2.5.1/version2-no-clients.txt"
    23  	pathStatusVersion3          = "testdata/v2.5.1/version3.txt"
    24  	pathStatusVersion3NoClients = "testdata/v2.5.1/version3-no-clients.txt"
    25  )
    26  
    27  func TestNew(t *testing.T) {
    28  }
    29  
    30  func TestOpenVPNStatusLog_Init(t *testing.T) {
    31  	tests := map[string]struct {
    32  		config   Config
    33  		wantFail bool
    34  	}{
    35  		"default config": {
    36  			config: New().Config,
    37  		},
    38  		"unset 'log_path'": {
    39  			wantFail: true,
    40  			config: Config{
    41  				LogPath: "",
    42  			},
    43  		},
    44  	}
    45  
    46  	for name, test := range tests {
    47  		t.Run(name, func(t *testing.T) {
    48  			ovpn := New()
    49  			ovpn.Config = test.config
    50  
    51  			if test.wantFail {
    52  				assert.False(t, ovpn.Init())
    53  			} else {
    54  				assert.True(t, ovpn.Init())
    55  			}
    56  		})
    57  	}
    58  }
    59  
    60  func TestOpenVPNStatusLog_Check(t *testing.T) {
    61  	tests := map[string]struct {
    62  		prepare  func() *OpenVPNStatusLog
    63  		wantFail bool
    64  	}{
    65  		"status version 1":                 {prepare: prepareCaseStatusVersion1},
    66  		"status version 1 with no clients": {prepare: prepareCaseStatusVersion1NoClients},
    67  		"status version 2":                 {prepare: prepareCaseStatusVersion2},
    68  		"status version 2 with no clients": {prepare: prepareCaseStatusVersion2NoClients},
    69  		"status version 3":                 {prepare: prepareCaseStatusVersion3},
    70  		"status version 3 with no clients": {prepare: prepareCaseStatusVersion3NoClients},
    71  		"empty file":                       {prepare: prepareCaseEmptyFile, wantFail: true},
    72  		"non-existent file":                {prepare: prepareCaseNonExistentFile, wantFail: true},
    73  	}
    74  
    75  	for name, test := range tests {
    76  		t.Run(name, func(t *testing.T) {
    77  			ovpn := test.prepare()
    78  
    79  			require.True(t, ovpn.Init())
    80  
    81  			if test.wantFail {
    82  				assert.False(t, ovpn.Check())
    83  			} else {
    84  				assert.True(t, ovpn.Check())
    85  			}
    86  		})
    87  	}
    88  }
    89  
    90  func TestOpenVPNStatusLog_Charts(t *testing.T) {
    91  	tests := map[string]struct {
    92  		prepare       func() *OpenVPNStatusLog
    93  		wantNumCharts int
    94  	}{
    95  		"status version 1 with user stats": {
    96  			prepare:       prepareCaseStatusVersion1WithUserStats,
    97  			wantNumCharts: len(charts) + len(userCharts)*2,
    98  		},
    99  		"status version 2 with user stats": {
   100  			prepare:       prepareCaseStatusVersion2WithUserStats,
   101  			wantNumCharts: len(charts) + len(userCharts)*2,
   102  		},
   103  		"status version 3 with user stats": {
   104  			prepare:       prepareCaseStatusVersion2WithUserStats,
   105  			wantNumCharts: len(charts) + len(userCharts)*2,
   106  		},
   107  		"status version with static key": {
   108  			prepare:       prepareCaseStatusStaticKey,
   109  			wantNumCharts: len(charts),
   110  		},
   111  	}
   112  
   113  	for name, test := range tests {
   114  		t.Run(name, func(t *testing.T) {
   115  			ovpn := test.prepare()
   116  
   117  			require.True(t, ovpn.Init())
   118  			_ = ovpn.Check()
   119  			_ = ovpn.Collect()
   120  
   121  			assert.Equal(t, test.wantNumCharts, len(*ovpn.Charts()))
   122  		})
   123  	}
   124  }
   125  
   126  func TestOpenVPNStatusLog_Collect(t *testing.T) {
   127  	tests := map[string]struct {
   128  		prepare  func() *OpenVPNStatusLog
   129  		expected map[string]int64
   130  	}{
   131  		"status version 1": {
   132  			prepare: prepareCaseStatusVersion1,
   133  			expected: map[string]int64{
   134  				"bytes_in":  6168,
   135  				"bytes_out": 6369,
   136  				"clients":   2,
   137  			},
   138  		},
   139  		"status version 1 with user stats": {
   140  			prepare: prepareCaseStatusVersion1WithUserStats,
   141  			expected: map[string]int64{
   142  				"bytes_in":                   6168,
   143  				"bytes_out":                  6369,
   144  				"clients":                    2,
   145  				"vpnclient2_bytes_in":        3084,
   146  				"vpnclient2_bytes_out":       3184,
   147  				"vpnclient2_connection_time": 63793143069,
   148  				"vpnclient_bytes_in":         3084,
   149  				"vpnclient_bytes_out":        3185,
   150  				"vpnclient_connection_time":  63793143069,
   151  			},
   152  		},
   153  		"status version 1 with no clients": {
   154  			prepare: prepareCaseStatusVersion1NoClients,
   155  			expected: map[string]int64{
   156  				"bytes_in":  0,
   157  				"bytes_out": 0,
   158  				"clients":   0,
   159  			},
   160  		},
   161  		"status version 2": {
   162  			prepare: prepareCaseStatusVersion2,
   163  			expected: map[string]int64{
   164  				"bytes_in":  6241,
   165  				"bytes_out": 6369,
   166  				"clients":   2,
   167  			},
   168  		},
   169  		"status version 2 with user stats": {
   170  			prepare: prepareCaseStatusVersion2WithUserStats,
   171  			expected: map[string]int64{
   172  				"bytes_in":                   6241,
   173  				"bytes_out":                  6369,
   174  				"clients":                    2,
   175  				"vpnclient2_bytes_in":        3157,
   176  				"vpnclient2_bytes_out":       3184,
   177  				"vpnclient2_connection_time": 264610,
   178  				"vpnclient_bytes_in":         3084,
   179  				"vpnclient_bytes_out":        3185,
   180  				"vpnclient_connection_time":  264609,
   181  			},
   182  		},
   183  		"status version 2 with no clients": {
   184  			prepare: prepareCaseStatusVersion2NoClients,
   185  			expected: map[string]int64{
   186  				"bytes_in":  0,
   187  				"bytes_out": 0,
   188  				"clients":   0,
   189  			},
   190  		},
   191  		"status version 3": {
   192  			prepare: prepareCaseStatusVersion3,
   193  			expected: map[string]int64{
   194  				"bytes_in":  7308,
   195  				"bytes_out": 7235,
   196  				"clients":   2,
   197  			},
   198  		},
   199  		"status version 3 with user stats": {
   200  			prepare: prepareCaseStatusVersion3WithUserStats,
   201  			expected: map[string]int64{
   202  				"bytes_in":                   7308,
   203  				"bytes_out":                  7235,
   204  				"clients":                    2,
   205  				"vpnclient2_bytes_in":        3654,
   206  				"vpnclient2_bytes_out":       3617,
   207  				"vpnclient2_connection_time": 265498,
   208  				"vpnclient_bytes_in":         3654,
   209  				"vpnclient_bytes_out":        3618,
   210  				"vpnclient_connection_time":  265496,
   211  			},
   212  		},
   213  		"status version 3 with no clients": {
   214  			prepare: prepareCaseStatusVersion3NoClients,
   215  			expected: map[string]int64{
   216  				"bytes_in":  0,
   217  				"bytes_out": 0,
   218  				"clients":   0,
   219  			},
   220  		},
   221  		"status with static key": {
   222  			prepare: prepareCaseStatusStaticKey,
   223  			expected: map[string]int64{
   224  				"bytes_in":  19265,
   225  				"bytes_out": 261631,
   226  				"clients":   0,
   227  			},
   228  		},
   229  		"empty file": {
   230  			prepare:  prepareCaseEmptyFile,
   231  			expected: nil,
   232  		},
   233  		"non-existent file": {
   234  			prepare:  prepareCaseNonExistentFile,
   235  			expected: nil,
   236  		},
   237  	}
   238  
   239  	for name, test := range tests {
   240  		t.Run(name, func(t *testing.T) {
   241  			ovpn := test.prepare()
   242  
   243  			require.True(t, ovpn.Init())
   244  			_ = ovpn.Check()
   245  
   246  			collected := ovpn.Collect()
   247  
   248  			copyConnTime(collected, test.expected)
   249  			assert.Equal(t, test.expected, collected)
   250  		})
   251  	}
   252  }
   253  
   254  func prepareCaseStatusVersion1() *OpenVPNStatusLog {
   255  	ovpn := New()
   256  	ovpn.LogPath = pathStatusVersion1
   257  	return ovpn
   258  }
   259  
   260  func prepareCaseStatusVersion1WithUserStats() *OpenVPNStatusLog {
   261  	ovpn := New()
   262  	ovpn.LogPath = pathStatusVersion1
   263  	ovpn.PerUserStats = matcher.SimpleExpr{
   264  		Includes: []string{"* *"},
   265  	}
   266  	return ovpn
   267  }
   268  
   269  func prepareCaseStatusVersion1NoClients() *OpenVPNStatusLog {
   270  	ovpn := New()
   271  	ovpn.LogPath = pathStatusVersion1NoClients
   272  	return ovpn
   273  }
   274  
   275  func prepareCaseStatusVersion2() *OpenVPNStatusLog {
   276  	ovpn := New()
   277  	ovpn.LogPath = pathStatusVersion2
   278  	return ovpn
   279  }
   280  
   281  func prepareCaseStatusVersion2WithUserStats() *OpenVPNStatusLog {
   282  	ovpn := New()
   283  	ovpn.LogPath = pathStatusVersion2
   284  	ovpn.PerUserStats = matcher.SimpleExpr{
   285  		Includes: []string{"* *"},
   286  	}
   287  	return ovpn
   288  }
   289  
   290  func prepareCaseStatusVersion2NoClients() *OpenVPNStatusLog {
   291  	ovpn := New()
   292  	ovpn.LogPath = pathStatusVersion2NoClients
   293  	return ovpn
   294  }
   295  
   296  func prepareCaseStatusVersion3() *OpenVPNStatusLog {
   297  	ovpn := New()
   298  	ovpn.LogPath = pathStatusVersion3
   299  	return ovpn
   300  }
   301  
   302  func prepareCaseStatusVersion3WithUserStats() *OpenVPNStatusLog {
   303  	ovpn := New()
   304  	ovpn.LogPath = pathStatusVersion3
   305  	ovpn.PerUserStats = matcher.SimpleExpr{
   306  		Includes: []string{"* *"},
   307  	}
   308  	return ovpn
   309  }
   310  
   311  func prepareCaseStatusVersion3NoClients() *OpenVPNStatusLog {
   312  	ovpn := New()
   313  	ovpn.LogPath = pathStatusVersion3NoClients
   314  	return ovpn
   315  }
   316  
   317  func prepareCaseStatusStaticKey() *OpenVPNStatusLog {
   318  	ovpn := New()
   319  	ovpn.LogPath = pathStaticKey
   320  	return ovpn
   321  }
   322  
   323  func prepareCaseEmptyFile() *OpenVPNStatusLog {
   324  	ovpn := New()
   325  	ovpn.LogPath = pathEmptyFile
   326  	return ovpn
   327  }
   328  
   329  func prepareCaseNonExistentFile() *OpenVPNStatusLog {
   330  	ovpn := New()
   331  	ovpn.LogPath = pathNonExistentFile
   332  	return ovpn
   333  }
   334  
   335  func copyConnTime(dst, src map[string]int64) {
   336  	for k, v := range src {
   337  		if !strings.HasSuffix(k, "connection_time") {
   338  			continue
   339  		}
   340  		if _, ok := dst[k]; !ok {
   341  			continue
   342  		}
   343  		dst[k] = v
   344  	}
   345  }