{"action":"created","comment":{"url":"https://api.github.com/repos/couchbase/sync_gateway/pulls/comments/153935195","pull_request_review_id":80020845,"id":153935195,"diff_hunk":"@@ -698,6 +698,196 @@ func TestMigrateWithExternalRevisions(t *testing.T) {\n \tassert.Equals(t, len(doc.Meta.RevTree.BodyMap), 2)\n }\n \n+// Write a doc via SDK with an expiry value.  Verify that expiry is preserved when doc is imported via DCP feed\n+func TestXattrFeedBasedImportPreservesExpiry(t *testing.T) {\n+\n+\tSkipImportTestsIfNotEnabled(t)\n+\n+\trt := RestTester{\n+\t\tSyncFn: `function(doc, oldDoc) { channel(doc.channels) }`,\n+\t\tDatabaseConfig: &DbConfig{\n+\t\t\tImportDocs: \"continuous\",\n+\t\t},\n+\t}\n+\tdefer rt.Close()\n+\tbucket := rt.Bucket()\n+\n+\trt.SendAdminRequest(\"PUT\", \"/_logging\", `{\"Import+\":true, \"CRUD+\":true}`)\n+\n+\t// 1. Create docs via the SDK with expiry set\n+\tmobileKey := \"TestXattrImportPreservesExpiry\"\n+\tmobileBody := make(map[string]interface{})\n+\tmobileBody[\"type\"] = \"mobile\"\n+\tmobileBody[\"channels\"] = \"ABC\"\n+\n+\t// Write directly to bucket with an expiry\n+\texpiryUnixEpoch := time.Now().Add(time.Second * 30).Unix()\n+\t_, err := bucket.Add(mobileKey, uint32(expiryUnixEpoch), mobileBody)\n+\tassertNoError(t, err, \"Error writing SDK doc\")\n+\n+\t// Wait until the change appears on the changes feed to ensure that it's been imported by this point\n+\tchanges, err := rt.WaitForChanges(1, \"/db/_changes\", \"\", true)\n+\tassertNoError(t, err, \"Error waiting for changes\")\n+\n+\tlog.Printf(\"changes: %+v\", changes)\n+\tchangeEntry := changes.Results[0]\n+\tassert.Equals(t, changeEntry.ID, mobileKey)\n+\n+\t// Double-check to make sure that it's been imported by checking the Sync Metadata in the xattr\n+\tassertXattrSyncMetaRevGeneration(t, bucket, mobileKey, 1)\n+\n+\t// Verify the expiry has been preserved after the import\n+\tgocbBucket := bucket.(*base.CouchbaseBucketGoCB)\n+\texpiry, err := gocbBucket.GetExpiry(mobileKey)\n+\tassertNoError(t, err, \"Error calling GetExpiry()\")\n+\tassert.True(t, expiry == uint32(expiryUnixEpoch))\n+\n+}\n+\n+// Test migration of a 1.5 doc that has an expiry value.\n+func TestFeedBasedMigrateWithExpiry(t *testing.T) {\n+\n+\tSkipImportTestsIfNotEnabled(t)\n+\n+\trt := RestTester{\n+\t\tSyncFn: `function(doc, oldDoc) { channel(doc.channels) }`,\n+\t\tDatabaseConfig: &DbConfig{\n+\t\t\tImportDocs: \"continuous\",\n+\t\t},\n+\t}\n+\tdefer rt.Close()\n+\tbucket := rt.Bucket()\n+\n+\trt.SendAdminRequest(\"PUT\", \"/_logging\", `{\"Import+\":true, \"CRUD+\":true}`)\n+\n+\t// Write doc in SG format directly to the bucket\n+\tkey := \"TestFeedBasedMigrateWithExpiry\"\n+\n+\t// Create via the SDK with sync metadata intact\n+\texpirySeconds := time.Second * 30\n+\tsyncMetaExpiry := time.Now().Add(expirySeconds)\n+\tbodyString := expiringRawDocWithSyncMeta(syncMetaExpiry)\n+\t_, err := bucket.Add(key, 0, []byte(bodyString))","path":"rest/import_test.go","position":73,"original_position":73,"commit_id":"f888afaf02c2dbe0cf3a9cfec7216f46f5e13036","original_commit_id":"f1d44af8f099f33fda9ff9c59f33fd7011da315d","user":{"login":"adamcfraser","id":8866453,"avatar_url":"https://avatars3.githubusercontent.com/u/8866453?v=4","gravatar_id":"","url":"https://api.github.com/users/adamcfraser","html_url":"https://github.com/adamcfraser","followers_url":"https://api.github.com/users/adamcfraser/followers","following_url":"https://api.github.com/users/adamcfraser/following{/other_user}","gists_url":"https://api.github.com/users/adamcfraser/gists{/gist_id}","starred_url":"https://api.github.com/users/adamcfraser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamcfraser/subscriptions","organizations_url":"https://api.github.com/users/adamcfraser/orgs","repos_url":"https://api.github.com/users/adamcfraser/repos","events_url":"https://api.github.com/users/adamcfraser/events{/privacy}","received_events_url":"https://api.github.com/users/adamcfraser/received_events","type":"User","site_admin":false},"body":"The expiry in the _sync metadata shouldn't be used as the source of truth - it's really just a lightweight way to retrieve expiry in case it's queried via the SG REST API.  In fact we could review whether it could be removed altogether now that we have GetMeta support.\r\n\r\nThe CBS expiry on the doc should always be used when working w/ expiry, even for migration.","created_at":"2017-11-29T22:31:24Z","updated_at":"2017-11-29T22:31:24Z","html_url":"https://github.com/couchbase/sync_gateway/pull/3109#discussion_r153935195","pull_request_url":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/couchbase/sync_gateway/pulls/comments/153935195"},"html":{"href":"https://github.com/couchbase/sync_gateway/pull/3109#discussion_r153935195"},"pull_request":{"href":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109"}},"in_reply_to_id":153916032},"pull_request":{"url":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109","id":155450901,"html_url":"https://github.com/couchbase/sync_gateway/pull/3109","diff_url":"https://github.com/couchbase/sync_gateway/pull/3109.diff","patch_url":"https://github.com/couchbase/sync_gateway/pull/3109.patch","issue_url":"https://api.github.com/repos/couchbase/sync_gateway/issues/3109","number":3109,"state":"open","locked":false,"title":"Feed based import and migration","user":{"login":"tleyden","id":296876,"avatar_url":"https://avatars1.githubusercontent.com/u/296876?v=4","gravatar_id":"","url":"https://api.github.com/users/tleyden","html_url":"https://github.com/tleyden","followers_url":"https://api.github.com/users/tleyden/followers","following_url":"https://api.github.com/users/tleyden/following{/other_user}","gists_url":"https://api.github.com/users/tleyden/gists{/gist_id}","starred_url":"https://api.github.com/users/tleyden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tleyden/subscriptions","organizations_url":"https://api.github.com/users/tleyden/orgs","repos_url":"https://api.github.com/users/tleyden/repos","events_url":"https://api.github.com/users/tleyden/events{/privacy}","received_events_url":"https://api.github.com/users/tleyden/received_events","type":"User","site_admin":false},"body":"https://github.com/couchbase/sync_gateway/issues/3054\r\n\r\nThis passes the following tests in integration mode:\r\n\r\n- TestXattrFeedBasedImportPreservesExpiry\r\n- TestFeedBasedMigrateWithExpiry\r\n\r\nand there are associated SG Accel changes here:\r\n\r\nhttps://github.com/couchbaselabs/sync-gateway-accel/tree/feature/issue_3054_preserve_expiry\r\n\r\nMeant for preliminary review before the on-demand import + migration changes","created_at":"2017-11-29T20:59:59Z","updated_at":"2017-11-29T22:31:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"84966ea0f758cc4a178b6ef1590308c52b3dbf8f","assignee":{"login":"adamcfraser","id":8866453,"avatar_url":"https://avatars3.githubusercontent.com/u/8866453?v=4","gravatar_id":"","url":"https://api.github.com/users/adamcfraser","html_url":"https://github.com/adamcfraser","followers_url":"https://api.github.com/users/adamcfraser/followers","following_url":"https://api.github.com/users/adamcfraser/following{/other_user}","gists_url":"https://api.github.com/users/adamcfraser/gists{/gist_id}","starred_url":"https://api.github.com/users/adamcfraser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamcfraser/subscriptions","organizations_url":"https://api.github.com/users/adamcfraser/orgs","repos_url":"https://api.github.com/users/adamcfraser/repos","events_url":"https://api.github.com/users/adamcfraser/events{/privacy}","received_events_url":"https://api.github.com/users/adamcfraser/received_events","type":"User","site_admin":false},"assignees":[{"login":"adamcfraser","id":8866453,"avatar_url":"https://avatars3.githubusercontent.com/u/8866453?v=4","gravatar_id":"","url":"https://api.github.com/users/adamcfraser","html_url":"https://github.com/adamcfraser","followers_url":"https://api.github.com/users/adamcfraser/followers","following_url":"https://api.github.com/users/adamcfraser/following{/other_user}","gists_url":"https://api.github.com/users/adamcfraser/gists{/gist_id}","starred_url":"https://api.github.com/users/adamcfraser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamcfraser/subscriptions","organizations_url":"https://api.github.com/users/adamcfraser/orgs","repos_url":"https://api.github.com/users/adamcfraser/repos","events_url":"https://api.github.com/users/adamcfraser/events{/privacy}","received_events_url":"https://api.github.com/users/adamcfraser/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109/commits","review_comments_url":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109/comments","review_comment_url":"https://api.github.com/repos/couchbase/sync_gateway/pulls/comments{/number}","comments_url":"https://api.github.com/repos/couchbase/sync_gateway/issues/3109/comments","statuses_url":"https://api.github.com/repos/couchbase/sync_gateway/statuses/f888afaf02c2dbe0cf3a9cfec7216f46f5e13036","head":{"label":"couchbase:feature/issue_3054_preserve_expiry","ref":"feature/issue_3054_preserve_expiry","sha":"f888afaf02c2dbe0cf3a9cfec7216f46f5e13036","user":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"repo":{"id":6082996,"name":"sync_gateway","full_name":"couchbase/sync_gateway","owner":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/couchbase/sync_gateway","description":"Connects Couchbase Lite to Couchbase Server","fork":false,"url":"https://api.github.com/repos/couchbase/sync_gateway","forks_url":"https://api.github.com/repos/couchbase/sync_gateway/forks","keys_url":"https://api.github.com/repos/couchbase/sync_gateway/keys{/key_id}","collaborators_url":"https://api.github.com/repos/couchbase/sync_gateway/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/couchbase/sync_gateway/teams","hooks_url":"https://api.github.com/repos/couchbase/sync_gateway/hooks","issue_events_url":"https://api.github.com/repos/couchbase/sync_gateway/issues/events{/number}","events_url":"https://api.github.com/repos/couchbase/sync_gateway/events","assignees_url":"https://api.github.com/repos/couchbase/sync_gateway/assignees{/user}","branches_url":"https://api.github.com/repos/couchbase/sync_gateway/branches{/branch}","tags_url":"https://api.github.com/repos/couchbase/sync_gateway/tags","blobs_url":"https://api.github.com/repos/couchbase/sync_gateway/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/couchbase/sync_gateway/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/couchbase/sync_gateway/git/refs{/sha}","trees_url":"https://api.github.com/repos/couchbase/sync_gateway/git/trees{/sha}","statuses_url":"https://api.github.com/repos/couchbase/sync_gateway/statuses/{sha}","languages_url":"https://api.github.com/repos/couchbase/sync_gateway/languages","stargazers_url":"https://api.github.com/repos/couchbase/sync_gateway/stargazers","contributors_url":"https://api.github.com/repos/couchbase/sync_gateway/contributors","subscribers_url":"https://api.github.com/repos/couchbase/sync_gateway/subscribers","subscription_url":"https://api.github.com/repos/couchbase/sync_gateway/subscription","commits_url":"https://api.github.com/repos/couchbase/sync_gateway/commits{/sha}","git_commits_url":"https://api.github.com/repos/couchbase/sync_gateway/git/commits{/sha}","comments_url":"https://api.github.com/repos/couchbase/sync_gateway/comments{/number}","issue_comment_url":"https://api.github.com/repos/couchbase/sync_gateway/issues/comments{/number}","contents_url":"https://api.github.com/repos/couchbase/sync_gateway/contents/{+path}","compare_url":"https://api.github.com/repos/couchbase/sync_gateway/compare/{base}...{head}","merges_url":"https://api.github.com/repos/couchbase/sync_gateway/merges","archive_url":"https://api.github.com/repos/couchbase/sync_gateway/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/couchbase/sync_gateway/downloads","issues_url":"https://api.github.com/repos/couchbase/sync_gateway/issues{/number}","pulls_url":"https://api.github.com/repos/couchbase/sync_gateway/pulls{/number}","milestones_url":"https://api.github.com/repos/couchbase/sync_gateway/milestones{/number}","notifications_url":"https://api.github.com/repos/couchbase/sync_gateway/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/couchbase/sync_gateway/labels{/name}","releases_url":"https://api.github.com/repos/couchbase/sync_gateway/releases{/id}","deployments_url":"https://api.github.com/repos/couchbase/sync_gateway/deployments","created_at":"2012-10-04T22:25:43Z","updated_at":"2017-11-28T01:54:47Z","pushed_at":"2017-11-29T22:05:50Z","git_url":"git://github.com/couchbase/sync_gateway.git","ssh_url":"git@github.com:couchbase/sync_gateway.git","clone_url":"https://github.com/couchbase/sync_gateway.git","svn_url":"https://github.com/couchbase/sync_gateway","homepage":"","size":20362,"stargazers_count":355,"watchers_count":355,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":109,"mirror_url":null,"archived":false,"open_issues_count":407,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":109,"open_issues":407,"watchers":355,"default_branch":"master"}},"base":{"label":"couchbase:master","ref":"master","sha":"821b4fdbdc7a243f1f5a23a019538f6a4c193571","user":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"repo":{"id":6082996,"name":"sync_gateway","full_name":"couchbase/sync_gateway","owner":{"login":"couchbase","id":605755,"avatar_url":"https://avatars1.githubusercontent.com/u/605755?v=4","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/couchbase/sync_gateway","description":"Connects Couchbase Lite to Couchbase Server","fork":false,"url":"https://api.github.com/repos/couchbase/sync_gateway","forks_url":"https://api.github.com/repos/couchbase/sync_gateway/forks","keys_url":"https://api.github.com/repos/couchbase/sync_gateway/keys{/key_id}","collaborators_url":"https://api.github.com/repos/couchbase/sync_gateway/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/couchbase/sync_gateway/teams","hooks_url":"https://api.github.com/repos/couchbase/sync_gateway/hooks","issue_events_url":"https://api.github.com/repos/couchbase/sync_gateway/issues/events{/number}","events_url":"https://api.github.com/repos/couchbase/sync_gateway/events","assignees_url":"https://api.github.com/repos/couchbase/sync_gateway/assignees{/user}","branches_url":"https://api.github.com/repos/couchbase/sync_gateway/branches{/branch}","tags_url":"https://api.github.com/repos/couchbase/sync_gateway/tags","blobs_url":"https://api.github.com/repos/couchbase/sync_gateway/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/couchbase/sync_gateway/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/couchbase/sync_gateway/git/refs{/sha}","trees_url":"https://api.github.com/repos/couchbase/sync_gateway/git/trees{/sha}","statuses_url":"https://api.github.com/repos/couchbase/sync_gateway/statuses/{sha}","languages_url":"https://api.github.com/repos/couchbase/sync_gateway/languages","stargazers_url":"https://api.github.com/repos/couchbase/sync_gateway/stargazers","contributors_url":"https://api.github.com/repos/couchbase/sync_gateway/contributors","subscribers_url":"https://api.github.com/repos/couchbase/sync_gateway/subscribers","subscription_url":"https://api.github.com/repos/couchbase/sync_gateway/subscription","commits_url":"https://api.github.com/repos/couchbase/sync_gateway/commits{/sha}","git_commits_url":"https://api.github.com/repos/couchbase/sync_gateway/git/commits{/sha}","comments_url":"https://api.github.com/repos/couchbase/sync_gateway/comments{/number}","issue_comment_url":"https://api.github.com/repos/couchbase/sync_gateway/issues/comments{/number}","contents_url":"https://api.github.com/repos/couchbase/sync_gateway/contents/{+path}","compare_url":"https://api.github.com/repos/couchbase/sync_gateway/compare/{base}...{head}","merges_url":"https://api.github.com/repos/couchbase/sync_gateway/merges","archive_url":"https://api.github.com/repos/couchbase/sync_gateway/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/couchbase/sync_gateway/downloads","issues_url":"https://api.github.com/repos/couchbase/sync_gateway/issues{/number}","pulls_url":"https://api.github.com/repos/couchbase/sync_gateway/pulls{/number}","milestones_url":"https://api.github.com/repos/couchbase/sync_gateway/milestones{/number}","notifications_url":"https://api.github.com/repos/couchbase/sync_gateway/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/couchbase/sync_gateway/labels{/name}","releases_url":"https://api.github.com/repos/couchbase/sync_gateway/releases{/id}","deployments_url":"https://api.github.com/repos/couchbase/sync_gateway/deployments","created_at":"2012-10-04T22:25:43Z","updated_at":"2017-11-28T01:54:47Z","pushed_at":"2017-11-29T22:05:50Z","git_url":"git://github.com/couchbase/sync_gateway.git","ssh_url":"git@github.com:couchbase/sync_gateway.git","clone_url":"https://github.com/couchbase/sync_gateway.git","svn_url":"https://github.com/couchbase/sync_gateway","homepage":"","size":20362,"stargazers_count":355,"watchers_count":355,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":109,"mirror_url":null,"archived":false,"open_issues_count":407,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":109,"open_issues":407,"watchers":355,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109"},"html":{"href":"https://github.com/couchbase/sync_gateway/pull/3109"},"issue":{"href":"https://api.github.com/repos/couchbase/sync_gateway/issues/3109"},"comments":{"href":"https://api.github.com/repos/couchbase/sync_gateway/issues/3109/comments"},"review_comments":{"href":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109/comments"},"review_comment":{"href":"https://api.github.com/repos/couchbase/sync_gateway/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/couchbase/sync_gateway/pulls/3109/commits"},"statuses":{"href":"https://api.github.com/repos/couchbase/sync_gateway/statuses/f888afaf02c2dbe0cf3a9cfec7216f46f5e13036"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"adamcfraser"}}