Added a number of "real" bookmark sync tests; see test_bookmark_syncing.js for information.
authorAtul Varma <varmaa@toolness.com>
Wed, 25 Jun 2008 14:30:53 -0700
changeset 44745 e7e4defa3d6804a9fb95693f410243bec2054502
parent 44744 f6c3e10b97b0a72f27085258634e749e3da91e04
child 44746 9b5c0dee9187f08a27054047ddc2e7d4c0e50222
child 44747 44649eec63a04eb86e6c27a30861d5b4e607af3b
child 44751 e1e0000282fc38df40835ed0b77c4dfaa476e9ac
push idunknown
push userunknown
push dateunknown
Added a number of "real" bookmark sync tests; see test_bookmark_syncing.js for information.
services/sync/tests/unit/bookmark_setup.js
services/sync/tests/unit/test_bookmark_syncing.js
services/sync/tests/unit/test_bookmark_syncing.log.expected
new file mode 100644
--- /dev/null
+++ b/services/sync/tests/unit/bookmark_setup.js
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// This file was originally taken from mozilla-central at:
+// http://hg.mozilla.org/index.cgi/mozilla-central/file/f171c57e016e/browser/components/places/tests/unit/head_bookmarks.js
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Places.
+ *
+ * The Initial Developer of the Original Code is
+ * Google Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Brian Ryner <bryner@brianryner.com>
+ *  Dietrich Ayala <dietrich@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const NS_APP_USER_PROFILE_50_DIR = "ProfD";
+
+function LOG(aMsg) {
+  aMsg = ("*** PLACES TESTS: " + aMsg);
+  Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).
+                                      logStringMessage(aMsg);
+  print(aMsg);
+}
+
+// If there's no location registered for the profile direcotry, register one now.
+var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
+var profileDir = null;
+try {
+  profileDir = dirSvc.get(NS_APP_USER_PROFILE_50_DIR, Ci.nsIFile);
+} catch (e) {}
+if (!profileDir) {
+  // Register our own provider for the profile directory.
+  // It will simply return the current directory.
+  var provider = {
+    getFile: function(prop, persistent) {
+      persistent.value = true;
+      if (prop == NS_APP_USER_PROFILE_50_DIR) {
+        return dirSvc.get("CurProcD", Ci.nsIFile);
+      }
+      throw Cr.NS_ERROR_FAILURE;
+    },
+    QueryInterface: function(iid) {
+      if (iid.equals(Ci.nsIDirectoryServiceProvider) ||
+          iid.equals(Ci.nsISupports)) {
+        return this;
+      }
+      throw Cr.NS_ERROR_NO_INTERFACE;
+    }
+  };
+  dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
+}
+
+var XULAppInfo = {
+  vendor: "Mozilla",
+  name: "PlacesTest",
+  ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
+  version: "1",
+  appBuildID: "2007010101",
+  platformVersion: "",
+  platformBuildID: "2007010101",
+  inSafeMode: false,
+  logConsoleErrors: true,
+  OS: "XPCShell",
+  XPCOMABI: "noarch-spidermonkey",
+
+  QueryInterface: function QueryInterface(iid) {
+    if (iid.equals(Ci.nsIXULAppInfo) ||
+        iid.equals(Ci.nsIXULRuntime) ||
+        iid.equals(Ci.nsISupports))
+      return this;
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  }
+};
+
+var XULAppInfoFactory = {
+  createInstance: function (outer, iid) {
+    if (outer != null)
+      throw Cr.NS_ERROR_NO_AGGREGATION;
+    return XULAppInfo.QueryInterface(iid);
+  }
+};
+
+var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+registrar.registerFactory(Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}"),
+                          "XULAppInfo", "@mozilla.org/xre/app-info;1",
+                          XULAppInfoFactory);
+
+var updateSvc = Cc["@mozilla.org/updates/update-service;1"].
+                getService(Ci.nsISupports);
+
+var iosvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+
+function uri(spec) {
+  return iosvc.newURI(spec, null, null);
+}
+
+function cleanUp() {
+  try {
+    // Delete a previously created sqlite file
+    var file = dirSvc.get('ProfD', Ci.nsIFile);
+    file.append("places.sqlite");
+    if (file.exists())
+      file.remove(false);
+
+    // Delete exported bookmarks html file
+    file = dirSvc.get('ProfD', Ci.nsIFile);
+    file.append("bookmarks.exported.html");
+    if (file.exists())
+      file.remove(false);
+  } catch(ex) { dump("Exception: " + ex); }
+}
+cleanUp();
--- a/services/sync/tests/unit/test_bookmark_syncing.js
+++ b/services/sync/tests/unit/test_bookmark_syncing.js
@@ -1,18 +1,65 @@
 Cu.import("resource://weave/engines/bookmarks.js");
 
