NONRTRIC-998: Servicemanager - Add API Docs
[nonrtric/plt/sme.git] / servicemanager / main_test.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2023-2024: OpenInfra Foundation Europe
6 //   %%
7 //   Licensed under the Apache License, Version 2.0 (the "License");
8 //   you may not use this file except in compliance with the License.
9 //   You may obtain a copy of the License at
10 //
11 //        http://www.apache.org/licenses/LICENSE-2.0
12 //
13 //   Unless required by applicable law or agreed to in writing, software
14 //   distributed under the License is distributed on an "AS IS" BASIS,
15 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 //   See the License for the specific language governing permissions and
17 //   limitations under the License.
18 //   ========================LICENSE_END===================================
19 //
20
21 package main
22
23 import (
24         "net/http"
25         "net/http/httptest"
26         "net/url"
27         "os"
28         "testing"
29
30         "github.com/deepmap/oapi-codegen/pkg/testutil"
31         "github.com/getkin/kin-openapi/openapi3"
32         "github.com/labstack/echo/v4"
33         "github.com/stretchr/testify/assert"
34         log "github.com/sirupsen/logrus"
35
36         "oransc.org/nonrtric/servicemanager/internal/common29122"
37         "oransc.org/nonrtric/servicemanager/internal/envreader"
38         "oransc.org/nonrtric/servicemanager/internal/kongclear"
39
40         "oransc.org/nonrtric/capifcore"
41         "oransc.org/nonrtric/servicemanager/mockkong"
42 )
43
44 var (
45         eServiceManager          *echo.Echo
46         eCapifWeb                *echo.Echo
47         eKong                    *echo.Echo
48         mockConfigReader         *envreader.MockConfigReader
49         serviceManagerServer *httptest.Server
50         capifServer              *httptest.Server
51         mockKongServer           *httptest.Server
52 )
53
54 // Init code to run before tests
55 func TestMain(m *testing.M) {
56         err := setupTest()
57         if err != nil {
58                 return
59         }
60
61         ret := m.Run()
62         if ret == 0 {
63                 teardown()
64         }
65         os.Exit(ret)
66 }
67
68 func setupTest() error {
69         // Start the mock Kong server
70         eKong = echo.New()
71         mockKong.RegisterHandlers(eKong)
72         mockKongServer = httptest.NewServer(eKong)
73
74         // Parse the server URL
75         parsedMockKongURL, err := url.Parse(mockKongServer.URL)
76         if err != nil {
77                 log.Fatalf("error parsing mock Kong URL: %v", err)
78                 return err
79         }
80
81         // Extract the host and port
82         mockKongHost := parsedMockKongURL.Hostname()
83         mockKongControlPlanePort := parsedMockKongURL.Port()
84
85         eCapifWeb = echo.New()
86         capifcore.RegisterHandlers(eCapifWeb, nil, nil)
87         capifServer = httptest.NewServer(eCapifWeb)
88
89         // Parse the server URL
90         parsedCapifURL, err := url.Parse(capifServer.URL)
91         if err != nil {
92                 log.Fatalf("error parsing mock Kong URL: %v", err)
93                 return err
94         }
95
96         // Extract the host and port
97         capifHost := parsedCapifURL.Hostname()
98         capifPort := parsedCapifURL.Port()
99
100         // Set up the mock config reader with the desired configuration for testing
101         mockConfigReader = &envreader.MockConfigReader{
102                 MockedConfig: map[string]string{
103                         "KONG_DOMAIN":             "kong",
104                         "KONG_PROTOCOL":           "http",
105                         "KONG_CONTROL_PLANE_IPV4": mockKongHost,
106                         "KONG_CONTROL_PLANE_PORT": mockKongControlPlanePort,
107                         "KONG_DATA_PLANE_IPV4":    "10.101.1.101",
108                         "KONG_DATA_PLANE_PORT":    "32080",
109                         "CAPIF_PROTOCOL":          "http",
110                         "CAPIF_IPV4":              capifHost,
111                         "CAPIF_PORT":              capifPort,
112                         "LOG_LEVEL":               "Info",
113                         "SERVICE_MANAGER_PORT":    "8095",
114                         "TEST_SERVICE_IPV4":       "10.101.1.101",
115                         "TEST_SERVICE_PORT":       "30951",
116                 },
117         }
118
119         myEnv, myPorts, err := mockConfigReader.ReadDotEnv()
120         if err != nil {
121                 log.Fatal("error loading environment file on setupTest")
122                 return err
123         }
124
125         eServiceManager = echo.New()
126         err = registerHandlers(eServiceManager, myEnv, myPorts)
127         if err != nil {
128                 log.Fatal("registerHandlers fatal error on setupTest")
129                 return err
130         }
131         serviceManagerServer = httptest.NewServer(eServiceManager)
132
133         return err
134 }
135
136
137 func teardown() error {
138         log.Trace("entering teardown")
139
140         myEnv, myPorts, err := mockConfigReader.ReadDotEnv()
141         if err != nil {
142                 log.Fatal("error loading environment file")
143                 return err
144         }
145
146         err = kongclear.KongClear(myEnv, myPorts)
147         if err != nil {
148                 log.Fatal("error clearing Kong on teardown")
149         }
150
151         mockKongServer.Close()
152         capifServer.Close()
153         serviceManagerServer.Close()
154
155         return err
156 }
157
158
159 func Test_routing(t *testing.T) {
160         type args struct {
161                 url          string
162                 returnStatus int
163                 method       string
164         }
165         tests := []struct {
166                 name string
167                 args args
168         }{
169                 {
170                         name: "Default path",
171                         args: args{
172                                 url:          "/",
173                                 returnStatus: http.StatusOK,
174                                 method:       "GET",
175                         },
176                 },
177                 {
178                         name: "Provider path",
179                         args: args{
180                                 url:          "/api-provider-management/v1/registrations/provider",
181                                 returnStatus: http.StatusNoContent,
182                                 method:       "DELETE",
183                         },
184                 },
185                 {
186                         name: "Publish path",
187                         args: args{
188                                 url:          "/published-apis/v1/apfId/service-apis/serviceId",
189                                 returnStatus: http.StatusNotFound,
190                                 method:       "GET",
191                         },
192                 },
193                 {
194                         name: "Discover path",
195                         args: args{
196                                 url:          "/service-apis/v1/allServiceAPIs?api-invoker-id=api_invoker_id",
197                                 returnStatus: http.StatusNotFound,
198                                 method:       "GET",
199                         },
200                 },
201                 {
202                         name: "Invoker path",
203                         args: args{
204                                 url:          "/api-invoker-management/v1/onboardedInvokers/invoker",
205                                 returnStatus: http.StatusNoContent,
206                                 method:       "DELETE",
207                         },
208                 },
209         }
210         for _, tt := range tests {
211                 t.Run(tt.name, func(t *testing.T) {
212                         var result *testutil.CompletedRequest
213                         if tt.args.method == "GET" {
214                                 result = testutil.NewRequest().Get(tt.args.url).Go(t, eServiceManager)
215                         } else if tt.args.method == "DELETE" {
216                                 result = testutil.NewRequest().Delete(tt.args.url).Go(t, eServiceManager)
217                         }
218
219                         assert.Equal(t, tt.args.returnStatus, result.Code(), tt.name)
220                 })
221         }
222 }
223
224 func TestGetSwagger(t *testing.T) {
225         type args struct {
226                 apiPath string
227                 apiName string
228         }
229         tests := []struct {
230                 name string
231                 args args
232         }{
233                 {
234                         name: "Provider api",
235                         args: args{
236                                 apiPath: "provider",
237                                 apiName: "Provider",
238                         },
239                 },
240                 {
241                         name: "Publish api",
242                         args: args{
243                                 apiPath: "publish",
244                                 apiName: "Publish",
245                         },
246                 },
247                 {
248                         name: "Invoker api",
249                         args: args{
250                                 apiPath: "invoker",
251                                 apiName: "Invoker",
252                         },
253                 },
254                 {
255                         name: "Discover api",
256                         args: args{
257                                 apiPath: "discover",
258                                 apiName: "Discover",
259                         },
260                 },
261         }
262         for _, tt := range tests {
263                 t.Run(tt.name, func(t *testing.T) {
264                         result := testutil.NewRequest().Get("/swagger/"+tt.args.apiPath).Go(t, eServiceManager)
265                         assert.Equal(t, http.StatusOK, result.Code())
266                         var swaggerResponse openapi3.T
267                         err := result.UnmarshalJsonToObject(&swaggerResponse)
268                         assert.Nil(t, err)
269                         assert.Contains(t, swaggerResponse.Info.Title, tt.args.apiName)
270                 })
271         }
272         invalidApi := "foobar"
273         result := testutil.NewRequest().Get("/swagger/"+invalidApi).Go(t, eServiceManager)
274         assert.Equal(t, http.StatusBadRequest, result.Code())
275         var errorResponse common29122.ProblemDetails
276         err := result.UnmarshalJsonToObject(&errorResponse)
277         assert.Nil(t, err)
278         assert.Contains(t, *errorResponse.Cause, "Invalid API")
279         assert.Contains(t, *errorResponse.Cause, invalidApi)
280 }