diff --git a/core/coreapi/name_test.go b/core/coreapi/name_test.go index 2b198b9c8ca..fb6ffdccc56 100644 --- a/core/coreapi/name_test.go +++ b/core/coreapi/name_test.go @@ -2,9 +2,11 @@ package coreapi_test import ( "context" + "github.com/ipfs/go-ipfs/core" "io" "io/ioutil" "math/rand" + "path" "testing" "time" @@ -21,45 +23,150 @@ func addTestObject(ctx context.Context, api coreiface.CoreAPI) (coreiface.Path, return api.Unixfs().Add(ctx, files.NewReaderFile("", "", ioutil.NopCloser(&io.LimitedReader{R: rnd, N: 4092}), nil)) } -func TestBasicPublishResolve(t *testing.T) { - ctx := context.Background() - nds, apis, err := makeAPISwarm(ctx, true, 5) +func appendPath(p coreiface.Path, sub string) coreiface.Path { + p, err := coreiface.ParsePath(path.Join(p.String(), sub)) if err != nil { - t.Fatal(err) - return + panic(err) } - n := nds[0] - api := apis[0] + return p +} - p, err := addTestObject(ctx, api) - if err != nil { - t.Fatal(err) - return - } +func TestPublishResolve(t *testing.T) { + ctx := context.Background() + init := func() (*core.IpfsNode, coreiface.CoreAPI, coreiface.Path) { + nds, apis, err := makeAPISwarm(ctx, true, 5) + if err != nil { + t.Fatal(err) + return nil, nil, nil + } + n := nds[0] + api := apis[0] - e, err := api.Name().Publish(ctx, p) - if err != nil { - t.Fatal(err) - return + p, err := addTestObject(ctx, api) + if err != nil { + t.Fatal(err) + return nil, nil, nil + } + return n, api, p } - if e.Name() != n.Identity.Pretty() { - t.Errorf("expected e.Name to equal '%s', got '%s'", n.Identity.Pretty(), e.Name()) - } + run := func(t *testing.T, ropts []opt.NameResolveOption) { + t.Run("basic", func(t *testing.T) { + n, api, p := init() + e, err := api.Name().Publish(ctx, p) + if err != nil { + t.Fatal(err) + return + } - if e.Value().String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) - } + if e.Name() != n.Identity.Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", n.Identity.Pretty(), e.Name()) + } - resPath, err := api.Name().Resolve(ctx, e.Name()) - if err != nil { - t.Fatal(err) - return - } + if e.Value().String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } - if resPath.String() != p.String() { - t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()) + resPath, err := api.Name().Resolve(ctx, e.Name(), ropts...) + if err != nil { + t.Fatal(err) + return + } + + if resPath.String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()) + } + }) + + t.Run("publishPath", func(t *testing.T) { + n, api, p := init() + e, err := api.Name().Publish(ctx, appendPath(p, "/test")) + if err != nil { + t.Fatal(err) + return + } + + if e.Name() != n.Identity.Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", n.Identity.Pretty(), e.Name()) + } + + if e.Value().String() != p.String()+"/test" { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name(), ropts...) + if err != nil { + t.Fatal(err) + return + } + + if resPath.String() != p.String()+"/test" { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/test") + } + }) + + t.Run("revolvePath", func(t *testing.T) { + n, api, p := init() + e, err := api.Name().Publish(ctx, p) + if err != nil { + t.Fatal(err) + return + } + + if e.Name() != n.Identity.Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", n.Identity.Pretty(), e.Name()) + } + + if e.Value().String() != p.String() { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name()+"/test", ropts...) + if err != nil { + t.Fatal(err) + return + } + + if resPath.String() != p.String()+"/test" { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/test") + } + }) + + t.Run("publishRevolvePath", func(t *testing.T) { + n, api, p := init() + e, err := api.Name().Publish(ctx, appendPath(p, "/a")) + if err != nil { + t.Fatal(err) + return + } + + if e.Name() != n.Identity.Pretty() { + t.Errorf("expected e.Name to equal '%s', got '%s'", n.Identity.Pretty(), e.Name()) + } + + if e.Value().String() != p.String()+"/a" { + t.Errorf("expected paths to match, '%s'!='%s'", e.Value().String(), p.String()) + } + + resPath, err := api.Name().Resolve(ctx, e.Name()+"/b", ropts...) + if err != nil { + t.Fatal(err) + return + } + + if resPath.String() != p.String()+"/a/b" { + t.Errorf("expected paths to match, '%s'!='%s'", resPath.String(), p.String()+"/a/b") + } + }) } + + t.Run("default", func(t *testing.T) { + run(t, []opt.NameResolveOption{}) + }) + + t.Run("nocache", func(t *testing.T) { + run(t, []opt.NameResolveOption{opt.Name.Cache(false)}) + }) } func TestBasicPublishResolveKey(t *testing.T) { diff --git a/namesys/namesys.go b/namesys/namesys.go index 8d486cdfb19..dddb0dff30a 100644 --- a/namesys/namesys.go +++ b/namesys/namesys.go @@ -100,6 +100,14 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts. key := segments[2] if p, ok := ns.cacheGet(key); ok { + if len(segments) > 3 { + var err error + p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3]) + if err != nil { + emitOnceResult(ctx, out, onceResult{value: p, err: err}) + } + } + out <- onceResult{value: p} close(out) return out @@ -139,7 +147,8 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts. // Attach rest of the path if len(segments) > 3 { - p, err := path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3]) + var err error + p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3]) if err != nil { emitOnceResult(ctx, out, onceResult{value: p, ttl: res.ttl, err: err}) }