veyron/runtimes/google/vsync: Parse and track transactions received
from the watch stream and the initiator log replay stream.

Change-Id: Ib9d6fa34fd282f1d1d3d93326da1f77461a85bdb
diff --git a/runtimes/google/vsync/watcher_test.go b/runtimes/google/vsync/watcher_test.go
index 7804409..90c1629 100644
--- a/runtimes/google/vsync/watcher_test.go
+++ b/runtimes/google/vsync/watcher_test.go
@@ -6,6 +6,7 @@
 	"bytes"
 	"fmt"
 	"os"
+	"reflect"
 	"testing"
 	"time"
 
@@ -362,6 +363,49 @@
 		}
 	}
 
+	// Verify transaction state for the first transaction.
+	node, err := s.dag.getNode(oidRoot, heads[0])
+	if err != nil {
+		t.Errorf("cannot find dag node for object %d %v: %s", oidRoot, heads[0], err)
+	}
+	if node.TxID == NoTxID {
+		t.Errorf("expecting non nil txid for object %d:%v", oidRoot, heads[0])
+	}
+	txMap, err := s.dag.getTransaction(node.TxID)
+	if err != nil {
+		t.Errorf("cannot find transaction for id %v: %s", node.TxID, err)
+	}
+	expTxMap := dagTxMap{
+		oidRoot: heads[0],
+		oidA:    storage.Version(0x57e9d1860d1d68d8),
+		oidB:    heads[2],
+	}
+	if !reflect.DeepEqual(txMap, expTxMap) {
+		t.Errorf("Data mismatch for txid %v txmap %v instead of %v",
+			node.TxID, txMap, expTxMap)
+	}
+
+	// Verify transaction state for the second transaction.
+	node, err = s.dag.getNode(oidA, heads[1])
+	if err != nil {
+		t.Errorf("cannot find dag node for object %d %v: %s", oidA, heads[1], err)
+	}
+	if node.TxID == NoTxID {
+		t.Errorf("expecting non nil txid for object %d:%v", oidA, heads[1])
+	}
+	txMap, err = s.dag.getTransaction(node.TxID)
+	if err != nil {
+		t.Errorf("cannot find transaction for id %v: %s", node.TxID, err)
+	}
+	expTxMap = dagTxMap{
+		oidA: heads[1],
+		oidC: heads[3],
+	}
+	if !reflect.DeepEqual(txMap, expTxMap) {
+		t.Errorf("Data mismatch for txid %v txmap %v instead of %v",
+			node.TxID, txMap, expTxMap)
+	}
+
 	expResmark := []byte{2, 0, 0, 0, 0, 0, 0, 0}
 
 	if bytes.Compare(s.devtab.head.Resmark, expResmark) != 0 {