Esempio 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")
	}
}
Esempio 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)
	}
}
Esempio 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")
	}
}
Esempio n. 4
0
func (h *Handler) doGet(w http.ResponseWriter, r *http.Request, id int64) {
	session := common.GetUserSession(r)
	if isIdValid(id) {
		var entryWithEtag vsafe.EntryWithEtag
		err := vsafedb.EntryByIdWithEtag(
			h.Store, nil, id, session.Key(), &entryWithEtag)
		if err == vsafedb.ErrNoSuchId {
			fmt.Fprintln(w, "No entry found.")
			return
		}
		if err != nil {
			http_util.ReportError(w, "Error reading database.", err)
			return
		}
		http_util.WriteTemplate(
			w,
			kTemplate,
			newView(
				fromEntry(&entryWithEtag.Entry, entryWithEtag.Etag),
				true,
				session.Key().Id,
				common.NewXsrfToken(r, kSingle),
				nil))
	} else {
		initValues := make(url.Values)
		initValues.Set("url", "http://")
		// Because this page is always POST, the presence of etag signals that
		// we are editing an entry, not fetching for the first time.
		// The value of etag in this context does not matter since we are editing
		// a new entry.
		initValues.Set("etag", "new")
		http_util.WriteTemplate(
			w,
			kTemplate,
			newView(
				initValues,
				false,
				session.Key().Id,
				common.NewXsrfToken(r, kSingle),
				nil))
	}
}