+load("bookmark_setup.js");
+
 // ----------------------------------------
 // Test Logic
 // ----------------------------------------
 
+function FakeMicrosummaryService() {
+  return {hasMicrosummary: function() { return false; }};
+}
+
 function run_test() {
   var syncTesting = new SyncTestingInfrastructure();
 
   function freshEngineSync(cb) {
     let engine = new BookmarksEngine();
+    engine._store.__ms = new FakeMicrosummaryService();
     engine.sync(cb);
   };
 
-  syncTesting.runAsyncFunc("initial sync", freshEngineSync);
+  function resetProfile() {
+    // Simulate going to another computer by removing stuff from our
+    // objects.
+    syncTesting.fakeFilesystem.fakeContents = {};
+    bms.removeItem(boogleBm);
+    bms.removeItem(yoogleBm);
+  }
+
+  let bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+    getService(Ci.nsINavBookmarksService);
+
+  cleanUp();
+
+  let boogleBm = bms.insertBookmark(bms.bookmarksMenuFolder,
+                                    uri("http://www.boogle.com"),
+                                    -1,
+                                    "Boogle");
+  bms.setItemGUID(boogleBm, "boogle-bookmark-guid");
+
+  syncTesting.runAsyncFunc("initial sync w/ one bookmark", freshEngineSync);
 
   syncTesting.runAsyncFunc("trivial re-sync", freshEngineSync);
+
+  let yoogleBm = bms.insertBookmark(bms.bookmarksMenuFolder,
+                                    uri("http://www.yoogle.com"),
+                                    -1,
+                                    "Yoogle");
+  bms.setItemGUID(yoogleBm, "yoogle-bookmark-guid");
+
+  syncTesting.runAsyncFunc("add bookmark and re-sync", freshEngineSync);
+
+  bms.moveItem(yoogleBm,
+               bms.bookmarksMenuFolder,
+               0);
+
+  syncTesting.runAsyncFunc("swap bookmark order and re-sync",
+                           freshEngineSync);
+
+  resetProfile();
+
+  syncTesting.runAsyncFunc("re-sync on second computer", freshEngineSync);
+
+  cleanUp();
 }
--- a/services/sync/tests/unit/test_bookmark_syncing.log.expected
+++ b/services/sync/tests/unit/test_bookmark_syncing.log.expected
@@ -1,33 +1,33 @@
 *** test pending
 Testing	INFO	-----------------------------------------
-Testing	INFO	Step 'initial sync' starting.
+Testing	INFO	Step 'initial sync w/ one bookmark' starting.
 Testing	INFO	-----------------------------------------
 Service.BmkEngine	INFO	Beginning sync
 Testing	INFO	HTTP MKCOL on user-data/bookmarks/deltas
 Service.RemoteStore	DEBUG	Downloading status file
 Testing	INFO	HTTP GET from user-data/bookmarks/status.json, returning status 404
 Service.BmkEngine	INFO	Initial upload to server
 Service.JsonFilter	DEBUG	Encoding data as JSON
 Testing	INFO	HTTP PUT to user-data/bookmarks/keys.json with data: {"ring":{},"bulkIV":null}
 Service.Resource	DEBUG	PUT request successful
 Service.JsonFilter	DEBUG	Encoding data as JSON
 Service.CryptoFilter	DEBUG	Encrypting data
 Service.Crypto	DEBUG	NOT encrypting data
