Browse Source

:gear: Minor enhancements

Unexpose several public methods from Node, and add a simple test for
services/files
Ettore Di Giacinto 3 years ago
parent
commit
aafbd86580

+ 2 - 2
cmd/api.go

@@ -39,10 +39,10 @@ A simple UI interface is available to display network data.`,
 			},
 			},
 		),
 		),
 		Action: func(c *cli.Context) error {
 		Action: func(c *cli.Context) error {
-			o, _ := cliToOpts(c)
+			o, _, ll := cliToOpts(c)
 			e := node.New(o...)
 			e := node.New(o...)
 
 
-			displayStart(e)
+			displayStart(ll)
 
 
 			// Start the node to the network, using our ledger
 			// Start the node to the network, using our ledger
 			if err := e.Start(context.Background()); err != nil {
 			if err := e.Start(context.Background()); err != nil {

+ 6 - 6
cmd/file.go

@@ -70,17 +70,17 @@ This is also the ID used to refer when receiving it.`,
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
-			o, _ := cliToOpts(c)
+			o, _, ll := cliToOpts(c)
 			e := node.New(o...)
 			e := node.New(o...)
 
 
-			displayStart(e)
+			displayStart(ll)
 
 
 			ledger, err := e.Ledger()
 			ledger, err := e.Ledger()
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
 
 
-			services.SendFile(context.Background(), ledger, e, e.Logger(), time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, path)
+			services.ShareFile(context.Background(), ledger, e, ll, time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, path)
 
 
 			// Start the node to the network, using our ledger
 			// Start the node to the network, using our ledger
 			if err := e.Start(context.Background()); err != nil {
 			if err := e.Start(context.Background()); err != nil {
@@ -115,10 +115,10 @@ func FileReceive() cli.Command {
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
-			o, _ := cliToOpts(c)
+			o, _, ll := cliToOpts(c)
 			e := node.New(o...)
 			e := node.New(o...)
 
 
-			displayStart(e)
+			displayStart(ll)
 
 
 			// Start the node to the network, using our ledger
 			// Start the node to the network, using our ledger
 			if err := e.Start(context.Background()); err != nil {
 			if err := e.Start(context.Background()); err != nil {
@@ -127,7 +127,7 @@ func FileReceive() cli.Command {
 
 
 			ledger, _ := e.Ledger()
 			ledger, _ := e.Ledger()
 
 
-			return services.ReceiveFile(context.Background(), ledger, e, e.Logger(), time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, path)
+			return services.ReceiveFile(context.Background(), ledger, e, ll, time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, path)
 		},
 		},
 	}
 	}
 }
 }

+ 4 - 2
cmd/join.go

@@ -31,16 +31,18 @@ Useful for setting up relays or hop nodes to improve the network connectivity.`,
 		UsageText: "edgevpn Start",
 		UsageText: "edgevpn Start",
 		Flags:     CommonFlags,
 		Flags:     CommonFlags,
 		Action: func(c *cli.Context) error {
 		Action: func(c *cli.Context) error {
-			o, _ := cliToOpts(c)
+			o, _, ll := cliToOpts(c)
 			e := node.New(o...)
 			e := node.New(o...)
 
 
-			displayStart(e)
+			displayStart(ll)
 
 
 			// Start the node to the network, using our ledger
 			// Start the node to the network, using our ledger
 			if err := e.Start(context.Background()); err != nil {
 			if err := e.Start(context.Background()); err != nil {
 				return err
 				return err
 			}
 			}
 
 
+			ll.Info("Joining p2p network")
+
 			for {
 			for {
 			}
 			}
 		},
 		},

+ 3 - 3
cmd/main.go

@@ -84,11 +84,11 @@ func Main() func(c *cli.Context) error {
 
 
 			os.Exit(0)
 			os.Exit(0)
 		}
 		}
-		o, vpnOpts := cliToOpts(c)
+		o, vpnOpts, ll := cliToOpts(c)
 
 
 		e := edgevpn.New(o...)
 		e := edgevpn.New(o...)
 
 
-		displayStart(e)
+		displayStart(ll)
 
 
 		ledger, err := e.Ledger()
 		ledger, err := e.Ledger()
 		if err != nil {
 		if err != nil {
@@ -100,7 +100,7 @@ func Main() func(c *cli.Context) error {
 		}
 		}
 
 
 		if err := vpn.Start(context.Background(), ledger, e, vpnOpts...); err != nil {
 		if err := vpn.Start(context.Background(), ledger, e, vpnOpts...); err != nil {
-			e.Logger().Fatal(err.Error())
+			ll.Fatal(err.Error())
 		}
 		}
 
 
 		return nil
 		return nil

+ 6 - 6
cmd/service.go

@@ -69,17 +69,17 @@ For example, '192.168.1.1:80', or '127.0.0.1:22'.`,
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
-			o, _ := cliToOpts(c)
+			o, _, ll := cliToOpts(c)
 			e := node.New(o...)
 			e := node.New(o...)
 
 
