Skip to content

Commit

Permalink
Fixed transport.Entry and various tests.
Browse files Browse the repository at this point in the history
* transport.Entry should contain an Edges field with a deterministic order of keys.

* Various tests have been fixed.

* Various examples are converted to tests.
  • Loading branch information
Evan Lin committed Aug 6, 2019
1 parent 705f367 commit ede62ed
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 220 deletions.
4 changes: 2 additions & 2 deletions cmd/skywire-cli/commands/tpdisc/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ var RootCmd = &cobra.Command{

func printTransportEntries(entries ...*transport.EntryWithStatus) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 5, ' ', tabwriter.TabIndent)
_, err := fmt.Fprintln(w, "id\ttype\tpublic\tregistered\tup\tlocal PK\tremote PK\topinion1\topinion2")
_, err := fmt.Fprintln(w, "id\ttype\tpublic\tregistered\tup\tedge1\tedge2\topinion1\topinion2")
internal.Catch(err)
for _, e := range entries {
_, err := fmt.Fprintf(w, "%s\t%s\t%t\t%d\t%t\t%s\t%s\t%t\t%t\n",
e.Entry.ID, e.Entry.Type, e.Entry.Public, e.Registered, e.IsUp, e.Entry.LocalPK(), e.Entry.RemotePK(), e.Statuses[0], e.Statuses[1])
e.Entry.ID, e.Entry.Type, e.Entry.Public, e.Registered, e.IsUp, e.Entry.Edges[0], e.Entry.Edges[1], e.Statuses[0], e.Statuses[1])
internal.Catch(err)
}
internal.Catch(w.Flush())
Expand Down
4 changes: 2 additions & 2 deletions pkg/transport-discovery/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,14 @@ func TestGetTransportByID(t *testing.T) {
func TestGetTransportsByEdge(t *testing.T) {
entry := &transport.EntryWithStatus{Entry: newTestEntry(), IsUp: true}
srv := httptest.NewServer(authHandler(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, fmt.Sprintf("/transports/edge:%s", entry.Entry.LocalPK()), r.URL.String())
assert.Equal(t, fmt.Sprintf("/transports/edge:%s", entry.Entry.Edges[0]), r.URL.String())
require.NoError(t, json.NewEncoder(w).Encode([]*transport.EntryWithStatus{entry}))
})))
defer srv.Close()

c, err := NewHTTP(srv.URL, testPubKey, testSecKey)
require.NoError(t, err)
entries, err := c.GetTransportsByEdge(context.Background(), entry.Entry.LocalPK())
entries, err := c.GetTransportsByEdge(context.Background(), entry.Entry.Edges[0])
require.NoError(t, err)

