consensus tests
License: MIT Signed-off-by: Hector Sanjuan <hector@protocol.ai>
This commit is contained in:
parent
98dc9f2289
commit
0f31995bd6
4
api.go
4
api.go
|
@ -7,9 +7,9 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
|
||||
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
|
||||
mux "github.com/gorilla/mux"
|
||||
)
|
||||
|
|
21
api_test.go
21
api_test.go
|
@ -8,20 +8,17 @@ import (
|
|||
"net/http"
|
||||
"testing"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
)
|
||||
|
||||
var (
|
||||
apiHost = "http://127.0.0.1:5000"
|
||||
apiHost = "http://127.0.0.1:10002" // should match testingConfig()
|
||||
)
|
||||
|
||||
func testClusterApi(t *testing.T) *ClusterHTTPAPI {
|
||||
//logging.SetDebugLogging()
|
||||
cfg := &ClusterConfig{
|
||||
ClusterAPIListenAddr: "127.0.0.1",
|
||||
ClusterAPIListenPort: 5000,
|
||||
}
|
||||
cfg := testingConfig()
|
||||
api, err := NewHTTPClusterAPI(cfg)
|
||||
// No keep alive! Otherwise tests hang with
|
||||
// connections re-used from previous tests
|
||||
|
@ -36,16 +33,6 @@ func testClusterApi(t *testing.T) *ClusterHTTPAPI {
|
|||
return api
|
||||
}
|
||||
|
||||
func simulateAnswer(ch <-chan ClusterRPC, answer interface{}, err error) {
|
||||
go func() {
|
||||
req := <-ch
|
||||
req.ResponseCh() <- RPCResponse{
|
||||
Data: answer,
|
||||
Error: err,
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func processResp(t *testing.T, httpResp *http.Response, err error, resp interface{}) {
|
||||
if err != nil {
|
||||
t.Fatal("error making get request: ", err)
|
||||
|
|
16
cluster.go
16
cluster.go
|
@ -7,15 +7,15 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
host "gx/ipfs/QmPTGbC34bPKaUm9wTxBo7zSCac7pDuG42ZmnXC718CKZZ/go-libp2p-host"
|
||||
multiaddr "gx/ipfs/QmUAQaWbKxGCUTuoQVvvicbQNZ9APF5pDGWyAZSe93AtKH/go-multiaddr"
|
||||
swarm "gx/ipfs/QmWfxnAiQ5TnnCgiX9ikVUKFNHRgGhbgKdx5DoKPELD7P4/go-libp2p-swarm"
|
||||
basichost "gx/ipfs/QmbzCT1CwxVZ2ednptC9RavuJe7Bv8DDi2Ne89qUrA37XM/go-libp2p/p2p/host/basic"
|
||||
peerstore "gx/ipfs/QmeXj9VAjmYQZxpmVz7VzccbJrpmr8qkCDSjfVNsPTWTYU/go-libp2p-peerstore"
|
||||
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
|
||||
crypto "gx/ipfs/QmfWDLQjGjVe4fr5CoztYW2DYYjRysMJrFe1RCsXLPTf46/go-libp2p-crypto"
|
||||
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
peerstore "github.com/libp2p/go-libp2p-peerstore"
|
||||
swarm "github.com/libp2p/go-libp2p-swarm"
|
||||
basichost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
multiaddr "github.com/multiformats/go-multiaddr"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
// Cluster is the main IPFS cluster component. It provides
|
||||
|
|
17
config_test.go
Normal file
17
config_test.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package ipfscluster
|
||||
|
||||
func testingConfig() *ClusterConfig {
|
||||
cfg := &ClusterConfig{
|
||||
ConsensusListenPort: 10000,
|
||||
ConsensusListenAddr: "127.0.0.1",
|
||||
ID: "QmUfSFm12eYCaRdypg48m8RqkXfLW7A2ZeGZb2skeHHDGA",
|
||||
PrivateKey: "CAASqAkwggSkAgEAAoIBAQDpT16IRF6bb9tHsCbQ7M+nb2aI8sz8xyt8PoAWM42ki+SNoESIxKb4UhFxixKvtEdGxNE6aUUVc8kFk6wTStJ/X3IGiMetwkXiFiUxabUF/8A6SyvnSVDm+wFuavugpVrZikjLcfrf2xOVgnG3deQQvd/qbAv14jTwMFl+T+8d/cXBo8Mn/leLZCQun/EJEnkXP5MjgNI8XcWUE4NnH3E0ESSm6Pkm8MhMDZ2fmzNgqEyJ0GVinNgSml3Pyha3PBSj5LRczLip/ie4QkKx5OHvX2L3sNv/JIUHse5HSbjZ1c/4oGCYMVTYCykWiczrxBUOlcr8RwnZLOm4n2bCt5ZhAgMBAAECggEAVkePwfzmr7zR7tTpxeGNeXHtDUAdJm3RWwUSASPXgb5qKyXVsm5nAPX4lXDE3E1i/nzSkzNS5PgIoxNVU10cMxZs6JW0okFx7oYaAwgAddN6lxQtjD7EuGaixN6zZ1k/G6vT98iS6i3uNCAlRZ9HVBmjsOF8GtYolZqLvfZ5izEVFlLVq/BCs7Y5OrDrbGmn3XupfitVWYExV0BrHpobDjsx2fYdTZkmPpSSvXNcm4Iq2AXVQzoqAfGo7+qsuLCZtVlyTfVKQjMvE2ffzN1dQunxixOvev/fz4WSjGnRpC6QLn6Oqps9+VxQKqKuXXqUJC+U45DuvA94Of9MvZfAAQKBgQD7xmXueXRBMr2+0WftybAV024ap0cXFrCAu+KWC1SUddCfkiV7e5w+kRJx6RH1cg4cyyCL8yhHZ99Z5V0Mxa/b/usuHMadXPyX5szVI7dOGgIC9q8IijN7B7GMFAXc8+qC7kivehJzjQghpRRAqvRzjDls4gmbNPhbH1jUiU124QKBgQDtOaW5/fOEtOq0yWbDLkLdjImct6oKMLhENL6yeIKjMYgifzHb2adk7rWG3qcMrdgaFtDVfqv8UmMEkzk7bSkovMVj3SkLzMz84ii1SkSfyaCXgt/UOzDkqAUYB0cXMppYA7jxHa2OY8oEHdBgmyJXdLdzJxCp851AoTlRUSePgQKBgQCQgKgUHOUaXnMEx88sbOuBO14gMg3dNIqM+Ejt8QbURmI8k3arzqA4UK8Tbb9+7b0nzXWanS5q/TT1tWyYXgW28DIuvxlHTA01aaP6WItmagrphIelERzG6f1+9ib/T4czKmvROvDIHROjq8lZ7ERs5Pg4g+sbh2VbdzxWj49EQQKBgFEna36ZVfmMOs7mJ3WWGeHY9ira2hzqVd9fe+1qNKbHhx7mDJR9fTqWPxuIh/Vac5dZPtAKqaOEO8OQ6f9edLou+ggT3LrgsS/B3tNGOPvA6mNqrk/Yf/15TWTO+I8DDLIXc+lokbsogC+wU1z5NWJd13RZZOX/JUi63vTmonYBAoGBAIpglLCH2sPXfmguO6p8QcQcv4RjAU1c0GP4P5PNN3Wzo0ItydVd2LHJb6MdmL6ypeiwNklzPFwTeRlKTPmVxJ+QPg1ct/3tAURN/D40GYw9ojDhqmdSl4HW4d6gHS2lYzSFeU5jkG49y5nirOOoEgHy95wghkh6BfpwHujYJGw4",
|
||||
IPFSAPIListenAddr: "127.0.0.1",
|
||||
IPFSAPIListenPort: 10001,
|
||||
ClusterAPIListenAddr: "127.0.0.1",
|
||||
ClusterAPIListenPort: 10002,
|
||||
RaftFolder: "./raftFolderFromTests",
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
25
consensus.go
25
consensus.go
|
@ -5,12 +5,12 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
host "gx/ipfs/QmPTGbC34bPKaUm9wTxBo7zSCac7pDuG42ZmnXC718CKZZ/go-libp2p-host"
|
||||
consensus "gx/ipfs/QmZ88KbrvZMJpXaNwAGffswcYKz8EbeafzAFGMCA6MEZKt/go-libp2p-consensus"
|
||||
libp2praft "gx/ipfs/QmdHo2LQKmGQ6rDAWFxnzNuW3z8b6Xmw3wEFsMQaj9Rsqj/go-libp2p-raft"
|
||||
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
|
||||
consensus "github.com/libp2p/go-libp2p-consensus"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
libp2praft "github.com/libp2p/go-libp2p-raft"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -40,7 +40,7 @@ type clusterLogOp struct {
|
|||
}
|
||||
|
||||
// ApplyTo applies the operation to the ClusterState
|
||||
func (op clusterLogOp) ApplyTo(cstate consensus.State) (consensus.State, error) {
|
||||
func (op *clusterLogOp) ApplyTo(cstate consensus.State) (consensus.State, error) {
|
||||
state, ok := cstate.(ClusterState)
|
||||
var err error
|
||||
if !ok {
|
||||
|
@ -99,7 +99,7 @@ type ClusterConsensus struct {
|
|||
|
||||
consensus consensus.OpLogConsensus
|
||||
actor consensus.Actor
|
||||
baseOp clusterLogOp
|
||||
baseOp *clusterLogOp
|
||||
rpcCh chan ClusterRPC
|
||||
|
||||
p2pRaft *libp2pRaftWrap
|
||||
|
@ -112,7 +112,7 @@ func NewClusterConsensus(cfg *ClusterConfig, host host.Host, state ClusterState)
|
|||
logger.Info("Starting Consensus component")
|
||||
ctx := context.Background()
|
||||
rpcCh := make(chan ClusterRPC, RPCMaxQueue)
|
||||
op := clusterLogOp{
|
||||
op := &clusterLogOp{
|
||||
ctx: context.Background(),
|
||||
rpcCh: rpcCh,
|
||||
}
|
||||
|
@ -154,7 +154,8 @@ func NewClusterConsensus(cfg *ClusterConfig, host host.Host, state ClusterState)
|
|||
// shutdown, along with the libp2p transport.
|
||||
func (cc *ClusterConsensus) Shutdown() error {
|
||||
logger.Info("Stopping Consensus component")
|
||||
|
||||
defer cc.p2pRaft.transport.Close()
|
||||
defer cc.p2pRaft.boltdb.Close() // important!
|
||||
// When we take snapshot, we make sure that
|
||||
// we re-start from the previous state, and that
|
||||
// we don't replay the log. This includes
|
||||
|
@ -163,7 +164,6 @@ func (cc *ClusterConsensus) Shutdown() error {
|
|||
_ = f.Error()
|
||||
f = cc.p2pRaft.raft.Shutdown()
|
||||
err := f.Error()
|
||||
cc.p2pRaft.transport.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -176,8 +176,8 @@ func (cc *ClusterConsensus) RpcChan() <-chan ClusterRPC {
|
|||
return cc.rpcCh
|
||||
}
|
||||
|
||||
func (cc *ClusterConsensus) op(c *cid.Cid, t clusterLogOpType) clusterLogOp {
|
||||
return clusterLogOp{
|
||||
func (cc *ClusterConsensus) op(c *cid.Cid, t clusterLogOpType) *clusterLogOp {
|
||||
return &clusterLogOp{
|
||||
Cid: c.String(),
|
||||
Type: t,
|
||||
}
|
||||
|
@ -228,6 +228,7 @@ func (cc *ClusterConsensus) Leader() peer.ID {
|
|||
return raftactor.Leader()
|
||||
}
|
||||
|
||||
// TODO
|
||||
func (cc *ClusterConsensus) Rollback(state ClusterState) error {
|
||||
return cc.consensus.Rollback(state)
|
||||
}
|
||||
|
|
164
consensus_test.go
Normal file
164
consensus_test.go
Normal file
|
@ -0,0 +1,164 @@
|
|||
package ipfscluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
func TestApplyToPin(t *testing.T) {
|
||||
op := &clusterLogOp{
|
||||
Cid: testCid,
|
||||
Type: LogOpPin,
|
||||
ctx: context.Background(),
|
||||
rpcCh: make(chan ClusterRPC, 1),
|
||||
}
|
||||
|
||||
st := NewMapState()
|
||||
op.ApplyTo(st)
|
||||
pins := st.ListPins()
|
||||
if len(pins) != 1 || pins[0].String() != testCid {
|
||||
t.Error("the state was not modified correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyToUnpin(t *testing.T) {
|
||||
op := &clusterLogOp{
|
||||
Cid: testCid,
|
||||
Type: LogOpUnpin,
|
||||
ctx: context.Background(),
|
||||
rpcCh: make(chan ClusterRPC, 1),
|
||||
}
|
||||
|
||||
st := NewMapState()
|
||||
c, _ := cid.Decode(testCid)
|
||||
st.AddPin(c)
|
||||
op.ApplyTo(st)
|
||||
pins := st.ListPins()
|
||||
if len(pins) != 0 {
|
||||
t.Error("the state was not modified correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyToBadState(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Error("should have recovered an error")
|
||||
}
|
||||
}()
|
||||
|
||||
op := &clusterLogOp{
|
||||
Cid: testCid,
|
||||
Type: LogOpUnpin,
|
||||
ctx: context.Background(),
|
||||
rpcCh: make(chan ClusterRPC, 1),
|
||||
}
|
||||
|
||||
var st interface{}
|
||||
op.ApplyTo(st)
|
||||
}
|
||||
|
||||
func TestApplyToBadCid(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Error("should have recovered an error")
|
||||
}
|
||||
}()
|
||||
|
||||
op := &clusterLogOp{
|
||||
Cid: "agadfaegf",
|
||||
Type: LogOpPin,
|
||||
ctx: context.Background(),
|
||||
rpcCh: make(chan ClusterRPC, 1),
|
||||
}
|
||||
|
||||
st := NewMapState()
|
||||
op.ApplyTo(st)
|
||||
}
|
||||
|
||||
func cleanRaft() {
|
||||
os.RemoveAll(testingConfig().RaftFolder)
|
||||
}
|
||||
|
||||
func testingClusterConsensus(t *testing.T) *ClusterConsensus {
|
||||
//logging.SetDebugLogging()
|
||||
cfg := testingConfig()
|
||||
ctx := context.Background()
|
||||
h, err := makeHost(ctx, cfg)
|
||||
if err != nil {
|
||||
t.Fatal("cannot create host:", err)
|
||||
}
|
||||
st := NewMapState()
|
||||
cc, err := NewClusterConsensus(cfg, h, st)
|
||||
if err != nil {
|
||||
t.Fatal("cannot create ClusterConsensus:", err)
|
||||
}
|
||||
// Oxygen for Raft to declare leader
|
||||
time.Sleep(1 * time.Second)
|
||||
return cc
|
||||
}
|
||||
|
||||
func TestShutdownClusterConsensus(t *testing.T) {
|
||||
// Bring it up twice to make sure shutdown cleans up properly
|
||||
// but also to make sure raft comes up ok when re-initialized
|
||||
defer cleanRaft()
|
||||
cc := testingClusterConsensus(t)
|
||||
err := cc.Shutdown()
|
||||
if err != nil {
|
||||
t.Fatal("ClusterConsensus cannot shutdown:", err)
|
||||
}
|
||||
cc = testingClusterConsensus(t)
|
||||
err = cc.Shutdown()
|
||||
if err != nil {
|
||||
t.Fatal("ClusterConsensus cannot shutdown:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsensusPin(t *testing.T) {
|
||||
cc := testingClusterConsensus(t)
|
||||
defer cleanRaft() // Remember defer runs in LIFO order
|
||||
defer cc.Shutdown()
|
||||
|
||||
c, _ := cid.Decode(testCid)
|
||||
err := cc.AddPin(c)
|
||||
if err != nil {
|
||||
t.Error("the operation did not make it to the log:", err)
|
||||
}
|
||||
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
st, err := cc.State()
|
||||
if err != nil {
|
||||
t.Error("error getting state:", err)
|
||||
}
|
||||
|
||||
pins := st.ListPins()
|
||||
if len(pins) != 1 || pins[0].String() != testCid {
|
||||
t.Error("the added pin should be in the state")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsensusUnpin(t *testing.T) {
|
||||
cc := testingClusterConsensus(t)
|
||||
defer cleanRaft()
|
||||
defer cc.Shutdown()
|
||||
|
||||
c, _ := cid.Decode(testCid2)
|
||||
err := cc.RmPin(c)
|
||||
if err != nil {
|
||||
t.Error("the operation did not make it to the log:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsensusLeader(t *testing.T) {
|
||||
cc := testingClusterConsensus(t)
|
||||
cfg := testingConfig()
|
||||
pId := cfg.ID
|
||||
defer cleanRaft()
|
||||
defer cc.Shutdown()
|
||||
if l := cc.Leader().Pretty(); l != pId {
|
||||
t.Errorf("expected %s but the leader appears as %s", pId, l)
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
|
||||
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
|
||||
logging "github.com/ipfs/go-log"
|
||||
|
||||
ipfscluster "github.com/ipfs/ipfs-cluster"
|
||||
)
|
||||
|
|
|
@ -10,12 +10,11 @@ package ipfscluster
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
|
||||
"time"
|
||||
|
||||
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
logging "github.com/ipfs/go-log"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
)
|
||||
|
||||
var logger = logging.Logger("ipfs-cluster")
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -58,3 +58,13 @@ func TestMakeRPC(t *testing.T) {
|
|||
time.Sleep(2 * time.Second)
|
||||
cancel()
|
||||
}
|
||||
|
||||
func simulateAnswer(ch <-chan ClusterRPC, answer interface{}, err error) {
|
||||
go func() {
|
||||
req := <-ch
|
||||
req.ResponseCh() <- RPCResponse{
|
||||
Data: answer,
|
||||
Error: err,
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
// IPFSHTTPConnector implements the IPFSConnector interface
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
func testServer(t *testing.T) *httptest.Server {
|
||||
|
@ -48,12 +48,10 @@ func testIPFSConnectorConfig(ts *httptest.Server) *ClusterConfig {
|
|||
h := strings.Split(url.Host, ":")
|
||||
i, _ := strconv.Atoi(h[1])
|
||||
|
||||
return &ClusterConfig{
|
||||
IPFSHost: h[0],
|
||||
IPFSPort: i,
|
||||
IPFSAPIListenAddr: "127.0.0.1",
|
||||
IPFSAPIListenPort: 5000,
|
||||
}
|
||||
cfg := testingConfig()
|
||||
cfg.IPFSHost = h[0]
|
||||
cfg.IPFSPort = i
|
||||
return cfg
|
||||
}
|
||||
|
||||
func ipfsConnector(t *testing.T) (*IPFSHTTPConnector, *httptest.Server) {
|
||||
|
@ -140,7 +138,8 @@ func TestProxy(t *testing.T) {
|
|||
defer ts.Close()
|
||||
defer ipfs.Shutdown()
|
||||
|
||||
res, err := http.Get("http://127.0.0.1:5000/api/v0/add?arg=" + testCid)
|
||||
// Address comes from testingConfig()
|
||||
res, err := http.Get("http://127.0.0.1:10001/api/v0/add?arg=" + testCid)
|
||||
if err != nil {
|
||||
t.Fatal("should forward requests to ipfs host: ", err)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
},
|
||||
{
|
||||
"author": "hsanjuan",
|
||||
"hash": "QmdHo2LQKmGQ6rDAWFxnzNuW3z8b6Xmw3wEFsMQaj9Rsqj",
|
||||
"hash": "QmaofA6ApgPQm8yRojC77dQbVUatYMihdyQjB7VsAqrks1",
|
||||
"name": "go-libp2p-raft",
|
||||
"version": "0.1.1"
|
||||
},
|
||||
|
|
23
raft.go
23
raft.go
|
@ -1,13 +1,12 @@
|
|||
package ipfscluster
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
host "gx/ipfs/QmPTGbC34bPKaUm9wTxBo7zSCac7pDuG42ZmnXC718CKZZ/go-libp2p-host"
|
||||
libp2praft "gx/ipfs/QmdHo2LQKmGQ6rDAWFxnzNuW3z8b6Xmw3wEFsMQaj9Rsqj/go-libp2p-raft"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
libp2praft "github.com/libp2p/go-libp2p-raft"
|
||||
|
||||
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
|
||||
hashiraft "github.com/hashicorp/raft"
|
||||
raftboltdb "github.com/hashicorp/raft-boltdb"
|
||||
|
@ -22,17 +21,20 @@ type libp2pRaftWrap struct {
|
|||
logStore hashiraft.LogStore
|
||||
stableStore hashiraft.StableStore
|
||||
peerstore *libp2praft.Peerstore
|
||||
boltdb *raftboltdb.BoltStore
|
||||
}
|
||||
|
||||
// This function does all heavy the work which is specifically related to
|
||||
// hashicorp's Raft. Other places should just rely on the Consensus interface.
|
||||
func makeLibp2pRaft(cfg *ClusterConfig, host host.Host, state ClusterState, op clusterLogOp) (*libp2praft.Consensus, *libp2praft.Actor, *libp2pRaftWrap, error) {
|
||||
func makeLibp2pRaft(cfg *ClusterConfig, host host.Host, state ClusterState, op *clusterLogOp) (*libp2praft.Consensus, *libp2praft.Actor, *libp2pRaftWrap, error) {
|
||||
logger.Debug("creating libp2p Raft transport")
|
||||
transport, err := libp2praft.NewLibp2pTransportWithHost(host)
|
||||
if err != nil {
|
||||
logger.Error("creating libp2p-raft transport: ", err)
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
logger.Debug("opening connections")
|
||||
transport.OpenConns()
|
||||
|
||||
pstore := &libp2praft.Peerstore{}
|
||||
|
@ -43,23 +45,27 @@ func makeLibp2pRaft(cfg *ClusterConfig, host host.Host, state ClusterState, op c
|
|||
}
|
||||
pstore.SetPeers(strPeers)
|
||||
|
||||
logger.Debug("creating OpLog")
|
||||
cons := libp2praft.NewOpLog(state, op)
|
||||
|
||||
raftCfg := hashiraft.DefaultConfig()
|
||||
raftCfg.EnableSingleNode = raftSingleMode
|
||||
logger.Debug("creating file snapshot store")
|
||||
snapshots, err := hashiraft.NewFileSnapshotStore(cfg.RaftFolder, maxSnapshots, nil)
|
||||
if err != nil {
|
||||
logger.Error("creating file snapshot store: ", err)
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
logger.Debug("creating BoltDB log store")
|
||||
logStore, err := raftboltdb.NewBoltStore(filepath.Join(cfg.RaftFolder, "raft.db"))
|
||||
if err != nil {
|
||||
logger.Error("creating bolt store: ", err)
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
r, err := hashiraft.NewRaft(raftCfg, cons, logStore, logStore, snapshots, pstore, transport)
|
||||
logger.Debug("creating Raft")
|
||||
r, err := hashiraft.NewRaft(raftCfg, cons.FSM(), logStore, logStore, snapshots, pstore, transport)
|
||||
if err != nil {
|
||||
logger.Error("initializing raft: ", err)
|
||||
return nil, nil, nil, err
|
||||
|
@ -72,9 +78,6 @@ func makeLibp2pRaft(cfg *ClusterConfig, host host.Host, state ClusterState, op c
|
|||
logStore: logStore,
|
||||
stableStore: logStore,
|
||||
peerstore: pstore,
|
||||
boltdb: logStore,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func cleanRaft(cfg *ClusterConfig) {
|
||||
os.RemoveAll(cfg.RaftFolder)
|
||||
}
|
||||
|
|
2
rpc.go
2
rpc.go
|
@ -1,6 +1,6 @@
|
|||
package ipfscluster
|
||||
|
||||
import cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
import cid "github.com/ipfs/go-cid"
|
||||
|
||||
// ClusterRPC supported operations.
|
||||
const (
|
||||
|
|
|
@ -3,7 +3,7 @@ package ipfscluster
|
|||
import (
|
||||
"testing"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
func TestRPC(t *testing.T) {
|
||||
|
|
2
state.go
2
state.go
|
@ -3,7 +3,7 @@ package ipfscluster
|
|||
import (
|
||||
"sync"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
// MapState is a very simple database to store
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"sync"
|
||||
|
||||
cid "gx/ipfs/QmcTcsTvfaeEBRFo1TkFgT8sRmgi1n1LTZpecfVP8fzpGD/go-cid"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
Loading…
Reference in New Issue
Block a user