Skip to content

Commit

Permalink
test(fetch): Rewrite fetch test. Don't run connect, test expectations.
Browse files Browse the repository at this point in the history
Merge pull request #1211 from qri-io/rewrite-fetch-test
  • Loading branch information
dustmop authored Mar 21, 2020
2 parents 0c6770f + fdf4fbb commit 1528f53
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 43 deletions.
166 changes: 123 additions & 43 deletions cmd/fetch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,157 @@ package cmd

import (
"context"
"fmt"
"net/http"
"regexp"
"testing"
"time"

"github.com/google/go-cmp/cmp"
"github.com/qri-io/qri/api"
"github.com/qri-io/qri/config"
"github.com/qri-io/qri/lib"
"github.com/qri-io/qri/logbook"
)

func TestFetchCommand(t *testing.T) {
r := NewTestRunner(t, "peer_a", "qri_test_fetch_a")
defer r.Delete()
a := NewTestRunner(t, "peer_a", "qri_test_fetch_a")
defer a.Delete()

ctx, done := context.WithCancel(context.Background())
defer done()
// TODO(dustmop): Move most of the below hooks into a common testRunner. Maybe the basic
// TestRunner will work?

cmdR := r.CreateCommandRunner(ctx)
err := executeCommand(cmdR, "qri save --body=testdata/movies/body_ten.csv me/test_movies")
// Set the location to New York so that timezone printing is consistent
location, err := time.LoadLocation("America/New_York")
if err != nil {
t.Fatal(err.Error())
panic(err)
}
locOrig := StringerLocation
StringerLocation = location

cmdR = r.CreateCommandRunner(ctx)
if err = executeCommand(cmdR, "qri save --body=testdata/movies/body_thirty.csv me/test_movies"); err != nil {
t.Fatal(err)
// Restore the location function
a.Teardown = func() {
StringerLocation = locOrig
}

cmdR = r.CreateCommandRunner(ctx)
if err = executeCommand(cmdR, "qri log peer_a/test_movies"); err != nil {
t.Fatal(err)
// Hook timestamp generation.
prevTimestampFunc := logbook.NewTimestamp
logbook.NewTimestamp = func() int64 {
return 1000
}
defer func() {
logbook.NewTimestamp = prevTimestampFunc
}()

// Save a version with some rows in its body
a.MustExec(t, "qri save --body=testdata/movies/body_ten.csv me/test_movies")

// Save another version with more rows
a.MustExec(t, "qri save --body=testdata/movies/body_thirty.csv me/test_movies")

text := r.GetCommandOutput()
// TODO (b5) - make this acutally inspect once we have stable timestamps in logs
if len(text) == 0 {
t.Errorf("expected log to produce a non-zero length output.")
// Get the log, should have two versions.
actual := a.MustExec(t, "qri log peer_a/test_movies")
expect := `1 Commit: /ipfs/QmbjY9YG6xKfrPxiXA9eBkJSZiiRRtfKoaS9LSnyVvCAuA
Date: Sun Dec 31 20:02:01 EST 2000
Storage: local
Size: 720 B
structure updated 3 fields
structure:
updated checksum
updated entries
updated length
2 Commit: /ipfs/QmXfgnK7XmyZcRfKrhDysRh5AcHqQntLy98i4joDqopqx6
Date: Sun Dec 31 20:01:01 EST 2000
Storage: local
Size: 224 B
created dataset
`
if diff := cmp.Diff(expect, actual); diff != "" {
t.Errorf("result mismatch (-want +got):%s\n", diff)
}

cmdR = r.CreateCommandRunner(ctx)
if err = executeCommand(cmdR, "qri config set remote.enabled true rpc.enabled false"); err != nil {
// Enable remote and RPC in the config
a.MustExec(t, "qri config set remote.enabled true rpc.enabled false")

ctx := context.Background()

// Create a remote that makes these versions available
remoteInst, err := lib.NewInstance(
ctx,
a.RepoRoot.QriPath,
lib.OptStdIOStreams(),
lib.OptSetIPFSPath(a.RepoRoot.IPFSPath),
)
if err != nil {
t.Fatal(err)
}
if err := remoteInst.Connect(ctx); err != nil {
t.Fatal(err)
}

cmdR = r.CreateCommandRunner(ctx)
go func() {
if err = executeCommand(cmdR, "qri connect"); err != nil {
t.Fatal(err)
}
}()

// TODO (b5) - this is horrible. we should block on a channel receive for connectedness
time.Sleep(time.Second * 5)
// Made an HTTP server for our remote
remoteServer := api.New(remoteInst)
httpServer := &http.Server{}
httpServer.Handler = api.NewServerRoutes(remoteServer)

// Serve on an available port
// TODO(dustmop): This port could actually be randomized to make this more robust
const RemotePort = 9876
apiConfig := config.API{
Enabled: true,
Port: RemotePort,
RemoteMode: true,
}
go api.StartServer(&apiConfig, httpServer)
defer httpServer.Close()

// Construct a second peer B.
b := NewTestRunner(t, "peer_b", "qri_test_fetch_b")
defer b.Delete()

cmdBr := b.CreateCommandRunner(ctx)
if err = executeCommand(cmdBr, "qri log peer_b/test_movies"); err == nil {
// Expect an error when trying to list an unavailable dataset
err = b.ExecCommand("qri log peer_b/test_movies")
expectErr := `repo: not found`
if err == nil {
t.Fatal("expected fetch on non-existant log to error")
}

cmdBr = b.CreateCommandRunner(ctx)
if err = executeCommand(cmdBr, "qri config set remotes.a_node http://localhost:2503"); err != nil {
t.Fatal(err)
if expectErr != err.Error() {
t.Errorf("error mismatch, expect: %s, got: %s", expectErr, err)
}

cmdBr = b.CreateCommandRunner(ctx)
if err = executeCommand(cmdBr, "qri fetch peer_a/test_movies --remote a_node"); err != nil {
t.Fatal(err)
// Assign peer A as a remote for peer B
cfgCmdText := fmt.Sprintf("qri config set remotes.a_node http://localhost:%d", RemotePort)
b.MustExec(t, cfgCmdText)

// Have peer B fetch from peer A, output correlates to the log from peer A earlier
actual = b.MustExec(t, "qri fetch peer_a/test_movies --remote a_node")
expect = `1 peer_a/test_movies
/ipfs/QmbjY9YG6xKfrPxiXA9eBkJSZiiRRtfKoaS9LSnyVvCAuA
foreign
720 B, 0 entries, 0 errors
2 peer_a/test_movies
/ipfs/QmXfgnK7XmyZcRfKrhDysRh5AcHqQntLy98i4joDqopqx6
foreign
224 B, 0 entries, 0 errors
`
if diff := cmp.Diff(expect, actual); diff != "" {
t.Errorf("result mismatch (-want +got):%s\n", diff)
}

cmdBr = b.CreateCommandRunner(ctx)
if err = executeCommand(cmdBr, "qri logbook --raw"); err != nil {
t.Fatal(err)
}
// Regex that replaces the timestamp with just static text
fixTs := regexp.MustCompile(`"timestamp":"[0-9TZ.:-]*"`)

text = b.GetCommandOutput()
t.Logf("%s", text)
// Verify the logbook on peer B doesn't contain the fetched info
output := b.MustExec(t, "qri logbook --raw")
actual = string(fixTs.ReplaceAll([]byte(output), []byte(`"timestamp":timeStampHere`)))
expect = `[{"ops":[{"type":"init","model":"user","name":"peer_b","authorID":"QmeL2mdVka1eahKENjehK6tBxkkpk5dNQ1qMcgWi7Hrb4B","timestamp":timeStampHere}]}]`
if diff := cmp.Diff(expect, actual); diff != "" {
t.Errorf("result mismatch (-want +got):%s\n", diff)
}
}
4 changes: 4 additions & 0 deletions remote/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ func NewRemote(node *p2p.QriNode, cfg *config.Remote, opts ...func(o *Options))
opt(o)
}

if node == nil {
return nil, fmt.Errorf("remote requires a non-nil node")
}

r := &Remote{
node: node,

Expand Down

0 comments on commit 1528f53

Please sign in to comment.