require.Len(t, entries, 1)
Expand Down
2 changes: 1 addition & 1 deletion pkg/transport/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (td *mockDiscoveryClient) GetTransportsByEdge(ctx context.Context, pk ciphe
td.Lock()
res := make([]*EntryWithStatus, 0)
for _, entry := range td.entries {
if entry.Entry.LocalPK() == pk || entry.Entry.RemotePK() == pk {
if entry.Entry.HasEdge(pk) {
e := &EntryWithStatus{}
*e = entry
res = append(res, e)
Expand Down
52 changes: 18 additions & 34 deletions pkg/transport/discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,33 @@ package transport_test

import (
"context"
"fmt"
"testing"

"github.com/stretchr/testify/require"

"github.com/skycoin/dmsg/cipher"

"github.com/skycoin/skywire/pkg/transport"
)

func ExampleNewDiscoveryMock() {
func TestNewDiscoveryMock(t *testing.T) {
dc := transport.NewDiscoveryMock()
pk1, _ := cipher.GenerateKeyPair()
pk1, _ := cipher.GenerateKeyPair() // local
pk2, _ := cipher.GenerateKeyPair()
entry := &transport.Entry{Type: "mock", LocalKey: pk1, RemoteKey: pk2}
entry := &transport.Entry{Type: "mock", Edges: transport.SortEdges(pk1, pk2)}

sEntry := &transport.SignedEntry{Entry: entry}

if err := dc.RegisterTransports(context.TODO(), sEntry); err == nil {
fmt.Println("RegisterTransport success")
} else {
fmt.Println(err.Error())
}

if entryWS, err := dc.GetTransportByID(context.TODO(), sEntry.Entry.ID); err == nil {
fmt.Println("GetTransportByID success")
fmt.Printf("entryWS.Entry.ID == sEntry.Entry.ID is %v\n", entryWS.Entry.ID == sEntry.Entry.ID)
} else {
fmt.Printf("%v", entryWS)
}

if entriesWS, err := dc.GetTransportsByEdge(context.TODO(), entry.LocalPK()); err == nil {
fmt.Println("GetTransportsByEdge success")
fmt.Printf("entriesWS[0].Entry.LocalPK() == entry.LocalPK() is %v\n", entriesWS[0].Entry.LocalPK() == entry.LocalPK())
}

if _, err := dc.UpdateStatuses(context.TODO(), &transport.Status{}); err == nil {
fmt.Println("UpdateStatuses success")
} else {
fmt.Println(err.Error())
}

// Output: RegisterTransport success
// GetTransportByID success
// entryWS.Entry.ID == sEntry.Entry.ID is true
// GetTransportsByEdge success
// entriesWS[0].Entry.LocalPK() == entry.LocalPK() is true
// UpdateStatuses success
require.NoError(t, dc.RegisterTransports(context.TODO(), sEntry))

entryWS, err := dc.GetTransportByID(context.TODO(), sEntry.Entry.ID)
require.NoError(t, err)
require.True(t, entryWS.Entry.ID == sEntry.Entry.ID)

entriesWS, err := dc.GetTransportsByEdge(context.TODO(), pk1)
require.NoError(t, err)
require.Equal(t, entry.Edges, entriesWS[0].Entry.Edges)

_, err = dc.UpdateStatuses(context.TODO(), &transport.Status{})
require.NoError(t, err)
}
80 changes: 40 additions & 40 deletions pkg/transport/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ type Entry struct {
// ID is the Transport ID that uniquely identifies the Transport.
ID uuid.UUID `json:"t_id"`

// LocalPK contains the local public key of the Transport's nodes
LocalKey cipher.PubKey `json:"local_pk"`

// Remote contains the local public key of the Transport's nodes
RemoteKey cipher.PubKey `json:"remote_pk"`
// Edges contains the public keys of the Transport's edge nodes (should only have 2 edges and the least-significant edge should come first).
Edges [2]cipher.PubKey `json:"edges"`

// Type represents the transport type.
Type string `json:"type"`
Expand All @@ -31,29 +28,37 @@ type Entry struct {
// NewEntry constructs *Entry
func NewEntry(localPK, remotePK cipher.PubKey, tpType string, public bool) *Entry {
return &Entry{
ID: MakeTransportID(localPK, remotePK, tpType, public),
LocalKey: localPK,
RemoteKey: remotePK,
Type: tpType,
Public: public,
ID: MakeTransportID(localPK, remotePK, tpType, public),
Edges: SortEdges(localPK, remotePK),
Type: tpType,
Public: public,
}
}

// LocalPK returns the local public key of the Transport's nodes.
func (e *Entry) LocalPK() cipher.PubKey {
return e.LocalKey
// SetEdges sets edges of Entry
func (e *Entry) SetEdges(localPK, remotePK cipher.PubKey) {
e.ID = MakeTransportID(localPK, remotePK, e.Type, e.Public)
e.Edges = SortEdges(localPK, remotePK)
}

// RemotePK returns the remote public key of the Transport's nodes.
func (e *Entry) RemotePK() cipher.PubKey {
return e.RemoteKey
// RemoteEdge returns the remote edge's public key.
func (e *Entry) RemoteEdge(local cipher.PubKey) cipher.PubKey {
for _, pk := range e.Edges {
if pk != local {
return pk
}
}
return local
}

// SetEdges sets edges of Entry
func (e *Entry) SetEdges(localPK, remotePK cipher.PubKey) {
e.ID = MakeTransportID(localPK, remotePK, e.Type, e.Public)
e.LocalKey = localPK
e.RemoteKey = remotePK
// HasEdge returns true if the provided edge is present in 'e.Edges' field.
func (e *Entry) HasEdge(edge cipher.PubKey) bool {
for _, pk := range e.Edges {
if pk == edge {
return true
}
}
return false
}

// String implements stringer
Expand All @@ -67,21 +72,18 @@ func (e *Entry) String() string {
res += fmt.Sprintf("\ttype: %s\n", e.Type)
res += fmt.Sprintf("\tid: %s\n", e.ID)
res += fmt.Sprintf("\tedges:\n")
res += fmt.Sprintf("\t\tlocal_pk 1: %s\n", e.LocalPK())
res += fmt.Sprintf("\t\tlocal_pk 2: %s\n", e.RemotePK())

res += fmt.Sprintf("\t\tedge 1: %s\n", e.Edges[0])
res += fmt.Sprintf("\t\tedge 2: %s\n", e.Edges[1])
return res
}

// ToBinary returns binary representation of an Entry
func (e *Entry) ToBinary() []byte {
localPK := e.LocalPK()
remotePK := e.RemotePK()
return append(
append(
append(e.ID[:], localPK[:]...),
remotePK[:]...),
[]byte(e.Type)...)
bEntry := e.ID[:]
for _, edge := range e.Edges {
bEntry = append(bEntry, edge[:]...)
}
return append(bEntry, []byte(e.Type)...)
}

// Signature returns signature for Entry calculated from binary
Expand All @@ -103,12 +105,11 @@ type SignedEntry struct {
}

// Index returns position of a given pk in edges
func (se *SignedEntry) Index(pk cipher.PubKey) int8 {
if pk == se.Entry.RemotePK() {
return 1
}
if pk == se.Entry.LocalPK() {
return 0
func (se *SignedEntry) Index(pk cipher.PubKey) int {
for i, edgePK := range se.Entry.Edges {
if pk == edgePK {
return i
}
}
return -1
}
Expand Down Expand Up @@ -140,9 +141,8 @@ func NewSignedEntry(entry *Entry, pk cipher.PubKey, secKey cipher.SecKey) (*Sign

}

// Status represents the current state of a Transport from the perspective
// from a Transport's single edge. Each Transport will have two perspectives;
// one from each of it's edges.
// Status represents the current state of a Transport from a Transport's single edge.
// Each Transport will have two perspectives; one from each of it's edges.
type Status struct {

// ID is the Transport ID that identifies the Transport that this status is regarding.
Expand Down
117 changes: 13 additions & 104 deletions pkg/transport/entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,102 +2,29 @@ package transport_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"

"github.com/google/uuid"
"github.com/skycoin/dmsg/cipher"

"github.com/skycoin/skywire/pkg/transport"
)

// ExampleNewEntry shows that with different order of edges:
// - Entry.ID is the same
// - Edges() call is the same
func ExampleNewEntry() {
func TestNewEntry(t *testing.T) {
pkA, _ := cipher.GenerateKeyPair()
pkB, _ := cipher.GenerateKeyPair()

entryAB := transport.NewEntry(pkA, pkB, "", true)
entryBA := transport.NewEntry(pkA, pkB, "", true)

if entryAB.ID == entryBA.ID {
fmt.Println("entryAB.ID == entryBA.ID")
}
if entryAB.LocalPK() == entryBA.LocalPK() {
fmt.Println("entryAB.LocalPK() == entryBA.LocalPK()")
}
if entryAB.RemotePK() == entryBA.RemotePK() {
fmt.Println("entryAB.RemotePK() == entryBA.RemotePK()")
}
// Output: entryAB.ID == entryBA.ID
// entryAB.LocalPK() == entryBA.LocalPK()
// entryAB.RemotePK() == entryBA.RemotePK()
}

func ExampleEntry_LocalPK() {
pkA, _ := cipher.GenerateKeyPair()
pkB, _ := cipher.GenerateKeyPair()

entryAB := transport.Entry{
ID: uuid.UUID{},
LocalKey: pkA,
RemoteKey: pkB,
Type: "",
Public: true,
}

entryBA := transport.Entry{
ID: uuid.UUID{},
LocalKey: pkB,
RemoteKey: pkA,
Type: "",
Public: true,
}

if entryAB.LocalKey != entryBA.LocalKey {
fmt.Println("entryAB.LocalKey != entryBA.LocalKey")
}

if entryAB.LocalPK() == entryBA.RemotePK() {
fmt.Println("entryAB.LocalPK() == entryBA.RemotePK()")
}

// Output: entryAB.LocalKey != entryBA.LocalKey
// entryAB.LocalPK() == entryBA.RemotePK()
}

func ExampleEntry_RemotePK() {
pkA, _ := cipher.GenerateKeyPair()
pkB, _ := cipher.GenerateKeyPair()

entryAB := transport.Entry{
ID: uuid.UUID{},
LocalKey: pkA,
RemoteKey: pkB,
Type: "",
Public: true,
}

entryBA := transport.Entry{
ID: uuid.UUID{},
LocalKey: pkB,
RemoteKey: pkA,
Type: "",
Public: true,
}

if entryAB.RemoteKey != entryBA.RemoteKey {
fmt.Println("entryAB.RemoteKey != entryBA.RemoteKey")
}

if entryAB.RemotePK() == entryBA.LocalPK() {
fmt.Println("entryAB.RemotePK() == entryBA.LocalPK()")
}

// Output: entryAB.RemoteKey != entryBA.RemoteKey
// entryAB.RemotePK() == entryBA.LocalPK()
assert.True(t, entryAB.Edges == entryBA.Edges)
assert.True(t, entryAB.ID == entryBA.ID)
assert.NotNil(t, entryAB.ID)
assert.NotNil(t, entryBA.ID)
}

func ExampleEntry_SetEdges() {
func TestEntry_SetEdges(t *testing.T) {
pkA, _ := cipher.GenerateKeyPair()
pkB, _ := cipher.GenerateKeyPair()

Expand All @@ -106,28 +33,10 @@ func ExampleEntry_SetEdges() {
entryAB.SetEdges(pkA, pkB)
entryBA.SetEdges(pkA, pkB)

if entryAB.LocalKey != entryBA.LocalKey {
fmt.Println("entryAB.LocalKey != entryBA.LocalKey")
} else {
fmt.Println("entryAB.LocalKey == entryBA.LocalKey")
}

if entryAB.RemoteKey != entryBA.RemoteKey {
fmt.Println("entryAB.RemoteKey != entryBA.RemoteKey")
} else {
fmt.Println("entryAB.RemoteKey != entryBA.RemoteKey")
}

if (entryAB.ID == entryBA.ID) && (entryAB.ID != uuid.UUID{}) {
fmt.Println("entryAB.ID != uuid.UUID{}")
fmt.Println("entryAB.ID == entryBA.ID")
}

// Output:
// entryAB.LocalKey == entryBA.LocalKey
// entryAB.RemoteKey != entryBA.RemoteKey
// entryAB.ID != uuid.UUID{}
// entryAB.ID == entryBA.ID
assert.True(t, entryAB.Edges == entryBA.Edges)
assert.True(t, entryAB.ID == entryBA.ID)
assert.NotNil(t, entryAB.ID)
assert.NotNil(t, entryBA.ID)
}

func ExampleSignedEntry_Sign() {
Expand Down
Loading

0 comments on commit ede62ed

Please sign in to comment.