Ejemplo n.º 1
0
func TestUpdateEntryWithEtagBadKey(t *testing.T) {
	origEntry := *kOrigEntry
	var store FakeStore
	newId, err := vsafedb.AddEntry(&store, nil, kKey, &origEntry)
	if err != nil {
		t.Fatalf("Error saving original entry %v", err)
	}
	var origEntryWithEtag vsafe.EntryWithEtag
	if err := vsafedb.EntryByIdWithEtag(
		store, nil, newId, kKey, &origEntryWithEtag); err != nil {
		t.Fatalf("Error readingoriginal entry %v", err)
	}
	update := functional.NewFilterer(changeToAnEntry)
	badKey := *kKey
	badKey.Id++
	if err := vsafedb.UpdateEntryWithEtag(
		store,
		kTransaction,
		newId,
		origEntryWithEtag.Etag,
		&badKey,
		update); err != vsafedb.ErrNoSuchId {
		t.Errorf("Expected ErrNoSuchId, got %v", err)
	}
	var readEntry vsafe.Entry
	if err := vsafedb.EntryById(store, nil, newId, kKey, &readEntry); err != nil {
		t.Fatalf("Error reading store: %v", err)
	}
	if readEntry != origEntryWithEtag.Entry {
		t.Errorf("Entry should not have been updated")
	}
}
Ejemplo n.º 2
0
func TestUpdateEntryWithEtag(t *testing.T) {
	origEntry := *kOrigEntry
	var store FakeStore
	newId, err := vsafedb.AddEntry(&store, nil, kKey, &origEntry)
	if err != nil {
		t.Fatalf("Error saving original entry %v", err)
	}
	var origEntryWithEtag vsafe.EntryWithEtag
	if err := vsafedb.EntryByIdWithEtag(
		store, nil, newId, kKey, &origEntryWithEtag); err != nil {
		t.Fatalf("Error reading original entry %v", err)
	}
	update := functional.NewFilterer(changeToAnEntry)
	if err := vsafedb.UpdateEntryWithEtag(
		store,
		kTransaction,
		newId,
		origEntryWithEtag.Etag,
		kKey,
		update); err != nil {
		t.Fatalf("Error updating store: %v", err)
	}
	var readEntry vsafe.Entry
	if err := vsafedb.EntryById(store, nil, newId, kKey, &readEntry); err != nil {
		t.Fatalf("Error reading store: %v", err)
	}
	entry := *kAnEntry
	entry.Owner = readEntry.Owner
	entry.Id = readEntry.Id
	if readEntry != entry {
		t.Errorf("Expected %v, got %v", entry, readEntry)
	}
}
Ejemplo n.º 3
0
func TestUpdateEntryConcurrent(t *testing.T) {
	origEntry := *kOrigEntry
	var store FakeStore
	newId, err := vsafedb.AddEntry(&store, nil, kKey, &origEntry)
	if err != nil {
		t.Fatalf("Error saving original entry %v", err)
	}
	var origEntryWithEtag vsafe.EntryWithEtag
	if err := vsafedb.EntryByIdWithEtag(
		store, nil, newId, kKey, &origEntryWithEtag); err != nil {
		t.Fatalf("Error reading original entry %v", err)
	}
	update := functional.NewFilterer(changeToAnEntry)
	updateSkipped := functional.NewFilterer(func(ptr interface{}) error {
		entryPtr := ptr.(*vsafe.Entry)
		*entryPtr = *kAnEntry
		return functional.Skipped
	})
	// An update that skips shouldn't throw an error even if etag is wrong
	if err := vsafedb.UpdateEntryWithEtag(
		store,
		kTransaction,
		newId,
		origEntryWithEtag.Etag+1,
		kKey,
		updateSkipped); err != nil {
		t.Fatalf("Error updating store: %v", err)
	}
	if err := vsafedb.UpdateEntryWithEtag(
		store,
		kTransaction,
		newId,
		origEntryWithEtag.Etag+1,
		kKey,
		update); err != vsafedb.ErrConcurrentModification {
		t.Errorf("Expected ErrConcurrentModfication, got %v", err)
	}
	var readEntry vsafe.Entry
	if err := vsafedb.EntryById(store, nil, newId, kKey, &readEntry); err != nil {
		t.Fatalf("Error reading store: %v", err)
	}
	if readEntry != origEntryWithEtag.Entry {
		t.Errorf("Entry should not have been updated")
	}
}
Ejemplo n.º 4
0
func (h *Handler) doPost(w http.ResponseWriter, r *http.Request, id int64) {
	var err error
	session := common.GetUserSession(r)
	if !common.VerifyXsrfToken(r, kSingle) {
		err = common.ErrXsrf
	} else if http_util.HasParam(r.Form, "delete") {
		if isIdValid(id) {
			err = h.Store.RemoveEntry(nil, id, session.User.GetOwner())
		}
	} else if http_util.HasParam(r.Form, "cancel") {
		// Do nothing
	} else {
		var mutation functional.Filterer
		mutation, err = toEntry(r.Form)
		if err == nil {
			if isIdValid(id) {
				tag, _ := strconv.ParseUint(r.Form.Get("etag"), 10, 64)
				err = h.Doer.Do(func(t db.Transaction) error {
					return vsafedb.UpdateEntryWithEtag(
						h.Store, t, id, tag, session.Key(), mutation)
				})
			} else {
				var newId int64
				var entry vsafe.Entry
				mutation.Filter(&entry)
				newId, err = vsafedb.AddEntry(h.Store, nil, session.Key(), &entry)
				if err == nil {
					id = newId
				}
			}
		}
	}
	if err == vsafedb.ErrConcurrentModification {
		err = errors.New("Someone else updated this entry after you started. Click cancel and try again.")
	}
	if err != nil {
		http_util.WriteTemplate(
			w,
			kTemplate,
			newView(
				r.Form,
				isIdValid(id),
				session.Key().Id,
				common.NewXsrfToken(r, kSingle),
				err))
	} else {
		goBack(w, r, id)
	}
}