1/*
2** Zabbix
3** Copyright (C) 2001-2021 Zabbix SIA
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18**/
19
20package memcached
21
22import (
23	"reflect"
24	"testing"
25	"time"
26
27	"zabbix.com/pkg/uri"
28)
29
30func TestConnManager_closeUnused(t *testing.T) {
31	connMgr := NewConnManager(1*time.Microsecond, 30*time.Second, hkInterval*time.Second)
32	defer connMgr.Destroy()
33
34	uri, _ := uri.New("tcp://127.0.0.1", nil)
35	_ = connMgr.create(*uri)
36
37	t.Run("Unused connections should have been deleted", func(t *testing.T) {
38		connMgr.closeUnused()
39		if len(connMgr.connections) != 0 {
40			t.Errorf("connMgr.connections expected to be empty, but actual length is %d", len(connMgr.connections))
41		}
42	})
43}
44
45func TestConnManager_closeAll(t *testing.T) {
46	connMgr := NewConnManager(300*time.Second, 30*time.Second, hkInterval*time.Second)
47	defer connMgr.Destroy()
48
49	uri, _ := uri.New("tcp://127.0.0.1", nil)
50	_ = connMgr.create(*uri)
51
52	t.Run("All connections should have been deleted", func(t *testing.T) {
53		connMgr.closeAll()
54		if len(connMgr.connections) != 0 {
55			t.Errorf("connMgr.connections expected to be empty, but actual length is %d", len(connMgr.connections))
56		}
57	})
58}
59
60func TestConnManager_create(t *testing.T) {
61	u, _ := uri.New("tcp://127.0.0.1", nil)
62
63	connMgr := NewConnManager(300*time.Second, 30*time.Second, hkInterval*time.Second)
64	defer connMgr.Destroy()
65
66	type args struct {
67		uri uri.URI
68	}
69
70	tests := []struct {
71		name      string
72		c         *ConnManager
73		args      args
74		want      *MCConn
75		wantPanic bool
76	}{
77		{
78			name:      "Should return *MCConn",
79			c:         connMgr,
80			args:      args{uri: *u},
81			want:      &MCConn{},
82			wantPanic: false,
83		},
84		{
85			name:      "Must panic if connection already exists",
86			c:         connMgr,
87			args:      args{uri: *u},
88			want:      nil,
89			wantPanic: true,
90		},
91	}
92
93	for _, tt := range tests {
94		t.Run(tt.name, func(t *testing.T) {
95			if tt.wantPanic {
96				defer func() {
97					if r := recover(); r == nil {
98						t.Error("ConnManager.create() must panic with runtime error")
99					}
100				}()
101			}
102
103			if got := tt.c.create(tt.args.uri); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
104				t.Errorf("ConnManager.create() = %v, want %v", got, tt.want)
105			}
106		})
107	}
108}
109
110func TestConnManager_get(t *testing.T) {
111	u, _ := uri.New("tcp://127.0.0.1", nil)
112
113	connMgr := NewConnManager(300*time.Second, 30*time.Second, hkInterval*time.Second)
114	defer connMgr.Destroy()
115
116	t.Run("Should return nil if connection does not exist", func(t *testing.T) {
117		if got := connMgr.get(*u); got != nil {
118			t.Errorf("ConnManager.get() = %v, want <nil>", got)
119		}
120	})
121
122	conn := connMgr.create(*u)
123	lastTimeAccess := conn.lastTimeAccess
124
125	t.Run("Should return connection if it exists", func(t *testing.T) {
126		got := connMgr.get(*u)
127		if !reflect.DeepEqual(got, conn) {
128			t.Errorf("ConnManager.get() = %v, want %v", got, conn)
129		}
130		if lastTimeAccess == got.lastTimeAccess {
131			t.Error("conn.lastTimeAccess should be updated, but it's not")
132		}
133	})
134}
135
136func TestConnManager_GetConnection(t *testing.T) {
137	var conn *MCConn
138
139	u, _ := uri.New("tcp://127.0.0.1", nil)
140
141	connMgr := NewConnManager(300*time.Second, 30*time.Second, hkInterval*time.Second)
142	defer connMgr.Destroy()
143
144	t.Run("Should create connection if it does not exist", func(t *testing.T) {
145		got := connMgr.GetConnection(*u)
146		if reflect.TypeOf(got) != reflect.TypeOf(conn) {
147			t.Errorf("ConnManager.GetConnection() = %s, want *MCConn", reflect.TypeOf(got))
148		}
149		conn = got
150	})
151
152	t.Run("Should return previously created connection", func(t *testing.T) {
153		got := connMgr.GetConnection(*u)
154		if !reflect.DeepEqual(got, conn) {
155			t.Errorf("ConnManager.GetConnection() = %v, want %v", got, conn)
156		}
157	})
158}
159