Implement SDL CLI 'healthcheck' -command
[ric-plt/sdlgo.git] / internal / cli / healthcheck_test.go
1 /*
2    Copyright (c) 2021 AT&T Intellectual Property.
3    Copyright (c) 2018-2021 Nokia.
4
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
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
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.
16 */
17
18 /*
19  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20  * platform project (RICP).
21  */
22
23 package cli_test
24
25 import (
26         "bytes"
27         "errors"
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"
32         "testing"
33 )
34
35 var hcMocks *healthCheckMocks
36
37 type healthCheckMocks struct {
38         dbIface *mocks.MockDB
39         dbErr   error
40         dbState sdlgoredis.DbState
41 }
42
43 func setupHcMockMasterDb(ip, port string, replicas uint32) {
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"
49 }
50
51 func setupHcMockReplicaDb() {
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{
57                                 Role: "slave",
58                         },
59                 },
60         }
61 }
62
63 func addHcMockReplicaDbState(ip, port, masterLinkOk string) {
64         if hcMocks.dbState.ReplicasDbState == nil {
65                 hcMocks.dbState.ReplicasDbState = new(sdlgoredis.ReplicasDbState)
66         }
67         hcMocks.dbState.ReplicasDbState.States = append(hcMocks.dbState.ReplicasDbState.States,
68                 &sdlgoredis.ReplicaDbState{
69                         Fields: sdlgoredis.ReplicaDbStateFields{
70                                 Role:             "slave",
71                                 Ip:               ip,
72                                 Port:             port,
73                                 MasterLinkStatus: masterLinkOk,
74                                 Flags:            "slave",
75                         },
76                 },
77         )
78 }
79
80 func newMockDatabase() *cli.Database {
81         db := &cli.Database{}
82         hcMocks.dbIface = new(mocks.MockDB)
83         hcMocks.dbIface.On("State").Return(&hcMocks.dbState, hcMocks.dbErr)
84         db.Instances = append(db.Instances, hcMocks.dbIface)
85         return db
86 }
87
88 func runHcCli() (string, error) {
89         buf := new(bytes.Buffer)
90         cmd := cli.NewHealthCheckCmdForTest(newMockDatabase)
91         cmd.SetOut(buf)
92
93         err := cmd.Execute()
94
95         return buf.String(), err
96 }
97
98 func TestCliHealthCheckCanShowHelp(t *testing.T) {
99         var expOkErr error
100         expHelp := "Usage:\n  " + "healthcheck [flags]"
101         expNokErr := errors.New("unknown flag: --some-unknown-flag")
102         tests := []struct {
103                 args      string
104                 expErr    error
105                 expOutput string
106         }{
107                 {args: "-h", expErr: expOkErr, expOutput: expHelp},
108                 {args: "--help", expErr: expOkErr, expOutput: expHelp},
109                 {args: "--some-unknown-flag", expErr: expNokErr, expOutput: expHelp},
110         }
111
112         for _, test := range tests {
113                 buf := new(bytes.Buffer)
114                 cmd := cli.NewHealthCheckCmd()
115                 cmd.SetOut(buf)
116                 cmd.SetArgs([]string{test.args})
117
118                 err := cmd.Execute()
119
120                 stdout := buf.String()
121                 assert.Equal(t, test.expErr, err)
122                 assert.Contains(t, stdout, test.expOutput)
123         }
124 }
125
126 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectly(t *testing.T) {
127         setupHcMockMasterDb("10.20.30.40", "6379", 2)
128         addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
129         addHcMockReplicaDbState("5.6.7.8", "6379", "ok")
130
131         stdout, err := runHcCli()
132
133         assert.Nil(t, err)
134         assert.Contains(t, stdout, "Overall status: OK")
135         assert.Contains(t, stdout, "Master (10.20.30.40:6379): OK")
136         assert.Contains(t, stdout, "Replica #1 (1.2.3.4:6379): OK")
137         assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): OK")
138
139 }
140
141 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenOneReplicaStateNotUp(t *testing.T) {
142         setupHcMockMasterDb("10.20.30.40", "6379", 2)
143         addHcMockReplicaDbState("1.2.3.4", "6379", "ok")
144         addHcMockReplicaDbState("5.6.7.8", "6379", "nok")
145
146         stdout, err := runHcCli()
147
148         assert.Nil(t, err)
149         assert.Contains(t, stdout, "Overall status: NOK")
150         assert.Contains(t, stdout, "Replica #2 (5.6.7.8:6379): NOK")
151         assert.Contains(t, stdout, "Replica link to the master is down")
152 }
153
154 func TestCliHealthCheckCanShowHaDeploymentStatusCorrectlyWhenDbStateQueryFails(t *testing.T) {
155         setupHcMockMasterDb("10.20.30.40", "6379", 0)
156         hcMocks.dbErr = errors.New("Some error")
157         expCliErr := errors.New("SDL CLI error: Some error")
158
159         buf := new(bytes.Buffer)
160         cmd := cli.NewHealthCheckCmdForTest(newMockDatabase)
161         cmd.SetErr(buf)
162
163         err := cmd.Execute()
164         stderr := buf.String()
165
166         assert.Equal(t, expCliErr, err)
167         assert.Contains(t, stderr, "Error: "+expCliErr.Error())
168 }
169
170 func TestCliHealthCheckCanShowHaDeploymentOkStatusCorrectlyWhenDbStateIsFromReplicaServer(t *testing.T) {
171         setupHcMockReplicaDb()
172
173         stdout, err := runHcCli()
174
175         assert.Nil(t, err)
176         assert.Contains(t, stdout, "Overall status: NOK")
177         assert.Contains(t, stdout, "Master (): NOK")
178 }
179
180 func TestCliHealthCheckCanShowStandaloneDeploymentOkStatusCorrectly(t *testing.T) {
181         setupHcMockMasterDb("10.20.30.40", "6379", 0)
182
183         stdout, err := runHcCli()
184
185         assert.Nil(t, err)
186         assert.Contains(t, stdout, "Overall status: OK")
187         assert.Contains(t, stdout, "Master (10.20.30.40:6379): OK")
188 }