Roll versions after J-Relase (master branch)
[nonrtric/plt/sme.git] / capifcore / internal / providermanagement / providermanagement_test.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2022: Nordix Foundation
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 providermanagement
22
23 import (
24         "fmt"
25         "net/http"
26         "os"
27         "testing"
28
29         "github.com/labstack/echo/v4"
30
31         "oransc.org/nonrtric/capifcore/internal/common29122"
32         provapi "oransc.org/nonrtric/capifcore/internal/providermanagementapi"
33
34         "github.com/deepmap/oapi-codegen/pkg/middleware"
35         "github.com/deepmap/oapi-codegen/pkg/testutil"
36         echomiddleware "github.com/labstack/echo/v4/middleware"
37         "github.com/stretchr/testify/assert"
38 )
39
40 var (
41         domainID      = "domain_id_rApp_domain"
42         otherDomainID = "domain_id_other_domain"
43         domainInfo    = "rApp domain"
44         funcInfoAPF   = "rApp as APF"
45         funcIdAPF     = "APF_id_rApp_as_APF"
46         funcInfoAMF   = "rApp as AMF"
47         funcIdAMF     = "AMF_id_rApp_as_AMF"
48         funcInfoAEF   = "rApp as AEF"
49         funcIdAEF     = "AEF_id_rApp_as_AEF"
50 )
51
52 func TestFailedUpdateValidProviderWithNewFunction(t *testing.T) {
53         managerUnderTest, requestHandler := getEcho()
54
55         provider := getProvider()
56         provider.ApiProvDomId = &domainID
57         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
58         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
59         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
60         managerUnderTest.registeredProviders[domainID] = provider
61
62         // Modify the provider
63         updatedProvider := getProvider()
64
65         // For this test case, we do not set updatedProvider.ApiProvDomId, so that we can test for a 400 error below.
66         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
67         (*updatedProvider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
68         (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
69         newDomainInfo := "New domain info"
70         updatedProvider.ApiProvDomInfo = &newDomainInfo
71         newFunctionInfo := "New function info"
72         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo
73         newFuncInfoAEF := "new func as AEF"
74         testFuncs := *updatedProvider.ApiProvFuncs
75         testFuncs = append(testFuncs, provapi.APIProviderFunctionDetails{
76                 ApiProvFuncInfo: &newFuncInfoAEF,
77                 ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
78                 RegInfo: provapi.RegistrationInformation{
79                         ApiProvPubKey: "key",
80                 },
81         })
82         updatedProvider.ApiProvFuncs = &testFuncs
83
84         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
85         assert.Equal(t, http.StatusBadRequest, result.Code())
86
87         var resultError common29122.ProblemDetails
88         err := result.UnmarshalJsonToObject(&resultError)
89         assert.NoError(t, err, "error unmarshaling response")
90
91         assert.Contains(t, *resultError.Cause, "APIProviderEnrolmentDetails ApiProvDomId doesn't match path parameter")
92         assert.False(t, managerUnderTest.IsFunctionRegistered("AEF_id_new_func_as_AEF"))
93 }
94
95 func TestRegisterValidProvider(t *testing.T) {
96         managerUnderTest, requestHandler := getEcho()
97
98         newProvider := getProvider()
99
100         // Register a valid provider
101         result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
102
103         assert.Equal(t, http.StatusCreated, result.Code())
104         var resultProvider provapi.APIProviderEnrolmentDetails
105         err := result.UnmarshalBodyToObject(&resultProvider)
106         assert.NoError(t, err, "error unmarshaling response")
107         assert.Equal(t, *resultProvider.ApiProvDomId, domainID)
108         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncId, funcIdAPF)
109         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[1].ApiProvFuncId, funcIdAMF)
110         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[2].ApiProvFuncId, funcIdAEF)
111         assert.Empty(t, resultProvider.FailReason)
112         assert.Equal(t, "http://example.com/registrations/"+*resultProvider.ApiProvDomId, result.Recorder.Header().Get(echo.HeaderLocation))
113         assert.True(t, managerUnderTest.IsFunctionRegistered("APF_id_rApp_as_APF"))
114
115         // Register same provider again should result in Forbidden
116         result = testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
117         var errorObj common29122.ProblemDetails
118         assert.Equal(t, http.StatusForbidden, result.Code())
119         err = result.UnmarshalBodyToObject(&errorObj)
120         assert.NoError(t, err, "error unmarshaling response")
121         assert.Equal(t, http.StatusForbidden, *errorObj.Status)
122         assert.Contains(t, *errorObj.Cause, "already registered")
123 }
124
125 func TestUpdateValidProviderWithNewFunction(t *testing.T) {
126         managerUnderTest, requestHandler := getEcho()
127
128         provider := getProvider()
129         provider.ApiProvDomId = &domainID
130         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
131         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
132         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
133         managerUnderTest.registeredProviders[domainID] = provider
134
135         // Modify the provider
136         updatedProvider := getProvider()
137         updatedProvider.ApiProvDomId = &domainID
138         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
139         (*updatedProvider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
140         (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
141         newDomainInfo := "New domain info"
142         updatedProvider.ApiProvDomInfo = &newDomainInfo
143         newFunctionInfo := "New function info"
144         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo
145         newFuncInfoAEF := "new func as AEF"
146         testFuncs := *updatedProvider.ApiProvFuncs
147         testFuncs = append(testFuncs, provapi.APIProviderFunctionDetails{
148                 ApiProvFuncInfo: &newFuncInfoAEF,
149                 ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
150                 RegInfo: provapi.RegistrationInformation{
151                         ApiProvPubKey: "key",
152                 },
153         })
154         updatedProvider.ApiProvFuncs = &testFuncs
155
156         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
157
158         var resultProvider provapi.APIProviderEnrolmentDetails
159         assert.Equal(t, http.StatusOK, result.Code())
160         err := result.UnmarshalBodyToObject(&resultProvider)
161         assert.NoError(t, err, "error unmarshaling response")
162         assert.Equal(t, newDomainInfo, *resultProvider.ApiProvDomInfo)
163         assert.Equal(t, newFunctionInfo, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncInfo)
164         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[3].ApiProvFuncId, "AEF_id_new_func_as_AEF")
165         assert.Empty(t, resultProvider.FailReason)
166         assert.True(t, managerUnderTest.IsFunctionRegistered("AEF_id_new_func_as_AEF"))
167 }
168
169 func TestUpdateValidProviderWithDeletedFunction(t *testing.T) {
170         managerUnderTest, requestHandler := getEcho()
171
172         provider := getProvider()
173         provider.ApiProvDomId = &domainID
174         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
175         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
176         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
177         managerUnderTest.registeredProviders[domainID] = provider
178
179         // Modify the provider
180         updatedProvider := getProvider()
181         updatedProvider.ApiProvDomId = &domainID
182         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
183         (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
184         testFuncs := []provapi.APIProviderFunctionDetails{
185                 (*updatedProvider.ApiProvFuncs)[0],
186                 (*updatedProvider.ApiProvFuncs)[2],
187         }
188         updatedProvider.ApiProvFuncs = &testFuncs
189
190         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
191
192         var resultProvider provapi.APIProviderEnrolmentDetails
193         assert.Equal(t, http.StatusOK, result.Code())
194         err := result.UnmarshalBodyToObject(&resultProvider)
195         assert.NoError(t, err, "error unmarshaling response")
196         assert.Len(t, (*resultProvider.ApiProvFuncs), 2)
197         assert.Empty(t, resultProvider.FailReason)
198         assert.False(t, managerUnderTest.IsFunctionRegistered(funcIdAMF))
199 }
200
201 func TestUpdateMissingFunction(t *testing.T) {
202         managerUnderTest, requestHandler := getEcho()
203
204         provider := getProvider()
205         provider.ApiProvDomId = &domainID
206         otherId := "otherId"
207         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &otherId
208         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
209         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
210         managerUnderTest.registeredProviders[domainID] = provider
211
212         // Modify the provider
213         updatedProvider := getProvider()
214         updatedProvider.ApiProvDomId = &domainID
215         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
216         newFunctionInfo := "New function info"
217         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo
218
219         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
220
221         var errorObj common29122.ProblemDetails
222         assert.Equal(t, http.StatusBadRequest, result.Code())
223         err := result.UnmarshalBodyToObject(&errorObj)
224         assert.NoError(t, err, "error unmarshaling response")
225         assert.Equal(t, http.StatusBadRequest, *errorObj.Status)
226         assert.Contains(t, *errorObj.Cause, funcIdAPF)
227         assert.Contains(t, *errorObj.Cause, "not registered")
228 }
229
230 func TestDeleteProvider(t *testing.T) {
231         managerUnderTest, requestHandler := getEcho()
232
233         provider := getProvider()
234         provider.ApiProvDomId = &domainID
235         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
236         managerUnderTest.registeredProviders[domainID] = provider
237         assert.True(t, managerUnderTest.IsFunctionRegistered(funcIdAPF))
238
239         result := testutil.NewRequest().Delete("/registrations/"+domainID).Go(t, requestHandler)
240
241         assert.Equal(t, http.StatusNoContent, result.Code())
242         assert.False(t, managerUnderTest.IsFunctionRegistered(funcIdAPF))
243 }
244 func TestProviderHandlingValidation(t *testing.T) {
245         _, requestHandler := getEcho()
246
247         newProvider := provapi.APIProviderEnrolmentDetails{}
248
249         // Register an invalid provider
250         result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
251
252         assert.Equal(t, http.StatusBadRequest, result.Code())
253         var problemDetails common29122.ProblemDetails
254         err := result.UnmarshalBodyToObject(&problemDetails)
255         assert.NoError(t, err, "error unmarshaling response")
256         assert.Equal(t, http.StatusBadRequest, *problemDetails.Status)
257         assert.Contains(t, *problemDetails.Cause, "missing")
258         assert.Contains(t, *problemDetails.Cause, "regSec")
259 }
260
261 func TestGetExposedFunctionsForPublishingFunction(t *testing.T) {
262         managerUnderTest := NewProviderManager()
263
264         provider := getProvider()
265         provider.ApiProvDomId = &domainID
266         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
267         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
268         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
269         managerUnderTest.registeredProviders[domainID] = provider
270         managerUnderTest.registeredProviders[otherDomainID] = getOtherProvider()
271
272         exposedFuncs := managerUnderTest.GetAefsForPublisher(funcIdAPF)
273         assert.Equal(t, 1, len(exposedFuncs))
274         assert.Equal(t, funcIdAEF, exposedFuncs[0])
275 }
276
277 func getProvider() provapi.APIProviderEnrolmentDetails {
278         testFuncs := []provapi.APIProviderFunctionDetails{
279                 {
280                         ApiProvFuncInfo: &funcInfoAPF,
281                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
282                         RegInfo: provapi.RegistrationInformation{
283                                 ApiProvPubKey: "key",
284                         },
285                 },
286                 {
287                         ApiProvFuncInfo: &funcInfoAMF,
288                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
289                         RegInfo: provapi.RegistrationInformation{
290                                 ApiProvPubKey: "key",
291                         },
292                 },
293                 {
294                         ApiProvFuncInfo: &funcInfoAEF,
295                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
296                         RegInfo: provapi.RegistrationInformation{
297                                 ApiProvPubKey: "key",
298                         },
299                 },
300         }
301         return provapi.APIProviderEnrolmentDetails{
302                 RegSec:         "sec",
303                 ApiProvDomInfo: &domainInfo,
304                 ApiProvFuncs:   &testFuncs,
305         }
306
307 }
308
309 func getOtherProvider() provapi.APIProviderEnrolmentDetails {
310         otherDomainInfo := "other domain"
311         otherFuncInfoAPF := "other as APF"
312         otherApfId := "APF_id_other_as_APF"
313         otherFuncInfoAMF := "other as AMF"
314         otherAmfId := "AMF_id_other_as_AMF"
315         otherFuncInfoAEF := "other as AEF"
316         otherAefId := "AEF_id_other_as_AEF"
317         testFuncs := []provapi.APIProviderFunctionDetails{
318                 {
319                         ApiProvFuncId:   &otherApfId,
320                         ApiProvFuncInfo: &otherFuncInfoAPF,
321                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
322                 },
323                 {
324                         ApiProvFuncId:   &otherAmfId,
325                         ApiProvFuncInfo: &otherFuncInfoAMF,
326                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
327                 },
328                 {
329                         ApiProvFuncId:   &otherAefId,
330                         ApiProvFuncInfo: &otherFuncInfoAEF,
331                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
332                 },
333         }
334         return provapi.APIProviderEnrolmentDetails{
335                 ApiProvDomId:   &otherDomainID,
336                 ApiProvDomInfo: &otherDomainInfo,
337                 ApiProvFuncs:   &testFuncs,
338         }
339
340 }
341
342 func getEcho() (*ProviderManager, *echo.Echo) {
343         swagger, err := provapi.GetSwagger()
344         if err != nil {
345                 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
346                 os.Exit(1)
347         }
348
349         swagger.Servers = nil
350
351         pm := NewProviderManager()
352
353         e := echo.New()
354         e.Use(echomiddleware.Logger())
355         e.Use(middleware.OapiRequestValidator(swagger))
356
357         provapi.RegisterHandlers(e, pm)
358         return pm, e
359 }