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 redis
21
22import (
23	"reflect"
24	"testing"
25	"time"
26
27	"github.com/mediocregopher/radix/v3"
28	"zabbix.com/pkg/uri"
29)
30
31func TestConnManager_closeUnused(t *testing.T) {
32	connMgr := NewConnManager(1*time.Microsecond, 30*time.Second, hkInterval*time.Second)
33	defer connMgr.Destroy()
34
35	u, _ := uri.New("tcp://127.0.0.1", nil)
36	_, _ = connMgr.create(*u)
37
38	t.Run("Unused connections should have been deleted", func(t *testing.T) {
39		connMgr.closeUnused()
40		if len(connMgr.connections) != 0 {
41			t.Errorf("connMgr.connections expected to be empty, but actual length is %d", len(connMgr.connections))
42		}
43	})
44}
45
46func TestConnManager_closeAll(t *testing.T) {
47	connMgr := NewConnManager(300*time.Second, 30*time.Second, hkInterval*time.Second)
48	defer connMgr.Destroy()
49
50	u, _ := uri.New("tcp://127.0.0.1", nil)
51	_, _ = connMgr.create(*u)
52
53	t.Run("All connections should have been deleted", func(t *testing.T) {
54		connMgr.closeAll()
55		if len(connMgr.connections) != 0 {
56			t.Errorf("connMgr.connections expected to be empty, but actual length is %d", len(connMgr.connections))
57		}
58	})
59}
60
61func TestConnManager_create(t *testing.T) {
62	u, _ := uri.New("tcp://127.0.0.1", nil)
63
64	connMgr := NewConnManager(300*time.Second, 30*time.Second, hkInterval*time.Second)
65	defer connMgr.Destroy()
66
67	connMgr.connections[*u] = &RedisConn{
68		client:         radix.Stub("", "", nil),
69		lastTimeAccess: time.Now(),
70	}
71
72	type args struct {
73		uri uri.URI
74	}
75
76	tests := []struct {
77		name      string
78		c         *ConnManager
79		args      args
80		want      *RedisConn
81		wantErr   bool
82		wantPanic bool
83	}{
84		{
85			name:      "Must panic if connection already exists",
86			c:         connMgr,
87			args:      args{uri: *u},
88			want:      nil,
89			wantErr:   false,
90			wantPanic: true,
91		},
92	}
93
94	for _, tt := range tests {
95		t.Run(tt.name, func(t *testing.T) {
96			if tt.wantPanic {
97				defer func() {
98					if r := recover(); r == nil {
99						t.Error("ConnManager.create() must panic with runtime error")
100					}
101				}()
102			}
103
104			got, err := tt.c.create(tt.args.uri)
105
106			if (err != nil) != tt.wantErr {
107				t.Errorf("ConnManager.create() error = %v, wantErr %v", err, tt.wantErr)
108				return
109			}
110
111			if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
112				t.Errorf("ConnManager.create() = %v, want %v", got, tt.want)
113			}
114		})
115	}
116}
117
118func TestConnManager_get(t *testing.T) {
119	u, _ := uri.New("tcp://127.0.0.1", nil)
120
121	connMgr := NewConnManager(300*time.Second, 30*time.Second, hkInterval*time.Second)
122	defer connMgr.Destroy()
123
124	t.Run("Should return nil if connection does not exist", func(t *testing.T) {
125		if got := connMgr.get(*u); got != nil {
126			t.Errorf("ConnManager.get() = %v, want <nil>", got)
127		}
128	})
129
130	lastTimeAccess := time.Now()
131	conn := &RedisConn{
132		client:         radix.Stub("", "", nil),
133		lastTimeAccess: lastTimeAccess,
134	}
135
136	connMgr.connections[*u] = conn
137
138	t.Run("Should return connection if it exists", func(t *testing.T) {
139		got := connMgr.get(*u)
140		if !reflect.DeepEqual(got, conn) {
141			t.Errorf("ConnManager.get() = %v, want %v", got, conn)
142		}
143		if lastTimeAccess == got.lastTimeAccess {
144			t.Error("conn.lastTimeAccess should be updated, but it's not")
145		}
146	})
147}
148