{"action":"created","comment":{"url":"https://api.github.com/repos/juju/juju/pulls/comments/89433639","pull_request_review_id":9977153,"id":89433639,"diff_hunk":"@@ -0,0 +1,242 @@\n+// Copyright 2016 Canonical Ltd.\n+// Licensed under the AGPLv3, see LICENCE file for details.\n+\n+package remoterelations_test\n+\n+import (\n+\t\"reflect\"\n+\t\"time\"\n+\n+\tjujutesting \"github.com/juju/testing\"\n+\tjc \"github.com/juju/testing/checkers\"\n+\tgc \"gopkg.in/check.v1\"\n+\n+\t\"github.com/juju/juju/apiserver/common\"\n+\t\"github.com/juju/juju/apiserver/params\"\n+\tapiservertesting \"github.com/juju/juju/apiserver/testing\"\n+\tcoretesting \"github.com/juju/juju/testing\"\n+\t\"github.com/juju/juju/watcher\"\n+\t\"github.com/juju/juju/worker\"\n+\t\"github.com/juju/juju/worker/remoterelations\"\n+\t\"github.com/juju/juju/worker/workertest\"\n+)\n+\n+var _ = gc.Suite(&remoteRelationsSuite{})\n+\n+type remoteRelationsSuite struct {\n+\tcoretesting.BaseSuite\n+\n+\tresources  *common.Resources\n+\tauthorizer *apiservertesting.FakeAuthorizer\n+\tfacade     *mockFacade\n+\tconfig     remoterelations.Config\n+\tstub       *jujutesting.Stub\n+}\n+\n+func (s *remoteRelationsSuite) SetUpTest(c *gc.C) {\n+\ts.BaseSuite.SetUpTest(c)\n+\n+\ts.stub = new(jujutesting.Stub)\n+\ts.facade = newMockFacade(s.stub)\n+\ts.config = remoterelations.Config{\n+\t\tFacade: s.facade,\n+\t}\n+}\n+\n+func (s *remoteRelationsSuite) waitForStubCalls(c *gc.C, expected []jujutesting.StubCall) {\n+\tvar calls []jujutesting.StubCall\n+\tfor a := coretesting.LongAttempt.Start(); a.Next(); {\n+\t\tcalls = s.stub.Calls()\n+\t\tif reflect.DeepEqual(calls, expected) {\n+\t\t\treturn\n+\t\t}\n+\t}\n+\tc.Fatalf(\"failed to see expected calls. saw: %v\", calls)\n+}\n+\n+func (s *remoteRelationsSuite) assertRemoteApplicationWorkers(c *gc.C) worker.Worker {\n+\t// Checks that the main worker loop responds to remote application events\n+\t// by starting relevant relation watchers.\n+\ts.facade.remoteApplications[\"db2\"] = newMockRemoteApplication(\"db2\", \"db2url\")\n+\ts.facade.remoteApplications[\"django\"] = newMockRemoteApplication(\"django\", \"djangourl\")\n+\tapplicationNames := []string{\"db2\", \"django\"}\n+\ts.facade.remoteApplicationsWatcher.changes <- applicationNames\n+\n+\tw, err := remoterelations.New(s.config)\n+\tc.Assert(err, jc.ErrorIsNil)\n+\texpected := []jujutesting.StubCall{\n+\t\t{\"WatchRemoteApplications\", nil},\n+\t\t{\"RemoteApplications\", []interface{}{[]string{\"db2\", \"django\"}}},\n+\t\t{\"WatchRemoteApplicationRelations\", []interface{}{\"db2\"}},\n+\t\t{\"WatchRemoteApplicationRelations\", []interface{}{\"django\"}},\n+\t}\n+\ts.waitForStubCalls(c, expected)\n+\tfor _, app := range applicationNames {\n+\t\tw, ok := s.facade.remoteApplicationRelationsWatchers[app]\n+\t\tc.Check(ok, jc.IsTrue)\n+\t\tw.CheckCalls(c, []jujutesting.StubCall{\n+\t\t\t{\"Changes\", []interface{}{}},\n+\t\t})\n+\t}\n+\treturn w\n+}\n+\n+func (s *remoteRelationsSuite) TestRemoteApplicationWorkers(c *gc.C) {\n+\tapplicationNames := []string{\"db2\", \"django\"}\n+\tw := s.assertRemoteApplicationWorkers(c)\n+\n+\tdefer func() {\n+\t\tworkertest.CleanKill(c, w)\n+\t\t// Check that relation watchers are stopped with the worker.\n+\t\tfor _, app := range applicationNames {\n+\t\t\tw, ok := s.facade.remoteApplicationRelationsWatchers[app]\n+\t\t\tc.Check(ok, jc.IsTrue)\n+\t\t\tfor a := coretesting.LongAttempt.Start(); a.Next(); {\n+\t\t\t\tif w.killed {\n+\t\t\t\t\tbreak\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tc.Check(w.killed, jc.IsTrue)\n+\t\t}\n+\t}()\n+}\n+\n+func (s *remoteRelationsSuite) TestRemoteApplicationRemoved(c *gc.C) {\n+\t// Checks that when a remote application is removed, the relation\n+\t// worker is killed.\n+\tw := s.assertRemoteApplicationWorkers(c)\n+\tdefer workertest.CleanKill(c, w)\n+\ts.stub.ResetCalls()\n+\n+\trelWatcher := s.facade.remoteApplicationRelationsWatchers[\"django\"]\n+\tdelete(s.facade.remoteApplications, \"django\")\n+\ts.facade.remoteApplicationsWatcher.changes <- []string{\"django\"}\n+\tfor a := coretesting.LongAttempt.Start(); a.Next(); {\n+\t\t_, ok := s.facade.remoteApplicationRelationsWatchers[\"django\"]\n+\t\tif !ok {\n+\t\t\tbreak\n+\t\t}\n+\t}\n+\tc.Check(relWatcher.killed, jc.IsTrue)\n+\texpected := []jujutesting.StubCall{\n+\t\t{\"RemoteApplications\", []interface{}{[]string{\"django\"}}},\n+\t}\n+\ts.waitForStubCalls(c, expected)\n+}\n+\n+func (s *remoteRelationsSuite) assertRemoteRelationsWorkers(c *gc.C) worker.Worker {\n+\tw := s.assertRemoteApplicationWorkers(c)\n+\ts.stub.ResetCalls()\n+\n+\ts.facade.relations[\"db2:db django:db\"] = newMockRelation(123)\n+\trelWatcher := s.facade.remoteApplicationRelationsWatchers[\"django\"]\n+\trelWatcher.changes <- []string{\"db2:db django:db\"}\n+\n+\texpected := []jujutesting.StubCall{\n+\t\t{\"RemoteRelations\", []interface{}{[]string{\"db2:db django:db\"}}},\n+\t\t{\"WatchLocalRelationUnits\", []interface{}{\"db2:db django:db\"}},\n+\t}\n+\ts.waitForStubCalls(c, expected)\n+\n+\tunitWatcher, ok := s.facade.relationsUnitsWatcher[\"db2:db django:db\"]\n+\tc.Check(ok, jc.IsTrue)\n+\tunitWatcher.CheckCalls(c, []jujutesting.StubCall{\n+\t\t{\"Changes\", []interface{}{}},\n+\t})\n+\treturn w\n+}\n+\n+func (s *remoteRelationsSuite) TestRemoteRelationsWorkers(c *gc.C) {\n+\tw := s.assertRemoteRelationsWorkers(c)\n+\n+\tdefer func() {","path":"worker/remoterelations/remoterelations_test.go","position":152,"original_position":152,"commit_id":"95d35e6cb4569f58ccfe944915d8aacd26ac5661","original_commit_id":"95d35e6cb4569f58ccfe944915d8aacd26ac5661","user":{"login":"axw","id":843579,"avatar_url":"https://avatars.githubusercontent.com/u/843579?v=3","gravatar_id":"","url":"https://api.github.com/users/axw","html_url":"https://github.com/axw","followers_url":"https://api.github.com/users/axw/followers","following_url":"https://api.github.com/users/axw/following{/other_user}","gists_url":"https://api.github.com/users/axw/gists{/gist_id}","starred_url":"https://api.github.com/users/axw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/axw/subscriptions","organizations_url":"https://api.github.com/users/axw/orgs","repos_url":"https://api.github.com/users/axw/repos","events_url":"https://api.github.com/users/axw/events{/privacy}","received_events_url":"https://api.github.com/users/axw/received_events","type":"User","site_admin":false},"body":"see comments for TestRemoteApplicationWorkers","created_at":"2016-11-24T04:10:56Z","updated_at":"2016-11-24T04:15:08Z","html_url":"https://github.com/juju/juju/pull/6609#discussion_r89433639","pull_request_url":"https://api.github.com/repos/juju/juju/pulls/6609","_links":{"self":{"href":"https://api.github.com/repos/juju/juju/pulls/comments/89433639"},"html":{"href":"https://github.com/juju/juju/pull/6609#discussion_r89433639"},"pull_request":{"href":"https://api.github.com/repos/juju/juju/pulls/6609"}}},"pull_request":{"url":"https://api.github.com/repos/juju/juju/pulls/6609","id":95110754,"html_url":"https://github.com/juju/juju/pull/6609","diff_url":"https://github.com/juju/juju/pull/6609.diff","patch_url":"https://github.com/juju/juju/pull/6609.patch","issue_url":"https://api.github.com/repos/juju/juju/issues/6609","number":6609,"state":"open","locked":false,"title":"Add basic boilerplate to remoterelation worker to watch relation unit changes","user":{"login":"wallyworld","id":5808968,"avatar_url":"https://avatars.githubusercontent.com/u/5808968?v=3","gravatar_id":"","url":"https://api.github.com/users/wallyworld","html_url":"https://github.com/wallyworld","followers_url":"https://api.github.com/users/wallyworld/followers","following_url":"https://api.github.com/users/wallyworld/following{/other_user}","gists_url":"https://api.github.com/users/wallyworld/gists{/gist_id}","starred_url":"https://api.github.com/users/wallyworld/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wallyworld/subscriptions","organizations_url":"https://api.github.com/users/wallyworld/orgs","repos_url":"https://api.github.com/users/wallyworld/repos","events_url":"https://api.github.com/users/wallyworld/events{/privacy}","received_events_url":"https://api.github.com/users/wallyworld/received_events","type":"User","site_admin":false},"body":"The remote relations work listen for remote applications. It starts listeners to respond to when relations are created, and then when units change on those relations. For now, we simply capture the change events for testing. Subsequent PRs will flesh out more detail, specifically propagating those settings changes to the remote model.\r\n\r\nQA: bootstrap lxd","created_at":"2016-11-24T03:05:55Z","updated_at":"2016-11-24T04:15:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ba4da9913517020eb24f78d5a336b7e22d757f19","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/juju/juju/pulls/6609/commits","review_comments_url":"https://api.github.com/repos/juju/juju/pulls/6609/comments","review_comment_url":"https://api.github.com/repos/juju/juju/pulls/comments{/number}","comments_url":"https://api.github.com/repos/juju/juju/issues/6609/comments","statuses_url":"https://api.github.com/repos/juju/juju/statuses/95d35e6cb4569f58ccfe944915d8aacd26ac5661","head":{"label":"wallyworld:cmr-worker-part1","ref":"cmr-worker-part1","sha":"95d35e6cb4569f58ccfe944915d8aacd26ac5661","user":{"login":"wallyworld","id":5808968,"avatar_url":"https://avatars.githubusercontent.com/u/5808968?v=3","gravatar_id":"","url":"https://api.github.com/users/wallyworld","html_url":"https://github.com/wallyworld","followers_url":"https://api.github.com/users/wallyworld/followers","following_url":"https://api.github.com/users/wallyworld/following{/other_user}","gists_url":"https://api.github.com/users/wallyworld/gists{/gist_id}","starred_url":"https://api.github.com/users/wallyworld/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wallyworld/subscriptions","organizations_url":"https://api.github.com/users/wallyworld/orgs","repos_url":"https://api.github.com/users/wallyworld/repos","events_url":"https://api.github.com/users/wallyworld/events{/privacy}","received_events_url":"https://api.github.com/users/wallyworld/received_events","type":"User","site_admin":false},"repo":{"id":20465218,"name":"juju","full_name":"wallyworld/juju","owner":{"login":"wallyworld","id":5808968,"avatar_url":"https://avatars.githubusercontent.com/u/5808968?v=3","gravatar_id":"","url":"https://api.github.com/users/wallyworld","html_url":"https://github.com/wallyworld","followers_url":"https://api.github.com/users/wallyworld/followers","following_url":"https://api.github.com/users/wallyworld/following{/other_user}","gists_url":"https://api.github.com/users/wallyworld/gists{/gist_id}","starred_url":"https://api.github.com/users/wallyworld/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wallyworld/subscriptions","organizations_url":"https://api.github.com/users/wallyworld/orgs","repos_url":"https://api.github.com/users/wallyworld/repos","events_url":"https://api.github.com/users/wallyworld/events{/privacy}","received_events_url":"https://api.github.com/users/wallyworld/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wallyworld/juju","description":"juju is devops distilled","fork":true,"url":"https://api.github.com/repos/wallyworld/juju","forks_url":"https://api.github.com/repos/wallyworld/juju/forks","keys_url":"https://api.github.com/repos/wallyworld/juju/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wallyworld/juju/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wallyworld/juju/teams","hooks_url":"https://api.github.com/repos/wallyworld/juju/hooks","issue_events_url":"https://api.github.com/repos/wallyworld/juju/issues/events{/number}","events_url":"https://api.github.com/repos/wallyworld/juju/events","assignees_url":"https://api.github.com/repos/wallyworld/juju/assignees{/user}","branches_url":"https://api.github.com/repos/wallyworld/juju/branches{/branch}","tags_url":"https://api.github.com/repos/wallyworld/juju/tags","blobs_url":"https://api.github.com/repos/wallyworld/juju/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wallyworld/juju/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wallyworld/juju/git/refs{/sha}","trees_url":"https://api.github.com/repos/wallyworld/juju/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wallyworld/juju/statuses/{sha}","languages_url":"https://api.github.com/repos/wallyworld/juju/languages","stargazers_url":"https://api.github.com/repos/wallyworld/juju/stargazers","contributors_url":"https://api.github.com/repos/wallyworld/juju/contributors","subscribers_url":"https://api.github.com/repos/wallyworld/juju/subscribers","subscription_url":"https://api.github.com/repos/wallyworld/juju/subscription","commits_url":"https://api.github.com/repos/wallyworld/juju/commits{/sha}","git_commits_url":"https://api.github.com/repos/wallyworld/juju/git/commits{/sha}","comments_url":"https://api.github.com/repos/wallyworld/juju/comments{/number}","issue_comment_url":"https://api.github.com/repos/wallyworld/juju/issues/comments{/number}","contents_url":"https://api.github.com/repos/wallyworld/juju/contents/{+path}","compare_url":"https://api.github.com/repos/wallyworld/juju/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wallyworld/juju/merges","archive_url":"https://api.github.com/repos/wallyworld/juju/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wallyworld/juju/downloads","issues_url":"https://api.github.com/repos/wallyworld/juju/issues{/number}","pulls_url":"https://api.github.com/repos/wallyworld/juju/pulls{/number}","milestones_url":"https://api.github.com/repos/wallyworld/juju/milestones{/number}","notifications_url":"https://api.github.com/repos/wallyworld/juju/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wallyworld/juju/labels{/name}","releases_url":"https://api.github.com/repos/wallyworld/juju/releases{/id}","deployments_url":"https://api.github.com/repos/wallyworld/juju/deployments","created_at":"2014-06-04T00:56:12Z","updated_at":"2016-01-11T16:57:01Z","pushed_at":"2016-11-24T04:11:35Z","git_url":"git://github.com/wallyworld/juju.git","ssh_url":"git@github.com:wallyworld/juju.git","clone_url":"https://github.com/wallyworld/juju.git","svn_url":"https://github.com/wallyworld/juju","homepage":null,"size":97664,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"juju:develop","ref":"develop","sha":"226ac191c9143c9e150262684c4b9d01669dfa8d","user":{"login":"juju","id":4604548,"avatar_url":"https://avatars.githubusercontent.com/u/4604548?v=3","gravatar_id":"","url":"https://api.github.com/users/juju","html_url":"https://github.com/juju","followers_url":"https://api.github.com/users/juju/followers","following_url":"https://api.github.com/users/juju/following{/other_user}","gists_url":"https://api.github.com/users/juju/gists{/gist_id}","starred_url":"https://api.github.com/users/juju/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juju/subscriptions","organizations_url":"https://api.github.com/users/juju/orgs","repos_url":"https://api.github.com/users/juju/repos","events_url":"https://api.github.com/users/juju/events{/privacy}","received_events_url":"https://api.github.com/users/juju/received_events","type":"Organization","site_admin":false},"repo":{"id":20445947,"name":"juju","full_name":"juju/juju","owner":{"login":"juju","id":4604548,"avatar_url":"https://avatars.githubusercontent.com/u/4604548?v=3","gravatar_id":"","url":"https://api.github.com/users/juju","html_url":"https://github.com/juju","followers_url":"https://api.github.com/users/juju/followers","following_url":"https://api.github.com/users/juju/following{/other_user}","gists_url":"https://api.github.com/users/juju/gists{/gist_id}","starred_url":"https://api.github.com/users/juju/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juju/subscriptions","organizations_url":"https://api.github.com/users/juju/orgs","repos_url":"https://api.github.com/users/juju/repos","events_url":"https://api.github.com/users/juju/events{/privacy}","received_events_url":"https://api.github.com/users/juju/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/juju/juju","description":"juju is devops distilled","fork":false,"url":"https://api.github.com/repos/juju/juju","forks_url":"https://api.github.com/repos/juju/juju/forks","keys_url":"https://api.github.com/repos/juju/juju/keys{/key_id}","collaborators_url":"https://api.github.com/repos/juju/juju/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/juju/juju/teams","hooks_url":"https://api.github.com/repos/juju/juju/hooks","issue_events_url":"https://api.github.com/repos/juju/juju/issues/events{/number}","events_url":"https://api.github.com/repos/juju/juju/events","assignees_url":"https://api.github.com/repos/juju/juju/assignees{/user}","branches_url":"https://api.github.com/repos/juju/juju/branches{/branch}","tags_url":"https://api.github.com/repos/juju/juju/tags","blobs_url":"https://api.github.com/repos/juju/juju/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/juju/juju/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/juju/juju/git/refs{/sha}","trees_url":"https://api.github.com/repos/juju/juju/git/trees{/sha}","statuses_url":"https://api.github.com/repos/juju/juju/statuses/{sha}","languages_url":"https://api.github.com/repos/juju/juju/languages","stargazers_url":"https://api.github.com/repos/juju/juju/stargazers","contributors_url":"https://api.github.com/repos/juju/juju/contributors","subscribers_url":"https://api.github.com/repos/juju/juju/subscribers","subscription_url":"https://api.github.com/repos/juju/juju/subscription","commits_url":"https://api.github.com/repos/juju/juju/commits{/sha}","git_commits_url":"https://api.github.com/repos/juju/juju/git/commits{/sha}","comments_url":"https://api.github.com/repos/juju/juju/comments{/number}","issue_comment_url":"https://api.github.com/repos/juju/juju/issues/comments{/number}","contents_url":"https://api.github.com/repos/juju/juju/contents/{+path}","compare_url":"https://api.github.com/repos/juju/juju/compare/{base}...{head}","merges_url":"https://api.github.com/repos/juju/juju/merges","archive_url":"https://api.github.com/repos/juju/juju/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/juju/juju/downloads","issues_url":"https://api.github.com/repos/juju/juju/issues{/number}","pulls_url":"https://api.github.com/repos/juju/juju/pulls{/number}","milestones_url":"https://api.github.com/repos/juju/juju/milestones{/number}","notifications_url":"https://api.github.com/repos/juju/juju/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/juju/juju/labels{/name}","releases_url":"https://api.github.com/repos/juju/juju/releases{/id}","deployments_url":"https://api.github.com/repos/juju/juju/deployments","created_at":"2014-06-03T14:28:10Z","updated_at":"2016-11-19T18:45:51Z","pushed_at":"2016-11-24T04:13:20Z","git_url":"git://github.com/juju/juju.git","ssh_url":"git@github.com:juju/juju.git","clone_url":"https://github.com/juju/juju.git","svn_url":"https://github.com/juju/juju","homepage":"juju.ubuntu.com","size":128687,"stargazers_count":534,"watchers_count":534,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":164,"mirror_url":null,"open_issues_count":22,"forks":164,"open_issues":22,"watchers":534,"default_branch":"staging"}},"_links":{"self":{"href":"https://api.github.com/repos/juju/juju/pulls/6609"},"html":{"href":"https://github.com/juju/juju/pull/6609"},"issue":{"href":"https://api.github.com/repos/juju/juju/issues/6609"},"comments":{"href":"https://api.github.com/repos/juju/juju/issues/6609/comments"},"review_comments":{"href":"https://api.github.com/repos/juju/juju/pulls/6609/comments"},"review_comment":{"href":"https://api.github.com/repos/juju/juju/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/juju/juju/pulls/6609/commits"},"statuses":{"href":"https://api.github.com/repos/juju/juju/statuses/95d35e6cb4569f58ccfe944915d8aacd26ac5661"}}}}
{"actor":{"display_login":"axw"}}