-			displayStart(e)
+			displayStart(ll)
 
 
 			ledger, err := e.Ledger()
 			ledger, err := e.Ledger()
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
 
 
-			services.ExposeService(context.Background(), ledger, e, e.Logger(), time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, address)
+			services.ExposeService(context.Background(), ledger, e, ll, time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, address)
 
 
 			// Join the node to the network, using our ledger
 			// Join the node to the network, using our ledger
 			if err := e.Start(context.Background()); err != nil {
 			if err := e.Start(context.Background()); err != nil {
@@ -117,10 +117,10 @@ to the service over the network`,
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
-			o, _ := cliToOpts(c)
+			o, _, ll := cliToOpts(c)
 			e := node.New(o...)
 			e := node.New(o...)
 
 
-			displayStart(e)
+			displayStart(ll)
 
 
 			// Join the node to the network, using our ledger
 			// Join the node to the network, using our ledger
 			if err := e.Start(context.Background()); err != nil {
 			if err := e.Start(context.Background()); err != nil {
@@ -128,7 +128,7 @@ to the service over the network`,
 			}
 			}
 
 
 			ledger, _ := e.Ledger()
 			ledger, _ := e.Ledger()
-			return services.ConnectToService(context.Background(), ledger, e, e.Logger(), time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, address)
+			return services.ConnectToService(context.Background(), ledger, e, ll, time.Duration(c.Int("ledger-announce-interval"))*time.Second, name, address)
 		},
 		},
 	}
 	}
 }
 }

+ 5 - 5
cmd/util.go

@@ -160,13 +160,13 @@ var CommonFlags []cli.Flag = []cli.Flag{
 		EnvVar: "EDGEVPNTOKEN",
 		EnvVar: "EDGEVPNTOKEN",
 	}}
 	}}
 
 
-func displayStart(e *node.Node) {
-	e.Logger().Info(Copyright)
+func displayStart(ll *logger.Logger) {
+	ll.Info(Copyright)
 
 
-	e.Logger().Infof("Version: %s commit: %s", internal.Version, internal.Commit)
+	ll.Infof("Version: %s commit: %s", internal.Version, internal.Commit)
 }
 }
 
 
-func cliToOpts(c *cli.Context) ([]node.Option, []vpn.Option) {
+func cliToOpts(c *cli.Context) ([]node.Option, []vpn.Option, *logger.Logger) {
 	config := c.String("config")
 	config := c.String("config")
 	address := c.String("address")
 	address := c.String("address")
 	router := c.String("router")
 	router := c.String("router")
@@ -269,5 +269,5 @@ func cliToOpts(c *cli.Context) ([]node.Option, []vpn.Option) {
 
 
 	}
 	}
 
 
-	return opts, vpnOpts
+	return opts, vpnOpts, llger
 }
 }

+ 1 - 2
pkg/hub/room.go

@@ -1,4 +1,4 @@
-// Copyright © 2021 Ettore Di Giacinto <[email protected]>
+// Copyright © 2021-2022 Ettore Di Giacinto <[email protected]>
 //
 //
 // This program is free software; you can redistribute it and/or modify
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // it under the terms of the GNU General Public License as published by
@@ -41,7 +41,6 @@ type Room struct {
 
 
 	roomName string
 	roomName string
 	self     peer.ID
 	self     peer.ID
-	nick     string
 }
 }
 
 
 // JoinRoom tries to subscribe to the PubSub topic for the room name, returning
 // JoinRoom tries to subscribe to the PubSub topic for the room name, returning

