diff --git a/lib/go/camli/test/fakeindex.go b/lib/go/camli/test/fakeindex.go index e647a2d91..3409e9e23 100644 --- a/lib/go/camli/test/fakeindex.go +++ b/lib/go/camli/test/fakeindex.go @@ -18,7 +18,9 @@ package test import ( "fmt" + "log" "os" + "strings" "sync" "time" @@ -32,6 +34,7 @@ type FakeIndex struct { size map[string]int64 ownerClaims map[string]search.ClaimList // "/" -> ClaimList signerAttrValue map[string]*blobref.BlobRef // "\0\0" -> blobref + path map[string]*search.Path // "\0\0" -> path cllk sync.Mutex clock int64 @@ -45,6 +48,7 @@ func NewFakeIndex() *FakeIndex { size: make(map[string]int64), ownerClaims: make(map[string]search.ClaimList), signerAttrValue: make(map[string]*blobref.BlobRef), + path: make(map[string]*search.Path), } } @@ -83,6 +87,21 @@ func (fi *FakeIndex) AddClaim(owner, permanode *blobref.BlobRef, claimType, attr } key := permanode.String() + "/" + owner.String() fi.ownerClaims[key] = append(fi.ownerClaims[key], claim) + + if claimType == "set-attribute" && strings.HasPrefix(attr, "camliPath:") { + suffix := attr[len("camliPath:"):] + path := &search.Path{ + Target: blobref.MustParse(value), + Suffix: suffix, + } + fi.path[fmt.Sprintf("%s\x00%s\x00%s", owner, permanode, suffix)] = path + } +} + +func (fi *FakeIndex) AddSignerAttrValue(signer *blobref.BlobRef, attr, val string, latest *blobref.BlobRef) { + fi.lk.Lock() + defer fi.lk.Unlock() + fi.signerAttrValue[fmt.Sprintf("%s\x00%s\x00%s", signer, attr, val)] = latest } // @@ -140,5 +159,14 @@ func (fi *FakeIndex) PathsLookup(signer, base *blobref.BlobRef, suffix string) ( } func (fi *FakeIndex) PathLookup(signer, base *blobref.BlobRef, suffix string, at *time.Time) (*search.Path, os.Error) { - panic("NOIMPL") + if at != nil { + panic("PathLookup with non-nil at not supported") + } + fi.lk.Lock() + defer fi.lk.Unlock() + if p, ok := fi.path[fmt.Sprintf("%s\x00%s\x00%s", signer, base, suffix)]; ok { + return p, nil + } + log.Printf("PathLookup miss for signer %q, base %q, suffix %q", signer, base, suffix) + return nil, os.ENOENT } diff --git a/server/go/camlistored/publish_test.go b/server/go/camlistored/publish_test.go index 048fab087..6db02e2a8 100644 --- a/server/go/camlistored/publish_test.go +++ b/server/go/camlistored/publish_test.go @@ -19,6 +19,7 @@ package main import ( "http" "http/httptest" + "strings" "testing" "camli/blobref" @@ -26,18 +27,78 @@ import ( "camli/test" ) -func TestPublishURLs(t *testing.T) { - fakeIndex := test.NewFakeIndex() - owner := blobref.MustParse("owner-123") - sh := search.NewHandler(fakeIndex, owner) - ph := &PublishHandler{ - RootName: "foo", - Search: sh, - } - rw := httptest.NewRecorder() - req, _ := http.NewRequest("GET", "http://foo.com/pics/singlepic", nil) - req.Header.Set("X-PrefixHandler-PathBase", "/pics/") - req.Header.Set("X-PrefixHandler-PathSuffix", "singlepic") - pr := ph.NewRequest(rw, req) - t.Logf("Got request: %#v", *pr) +type publishURLTest struct { + path string // input + + subject string // expected +} + +var publishURLTests = []publishURLTest{ + { + path: "/pics/singlepic", + subject: "picpn-123", + }, + { + path: "/pics/camping", + subject: "gal-123", + }, + { + path: "/pics/camping/-/m9876543210", + subject: "picpn-98765432100", + }, +} + +func TestPublishURLs(t *testing.T) { + owner := blobref.MustParse("owner-123") + picNode := blobref.MustParse("picpn-123") + galRef := blobref.MustParse("gal-123") + rootRef := blobref.MustParse("root-abc") + camp0 := blobref.MustParse("picpn-98765432100") + camp1 := blobref.MustParse("picpn-98765432111") + camp0f := blobref.MustParse("picfile-98765432f00") + camp1f := blobref.MustParse("picfile-98765432f10") + + rootName := "foo" + + for ti, tt := range publishURLTests { + idx := test.NewFakeIndex() + idx.AddSignerAttrValue(owner, "camliRoot", rootName, rootRef) + sh := search.NewHandler(idx, owner) + ph := &PublishHandler{ + RootName: rootName, + Search: sh, + } + rw := httptest.NewRecorder() + if !strings.HasPrefix(tt.path, "/pics/") { + panic("expected /pics/ prefix on " + tt.path) + } + req, _ := http.NewRequest("GET", "http://foo.com"+tt.path, nil) + req.Header.Set("X-PrefixHandler-PathBase", "/pics/") + req.Header.Set("X-PrefixHandler-PathSuffix", tt.path[len("/pics/"):]) + + idx.AddMeta(owner, "text/x-openpgp-public-key", 100) + for _, br := range []*blobref.BlobRef{picNode, galRef, rootRef, camp0, camp1} { + idx.AddMeta(br, "application/json; camliType=permanode", 100) + } + for _, br := range []*blobref.BlobRef{camp0f, camp1f} { + idx.AddMeta(br, "application/json; camliType=file", 100) + } + + idx.AddClaim(owner, rootRef, "set-attribute", "camliPath:singlepic", picNode.String()) + idx.AddClaim(owner, rootRef, "set-attribute", "camliPath:camping", galRef.String()) + idx.AddClaim(owner, galRef, "add-attribute", "camliMember", camp0.String()) + idx.AddClaim(owner, galRef, "add-attribute", "camliMember", camp1.String()) + idx.AddClaim(owner, camp0, "set-attribute", "camliContent", camp0f.String()) + idx.AddClaim(owner, camp1, "set-attribute", "camliContent", camp1f.String()) + pr := ph.NewRequest(rw, req) + + err := pr.findSubject() + if err != nil { + t.Errorf("test #%d, findSubject: %v", ti, err) + continue + } + if pr.subject.String() != tt.subject { + t.Errorf("test #%d, got subject %q, want %q", ti, pr.subject, tt.subject) + } + } }