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) {
44 hcMocks = new(healthCheckMocks)
45 hcMocks.dbState.PrimaryDbState.Fields.Role = "master"
46 hcMocks.dbState.PrimaryDbState.Fields.Ip = ip
47 hcMocks.dbState.PrimaryDbState.Fields.Port = port
48 hcMocks.dbState.PrimaryDbState.Fields.Flags = "master"
51 func setupHcMockReplicaDb(ip, port string) {
52 hcMocks = new(healthCheckMocks)
53 hcMocks.dbState.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
54 hcMocks.dbState.ReplicasDbState.States = []*sdlgoredis.ReplicaDbState{
55 &sdlgoredis.ReplicaDbState{
56 Fields: sdlgoredis.ReplicaDbStateFields{
63 func setupHcMockSentinelDb(ip, port string) {
64 hcMocks = new(healthCheckMocks)
65 hcMocks.dbState.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
66 hcMocks.dbState.SentinelsDbState.States = []*sdlgoredis.SentinelDbState{
67 &sdlgoredis.SentinelDbState{
68 Fields: sdlgoredis.SentinelDbStateFields{
76 func addHcMockReplicaDbState(ip, port, primaryLinkOk string) {
77 if hcMocks.dbState.ReplicasDbState == nil {
78 hcMocks.dbState.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
80 hcMocks.dbState.ReplicasDbState.States = append(hcMocks.dbState.ReplicasDbState.States,
81 &sdlgoredis.ReplicaDbState{
82 Fields: sdlgoredis.ReplicaDbStateFields{
86 PrimaryLinkStatus: primaryLinkOk,
93 func addHcMockSentinelDbState(ip, port, flags string) {
94 if hcMocks.dbState.SentinelsDbState == nil {
95 hcMocks.dbState.SentinelsDbState = new(sdlgoredis.SentinelsDbState)
97 hcMocks.dbState.SentinelsDbState.States = append(hcMocks.dbState.SentinelsDbState.States,
98 &sdlgoredis.SentinelDbState{
99 Fields: sdlgoredis.SentinelDbStateFields{
108 func newMockDatabase() *cli.Database {
109 db := &cli.Database{}
110 hcMocks.dbIface = new(mocks.MockDB)
111 hcMocks.dbIface.On("State").Return(&hcMocks.dbState, hcMocks.dbErr)
112 db.Instances = append(db.Instances, hcMocks.dbIface)
116 func runHcCli() (string, error) {
117 buf := new(bytes.Buffer)
118 cmd := cli.NewHealthCheckCmd(newMockDatabase)
123 return buf.String(), err
126 func TestCliHealthCheckCanShowHelp(t *testing.T) {
128 expHelp := "Usage:\n " + "healthcheck [flags]"
129 expNokErr := errors.New("unknown flag: --some-unknown-flag")
130 expArgCntErr := errors.New("accepts 0 arg(s), received 1")
136 {args: "-h", expErr: expOkErr, expOutput: expHelp},
137 {args: "--help", expErr: expOkErr, expOutput: expHelp},
138 {args: "--some-unknown-flag", expErr: expNokErr, expOutput: expHelp},
139 {args: "some-extra-argument", expErr: expArgCntErr, expOutput: expHelp},
142 for _, test := range tests {
143 buf := new(bytes.Buffer)
144 cmd := cli.NewHealthCheckCmd(newMockDatabase)
146 cmd.SetArgs([]string{test.args})
150 stdout := buf.String()
151 assert.Equal(t, test.expErr, err)
152 assert.Contains(t, stdout, test.expOutput)
156 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectly(t *testing.T) {
157 setupHcMockPrimaryDb("10.20.30.40", "6379")
158 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
159 addHcMockReplicaDbState("5.6.7.8", "6379", "ok")
160 addHcMockSentinelDbState("1.2.3.4", "26379", "sentinel")
161 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
163 stdout, err := runHcCli()
166 assert.Contains(t, stdout, "Overall status: OK")
167 assert.Contains(t, stdout, "Primary (10.20.30.40:6379): OK")
168 assert.Contains(t, stdout, "Replica #1 (1.2.3.4:6379): OK")
169 assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): OK")
173 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenOneReplicaStateNotUp(t *testing.T) {
174 setupHcMockPrimaryDb("10.20.30.40", "6379")
175 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
176 addHcMockReplicaDbState("5.6.7.8", "6379", "nok")
177 addHcMockSentinelDbState("1.2.3.4", "26379", "sentinel")
178 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
180 stdout, err := runHcCli()
183 assert.Contains(t, stdout, "Overall status: NOK")
184 assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): NOK")
185 assert.Contains(t, stdout, "Replica link to the primary is down")
188 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenOneSentinelStateNotUp(t *testing.T) {
189 setupHcMockPrimaryDb("10.20.30.40", "6379")
190 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
191 addHcMockReplicaDbState("5.6.7.8", "6379", "ok")
192 addHcMockSentinelDbState("1.2.3.4", "26379", "some-failure")
193 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
195 stdout, err := runHcCli()
198 assert.Contains(t, stdout, "Overall status: NOK")
199 assert.Contains(t, stdout, "Replica #1 (1.2.3.4:6379): OK")
200 assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): OK")
201 assert.Contains(t, stdout, "Sentinel #1 (1.2.3.4:26379): NOK")
202 assert.Contains(t, stdout, "Sentinel flags are 'some-failure', expected 'sentinel'")
205 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenDbStateQueryFails(t *testing.T) {
206 setupHcMockPrimaryDb("10.20.30.40", "6379")
207 hcMocks.dbErr = errors.New("Some error")
209 buf := new(bytes.Buffer)
210 cmd := cli.NewHealthCheckCmd(newMockDatabase)
214 stderr := buf.String()
216 assert.Equal(t, hcMocks.dbErr, err)
217 assert.Contains(t, stderr, "Error: "+hcMocks.dbErr.Error())
220 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectlyWhenDbStateIsFromReplicaOnly(t *testing.T) {
221 setupHcMockReplicaDb("1.2.3.4", "6379")
223 stdout, err := runHcCli()
226 assert.Contains(t, stdout, "Overall status: NOK")
227 assert.Contains(t, stdout, "Primary (): NOK")
230 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectlyWhenDbStateIsFromSentinelOnly(t *testing.T) {
231 setupHcMockSentinelDb("1.2.3.4", "26379")
233 stdout, err := runHcCli()
236 assert.Contains(t, stdout, "Overall status: NOK")
237 assert.Contains(t, stdout, "Primary (): NOK")
240 func TestCliHealthCheckCanShowStandaloneDeploymentOkStatusCorrectly(t *testing.T) {
241 setupHcMockPrimaryDb("10.20.30.40", "6379")
243 stdout, err := runHcCli()
246 assert.Contains(t, stdout, "Overall status: OK")
247 assert.Contains(t, stdout, "Primary (10.20.30.40:6379): OK")