+ 6 - 6
pkg/node/message.go

@@ -1,4 +1,4 @@
-// Copyright © 2021 Ettore Di Giacinto <[email protected]>
+// Copyright © 2021-2022 Ettore Di Giacinto <[email protected]>
 //
 //
 // This program is free software; you can redistribute it and/or modify
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // it under the terms of the GNU General Public License as published by
@@ -19,28 +19,28 @@ import (
 	hub "github.com/mudler/edgevpn/pkg/hub"
 	hub "github.com/mudler/edgevpn/pkg/hub"
 )
 )
 
 
-// MessageWriter is a struct returned by the node that satisfies the io.Writer interface
+// messageWriter is a struct returned by the node that satisfies the io.Writer interface
 // on the underlying hub.
 // on the underlying hub.
 // Everything Write into the message writer is enqueued to a message channel
 // Everything Write into the message writer is enqueued to a message channel
 // which is sealed and processed by the node
 // which is sealed and processed by the node
-type MessageWriter struct {
+type messageWriter struct {
 	input chan<- *hub.Message
 	input chan<- *hub.Message
 	c     Config
 	c     Config
 	mess  *hub.Message
 	mess  *hub.Message
 }
 }
 
 
 // Write writes a slice of bytes to the message channel
 // Write writes a slice of bytes to the message channel
-func (mw *MessageWriter) Write(p []byte) (n int, err error) {
+func (mw *messageWriter) Write(p []byte) (n int, err error) {
 	return mw.Send(mw.mess.WithMessage(string(p)))
 	return mw.Send(mw.mess.WithMessage(string(p)))
 }
 }
 
 
 // WriteString writes a string to the message channel
 // WriteString writes a string to the message channel
-func (mw *MessageWriter) WriteString(p string) (n int, err error) {
+func (mw *messageWriter) WriteString(p string) (n int, err error) {
 	return mw.Send(mw.mess.WithMessage(p))
 	return mw.Send(mw.mess.WithMessage(p))
 }
 }
 
 
 // Send sends a message to the channel
 // Send sends a message to the channel
-func (mw *MessageWriter) Send(copy *hub.Message) (n int, err error) {
+func (mw *messageWriter) Send(copy *hub.Message) (n int, err error) {
 	mw.input <- copy
 	mw.input <- copy
 	return len(copy.Message), nil
 	return len(copy.Message), nil
 }
 }

+ 10 - 11
pkg/node/node.go

@@ -69,16 +69,20 @@ func New(p ...Option) *Node {
 	}
 	}
 }
 }
 
 
+// AddStreamHandler adds a stream handler for the given protocol.
+// Note: must be called before Start().
 func (e *Node) AddStreamHandler(id protocol.Protocol, s types.StreamHandler) {
 func (e *Node) AddStreamHandler(id protocol.Protocol, s types.StreamHandler) {
 	e.config.StreamHandlers[id.ID()] = s
 	e.config.StreamHandlers[id.ID()] = s
 }
 }
 
 
