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