-Testing	INFO	HTTP PUT to user-data/bookmarks/snapshot.json with data: {"menu":{"type":"folder"},"toolbar":{"type":"folder"},"unfiled":{"type":"folder"}}
+Testing	INFO	HTTP PUT to user-data/bookmarks/snapshot.json with data: {"boogle-bookmark-guid":{"parentGUID":"menu","index":0,"type":"bookmark","title":"Boogle","URI":"http://www.boogle.com/","tags":[],"keyword":null},"menu":{"type":"folder"},"toolbar":{"type":"folder"},"unfiled":{"type":"folder"}}
 Service.Resource	DEBUG	PUT request successful
 Service.JsonFilter	DEBUG	Encoding data as JSON
-Testing	INFO	HTTP PUT to user-data/bookmarks/status.json with data: {"GUID":"fake-guid-0","formatVersion":2,"snapVersion":0,"maxVersion":0,"snapEncryption":"none","deltasEncryption":"none","itemCount":3}
+Testing	INFO	HTTP PUT to user-data/bookmarks/status.json with data: {"GUID":"fake-guid-0","formatVersion":2,"snapVersion":0,"maxVersion":0,"snapEncryption":"none","deltasEncryption":"none","itemCount":4}
 Service.Resource	DEBUG	PUT request successful
 Service.RemoteStore	INFO	Full upload to server successful
 Service.SnapStore	INFO	Saving snapshot to disk
 Testing	INFO	Opening 'weave/snapshots/bookmarks.json' for writing.
-Testing	INFO	Writing data to local file 'weave/snapshots/bookmarks.json': {"version":0,"GUID":"fake-guid-0","snapshot":{"menu":{"type":"folder"},"toolbar":{"type":"folder"},"unfiled":{"type":"folder"}}}
-Testing	INFO	Step 'initial sync' succeeded.
+Testing	INFO	Writing data to local file 'weave/snapshots/bookmarks.json': {"version":0,"GUID":"fake-guid-0","snapshot":{"boogle-bookmark-guid":{"parentGUID":"menu","index":0,"type":"bookmark","title":"Boogle","URI":"http://www.boogle.com/","tags":[],"keyword":null},"menu":{"type":"folder"},"toolbar":{"type":"folder"},"unfiled":{"type":"folder"}}}
+Testing	INFO	Step 'initial sync w/ one bookmark' succeeded.
 Testing	INFO	-----------------------------------------
 Testing	INFO	Step 'trivial re-sync' starting.
 Testing	INFO	-----------------------------------------
 Testing	INFO	Opening 'weave/snapshots/bookmarks.json' for reading.
 Testing	INFO	Reading from stream.
 Service.SnapStore	INFO	Read saved snapshot from disk
 Service.BmkEngine	INFO	Beginning sync
 Testing	INFO	HTTP MKCOL on user-data/bookmarks/deltas
@@ -37,11 +37,144 @@ Service.Resource	DEBUG	GET request succe
 Service.JsonFilter	DEBUG	Decoding JSON data
 Service.RemoteStore	DEBUG	Downloading status file... done
 Service.BmkEngine	INFO	Local snapshot version: 0
 Service.BmkEngine	INFO	Server maxVersion: 0
 Service.RemoteStore	DEBUG	Using last sync snapshot as server snapshot (snap version == max version)
 Service.RemoteStore	TRACE	Local snapshot version == server maxVersion
 Service.BmkEngine	INFO	Sync complete: no changes needed on client or server
 Testing	INFO	Step 'trivial re-sync' succeeded.
