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 setupHcMockMasterDb(ip, port string) {
44 hcMocks = new(healthCheckMocks)
45 hcMocks.dbState.MasterDbState.Fields.Role = "master"
46 hcMocks.dbState.MasterDbState.Fields.Ip = ip
47 hcMocks.dbState.MasterDbState.Fields.Port = port
48 hcMocks.dbState.MasterDbState.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, masterLinkOk 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 MasterLinkStatus: masterLinkOk,
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")
135 {args: "-h", expErr: expOkErr, expOutput: expHelp},
136 {args: "--help", expErr: expOkErr, expOutput: expHelp},
137 {args: "--some-unknown-flag", expErr: expNokErr, expOutput: expHelp},
140 for _, test := range tests {
141 buf := new(bytes.Buffer)
142 cmd := cli.NewHealthCheckCmd(newMockDatabase)
144 cmd.SetArgs([]string{test.args})
148 stdout := buf.String()
149 assert.Equal(t, test.expErr, err)
150 assert.Contains(t, stdout, test.expOutput)
154 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectly(t *testing.T) {
155 setupHcMockMasterDb("10.20.30.40", "6379")
156 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
157 addHcMockReplicaDbState("5.6.7.8", "6379", "ok")
158 addHcMockSentinelDbState("1.2.3.4", "26379", "sentinel")
159 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
161 stdout, err := runHcCli()
164 assert.Contains(t, stdout, "Overall status: OK")
165 assert.Contains(t, stdout, "Master (10.20.30.40:6379): OK")
166 assert.Contains(t, stdout, "Replica #1 (1.2.3.4:6379): OK")
167 assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): OK")
171 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenOneReplicaStateNotUp(t *testing.T) {
172 setupHcMockMasterDb("10.20.30.40", "6379")
173 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
174 addHcMockReplicaDbState("5.6.7.8", "6379", "nok")
175 addHcMockSentinelDbState("1.2.3.4", "26379", "sentinel")
176 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
178 stdout, err := runHcCli()
181 assert.Contains(t, stdout, "Overall status: NOK")
182 assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): NOK")
183 assert.Contains(t, stdout, "Replica link to the master is down")
186 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenOneSentinelStateNotUp(t *testing.T) {
187 setupHcMockMasterDb("10.20.30.40", "6379")
188 addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
189 addHcMockReplicaDbState("5.6.7.8", "6379", "ok")
190 addHcMockSentinelDbState("1.2.3.4", "26379", "some-failure")
191 addHcMockSentinelDbState("5.6.7.8", "26379", "sentinel")
193 stdout, err := runHcCli()
196 assert.Contains(t, stdout, "Overall status: NOK")
197 assert.Contains(t, stdout, "Replica #1 (1.2.3.4:6379): OK")
198 assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): OK")
199 assert.Contains(t, stdout, "Sentinel #1 (1.2.3.4:26379): NOK")
200 assert.Contains(t, stdout, "Sentinel flags are 'some-failure', expected 'sentinel'")
203 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenDbStateQueryFails(t *testing.T) {
204 setupHcMockMasterDb("10.20.30.40", "6379")
205 hcMocks.dbErr = errors.New("Some error")
206 expCliErr := errors.New("SDL CLI error: Some error")
208 buf := new(bytes.Buffer)
209 cmd := cli.NewHealthCheckCmd(newMockDatabase)
213 stderr := buf.String()
215 assert.Equal(t, expCliErr, err)
216 assert.Contains(t, stderr, "Error: "+expCliErr.Error())
219 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectlyWhenDbStateIsFromReplicaOnly(t *testing.T) {
220 setupHcMockReplicaDb("1.2.3.4", "6379")
222 stdout, err := runHcCli()
225 assert.Contains(t, stdout, "Overall status: NOK")
226 assert.Contains(t, stdout, "Master (): NOK")
229 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectlyWhenDbStateIsFromSentinelOnly(t *testing.T) {
230 setupHcMockSentinelDb("1.2.3.4", "26379")
232 stdout, err := runHcCli()
235 assert.Contains(t, stdout, "Overall status: NOK")
236 assert.Contains(t, stdout, "Master (): NOK")
239 func TestCliHealthCheckCanShowStandaloneDeploymentOkStatusCorrectly(t *testing.T) {
240 setupHcMockMasterDb("10.20.30.40", "6379")
242 stdout, err := runHcCli()
245 assert.Contains(t, stdout, "Overall status: OK")
246 assert.Contains(t, stdout, "Master (10.20.30.40:6379): OK")