@@ -56,7 +56,7 @@ func TestJournalExclWrite(t *testing.T) {
 }
 
 // bob creates a conflicting file while running the journal.
-func TestJournalCRSimple(t *testing.T) {
+func TestJournalCrSimple(t *testing.T) {
 	test(t, journal(),
 		users("alice", "bob"),
 		as(alice,
// Copyright 2016 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

// These tests all do one conflict-free operation while a user is unstaged.

package test

import (
	"testing"
	"time"
)

// bob creates a file while running the journal.
func TestJournalSimple(t *testing.T) {
	test(t, journal(),
		users("alice", "bob"),
		as(alice,
			mkdir("a"),
		),
		as(bob,
			enableJournal(),
			mkfile("a/b", "hello"),
			// Check the data -- this should read from the journal if
			// it hasn't flushed yet.
			lsdir("a/", m{"b$": "FILE"}),
			read("a/b", "hello"),
			flushJournal(),
		),
		as(alice,
			lsdir("a/", m{"b$": "FILE"}),
			read("a/b", "hello"),
		),
	)
}

// bob exclusively creates a file while running the journal.  For now
// this is treated like a normal file create.
func TestJournalExclWrite(t *testing.T) {
	test(t, journal(),
		users("alice", "bob"),
		as(alice,
			mkdir("a"),
		),
		as(bob,
			enableJournal(),
			mkfile("a/c", "hello"),
			mkfileexcl("a/b"),
			lsdir("a/", m{"b$": "FILE", "c$": "FILE"}),
			flushJournal(),
		),
		as(alice,
			lsdir("a/", m{"b$": "FILE", "c$": "FILE"}),
		),
	)
}

// bob creates a conflicting file while running the journal.
func TestJournalCRSimple(t *testing.T) {
	test(t, journal(),
		users("alice", "bob"),
		as(alice,
			mkdir("a"),
		),
		as(bob,
			enableJournal(),
			pauseJournal(),
			mkfile("a/b", "uh oh"),
			// Don't flush yet.
		),
		as(alice,
			mkfile("a/b", "hello"),
		),
		as(bob, noSync(),
			resumeJournal(),
			// This should kick off conflict resolution.
			flushJournal(),
		),
		as(bob,
			lsdir("a/", m{"b$": "FILE", crnameEsc("b", bob): "FILE"}),
			read("a/b", "hello"),
			read(crname("a/b", bob), "uh oh"),
		),
		as(alice,
			lsdir("a/", m{"b$": "FILE", crnameEsc("b", bob): "FILE"}),
			read("a/b", "hello"),
			read(crname("a/b", bob), "uh oh"),
		),
	)
}

// bob writes a multi-block file that conflicts with a file created by
// alice when journaling is on.
func TestJournalCrConflictUnmergedWriteMultiblockFile(t *testing.T) {
	test(t, journal(), blockSize(20),
		users("alice", "bob"),
		as(alice,
			mkdir("a"),
		),
		as(bob,
			enableJournal(),
			disableUpdates(),
		),
		as(alice,
			write("a/b", "hello"),
		),
		as(bob, noSync(),
			write("a/b", ntimesString(15, "0123456789")),
			flushJournal(),
			reenableUpdates(),
		),
		as(bob,
			lsdir("a/", m{"b$": "FILE", crnameEsc("b", bob): "FILE"}),
			read("a/b", "hello"),
			read(crname("a/b", bob), ntimesString(15, "0123456789")),
		),
		as(alice,
			lsdir("a/", m{"b$": "FILE", crnameEsc("b", bob): "FILE"}),
			read("a/b", "hello"),
			read(crname("a/b", bob), ntimesString(15, "0123456789")),
		),
	)
}

// Check that simple quota reclamation works when journaling is enabled.
func TestJournalQRSimple(t *testing.T) {
	test(t, journal(),
		users("alice"),
		as(alice,
			mkfile("a", "hello"),
			addTime(1*time.Minute),
			enableJournal(),
			mkfile("b", "hello2"),
			rm("b"),
			addTime(2*time.Minute),
			flushJournal(),
			pauseJournal(),
			addTime(2*time.Minute),
			mkfile("c", "hello3"),
			mkfile("d", "hello4"),
			addTime(2*time.Minute),
			forceQuotaReclamation(),
			resumeJournal(),
		),
	)
}

// bob rekeys for charlie while journaling, but gets converted to a
// conflict branch so the rekey fails.
func TestJournalRekeyErrorAfterConflict(t *testing.T) {
	test(t, journal(),
		users("alice", "bob", "charlie"),
		inPrivateTlf("alice,bob,charlie@twitter"),
		as(alice,
			mkfile("a", "hello"),
		),
		as(bob,
			enableJournal(),
			mkfile("b", "hello2"),
			read("a", "hello"),
			read("b", "hello2"),
			disableUpdates(),
		),
		as(alice,
			// Cause conflict with bob.
			mkfile("c", "hello3"),
		),
		as(bob, noSync(),
			pauseJournal(),
			mkfile("d", "hello4"),
		),
		as(bob, noSync(), stallDelegateOnMDPut()),
		addNewAssertion("charlie", "charlie@twitter"),
		parallel(
			as(bob, noSync(),
				expectError(rekey(),
					"Conflict during a rekey, not retrying"),
			),
			// Don't let the journal flush until the rekey is about to
			// hit it, so that bob is not staged yet.
			as(bob, noSync(),
				waitForStalledMDPut(),
				resumeJournal(),
				undoStallOnMDPut(),
				reenableUpdates(),
				flushJournal(),
			),
		),
		as(charlie,
			expectError(initRoot(), "MDServer Unauthorized"),
		),
		as(alice,
			rekey(),
		),
		inPrivateTlfNonCanonical("alice,bob,charlie@twitter",
			"alice,bob,charlie"),
		as(bob, // ensure bob syncs his resolution
			read("a", "hello"),
			read("b", "hello2"),
			read("c", "hello3"),
			read("d", "hello4"),
		),
		as(charlie,
			read("a", "hello"),
			read("b", "hello2"),
			read("c", "hello3"),
			read("d", "hello4"),
		),
	)
}

Do you know why this test didn't catch this?