+Testing	INFO	-----------------------------------------
+Testing	INFO	Step 'add bookmark and re-sync' starting.
+Testing	INFO	-----------------------------------------
+Testing	INFO	Opening 'weave/snapshots/bookmarks.json' for reading.
+Testing	INFO	Reading from stream.
+Service.SnapStore	INFO	Read saved snapshot from disk
+Service.BmkEngine	INFO	Beginning sync
+Testing	INFO	HTTP MKCOL on user-data/bookmarks/deltas
+Service.RemoteStore	DEBUG	Downloading status file
+Testing	INFO	HTTP GET from user-data/bookmarks/status.json, returning status 200
+Service.Resource	DEBUG	GET request successful
+Service.JsonFilter	DEBUG	Decoding JSON data
+Service.RemoteStore	DEBUG	Downloading status file... done
+Service.BmkEngine	INFO	Local snapshot version: 0
+Service.BmkEngine	INFO	Server maxVersion: 0
+Service.RemoteStore	DEBUG	Using last sync snapshot as server snapshot (snap version == max version)
+Service.RemoteStore	TRACE	Local snapshot version == server maxVersion
+Service.BmkEngine	INFO	Reconciling client/server updates
+Service.BMSync	DEBUG	Reconciling 1 against 0 commands
+Service.BmkEngine	INFO	Changes for client: 0
+Service.BmkEngine	INFO	Predicted changes for server: 1
+Service.BmkEngine	INFO	Client conflicts: 0
+Service.BmkEngine	INFO	Server conflicts: 0
+Service.BmkEngine	INFO	Actual changes for server: 1
+Service.BmkEngine	DEBUG	Actual changes for server: [{"action":"create","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null}}]
+Service.BmkEngine	INFO	Uploading changes to server
+Service.JsonFilter	DEBUG	Encoding data as JSON
+Service.CryptoFilter	DEBUG	Encrypting data
+Service.Crypto	DEBUG	NOT encrypting data
+Testing	INFO	HTTP PUT to user-data/bookmarks/deltas/1 with data: [{"action":"create","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null}}]
+Service.ResourceSet	DEBUG	PUT request successful
+Service.JsonFilter	DEBUG	Encoding data as JSON
+Testing	INFO	HTTP PUT to user-data/bookmarks/status.json with data: {"GUID":"fake-guid-0","formatVersion":2,"snapVersion":0,"maxVersion":1,"snapEncryption":"none","deltasEncryption":"none","itemCount":5}
+Service.Resource	DEBUG	PUT request successful
+Service.BmkEngine	INFO	Successfully updated deltas and status on server
+Service.SnapStore	INFO	Saving snapshot to disk
+Testing	INFO	Opening 'weave/snapshots/bookmarks.json' for writing.
+Testing	INFO	Writing data to local file 'weave/snapshots/bookmarks.json': {"version":1,"GUID":"fake-guid-0","snapshot":{"boogle-bookmark-guid":{"parentGUID":"menu","index":0,"type":"bookmark","title":"Boogle","URI":"http://www.boogle.com/","tags":[],"keyword":null},"yoogle-bookmark-guid":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null},"menu":{"type":"folder"},"toolbar":{"type":"folder"},"unfiled":{"type":"folder"}}}
+Service.BmkEngine	INFO	Sync complete
+Testing	INFO	Step 'add bookmark and re-sync' succeeded.
+Testing	INFO	-----------------------------------------
+Testing	INFO	Step 'swap bookmark order and re-sync' starting.
+Testing	INFO	-----------------------------------------
+Testing	INFO	Opening 'weave/snapshots/bookmarks.json' for reading.
+Testing	INFO	Reading from stream.
+Service.SnapStore	INFO	Read saved snapshot from disk
+Service.BmkEngine	INFO	Beginning sync
+Testing	INFO	HTTP MKCOL on user-data/bookmarks/deltas
+Service.RemoteStore	DEBUG	Downloading status file
+Testing	INFO	HTTP GET from user-data/bookmarks/status.json, returning status 200
+Service.Resource	DEBUG	GET request successful
+Service.JsonFilter	DEBUG	Decoding JSON data
+Service.RemoteStore	DEBUG	Downloading status file... done
+Service.BmkEngine	INFO	Local snapshot version: 1
+Service.BmkEngine	INFO	Server maxVersion: 1
+Service.RemoteStore	DEBUG	Using last sync snapshot as server snapshot (snap version == max version)
+Service.RemoteStore	TRACE	Local snapshot version == server maxVersion
+Service.BmkEngine	INFO	Reconciling client/server updates
+Service.BMSync	DEBUG	Reconciling 2 against 0 commands
+Service.BmkEngine	INFO	Changes for client: 0
+Service.BmkEngine	INFO	Predicted changes for server: 2
+Service.BmkEngine	INFO	Client conflicts: 0
+Service.BmkEngine	INFO	Server conflicts: 0
+Service.BmkEngine	INFO	Actual changes for server: 2
+Service.BmkEngine	DEBUG	Actual changes for server: [{"action":"edit","GUID":"boogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"index":1,"type":"bookmark"}},{"action":"edit","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"index":0,"type":"bookmark"}}]
+Service.BmkEngine	INFO	Uploading changes to server
+Service.JsonFilter	DEBUG	Encoding data as JSON
+Service.CryptoFilter	DEBUG	Encrypting data
+Service.Crypto	DEBUG	NOT encrypting data
+Testing	INFO	HTTP PUT to user-data/bookmarks/deltas/2 with data: [{"action":"edit","GUID":"boogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"index":1,"type":"bookmark"}},{"action":"edit","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"index":0,"type":"bookmark"}}]
+Service.ResourceSet	DEBUG	PUT request successful
+Service.JsonFilter	DEBUG	Encoding data as JSON
+Testing	INFO	HTTP PUT to user-data/bookmarks/status.json with data: {"GUID":"fake-guid-0","formatVersion":2,"snapVersion":0,"maxVersion":2,"snapEncryption":"none","deltasEncryption":"none","itemCount":5}
+Service.Resource	DEBUG	PUT request successful
+Service.BmkEngine	INFO	Successfully updated deltas and status on server
+Service.SnapStore	INFO	Saving snapshot to disk
+Testing	INFO	Opening 'weave/snapshots/bookmarks.json' for writing.
+Testing	INFO	Writing data to local file 'weave/snapshots/bookmarks.json': {"version":2,"GUID":"fake-guid-0","snapshot":{"yoogle-bookmark-guid":{"parentGUID":"menu","index":0,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null},"boogle-bookmark-guid":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Boogle","URI":"http://www.boogle.com/","tags":[],"keyword":null},"menu":{"type":"folder"},"toolbar":{"type":"folder"},"unfiled":{"type":"folder"}}}
+Service.BmkEngine	INFO	Sync complete
+Testing	INFO	Step 'swap bookmark order and re-sync' succeeded.
+Testing	INFO	-----------------------------------------
+Testing	INFO	Step 're-sync on second computer' starting.
+Testing	INFO	-----------------------------------------
+Service.BmkEngine	INFO	Beginning sync
+Testing	INFO	HTTP MKCOL on user-data/bookmarks/deltas
+Service.RemoteStore	DEBUG	Downloading status file
+Testing	INFO	HTTP GET from user-data/bookmarks/status.json, returning status 200
+Service.Resource	DEBUG	GET request successful
+Service.JsonFilter	DEBUG	Decoding JSON data
+Service.RemoteStore	DEBUG	Downloading status file... done
+Service.BmkEngine	DEBUG	Remote/local sync GUIDs do not match.  Forcing initial sync.
+Service.BmkEngine	INFO	Local snapshot version: -1
+Service.BmkEngine	INFO	Server maxVersion: 2
+Service.RemoteStore	TRACE	Getting latest from snap --> scratch
+Service.RemoteStore	INFO	Downloading all server data from scratch
+Testing	INFO	HTTP GET from user-data/bookmarks/snapshot.json, returning status 200
+Service.Resource	DEBUG	GET request successful
+Service.CryptoFilter	DEBUG	Decrypting data
+Service.Crypto	DEBUG	NOT decrypting data
+Service.JsonFilter	DEBUG	Decoding JSON data
+Testing	INFO	HTTP GET from user-data/bookmarks/deltas/1, returning status 200
+Service.ResourceSet	DEBUG	GET request successful
+Service.CryptoFilter	DEBUG	Decrypting data
+Service.Crypto	DEBUG	NOT decrypting data
+Service.JsonFilter	DEBUG	Decoding JSON data
+Service.SnapStore	TRACE	Processing command: {"action":"create","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null}}
+Testing	INFO	HTTP GET from user-data/bookmarks/deltas/2, returning status 200
+Service.ResourceSet	DEBUG	GET request successful
+Service.CryptoFilter	DEBUG	Decrypting data
+Service.Crypto	DEBUG	NOT decrypting data
+Service.JsonFilter	DEBUG	Decoding JSON data
+Service.SnapStore	TRACE	Processing command: {"action":"edit","GUID":"boogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"index":1,"type":"bookmark"}}
+Service.SnapStore	TRACE	Processing command: {"action":"edit","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"index":0,"type":"bookmark"}}
+Service.BmkEngine	INFO	Reconciling client/server updates
+Service.BMSync	DEBUG	Reconciling 3 against 5 commands
+Service.BmkEngine	INFO	Changes for client: 2
+Service.BmkEngine	INFO	Predicted changes for server: 0
+Service.BmkEngine	INFO	Client conflicts: 0
+Service.BmkEngine	INFO	Server conflicts: 0
+Service.BmkEngine	INFO	Applying changes locally
+Service.SnapStore	TRACE	Processing command: {"action":"create","GUID":"boogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Boogle","URI":"http://www.boogle.com/","tags":[],"keyword":null}}
+Service.SnapStore	TRACE	Processing command: {"action":"create","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"parentGUID":"menu","index":0,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null}}
+Service.BStore	TRACE	Processing command: {"action":"create","GUID":"boogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Boogle","URI":"http://www.boogle.com/","tags":[],"keyword":null}}
+Service.BStore	DEBUG	 -> creating bookmark "Boogle"
+Service.BStore	TRACE	Processing command: {"action":"create","GUID":"yoogle-bookmark-guid","depth":1,"parents":["menu"],"data":{"parentGUID":"menu","index":0,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null}}
+Service.BStore	DEBUG	 -> creating bookmark "Yoogle"
+Service.SnapStore	INFO	Saving snapshot to disk
+Testing	INFO	Opening 'weave/snapshots/bookmarks.json' for writing.
+Testing	INFO	Writing data to local file 'weave/snapshots/bookmarks.json': {"version":2,"GUID":"fake-guid-0","snapshot":{"menu":{"type":"folder"},"toolbar":{"type":"folder"},"unfiled":{"type":"folder"},"boogle-bookmark-guid":{"parentGUID":"menu","index":1,"type":"bookmark","title":"Boogle","URI":"http://www.boogle.com/","tags":[],"keyword":null},"yoogle-bookmark-guid":{"parentGUID":"menu","index":0,"type":"bookmark","title":"Yoogle","URI":"http://www.yoogle.com/","tags":[],"keyword":null}}}
+Service.BmkEngine	INFO	Actual changes for server: 0
+Service.BmkEngine	DEBUG	Actual changes for server: []
+Service.BmkEngine	INFO	Sync complete
+Testing	INFO	Step 're-sync on second computer' succeeded.
 *** test finished
 *** exiting
 *** PASS ***