@@ -7,8 +7,12 @@ import (
77 "log/slog"
88 "net/http"
99 "net/http/httptest"
10+ "net/netip"
1011 "testing"
1112
13+ mdmv1 "github.com/metal-stack/masterdata-api/api/v1"
14+ mdmv1mock "github.com/metal-stack/masterdata-api/api/v1/mocks"
15+ mdm "github.com/metal-stack/masterdata-api/pkg/client"
1216 "github.com/metal-stack/metal-lib/httperrors"
1317 "github.com/metal-stack/metal-lib/pkg/pointer"
1418 r "gopkg.in/rethinkdb/rethinkdb-go.v6"
@@ -21,6 +25,7 @@ import (
2125
2226 restful "github.com/emicklei/go-restful/v3"
2327 "github.com/metal-stack/metal-api/cmd/metal-api/internal/testdata"
28+ testifymock "github.com/stretchr/testify/mock"
2429 "github.com/stretchr/testify/require"
2530)
2631
@@ -420,99 +425,128 @@ func Test_networkResource_createNetwork(t *testing.T) {
420425 }
421426}
422427
423- // func Test_networkResource_allocateNetwork(t *testing.T) {
424- // log := slog.Default()
425- // tests := []struct {
426- // name string
427- // networkName string
428- // partitionID string
429- // projectID string
430- // childprefixlength *uint8
431- // addressFamily *string
432- // shared bool
433- // expectedStatus int
434- // expectedErrorMessage string
435- // }{
436- // {
437- // name: "simple ipv4",
438- // networkName: "tenantv4",
439- // partitionID: "1",
440- // projectID: "project-1",
441- // expectedStatus: http.StatusCreated,
442- // },
443- // {
444- // name: "ipv6 without ipv6 super",
445- // networkName: "tenantv6",
446- // partitionID: "1",
447- // projectID: "project-1",
448- // addressFamily: pointer.Pointer("ipv6"),
449- // expectedStatus: http.StatusUnprocessableEntity,
450- // expectedErrorMessage: "no supernetwork for addressfamily:IPv6 found",
451- // },
452- // }
453- // for _, tt := range tests {
454- // ds, mock := datastore.InitMockDB(t)
455-
456- // ipamer, err := testdata.InitMockIpamData(mock, false)
457- // require.Nil(t, err)
458- // mock.On(r.DB("mockdb").Table("network").Filter(r.MockAnything()).Filter(r.MockAnything())).Return(metal.Networks{testdata.Nw1, testdata.Nw2}, nil)
459- // changes := []r.ChangeResponse{{OldValue: map[string]interface{}{"id": float64(42)}}}
460- // mock.On(r.DB("mockdb").Table("integerpool").Limit(1).Delete(r.
461- // DeleteOpts{ReturnChanges: true})).Return(r.WriteResponse{Changes: changes}, nil)
462-
463- // mock.On(r.DB("mockdb").Table("partition").Get(r.MockAnything())).Return(
464- // metal.Partition{
465- // Base: metal.Base{ID: tt.partitionID},
466- // },
467- // nil,
468- // )
469- // testdata.InitMockDBData(mock)
470-
471- // psc := mdmock.ProjectServiceClient{}
472- // psc.On("Get", context.Background(), &mdmv1.ProjectGetRequest{Id: "project-1"}).Return(&mdmv1.ProjectResponse{
473- // Project: &mdmv1.Project{
474- // Meta: &mdmv1.Meta{Id: tt.projectID},
475- // },
476- // }, nil,
477- // )
478- // tsc := mdmock.TenantServiceClient{}
479-
480- // mdc := mdm.NewMock(&psc, &tsc)
481-
482- // networkservice := NewNetwork(log, ds, ipamer, mdc)
483- // container := restful.NewContainer().Add(networkservice)
484-
485- // allocateRequest := &v1.NetworkAllocateRequest{
486- // Describable: v1.Describable{Name: &tt.networkName},
487- // NetworkBase: v1.NetworkBase{PartitionID: &tt.partitionID, ProjectID: &tt.projectID},
488- // AddressFamily: tt.addressFamily,
489- // Length: tt.childprefixlength,
490- // }
491-
492- // js, _ := json.Marshal(allocateRequest)
493- // body := bytes.NewBuffer(js)
494- // req := httptest.NewRequest("POST", "/v1/network/allocate", body)
495- // req.Header.Add("Content-Type", "application/json")
496- // container = injectAdmin(log, container, req)
497- // w := httptest.NewRecorder()
498- // container.ServeHTTP(w, req)
499-
500- // resp := w.Result()
501- // require.Equal(t, tt.expectedStatus, resp.StatusCode, w.Body.String())
502- // if tt.expectedStatus > 300 {
503- // var result httperrors.HTTPErrorResponse
504- // err := json.NewDecoder(resp.Body).Decode(&result)
505-
506- // require.Nil(t, err)
507- // require.Equal(t, tt.expectedErrorMessage, result.Message)
508- // } else {
509- // var result v1.NetworkResponse
510- // err = json.NewDecoder(resp.Body).Decode(&result)
511- // require.Nil(t, err)
512- // require.Equal(t, tt.networkName, *result.Name)
513- // require.Equal(t, tt.partitionID, *result.PartitionID)
514- // require.Equal(t, tt.projectID, *result.ProjectID)
515- // // TODO check af and length
516- // }
517- // }
518- // }
428+ func Test_networkResource_allocateNetwork (t * testing.T ) {
429+ log := slog .Default ()
430+ tests := []struct {
431+ name string
432+ networkName string
433+ partitionID string
434+ projectID string
435+ childprefixlength * uint8
436+ addressFamily * string
437+ shared bool
438+ expectedStatus int
439+ expectedErrorMessage string
440+ }{
441+ {
442+ name : "simple ipv4, default childprefixlength" ,
443+ networkName : "tenantv4" ,
444+ partitionID : testdata .Partition1 .ID ,
445+ projectID : "project-1" ,
446+ expectedStatus : http .StatusCreated ,
447+ },
448+ {
449+ name : "simple ipv4, specific childprefixlength" ,
450+ networkName : "tenantv4.2" ,
451+ partitionID : testdata .Partition1 .ID ,
452+ projectID : "project-1" ,
453+ childprefixlength : pointer .Pointer (uint8 (29 )),
454+ expectedStatus : http .StatusCreated ,
455+ },
456+ {
457+ name : "ipv6 without ipv6 super" ,
458+ networkName : "tenantv6" ,
459+ partitionID : testdata .Partition1 .ID ,
460+ projectID : "project-1" ,
461+ addressFamily : pointer .Pointer ("ipv6" ),
462+ expectedStatus : http .StatusBadRequest ,
463+ expectedErrorMessage : "no supernetwork for addressfamily:IPv6 found" ,
464+ },
465+ }
466+ for _ , tt := range tests {
467+ ds , mock := datastore .InitMockDB (t )
468+
469+ supernetwork := testdata .Nw1
470+ ipamer , err := testdata .InitMockIpamData (mock , false )
471+ require .NoError (t , err )
472+ mock .On (r .DB ("mockdb" ).Table ("network" ).Filter (r .MockAnything ()).Filter (r .MockAnything ())).Return (metal.Networks {supernetwork }, nil )
473+ changes := []r.ChangeResponse {{OldValue : map [string ]interface {}{"id" : float64 (42 )}}}
474+ mock .On (r .DB ("mockdb" ).Table ("integerpool" ).Limit (1 ).Delete (r.
475+ DeleteOpts {ReturnChanges : true })).Return (r.WriteResponse {Changes : changes }, nil )
476+
477+ mock .On (r .DB ("mockdb" ).Table ("partition" ).Get (r .MockAnything ())).Return (
478+ metal.Partition {
479+ Base : metal.Base {ID : tt .partitionID },
480+ },
481+ nil ,
482+ )
483+ testdata .InitMockDBData (mock )
484+
485+ psc := mdmv1mock.ProjectServiceClient {}
486+ psc .On ("Get" , testifymock .Anything , & mdmv1.ProjectGetRequest {Id : "project-1" }).Return (& mdmv1.ProjectResponse {
487+ Project : & mdmv1.Project {
488+ Meta : & mdmv1.Meta {Id : tt .projectID },
489+ },
490+ }, nil ,
491+ )
492+ tsc := mdmv1mock.TenantServiceClient {}
493+
494+ mdc := mdm .NewMock (& psc , & tsc , nil , nil )
495+
496+ networkservice := NewNetwork (log , ds , ipamer , mdc )
497+ container := restful .NewContainer ().Add (networkservice )
498+
499+ allocateRequest := & v1.NetworkAllocateRequest {
500+ Describable : v1.Describable {Name : & tt .networkName },
501+ NetworkBase : v1.NetworkBase {PartitionID : & tt .partitionID , ProjectID : & tt .projectID },
502+ AddressFamily : tt .addressFamily ,
503+ Length : tt .childprefixlength ,
504+ }
505+
506+ js , err := json .Marshal (allocateRequest )
507+ require .NoError (t , err )
508+
509+ body := bytes .NewBuffer (js )
510+ req := httptest .NewRequest ("POST" , "/v1/network/allocate" , body )
511+ req .Header .Add ("Content-Type" , "application/json" )
512+ container = injectAdmin (log , container , req )
513+ w := httptest .NewRecorder ()
514+ container .ServeHTTP (w , req )
515+
516+ resp := w .Result ()
517+ defer resp .Body .Close ()
518+ require .Equal (t , tt .expectedStatus , resp .StatusCode , w .Body .String ())
519+ if tt .expectedStatus > 300 {
520+ var result httperrors.HTTPErrorResponse
521+ err := json .NewDecoder (resp .Body ).Decode (& result )
522+
523+ require .NoError (t , err )
524+ require .Equal (t , tt .expectedErrorMessage , result .Message )
525+ } else {
526+ var result v1.NetworkResponse
527+ err = json .NewDecoder (resp .Body ).Decode (& result )
528+
529+ requestAF := "ipv4"
530+ if tt .addressFamily != nil {
531+ requestAF = "ipv6"
532+ }
533+
534+ require .GreaterOrEqual (t , len (result .Prefixes ), 1 )
535+ resultFirstPrefix := netip .MustParsePrefix (result .Prefixes [0 ])
536+ af := "ipv4"
537+ if resultFirstPrefix .Addr ().Is6 () {
538+ af = "ipv6"
539+ }
540+ expectedLength := * supernetwork .ChildPrefixLength
541+ if tt .childprefixlength != nil {
542+ expectedLength = * tt .childprefixlength
543+ }
544+ require .NoError (t , err )
545+ require .Equal (t , tt .networkName , * result .Name )
546+ require .Equal (t , tt .partitionID , * result .PartitionID )
547+ require .Equal (t , tt .projectID , * result .ProjectID )
548+ require .Equal (t , requestAF , af )
549+ require .Equal (t , int (expectedLength ), resultFirstPrefix .Bits ())
550+ }
551+ }
552+ }
0 commit comments