Updates for G Maintenance release
[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 TestRegisterValidProvider(t *testing.T) {
53         managerUnderTest, requestHandler := getEcho()
54
55         newProvider := getProvider()
56
57         // Register a valid provider
58         result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
59
60         assert.Equal(t, http.StatusCreated, result.Code())
61         var resultProvider provapi.APIProviderEnrolmentDetails
62         err := result.UnmarshalBodyToObject(&resultProvider)
63         assert.NoError(t, err, "error unmarshaling response")
64         assert.Equal(t, *resultProvider.ApiProvDomId, domainID)
65         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncId, funcIdAPF)
66         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[1].ApiProvFuncId, funcIdAMF)
67         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[2].ApiProvFuncId, funcIdAEF)
68         assert.Empty(t, resultProvider.FailReason)
69         assert.Equal(t, "http://example.com/registrations/"+*resultProvider.ApiProvDomId, result.Recorder.Header().Get(echo.HeaderLocation))
70         assert.True(t, managerUnderTest.IsFunctionRegistered("APF_id_rApp_as_APF"))
71
72         // Register same provider again should result in Forbidden
73         result = testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
74         var errorObj common29122.ProblemDetails
75         assert.Equal(t, http.StatusForbidden, result.Code())
76         err = result.UnmarshalBodyToObject(&errorObj)
77         assert.NoError(t, err, "error unmarshaling response")
78         assert.Equal(t, http.StatusForbidden, *errorObj.Status)
79         assert.Contains(t, *errorObj.Cause, "already registered")
80 }
81
82 func TestUpdateValidProviderWithNewFunction(t *testing.T) {
83         managerUnderTest, requestHandler := getEcho()
84
85         provider := getProvider()
86         provider.ApiProvDomId = &domainID
87         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
88         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
89         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
90         managerUnderTest.registeredProviders[domainID] = provider
91
92         // Modify the provider
93         updatedProvider := getProvider()
94         updatedProvider.ApiProvDomId = &domainID
95         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
96         (*updatedProvider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
97         (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
98         newDomainInfo := "New domain info"
99         updatedProvider.ApiProvDomInfo = &newDomainInfo
100         newFunctionInfo := "New function info"
101         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo
102         newFuncInfoAEF := "new func as AEF"
103         testFuncs := *updatedProvider.ApiProvFuncs
104         testFuncs = append(testFuncs, provapi.APIProviderFunctionDetails{
105                 ApiProvFuncInfo: &newFuncInfoAEF,
106                 ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
107                 RegInfo: provapi.RegistrationInformation{
108                         ApiProvPubKey: "key",
109                 },
110         })
111         updatedProvider.ApiProvFuncs = &testFuncs
112
113         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
114
115         var resultProvider provapi.APIProviderEnrolmentDetails
116         assert.Equal(t, http.StatusOK, result.Code())
117         err := result.UnmarshalBodyToObject(&resultProvider)
118         assert.NoError(t, err, "error unmarshaling response")
119         assert.Equal(t, newDomainInfo, *resultProvider.ApiProvDomInfo)
120         assert.Equal(t, newFunctionInfo, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncInfo)
121         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[3].ApiProvFuncId, "AEF_id_new_func_as_AEF")
122         assert.Empty(t, resultProvider.FailReason)
123         assert.True(t, managerUnderTest.IsFunctionRegistered("AEF_id_new_func_as_AEF"))
124 }
125
126 func TestUpdateValidProviderWithDeletedFunction(t *testing.T) {
127         managerUnderTest, requestHandler := getEcho()
128
129         provider := getProvider()
130         provider.ApiProvDomId = &domainID
131         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
132         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
133         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
134         managerUnderTest.registeredProviders[domainID] = provider
135
136         // Modify the provider
137         updatedProvider := getProvider()
138         updatedProvider.ApiProvDomId = &domainID
139         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
140         (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
141         testFuncs := []provapi.APIProviderFunctionDetails{
142                 (*updatedProvider.ApiProvFuncs)[0],
143                 (*updatedProvider.ApiProvFuncs)[2],
144         }
145         updatedProvider.ApiProvFuncs = &testFuncs
146
147         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
148
149         var resultProvider provapi.APIProviderEnrolmentDetails
150         assert.Equal(t, http.StatusOK, result.Code())
151         err := result.UnmarshalBodyToObject(&resultProvider)
152         assert.NoError(t, err, "error unmarshaling response")
153         assert.Len(t, (*resultProvider.ApiProvFuncs), 2)
154         assert.Empty(t, resultProvider.FailReason)
155         assert.False(t, managerUnderTest.IsFunctionRegistered(funcIdAMF))
156 }
157
158 func TestUpdateMissingFunction(t *testing.T) {
159         managerUnderTest, requestHandler := getEcho()
160
161         provider := getProvider()
162         provider.ApiProvDomId = &domainID
163         otherId := "otherId"
164         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &otherId
165         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
166         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
167         managerUnderTest.registeredProviders[domainID] = provider
168
169         // Modify the provider
170         updatedProvider := getProvider()
171         updatedProvider.ApiProvDomId = &domainID
172         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
173         newFunctionInfo := "New function info"
174         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo
175
176         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
177
178         var errorObj common29122.ProblemDetails
179         assert.Equal(t, http.StatusBadRequest, result.Code())
180         err := result.UnmarshalBodyToObject(&errorObj)
181         assert.NoError(t, err, "error unmarshaling response")
182         assert.Equal(t, http.StatusBadRequest, *errorObj.Status)
183         assert.Contains(t, *errorObj.Cause, funcIdAPF)
184         assert.Contains(t, *errorObj.Cause, "not registered")
185 }
186
187 func TestDeleteProvider(t *testing.T) {
188         managerUnderTest, requestHandler := getEcho()
189
190         provider := getProvider()
191         provider.ApiProvDomId = &domainID
192         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
193         managerUnderTest.registeredProviders[domainID] = provider
194         assert.True(t, managerUnderTest.IsFunctionRegistered(funcIdAPF))
195
196         result := testutil.NewRequest().Delete("/registrations/"+domainID).Go(t, requestHandler)
197
198         assert.Equal(t, http.StatusNoContent, result.Code())
199         assert.False(t, managerUnderTest.IsFunctionRegistered(funcIdAPF))
200 }
201 func TestProviderHandlingValidation(t *testing.T) {
202         _, requestHandler := getEcho()
203
204         newProvider := provapi.APIProviderEnrolmentDetails{}
205
206         // Register an invalid provider
207         result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
208
209         assert.Equal(t, http.StatusBadRequest, result.Code())
210         var problemDetails common29122.ProblemDetails
211         err := result.UnmarshalBodyToObject(&problemDetails)
212         assert.NoError(t, err, "error unmarshaling response")
213         assert.Equal(t, http.StatusBadRequest, *problemDetails.Status)
214         assert.Contains(t, *problemDetails.Cause, "missing")
215         assert.Contains(t, *problemDetails.Cause, "regSec")
216 }
217
218 func TestGetExposedFunctionsForPublishingFunction(t *testing.T) {
219         managerUnderTest := NewProviderManager()
220
221         provider := getProvider()
222         provider.ApiProvDomId = &domainID
223         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
224         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
225         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
226         managerUnderTest.registeredProviders[domainID] = provider
227         managerUnderTest.registeredProviders[otherDomainID] = getOtherProvider()
228
229         exposedFuncs := managerUnderTest.GetAefsForPublisher(funcIdAPF)
230         assert.Equal(t, 1, len(exposedFuncs))
231         assert.Equal(t, funcIdAEF, exposedFuncs[0])
232 }
233
234 func getProvider() provapi.APIProviderEnrolmentDetails {
235         testFuncs := []provapi.APIProviderFunctionDetails{
236                 {
237                         ApiProvFuncInfo: &funcInfoAPF,
238                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
239                         RegInfo: provapi.RegistrationInformation{
240                                 ApiProvPubKey: "key",
241                         },
242                 },
243                 {
244                         ApiProvFuncInfo: &funcInfoAMF,
245                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
246                         RegInfo: provapi.RegistrationInformation{
247                                 ApiProvPubKey: "key",
248                         },
249                 },
250                 {
251                         ApiProvFuncInfo: &funcInfoAEF,
252                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
253                         RegInfo: provapi.RegistrationInformation{
254                                 ApiProvPubKey: "key",
255                         },
256                 },
257         }
258         return provapi.APIProviderEnrolmentDetails{
259                 RegSec:         "sec",
260                 ApiProvDomInfo: &domainInfo,
261                 ApiProvFuncs:   &testFuncs,
262         }
263
264 }
265
266 func getOtherProvider() provapi.APIProviderEnrolmentDetails {
267         otherDomainInfo := "other domain"
268         otherFuncInfoAPF := "other as APF"
269         otherApfId := "APF_id_other_as_APF"
270         otherFuncInfoAMF := "other as AMF"
271         otherAmfId := "AMF_id_other_as_AMF"
272         otherFuncInfoAEF := "other as AEF"
273         otherAefId := "AEF_id_other_as_AEF"
274         testFuncs := []provapi.APIProviderFunctionDetails{
275                 {
276                         ApiProvFuncId:   &otherApfId,
277                         ApiProvFuncInfo: &otherFuncInfoAPF,
278                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
279                 },
280                 {
281                         ApiProvFuncId:   &otherAmfId,
282                         ApiProvFuncInfo: &otherFuncInfoAMF,
283                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
284                 },
285                 {
286                         ApiProvFuncId:   &otherAefId,
287                         ApiProvFuncInfo: &otherFuncInfoAEF,
288                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
289                 },
290         }
291         return provapi.APIProviderEnrolmentDetails{
292                 ApiProvDomId:   &otherDomainID,
293                 ApiProvDomInfo: &otherDomainInfo,
294                 ApiProvFuncs:   &testFuncs,
295         }
296
297 }
298
299 func getEcho() (*ProviderManager, *echo.Echo) {
300         swagger, err := provapi.GetSwagger()
301         if err != nil {
302                 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
303                 os.Exit(1)
304         }
305
306         swagger.Servers = nil
307
308         pm := NewProviderManager()
309
310         e := echo.New()
311         e.Use(echomiddleware.Logger())
312         e.Use(middleware.OapiRequestValidator(swagger))
313
314         provapi.RegisterHandlers(e, pm)
315         return pm, e
316 }