-// Ledger return the ledger associated to the node
+// Ledger return the ledger which uses the node
+// connection to broadcast messages
 func (e *Node) Ledger() (*blockchain.Ledger, error) {
 func (e *Node) Ledger() (*blockchain.Ledger, error) {
 	if e.ledger != nil {
 	if e.ledger != nil {
 		return e.ledger, nil
 		return e.ledger, nil
 	}
 	}
-	mw, err := e.MessageWriter()
+
+	mw, err := e.messageWriter()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -118,24 +122,19 @@ func (e *Node) Start(ctx context.Context) error {
 	return nil
 	return nil
 }
 }
 
 
-// MessageWriter returns a new MessageWriter bound to the edgevpn instance
+// messageWriter returns a new MessageWriter bound to the edgevpn instance
 // with the given options
 // with the given options
-func (e *Node) MessageWriter(opts ...hub.MessageOption) (*MessageWriter, error) {
+func (e *Node) messageWriter(opts ...hub.MessageOption) (*messageWriter, error) {
 	mess := &hub.Message{}
 	mess := &hub.Message{}
 	mess.Apply(opts...)
 	mess.Apply(opts...)
 
 
-	return &MessageWriter{
+	return &messageWriter{
 		c:     e.config,
 		c:     e.config,
 		input: e.inputCh,
 		input: e.inputCh,
 		mess:  mess,
 		mess:  mess,
 	}, nil
 	}, nil
 }
 }
 
 
-// Logger returns the node logger
-func (e *Node) Logger() log.StandardLogger {
-	return e.config.Logger
-}
-
 func (e *Node) startNetwork(ctx context.Context) error {
 func (e *Node) startNetwork(ctx context.Context) error {
 	e.config.Logger.Debug("Generating host data")
 	e.config.Logger.Debug("Generating host data")
 
 
@@ -175,6 +174,6 @@ func (e *Node) startNetwork(ctx context.Context) error {
 
 
 	go e.handleEvents(ctx)
 	go e.handleEvents(ctx)
 
 
-	e.Logger().Debug("Network started")
+	e.config.Logger.Debug("Network started")
 	return nil
 	return nil
 }
 }

+ 1 - 1
pkg/node/node_suite_test.go

@@ -24,5 +24,5 @@ import (
 
 
 func TestEdgeVPN(t *testing.T) {
 func TestEdgeVPN(t *testing.T) {
 	RegisterFailHandler(Fail)
 	RegisterFailHandler(Fail)
-	RunSpecs(t, "EdgeVPN Suite")
+	RunSpecs(t, "Node Suite")
 }
 }

+ 1 - 1
pkg/node/node_test.go

@@ -29,7 +29,7 @@ import (
 	. "github.com/mudler/edgevpn/pkg/node"
 	. "github.com/mudler/edgevpn/pkg/node"
 )
 )
 
 
-var _ = Describe("EdgeVPN", func() {
+var _ = Describe("Node", func() {
 	token := GenerateNewConnectionData().Base64()
 	token := GenerateNewConnectionData().Base64()
 
 
 	l := Logger(logger.New(log.LevelFatal))
 	l := Logger(logger.New(log.LevelFatal))

+ 5 - 5
pkg/services/files.go

@@ -31,7 +31,11 @@ import (
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 )
 )
 
 
-func SendFile(ctx context.Context, ledger *blockchain.Ledger, node types.Node, l log.StandardLogger, announcetime time.Duration, fileID, filepath string) error {
+func ShareFile(ctx context.Context, ledger *blockchain.Ledger, node types.Node, l log.StandardLogger, announcetime time.Duration, fileID, filepath string) error {
+	_, err := os.Stat(filepath)
+	if err != nil {
+		return err
+	}
 
 
 	l.Infof("Serving '%s' as '%s'", filepath, fileID)
 	l.Infof("Serving '%s' as '%s'", filepath, fileID)
 
 
@@ -52,10 +56,6 @@ func SendFile(ctx context.Context, ledger *blockchain.Ledger, node types.Node, l
 			}
 			}
 		},
 		},
 	)
 	)
-	_, err := os.Stat(filepath)
-	if err != nil {
-		return err
-	}
 
 
 	// 2) Set a stream handler
 	// 2) Set a stream handler
 	//    which connect to the given address/Port and Send what we receive from the Stream.
 	//    which connect to the given address/Port and Send what we receive from the Stream.

+ 83 - 0
pkg/services/files_test.go

@@ -0,0 +1,83 @@
+// Copyright © 2022 Ettore Di Giacinto <[email protected]>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, see <http://www.gnu.org/licenses/>.
+
+package services_test
+
+import (
+	"context"
+	"io/ioutil"
+	"os"
+	"time"
+
+	"github.com/ipfs/go-log"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+
+	"github.com/mudler/edgevpn/pkg/blockchain"
+	"github.com/mudler/edgevpn/pkg/logger"
+	node "github.com/mudler/edgevpn/pkg/node"
+	. "github.com/mudler/edgevpn/pkg/services"
+)
+
+var _ = Describe("File services", func() {
+	token := node.GenerateNewConnectionData().Base64()
+
+	logg := logger.New(log.LevelError)
+	l := node.Logger(logg)
+
+	e := node.New(node.FromBase64(true, true, token), node.WithStore(&blockchain.MemoryStore{}), l)
+	e2 := node.New(node.FromBase64(true, true, token), node.WithStore(&blockchain.MemoryStore{}), l)
+
+	Context("File sharing", func() {
+		It("sends and receive files between two nodes", func() {
+			ctx, cancel := context.WithCancel(context.Background())
+			defer cancel()
+
+			fileUUID := "test"
+
+			le, _ := e.Ledger()
+
+			f, err := ioutil.TempFile("", "test")
+			Expect(err).ToNot(HaveOccurred())
+
+			defer os.RemoveAll(f.Name())
+
+			ioutil.WriteFile(f.Name(), []byte("testfile"), os.ModePerm)
+
+			// First node expose a file
+			err = ShareFile(ctx, le, e, logg, 1*time.Second, fileUUID, f.Name())
+			Expect(err).ToNot(HaveOccurred())
+
+			e.Start(ctx)
+			e2.Start(ctx)
+
+			Eventually(func() string {
+				ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+				defer cancel()
+
+				f, err := ioutil.TempFile("", "test")
+				Expect(err).ToNot(HaveOccurred())
+
+				defer os.RemoveAll(f.Name())
+
+				ll, _ := e2.Ledger()
+
+				ReceiveFile(ctx, ll, e2, logg, 1*time.Second, fileUUID, f.Name())
+				b, _ := ioutil.ReadFile(f.Name())
+				return string(b)
+			}, 100*time.Second, 1*time.Second).Should(Equal("testfile"))
+		})
+	})
+})

+ 28 - 0
pkg/services/services_suite_test.go

@@ -0,0 +1,28 @@
+// Copyright © 2022 Ettore Di Giacinto <[email protected]>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, see <http://www.gnu.org/licenses/>.
+
+package services_test
+
+import (
+	"testing"
+
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+)
+
+func TestServices(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Services Suite")
+}

+ 90 - 0
pkg/services/services_test.go

@@ -0,0 +1,90 @@
+// Copyright © 2022 Ettore Di Giacinto <[email protected]>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, see <http://www.gnu.org/licenses/>.
+
+package services_test
+
+import (
+	"context"
+	"io/ioutil"
+	"net/http"
+	"time"
+
+	"github.com/ipfs/go-log"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+
+	"github.com/mudler/edgevpn/pkg/blockchain"
+	"github.com/mudler/edgevpn/pkg/logger"
+	node "github.com/mudler/edgevpn/pkg/node"
+	. "github.com/mudler/edgevpn/pkg/services"
+)
+
+func get(url string) string {
+	client := &http.Client{
+		CheckRedirect: func(req *http.Request, via []*http.Request) error {
+			return http.ErrUseLastResponse
+		},
+		Timeout: 1 * time.Second,
+	}
+	resp, err := client.Get(url)
+	if err != nil {
+		return ""
+	}
+
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return ""
+	}
+
+	return string(body)
+}
+
+var _ = Describe("Expose services", func() {
+	token := node.GenerateNewConnectionData().Base64()
+
+	logg := logger.New(log.LevelFatal)
+	l := node.Logger(logg)
+
+	e := node.New(node.FromBase64(true, true, token), node.WithStore(&blockchain.MemoryStore{}), l)
+	e2 := node.New(node.FromBase64(true, true, token), node.WithStore(&blockchain.MemoryStore{}), l)
+
+	Context("Service sharing", func() {
+		It("expose services and can connect to them", func() {
+			ctx, cancel := context.WithCancel(context.Background())
+			defer cancel()
+
+			serviceUUID := "test"
+
+			le, _ := e.Ledger()
+
+			// First node expose a service
+			// redirects to google:80
+			ExposeService(ctx, le, e, logg, 1*time.Second, serviceUUID, "142.250.184.35:80")
+
+			e.Start(ctx)
+			e2.Start(ctx)
+
+			ll, _ := e2.Ledger()
+
+			go ConnectToService(ctx, ll, e2, logg, 1*time.Second, serviceUUID, "127.0.0.1:9999")
+
+			Eventually(func() string {
+				return get("http://127.0.0.1:9999")
+			}, 60*time.Second, 1*time.Second).Should(ContainSubstring("The document has moved"))
+		})
+	})
+})