2 Copyright (c) 2021 AT&T Intellectual Property.
3 Copyright (c) 2018-2021 Nokia.
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
19 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20 * platform project (RICP).
28 "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/cli"
29 "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/mocks"
30 "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
31 "github.com/stretchr/testify/assert"
35 var hcMocks *healthCheckMocks
37 type healthCheckMocks struct {
40 dbState sdlgoredis.DbState
43 func setupHcMockPrimaryDb(ip, port string, nodes int) {
44 hcMocks = new(healthCheckMocks)
45 hcMocks.dbState.ConfigNodeCnt = nodes
46 hcMocks.dbState.PrimaryDbState.Fields.Role = "master"
47 hcMocks.dbState.PrimaryDbState.Fields.Ip = ip
48 hcMocks.dbState.PrimaryDbState.Fields.Port = port
49 hcMocks.dbState.PrimaryDbState.Fields.Flags = "master"
50 hcMocks.dbState.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
51 hcMocks.dbState.ReplicasDbState.States = []*sdlgoredis.ReplicaDbState{}
52 hcMocks.dbState.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
53 hcMocks.dbState.SentinelsDbState.States = []*sdlgoredis.SentinelDbState{}
56 func setupHcMockReplicaDb(nodes int) {
57 hcMocks = new(healthCheckMocks)
58 hcMocks.dbState.ConfigNodeCnt = nodes
59 hcMocks.dbState.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
60 hcMocks.dbState.ReplicasDbState.States = []*sdlgoredis.ReplicaDbState{}
61 hcMocks.dbState.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
62 hcMocks.dbState.SentinelsDbState.States = []*sdlgoredis.SentinelDbState{}
65 func setupHcMockSentinelDb(ip, port string, nodes int) {
66 hcMocks = new(healthCheckMocks)
67 hcMocks.dbState.ConfigNodeCnt = nodes
68 hcMocks.dbState.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
69 hcMocks.dbState.SentinelsDbState.States = []*sdlgoredis.SentinelDbState{}
72 func addHcMockReplicaDbState(ip, port, primaryLinkOk string) {
73 if hcMocks.dbState.ReplicasDbState == nil {
74 hcMocks.dbState.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
76 hcMocks.dbState.ReplicasDbState.States = append(hcMocks.dbState.ReplicasDbState.States,
77 &sdlgoredis.ReplicaDbState{
78 Fields: sdlgoredis.ReplicaDbStateFields{
82 PrimaryLinkStatus: primaryLinkOk,
89 func addHcMockSentinelDbState(ip, port, flags string) {
90 if hcMocks.dbState.SentinelsDbState == nil {
91 hcMocks.dbState.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
93 hcMocks.dbState.SentinelsDbState.States = append(hcMocks.dbState.SentinelsDbState.States,
94 &sdlgoredis.SentinelDbState{
95 Fields: sdlgoredis.SentinelDbStateFields{
104 func newMockDatabase() *cli.Database {
105 db := &cli.Database{}
106 hcMocks.dbIface = new(mocks.MockDB)
107 hcMocks.dbIface.On("State").Return(&hcMocks.dbState, hcMocks.dbErr)
108 db.Instances = append(db.Instances, hcMocks.dbIface)
112 func runHcCli() (string, error) {
113 buf := new(bytes.Buffer)
114 cmd := cli.NewHealthCheckCmd(newMockDatabase)
119 return buf.String(), err
122 func TestCliHealthCheckCanShowHelp(t *testing.T) {
124 expHelp := "Usage:\n " + "healthcheck [flags]"
125 expNokErr := errors.New("unknown flag: --some-unknown-flag")
126 expArgCntErr := errors.New("accepts 0 arg(s), received 1")
132 {args: "-h", expErr: expOkErr, expOutput: expHelp},
133 {args: "--help", expErr: expOkErr, expOutput: expHelp},
134 {args: "--some-unknown-flag", expErr: expNokErr, expOutput: expHelp},
135 {args: "some-extra-argument", expErr: expArgCntErr, expOutput: expHelp},
138 for _, test := range tests {
139 buf := new(bytes.Buffer)
140 cmd := cli.NewHealthCheckCmd(newMockDatabase)
142 cmd.SetArgs([]string{test.args})
146 stdout := buf.String()
147 assert.Equal(t, test.expErr, err)
148 assert.Contains(t, stdout, test.expOutput)
152 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectly(t *testing.T) {
154 "Overall status: OK\n\n" +
155 "CLUSTER ROLE ADDRESS STATUS ERROR \n" +
156 "0 primary 10.20.30.40:6379 OK <none> \n" +
157 "0 replica 1.2.3.4:6379 OK <none> \n" +
158 "0 replica 5.6.7.8:6379 OK <none> \n"
159 setupHcMockPrimaryDb("10.20.30.40", "6379", 3)
160 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
161 addHcMockReplicaDbState("5.6.7.8", "6379", "ok")
162 addHcMockSentinelDbState("1.2.3.4", "26379", "sentinel")
163 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
165 stdout, err := runHcCli()
168 assert.Equal(t, expOut, stdout)
171 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenOneReplicaStateNotUp(t *testing.T) {
173 "Overall status: NOK\n\n" +
174 "CLUSTER ROLE ADDRESS STATUS ERROR \n" +
175 "0 primary 10.20.30.40:6379 OK <none> \n" +
176 "0 replica 1.2.3.4:6379 OK <none> \n" +
177 "0 replica 5.6.7.8:6379 NOK Replica link to the primary is down \n"
178 setupHcMockPrimaryDb("10.20.30.40", "6379", 3)
179 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
180 addHcMockReplicaDbState("5.6.7.8", "6379", "nok")
181 addHcMockSentinelDbState("1.2.3.4", "26379", "sentinel")
182 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
184 stdout, err := runHcCli()
187 assert.Equal(t, expOut, stdout)
190 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenOneSentinelStateNotUp(t *testing.T) {
192 "Overall status: NOK\n\n" +
193 "CLUSTER ROLE ADDRESS STATUS ERROR \n" +
194 "0 primary 10.20.30.40:6379 OK <none> \n" +
195 "0 replica 1.2.3.4:6379 OK <none> \n" +
196 "0 replica 5.6.7.8:6379 OK <none> \n" +
197 "0 sentinel 1.2.3.4:26379 NOK Sentinel flags are 'some-failure', expected 'sentinel' \n"
198 setupHcMockPrimaryDb("10.20.30.40", "6379", 3)
199 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
200 addHcMockReplicaDbState("5.6.7.8", "6379", "ok")
201 addHcMockSentinelDbState("1.2.3.4", "26379", "some-failure")
202 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
204 stdout, err := runHcCli()
207 assert.Equal(t, expOut, stdout)
210 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenNoReplicas(t *testing.T) {
212 "Overall status: NOK\n\n" +
213 "CLUSTER ROLE ADDRESS STATUS ERROR \n" +
214 "0 primary 10.20.30.40:6379 OK <none> \n" +
215 "0 replica <none> NOK Configured DBAAS nodes 3 but only 1 primary and 0 replicas \n"
216 setupHcMockPrimaryDb("10.20.30.40", "6379", 3)
217 addHcMockSentinelDbState("1.2.3.4", "26379", "sentinel")
218 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
220 stdout, err := runHcCli()
223 assert.Equal(t, expOut, stdout)
226 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenDbStateQueryFails(t *testing.T) {
227 setupHcMockPrimaryDb("10.20.30.40", "6379", 3)
228 hcMocks.dbErr = errors.New("Some error")
230 buf := new(bytes.Buffer)
231 cmd := cli.NewHealthCheckCmd(newMockDatabase)
235 stderr := buf.String()
237 assert.Equal(t, hcMocks.dbErr, err)
238 assert.Contains(t, stderr, "Error: Some error")
241 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectlyWhenDbStateIsFromReplicaOnly(t *testing.T) {
243 "Overall status: NOK\n\n" +
244 "CLUSTER ROLE ADDRESS STATUS ERROR \n" +
245 "0 primary <none> NOK No primary DB, current role '' \n" +
246 "0 replica 1.2.3.4:6379 NOK Replica link to the primary is down \n" +
247 "0 replica 5.6.7.8:6379 NOK Replica link to the primary is down \n"
248 setupHcMockReplicaDb(3)
249 addHcMockReplicaDbState("1.2.3.4", "6379", "nok")
250 addHcMockReplicaDbState("5.6.7.8", "6379", "nok")
252 stdout, err := runHcCli()
255 assert.Equal(t, expOut, stdout)
258 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectlyWhenDbStateIsFromSentinelOnly(t *testing.T) {
260 "Overall status: NOK\n\n" +
261 "CLUSTER ROLE ADDRESS STATUS ERROR \n" +
262 "0 primary <none> NOK No primary DB, current role '' \n"
263 setupHcMockSentinelDb("1.2.3.4", "26379", 3)
265 stdout, err := runHcCli()
268 assert.Equal(t, expOut, stdout)
271 func TestCliHealthCheckCanShowStandaloneDeploymentOkStatusCorrectly(t *testing.T) {
273 "Overall status: OK\n\n" +
274 "CLUSTER ROLE ADDRESS STATUS ERROR \n" +
275 "0 primary 10.20.30.40:6379 OK <none> \n"
276 setupHcMockPrimaryDb("10.20.30.40", "6379", 1)
278 stdout, err := runHcCli()
281 assert.Equal(t, expOut, stdout)