{"action":"created","comment":{"url":"https://api.github.com/repos/openshift/origin/pulls/comments/39733437","id":39733437,"diff_hunk":"@@ -0,0 +1,258 @@\n+package ha\n+\n+/*\n+This controllers test suite is not part of the \"default\" group, because its\n+testing involves terminating and launching controllers components of OpenShift.\n+Therefore it can't be run in parallel.\n+*/\n+\n+import (\n+\t\"bufio\"\n+\t\"fmt\"\n+\t\"io\"\n+\t\"os/exec\"\n+\t\"regexp\"\n+\t\"strings\"\n+\t\"time\"\n+\n+\tg \"github.com/onsi/ginkgo\"\n+\to \"github.com/onsi/gomega\"\n+\n+\texutil \"github.com/openshift/origin/test/extended/util\"\n+)\n+\n+var _ = g.Describe(\"ha: Election of OpenShift controllers\", func() {\n+\tdefer g.GinkgoRecover()\n+\tvar (\n+\t\tpodConfig  = exutil.FixturePath(\"fixtures\", \"hello-world-pod.json\")\n+\t\treExitCode = regexp.MustCompile(`(?i)exitcode:(\\d+)`)\n+\t)\n+\n+\t// Run a controller manager with one intitial controllers instance.\n+\t// Running controllers are needed for NewCLI to run.\n+\t// FIXME: seems like OutputDir is unset at this moment (execution of the first test)\n+\tm, _err := exutil.NewControllersManager(exutil.MasterConfigPath(), 0, 8444, exutil.TestContext.OutputDir)\n+\tif _err != nil {\n+\t\tg.Fail(fmt.Sprintf(\"Failed to initialize controllers instance: %v\\n\", _err))\n+\t}\n+\t// FIXME: Controllers instance immediatelly terminates after acquiring its lease without following sleep\n+\ttime.Sleep(1 * time.Second)\n+\n+\t// One controllers instance needs to be running before CLI can be initialized\n+\t_, _err = m.StartNewInstance()\n+\tif _err != nil {\n+\t\tg.Fail(fmt.Sprintf(\"Failed to initialize controllers instance: %v\\n\", _err))\n+\t}\n+\t_, _, _err = m.WaitForActive(time.Second * 2)\n+\tif _err != nil {\n+\t\tg.Fail(_err.Error())\n+\t}\n+\n+\toc := exutil.NewCLI(\"controller-leases\", exutil.KubeConfigPath())\n+\n+\t// WaitForPod blocks until given pod terminates.\n+\t// FIXME: this is probably too complicated\n+\t// FIXME: consider using oc logs directly\n+\tWaitForPod := func(podName string, timeout time.Duration) {\n+\t\tstart := time.Now()\n+\t\tcmd := exec.Command(\"oc\", \"get\", \"-n\", oc.Namespace(), \"--watch\", \"--no-headers\", \"pod\", podName)\n+\t\tstdout, err := cmd.StdoutPipe()\n+\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t\tstderr, err := cmd.StderrPipe()\n+\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t\tec := make(chan error)\n+\t\terr = cmd.Start()\n+\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\n+\t\t// log stderr\n+\t\tgo func() {\n+\t\t\tio.Copy(g.GinkgoWriter, stderr)\n+\t\t}()\n+\n+\t\t// log stdout and look for exited state\n+\t\tgo func() {\n+\t\t\tbufReader := bufio.NewReader(stdout)\n+\t\t\tfor {\n+\t\t\t\tline, err := bufReader.ReadString('\\n')\n+\t\t\t\tif err != nil {\n+\t\t\t\t\tec <- err\n+\t\t\t\t\treturn\n+\t\t\t\t}\n+\t\t\t\tg.GinkgoWriter.Write([]byte(fmt.Sprintf(\"`oc get --watch` output: %s\", line)))\n+\t\t\t\tsubmatch := reExitCode.FindStringSubmatch(line)\n+\t\t\t\tif len(submatch) > 1 {\n+\t\t\t\t\tif submatch[1] != \"0\" {\n+\t\t\t\t\t\tec <- fmt.Errorf(\"Pod terminated with unexpected exit code (%s)\", submatch[1])\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\tec <- nil\n+\t\t\t\t\t}\n+\t\t\t\t\treturn\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}()\n+\n+\t\tselect {\n+\t\tcase err := <-ec:\n+\t\t\tif err != nil && err != io.EOF {\n+\t\t\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t\t\t}\n+\t\t\tif err == nil {\n+\t\t\t\tcmd.Process.Kill()\n+\t\t\t\tcmd.Wait()\n+\t\t\t} else {\n+\t\t\t\to.Expect(cmd.Wait()).NotTo(o.HaveOccurred())\n+\t\t\t}\n+\t\tcase <-time.After(start.Add(timeout).Sub(time.Now())):\n+\t\t\tg.Fail(fmt.Sprintf(\"Timeout (%s) occurred while waiting for pod's exit\", timeout.String()))\n+\t\t}\n+\t}\n+\n+\tStartPod := func() {\n+\t\tg.By(fmt.Sprintf(\"\\n HA TEST:  Creating a pod from %s\", podConfig))\n+\t\terr := oc.Run(\"create\").Args(\"-f\", podConfig).Execute()\n+\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\n+\t\tg.By(\"\\n HA TEST:  Wait for pod's exit\")\n+\t\tWaitForPod(\"helloworld-pod\", time.Second*50)\n+\n+\t\tg.By(\"\\n HA TEST:  Check pod's output\")\n+\t\tout, err := oc.Run(\"logs\").Args(\"--interactive=false\", \"helloworld-pod\").Output()\n+\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t\to.Expect(strings.Contains(strings.ToLower(out), \"hello from docker\"))\n+\t}\n+\n+\t// EnsureOneInstanceActive releases any inactive controllers instances and\n+\t// makes sure that one is active.\n+\tEnsureOneInstanceActive := func() {\n+\t\tl := m.Len()\n+\t\tswitch {\n+\t\tcase l > 1:\n+\t\t\tg.By(\"\\n HA TEST:  Releasing inactive controllers\")\n+\t\t\tm.ReleaseControllers(m.GetInactive()...)\n+\t\tcase l == 0:\n+\t\t\tg.By(\"\\n HA TEST:  Launching initial controllers instance\")\n+\t\t\t// Speed up controllers election by deleting current lease\n+\t\t\tm.DeleteLease()\n+\t\t\t_, err := m.StartNewInstance()\n+\t\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t\t\to.Expect(m.Len()).To(o.Equal(1))\n+\t\t\t_, _, err = m.WaitForActive(time.Second)\n+\t\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t\t}\n+\t\to.Expect(m.Len()).To(o.Equal(1))\n+\t}\n+\n+\tTerminateActive := func() *exutil.Controllers {\n+\t\tg.By(\"\\n HA TEST:  Terminating active controllers instance\")\n+\t\tctrls, err := m.GetActive()\n+\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t\tm.ReleaseControllers(ctrls)\n+\t\to.Expect(ctrls.Exited()).To(o.BeTrue())\n+\t\treturn ctrls\n+\t}\n+\n+\tg.JustBeforeEach(func() {\n+\t\toc.SetOutputDir(exutil.TestContext.OutputDir)\n+\n+\t\to.Expect(m.Len()).To(o.Equal(1))\n+\t\tg.By(\"\\n HA TEST:  waiting for deployer service account\")\n+\t\terr := exutil.WaitForDeployerAccount(oc.KubeREST().ServiceAccounts(oc.Namespace()))\n+\t\to.Expect(err).NotTo(o.HaveOccurred())\n+\t})\n+\n+\tg.AfterEach(func() {\n+\t\tEnsureOneInstanceActive()\n+\t})\n+\n+\tg.Describe(\"\\n HA TEST:  Delete an active lease\", func() {","path":"test/extended/ha/ha.go","position":167,"original_position":167,"commit_id":"4e0cbd8ccbea243ac8927bb2e061e7c57a392f8c","original_commit_id":"4e0cbd8ccbea243ac8927bb2e061e7c57a392f8c","user":{"login":"miminar","id":1478803,"avatar_url":"https://avatars.githubusercontent.com/u/1478803?v=3","gravatar_id":"","url":"https://api.github.com/users/miminar","html_url":"https://github.com/miminar","followers_url":"https://api.github.com/users/miminar/followers","following_url":"https://api.github.com/users/miminar/following{/other_user}","gists_url":"https://api.github.com/users/miminar/gists{/gist_id}","starred_url":"https://api.github.com/users/miminar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miminar/subscriptions","organizations_url":"https://api.github.com/users/miminar/orgs","repos_url":"https://api.github.com/users/miminar/repos","events_url":"https://api.github.com/users/miminar/events{/privacy}","received_events_url":"https://api.github.com/users/miminar/received_events","type":"User","site_admin":false},"body":"I'm not sure myself. I just wanted to be consistent with another non-default test [forcepull](https://github.com/miminar/origin/blob/test-active-active/test/extended/builds/forcepull.go#L69). @gabemontero ^^? But since other non-default test `networking` doesn't use these prefixes, I think they can be removed.","created_at":"2015-09-17T11:02:40Z","updated_at":"2015-09-17T11:02:40Z","html_url":"https://github.com/openshift/origin/pull/4628#discussion_r39733437","pull_request_url":"https://api.github.com/repos/openshift/origin/pulls/4628","_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments/39733437"},"html":{"href":"https://github.com/openshift/origin/pull/4628#discussion_r39733437"},"pull_request":{"href":"https://api.github.com/repos/openshift/origin/pulls/4628"}}},"pull_request":{"url":"https://api.github.com/repos/openshift/origin/pulls/4628","id":44767130,"html_url":"https://github.com/openshift/origin/pull/4628","diff_url":"https://github.com/openshift/origin/pull/4628.diff","patch_url":"https://github.com/openshift/origin/pull/4628.patch","issue_url":"https://api.github.com/repos/openshift/origin/issues/4628","number":4628,"state":"open","locked":false,"title":"Added active/active test suite","user":{"login":"miminar","id":1478803,"avatar_url":"https://avatars.githubusercontent.com/u/1478803?v=3","gravatar_id":"","url":"https://api.github.com/users/miminar","html_url":"https://github.com/miminar","followers_url":"https://api.github.com/users/miminar/followers","following_url":"https://api.github.com/users/miminar/following{/other_user}","gists_url":"https://api.github.com/users/miminar/gists{/gist_id}","starred_url":"https://api.github.com/users/miminar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miminar/subscriptions","organizations_url":"https://api.github.com/users/miminar/orgs","repos_url":"https://api.github.com/users/miminar/repos","events_url":"https://api.github.com/users/miminar/events{/privacy}","received_events_url":"https://api.github.com/users/miminar/received_events","type":"User","site_admin":false},"body":"Added testing framework for controllers election.\n\nTests Can be run with:\n\n    ./hack/test-extended.sh ha\n\nIn their setup a standalone etcd server, api server and a node are\nlaunched. Individual controllers are started/terminated by ginkgo test\nsuite (prefixed with `ha:`).","created_at":"2015-09-11T10:22:51Z","updated_at":"2015-09-17T11:02:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"19bd9b46777c770b547ba24c91f1cedf69c8c8ed","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/openshift/origin/pulls/4628/commits","review_comments_url":"https://api.github.com/repos/openshift/origin/pulls/4628/comments","review_comment_url":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openshift/origin/issues/4628/comments","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/4e0cbd8ccbea243ac8927bb2e061e7c57a392f8c","head":{"label":"miminar:test-active-active","ref":"test-active-active","sha":"4e0cbd8ccbea243ac8927bb2e061e7c57a392f8c","user":{"login":"miminar","id":1478803,"avatar_url":"https://avatars.githubusercontent.com/u/1478803?v=3","gravatar_id":"","url":"https://api.github.com/users/miminar","html_url":"https://github.com/miminar","followers_url":"https://api.github.com/users/miminar/followers","following_url":"https://api.github.com/users/miminar/following{/other_user}","gists_url":"https://api.github.com/users/miminar/gists{/gist_id}","starred_url":"https://api.github.com/users/miminar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miminar/subscriptions","organizations_url":"https://api.github.com/users/miminar/orgs","repos_url":"https://api.github.com/users/miminar/repos","events_url":"https://api.github.com/users/miminar/events{/privacy}","received_events_url":"https://api.github.com/users/miminar/received_events","type":"User","site_admin":false},"repo":{"id":36652057,"name":"origin","full_name":"miminar/origin","owner":{"login":"miminar","id":1478803,"avatar_url":"https://avatars.githubusercontent.com/u/1478803?v=3","gravatar_id":"","url":"https://api.github.com/users/miminar","html_url":"https://github.com/miminar","followers_url":"https://api.github.com/users/miminar/followers","following_url":"https://api.github.com/users/miminar/following{/other_user}","gists_url":"https://api.github.com/users/miminar/gists{/gist_id}","starred_url":"https://api.github.com/users/miminar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miminar/subscriptions","organizations_url":"https://api.github.com/users/miminar/orgs","repos_url":"https://api.github.com/users/miminar/repos","events_url":"https://api.github.com/users/miminar/events{/privacy}","received_events_url":"https://api.github.com/users/miminar/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/miminar/origin","description":"OpenShift 3 - build, deploy, and manage your applications with Docker and Kubernetes","fork":true,"url":"https://api.github.com/repos/miminar/origin","forks_url":"https://api.github.com/repos/miminar/origin/forks","keys_url":"https://api.github.com/repos/miminar/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/miminar/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/miminar/origin/teams","hooks_url":"https://api.github.com/repos/miminar/origin/hooks","issue_events_url":"https://api.github.com/repos/miminar/origin/issues/events{/number}","events_url":"https://api.github.com/repos/miminar/origin/events","assignees_url":"https://api.github.com/repos/miminar/origin/assignees{/user}","branches_url":"https://api.github.com/repos/miminar/origin/branches{/branch}","tags_url":"https://api.github.com/repos/miminar/origin/tags","blobs_url":"https://api.github.com/repos/miminar/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/miminar/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/miminar/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/miminar/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/miminar/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/miminar/origin/languages","stargazers_url":"https://api.github.com/repos/miminar/origin/stargazers","contributors_url":"https://api.github.com/repos/miminar/origin/contributors","subscribers_url":"https://api.github.com/repos/miminar/origin/subscribers","subscription_url":"https://api.github.com/repos/miminar/origin/subscription","commits_url":"https://api.github.com/repos/miminar/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/miminar/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/miminar/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/miminar/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/miminar/origin/contents/{+path}","compare_url":"https://api.github.com/repos/miminar/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/miminar/origin/merges","archive_url":"https://api.github.com/repos/miminar/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/miminar/origin/downloads","issues_url":"https://api.github.com/repos/miminar/origin/issues{/number}","pulls_url":"https://api.github.com/repos/miminar/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/miminar/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/miminar/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/miminar/origin/labels{/name}","releases_url":"https://api.github.com/repos/miminar/origin/releases{/id}","created_at":"2015-06-01T09:53:10Z","updated_at":"2015-06-01T09:53:14Z","pushed_at":"2015-09-15T11:44:12Z","git_url":"git://github.com/miminar/origin.git","ssh_url":"git@github.com:miminar/origin.git","clone_url":"https://github.com/miminar/origin.git","svn_url":"https://github.com/miminar/origin","homepage":"http://www.openshift.org","size":137744,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"openshift:master","ref":"master","sha":"1662e2d364d188f32a269898f65ae2cdd8892dc3","user":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"repo":{"id":22442668,"name":"origin","full_name":"openshift/origin","owner":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openshift/origin","description":"OpenShift 3 - build, deploy, and manage your applications with Docker and Kubernetes","fork":false,"url":"https://api.github.com/repos/openshift/origin","forks_url":"https://api.github.com/repos/openshift/origin/forks","keys_url":"https://api.github.com/repos/openshift/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openshift/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openshift/origin/teams","hooks_url":"https://api.github.com/repos/openshift/origin/hooks","issue_events_url":"https://api.github.com/repos/openshift/origin/issues/events{/number}","events_url":"https://api.github.com/repos/openshift/origin/events","assignees_url":"https://api.github.com/repos/openshift/origin/assignees{/user}","branches_url":"https://api.github.com/repos/openshift/origin/branches{/branch}","tags_url":"https://api.github.com/repos/openshift/origin/tags","blobs_url":"https://api.github.com/repos/openshift/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openshift/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openshift/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/openshift/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/openshift/origin/languages","stargazers_url":"https://api.github.com/repos/openshift/origin/stargazers","contributors_url":"https://api.github.com/repos/openshift/origin/contributors","subscribers_url":"https://api.github.com/repos/openshift/origin/subscribers","subscription_url":"https://api.github.com/repos/openshift/origin/subscription","commits_url":"https://api.github.com/repos/openshift/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/openshift/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/openshift/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/openshift/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/openshift/origin/contents/{+path}","compare_url":"https://api.github.com/repos/openshift/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openshift/origin/merges","archive_url":"https://api.github.com/repos/openshift/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openshift/origin/downloads","issues_url":"https://api.github.com/repos/openshift/origin/issues{/number}","pulls_url":"https://api.github.com/repos/openshift/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/openshift/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/openshift/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openshift/origin/labels{/name}","releases_url":"https://api.github.com/repos/openshift/origin/releases{/id}","created_at":"2014-07-30T20:04:05Z","updated_at":"2015-09-15T16:17:31Z","pushed_at":"2015-09-17T11:01:57Z","git_url":"git://github.com/openshift/origin.git","ssh_url":"git@github.com:openshift/origin.git","clone_url":"https://github.com/openshift/origin.git","svn_url":"https://github.com/openshift/origin","homepage":"http://www.openshift.org","size":223379,"stargazers_count":682,"watchers_count":682,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":413,"mirror_url":null,"open_issues_count":536,"forks":413,"open_issues":536,"watchers":682,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/4628"},"html":{"href":"https://github.com/openshift/origin/pull/4628"},"issue":{"href":"https://api.github.com/repos/openshift/origin/issues/4628"},"comments":{"href":"https://api.github.com/repos/openshift/origin/issues/4628/comments"},"review_comments":{"href":"https://api.github.com/repos/openshift/origin/pulls/4628/comments"},"review_comment":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openshift/origin/pulls/4628/commits"},"statuses":{"href":"https://api.github.com/repos/openshift/origin/statuses/4e0cbd8ccbea243ac8927bb2e061e7c57a392f8c"}}}}