Skip to content

Instantly share code, notes, and snippets.

@cstockton
Created June 18, 2018 20:49
Show Gist options
  • Save cstockton/db3cc222471e4e9858d3b60290e3b7f8 to your computer and use it in GitHub Desktop.
Save cstockton/db3cc222471e4e9858d3b60290e3b7f8 to your computer and use it in GitHub Desktop.
package deletetest
import (
"context"
"encoding/json"
"io"
"testing"
"time"
gobgpapi "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/packet/bgp"
"github.com/osrg/gobgp/table"
// "github.secureserver.net/infosec-network/go-protect/pkg/internal/worker"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
func newPath(length uint8, pfx, nh string) *table.Path {
addr := bgp.NewIPAddrPrefix(length, pfx)
attrs := []bgp.PathAttributeInterface{
bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP),
bgp.NewPathAttributeNextHop(nh),
bgp.NewPathAttributeCommunities([]uint32{105546}),
}
return table.NewPath(nil, addr, false, attrs, time.Now().In(time.UTC), false)
}
func helpClient(ctx context.Context, tb testing.TB) gobgpapi.GobgpApiClient {
conn, err := grpc.DialContext(ctx, "localhost:51053",
grpc.WithInsecure(),
grpc.WithTimeout(time.Second*30),
)
if err != nil {
tb.Fatal(err)
}
return gobgpapi.NewGobgpApiClient(conn)
}
func helpDump(tb testing.TB, label string, v interface{}) {
d, err := json.MarshalIndent(v, "", " ")
if err != nil {
tb.Logf("%v: (err %v):\n%v\n", label, err, d)
return
}
tb.Logf("%v:\n%v\n", label, string(d))
}
// Tested against 1.32
// ================================================
func TestDelete(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
cli := helpClient(ctx, t)
pool := New(4)
worker := pool.Worker(cli)
// go worker.Work(ctx) // for InjectMrt streaming.
go worker(ctx) // for InjectMrt streaming.
get := func(tb testing.TB, pfx string) *table.Path {
stream, err := cli.GetPath(ctx, &gobgpapi.GetPathRequest{
Type: gobgpapi.Resource_GLOBAL,
Family: uint32(bgp.RF_IPv4_UC),
Prefixes: []*gobgpapi.TableLookupPrefix{
{
Prefix: pfx,
LookupOption: gobgpapi.TableLookupOption_LOOKUP_EXACT,
},
},
})
if err != nil {
tb.Fatal(err)
}
defer closeStream(stream)
p, err := stream.Recv()
if err != nil {
if err == io.EOF {
return nil
}
tb.Fatal(err)
}
path, err := p.ToNativePath()
if err != nil {
tb.Fatal(err)
}
return path
}
add := func(tb testing.TB, length uint8, pfx, nh string) *table.Path {
p := newPath(length, pfx, nh)
_, err := cli.AddPath(ctx, &gobgpapi.AddPathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(p, nil),
})
if err != nil {
tb.Fatalf("exp nil err from AddPath; got %v", err)
}
return p
}
addMrt := func(tb testing.TB, length uint8, pfx, nh string) *table.Path {
p := newPath(length, pfx, nh)
if err := pool.Send(ctx, p); err != nil {
tb.Fatalf("exp nil err from AddPath; got %v", err)
}
search := p.GetNlri().String()
for i := 0; i < 20; i++ {
time.Sleep(time.Second / 10)
if get(tb, search) != nil {
return p
}
}
return p
}
t.Run("Length32", func(t *testing.T) {
t.Run("AddPath/Delete/ByGetPath", func(t *testing.T) {
added := add(t, 32, "10.0.0.1", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got, nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByGetPath", func(t *testing.T) {
added := addMrt(t, 32, "10.0.0.2", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got, nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByClonedGetPath", func(t *testing.T) {
added := add(t, 32, "10.0.0.3", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got.Clone(true), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByClonedGetPath", func(t *testing.T) {
added := addMrt(t, 32, "10.0.0.4", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got.Clone(true), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByNewPath", func(t *testing.T) {
added := add(t, 32, "10.0.0.5", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(newPath(32, "10.0.0.5", "192.168.0.1"), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByNewPath", func(t *testing.T) {
added := addMrt(t, 32, "10.0.0.6", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(newPath(32, "10.0.0.6", "192.168.0.1"), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByOfficialClientMethod", func(t *testing.T) {
added := add(t, 32, "10.0.0.7", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
nlri := got.GetNlri()
n, err := nlri.Serialize()
if err != nil {
t.Fatal(err)
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: &gobgpapi.Path{
Nlri: n,
Family: uint32(got.GetRouteFamily()),
Identifier: nlri.PathIdentifier(),
LocalIdentifier: nlri.PathLocalIdentifier(),
},
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByOfficialClientMethod", func(t *testing.T) {
added := addMrt(t, 32, "10.0.0.8", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
nlri := got.GetNlri()
n, err := nlri.Serialize()
if err != nil {
t.Fatal(err)
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: &gobgpapi.Path{
Nlri: n,
Family: uint32(got.GetRouteFamily()),
Identifier: nlri.PathIdentifier(),
LocalIdentifier: nlri.PathLocalIdentifier(),
},
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByGetPathSetWithdraw", func(t *testing.T) {
added := add(t, 32, "10.0.0.9", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got, nil),
}
req.Path.IsWithdraw = true
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByGetPath/ClearNils", func(t *testing.T) {
added := add(t, 32, "10.0.0.10", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got, nil),
}
req.Path.SourceId = ""
req.Path.NeighborIp = ""
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByGetPath/ClearAsn", func(t *testing.T) {
added := add(t, 32, "10.0.0.11", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got, nil),
}
// req.Path.LocalIdentifier = 0
req.Path.SourceAsn = 0
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
})
t.Run("Length24", func(t *testing.T) {
t.Run("AddPath/Delete/ByGetPath", func(t *testing.T) {
added := add(t, 24, "10.0.1.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got, nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByGetPath", func(t *testing.T) {
added := addMrt(t, 24, "10.0.2.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got, nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByClonedGetPath", func(t *testing.T) {
added := add(t, 24, "10.0.3.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got.Clone(true), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByClonedGetPath", func(t *testing.T) {
added := addMrt(t, 24, "10.0.4.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(got.Clone(true), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByNewPath", func(t *testing.T) {
added := add(t, 24, "10.0.5.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(newPath(24, "10.0.5.0", "192.168.0.1"), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByNewPath", func(t *testing.T) {
added := addMrt(t, 24, "10.0.6.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: gobgpapi.ToPathApi(newPath(24, "10.0.6.0", "192.168.0.1"), nil),
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("AddPath/Delete/ByOfficialClientMethod", func(t *testing.T) {
added := add(t, 24, "10.0.7.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
nlri := got.GetNlri()
n, err := nlri.Serialize()
if err != nil {
t.Fatal(err)
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: &gobgpapi.Path{
Nlri: n,
Family: uint32(got.GetRouteFamily()),
Identifier: nlri.PathIdentifier(),
LocalIdentifier: nlri.PathLocalIdentifier(),
},
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
t.Run("InjectMrt/Delete/ByOfficialClientMethod", func(t *testing.T) {
added := addMrt(t, 24, "10.0.8.0", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
nlri := got.GetNlri()
n, err := nlri.Serialize()
if err != nil {
t.Fatal(err)
}
req := gobgpapi.DeletePathRequest{
Resource: gobgpapi.Resource_GLOBAL,
Path: &gobgpapi.Path{
Nlri: n,
Family: uint32(got.GetRouteFamily()),
Identifier: nlri.PathIdentifier(),
LocalIdentifier: nlri.PathLocalIdentifier(),
},
}
helpDump(t, "*api.Path:", req.Path)
if _, err := cli.DeletePath(ctx, &req); err != nil {
t.Fatal(err)
}
verify := get(t, added.GetNlri().String())
if verify != nil {
t.Errorf("verify failed, found path: %v", verify)
}
})
})
t.Run("Compare/ClonedVsNew", func(t *testing.T) {
added := add(t, 32, "10.0.0.9", "192.168.0.1")
got := get(t, added.GetNlri().String())
if got == nil {
t.Fatal("path was not added")
}
helpDump(t, `GetPath`, gobgpapi.ToPathApi(got, nil))
cloned := gobgpapi.ToPathApi(got.Clone(true), nil)
helpDump(t, `GetPath.Clone`, cloned)
create := gobgpapi.ToPathApi(newPath(32, "10.0.0.9", "192.168.0.1"), nil)
helpDump(t, `table.NewPath`, create)
t.Fail()
})
}
// still not even sure if this is how you properly close streams, see:
//
// https://github.com/grpc/grpc-go/issues/2015
//
func closeStream(stream grpc.ClientStream) (err error) {
stream.CloseSend()
switch T := stream.(type) {
case gobgpapi.GobgpApi_GetPathClient:
for err == nil {
_, err = T.Recv()
}
}
return
}
type request struct {
ctx context.Context
req gobgpapi.InjectMrtRequest
errCh chan error
}
func newRequest() *request {
return &request{
req: gobgpapi.InjectMrtRequest{
Resource: gobgpapi.Resource_GLOBAL,
Paths: make([]*gobgpapi.Path, 0, 16),
},
errCh: make(chan error),
}
}
// Pool provides a pool of GoBGP path injectmrt workers.
type Pool struct {
poolCh chan *request
workCh chan *request
}
// New returns a new *Pool of the given size, which represents the number of request
// slots available in the pool.
func New(size int) *Pool {
if size <= 0 {
panic("injectmrt: size must be >= 1")
}
p := &Pool{
workCh: make(chan *request),
poolCh: make(chan *request, size),
}
for i := 0; i < size; i++ {
p.poolCh <- newRequest()
}
return p
}
// acquire attempts to acquire a request from the pool.
func (p *Pool) acquire(ctx context.Context) (*request, error) {
select {
case r := <-p.poolCh:
r.ctx = ctx
r.req.Paths = r.req.Paths[0:0]
return r, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
// release attempts to release the request back to the pool.
func (p *Pool) release(r *request) {
select {
case p.poolCh <- r:
default:
panic("injectmrt: release beyond bounds")
}
}
// Send attempts to send a path via the gobgp inject mrt api.
func (p *Pool) Send(ctx context.Context, ps ...*table.Path) error {
r, err := p.acquire(ctx)
if err != nil {
return err
}
defer p.release(r)
// add paths
for _, p := range ps {
r.req.Paths = append(r.req.Paths, gobgpapi.ToPathApi(p, nil))
}
select {
case p.workCh <- r:
select {
case err := <-r.errCh:
return err
case <-ctx.Done():
return ctx.Err()
}
case <-ctx.Done():
return ctx.Err()
}
}
// Worker returns an implementation of worker.Work that will use the given
// client to process Pool requests.
// func (p *Pool) Worker(cli gobgpapi.GobgpApiClient) worker.Worker {
func (p *Pool) Worker(cli gobgpapi.GobgpApiClient) func(ctx context.Context) error {
return func(ctx context.Context) error {
sr, err := cli.InjectMrt(ctx)
if err != nil {
return err
}
defer func() {
sr.CloseAndRecv()
sr.CloseSend()
}()
for {
select {
case r := <-p.workCh:
err := sr.Send(&r.req)
// Can't select ctx.Done() here, but also don't need to. A recv guarantees
// that r.ctx is done, or a receiver is ready.
select {
case r.errCh <- err:
case <-r.ctx.Done(): // Request ctx is done, will never be received.
}
// Handle potential failure scenarios.
switch {
case err == nil:
continue
case err == io.EOF:
return nil
case grpc.Code(err) == codes.Canceled:
return context.Canceled
default:
return err // Let exponential backoff trigger
}
case <-ctx.Done():
return ctx.Err()
}
}
}
}
=== RUN TestDelete
=== RUN TestDelete/Length32
=== RUN TestDelete/Length32/AddPath/Delete/ByGetPath
=== RUN TestDelete/Length32/InjectMrt/Delete/ByGetPath
=== RUN TestDelete/Length32/AddPath/Delete/ByClonedGetPath
=== RUN TestDelete/Length32/InjectMrt/Delete/ByClonedGetPath
=== RUN TestDelete/Length32/AddPath/Delete/ByNewPath
=== RUN TestDelete/Length32/InjectMrt/Delete/ByNewPath
=== RUN TestDelete/Length32/AddPath/Delete/ByOfficialClientMethod
=== RUN TestDelete/Length32/InjectMrt/Delete/ByOfficialClientMethod
=== RUN TestDelete/Length32/AddPath/Delete/ByGetPathSetWithdraw
=== RUN TestDelete/Length32/AddPath/Delete/ByGetPath/ClearNils
=== RUN TestDelete/Length32/AddPath/Delete/ByGetPath/ClearAsnAndIdent
=== RUN TestDelete/Length24
=== RUN TestDelete/Length24/AddPath/Delete/ByGetPath
=== RUN TestDelete/Length24/InjectMrt/Delete/ByGetPath
=== RUN TestDelete/Length24/AddPath/Delete/ByClonedGetPath
=== RUN TestDelete/Length24/InjectMrt/Delete/ByClonedGetPath
=== RUN TestDelete/Length24/AddPath/Delete/ByNewPath
=== RUN TestDelete/Length24/InjectMrt/Delete/ByNewPath
=== RUN TestDelete/Length24/AddPath/Delete/ByOfficialClientMethod
=== RUN TestDelete/Length24/InjectMrt/Delete/ByOfficialClientMethod
=== RUN TestDelete/Compare/ClonedVsNew
--- FAIL: TestDelete (0.86s)
--- FAIL: TestDelete/Length32 (0.44s)
--- FAIL: TestDelete/Length32/AddPath/Delete/ByGetPath (0.01s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAE=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:139: verify failed, found path: { 10.0.0.1/32 | src: local, nh: 192.168.0.1 }
--- FAIL: TestDelete/Length32/InjectMrt/Delete/ByGetPath (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAI=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:162: verify failed, found path: { 10.0.0.2/32 | src: local, nh: 192.168.0.1 }
--- FAIL: TestDelete/Length32/AddPath/Delete/ByClonedGetPath (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAM=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"is_withdraw": true,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:185: verify failed, found path: { 10.0.0.3/32 | src: local, nh: 192.168.0.1 }
--- FAIL: TestDelete/Length32/InjectMrt/Delete/ByClonedGetPath (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAQ=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"is_withdraw": true,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:208: verify failed, found path: { 10.0.0.4/32 | src: local, nh: 192.168.0.1 }
--- PASS: TestDelete/Length32/AddPath/Delete/ByNewPath (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAU=",
"pattrs": [
"QAEBAA==",
"QAMEwKgAAQ==",
"wAgEAAGcSg=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537
}
--- PASS: TestDelete/Length32/InjectMrt/Delete/ByNewPath (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAY=",
"pattrs": [
"QAEBAA==",
"QAMEwKgAAQ==",
"wAgEAAGcSg=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537
}
--- PASS: TestDelete/Length32/AddPath/Delete/ByOfficialClientMethod (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAc=",
"family": 65537,
"local_identifier": 1
}
--- PASS: TestDelete/Length32/InjectMrt/Delete/ByOfficialClientMethod (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAg=",
"family": 65537,
"local_identifier": 1
}
--- FAIL: TestDelete/Length32/AddPath/Delete/ByGetPathSetWithdraw (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAk=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"is_withdraw": true,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:346: verify failed, found path: { 10.0.0.9/32 | src: local, nh: 192.168.0.1 }
--- FAIL: TestDelete/Length32/AddPath/Delete/ByGetPath/ClearNils (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAo=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"local_identifier": 1
}
deletetest_test.go:371: verify failed, found path: { 10.0.0.10/32 | src: local, nh: 192.168.0.1 }
--- PASS: TestDelete/Length32/AddPath/Delete/ByGetPath/ClearAsnAndIdent (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "IAoAAAs=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
--- FAIL: TestDelete/Length24 (0.42s)
--- FAIL: TestDelete/Length24/AddPath/Delete/ByGetPath (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoAAQ==",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:421: verify failed, found path: { 10.0.1.0/24 | src: local, nh: 192.168.0.1 }
--- FAIL: TestDelete/Length24/InjectMrt/Delete/ByGetPath (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoAAg==",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354908,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:444: verify failed, found path: { 10.0.2.0/24 | src: local, nh: 192.168.0.1 }
--- FAIL: TestDelete/Length24/AddPath/Delete/ByClonedGetPath (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoAAw==",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354909,
"is_withdraw": true,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:467: verify failed, found path: { 10.0.3.0/24 | src: local, nh: 192.168.0.1 }
--- FAIL: TestDelete/Length24/InjectMrt/Delete/ByClonedGetPath (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoABA==",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354909,
"is_withdraw": true,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:490: verify failed, found path: { 10.0.4.0/24 | src: local, nh: 192.168.0.1 }
--- PASS: TestDelete/Length24/AddPath/Delete/ByNewPath (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoABQ==",
"pattrs": [
"QAEBAA==",
"QAMEwKgAAQ==",
"wAgEAAGcSg=="
],
"age": 1529354909,
"validation_detail": {},
"family": 65537
}
--- PASS: TestDelete/Length24/InjectMrt/Delete/ByNewPath (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoABg==",
"pattrs": [
"QAEBAA==",
"QAMEwKgAAQ==",
"wAgEAAGcSg=="
],
"age": 1529354909,
"validation_detail": {},
"family": 65537
}
--- PASS: TestDelete/Length24/AddPath/Delete/ByOfficialClientMethod (0.00s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoABw==",
"family": 65537,
"local_identifier": 1
}
--- PASS: TestDelete/Length24/InjectMrt/Delete/ByOfficialClientMethod (0.10s)
deletetest_test.go:45: *api.Path::
{
"nlri": "GAoACA==",
"family": 65537,
"local_identifier": 1
}
--- FAIL: TestDelete/Compare/ClonedVsNew (0.00s)
deletetest_test.go:45: GetPath:
{
"nlri": "IAoAAAk=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354909,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:45: GetPath.Clone:
{
"nlri": "IAoAAAk=",
"pattrs": [
"QAEBAA==",
"wAgEAAGcSg==",
"QAMEwKgAAQ=="
],
"age": 1529354909,
"is_withdraw": true,
"validation_detail": {},
"family": 65537,
"source_asn": 26496,
"source_id": "\u003cnil\u003e",
"neighbor_ip": "\u003cnil\u003e",
"local_identifier": 1
}
deletetest_test.go:45: table.NewPath:
{
"nlri": "IAoAAAk=",
"pattrs": [
"QAEBAA==",
"QAMEwKgAAQ==",
"wAgEAAGcSg=="
],
"age": 1529354909,
"validation_detail": {},
"family": 65537
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment