github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/e2e/health_test.go (about) 1 /* 2 Copyright hechain All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package e2e 8 9 import ( 10 "encoding/json" 11 "fmt" 12 "io/ioutil" 13 "net" 14 "net/http" 15 "os" 16 "syscall" 17 18 docker "github.com/fsouza/go-dockerclient" 19 "github.com/hechain20/hechain/integration/nwo" 20 "github.com/hechain20/hechain/integration/nwo/runner" 21 "github.com/hyperledger/fabric-lib-go/healthz" 22 . "github.com/onsi/ginkgo" 23 . "github.com/onsi/gomega" 24 "github.com/tedsuo/ifrit" 25 "github.com/tedsuo/ifrit/ginkgomon" 26 ) 27 28 var _ = Describe("Health", func() { 29 var ( 30 testDir string 31 client *docker.Client 32 network *nwo.Network 33 process ifrit.Process 34 ) 35 36 BeforeEach(func() { 37 var err error 38 testDir, err = ioutil.TempDir("", "e2e") 39 Expect(err).NotTo(HaveOccurred()) 40 41 client, err = docker.NewClientFromEnv() 42 Expect(err).NotTo(HaveOccurred()) 43 44 config := nwo.BasicEtcdRaft() 45 network = nwo.New(config, testDir, client, StartPort(), components) 46 network.GenerateConfigTree() 47 network.Bootstrap() 48 }) 49 50 AfterEach(func() { 51 if process != nil { 52 process.Signal(syscall.SIGTERM) 53 Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) 54 } 55 if network != nil { 56 network.Cleanup() 57 } 58 os.RemoveAll(testDir) 59 }) 60 61 Describe("CouchDB health checks", func() { 62 var ( 63 couchAddr string 64 authClient *http.Client 65 healthURL string 66 peer *nwo.Peer 67 couchDB *runner.CouchDB 68 couchProcess ifrit.Process 69 ) 70 71 BeforeEach(func() { 72 couchDB = &runner.CouchDB{} 73 couchProcess = ifrit.Invoke(couchDB) 74 Eventually(couchProcess.Ready(), runner.DefaultStartTimeout).Should(BeClosed()) 75 Consistently(couchProcess.Wait()).ShouldNot(Receive()) 76 couchAddr = couchDB.Address() 77 78 peer = network.Peer("Org1", "peer0") 79 core := network.ReadPeerConfig(peer) 80 core.Ledger.State.StateDatabase = "CouchDB" 81 core.Ledger.State.CouchDBConfig.CouchDBAddress = couchAddr 82 network.WritePeerConfig(peer, core) 83 84 peerRunner := network.PeerRunner(peer) 85 process = ginkgomon.Invoke(peerRunner) 86 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 87 88 authClient, _ = nwo.PeerOperationalClients(network, peer) 89 healthURL = fmt.Sprintf("https://127.0.0.1:%d/healthz", network.PeerPort(peer, nwo.OperationsPort)) 90 }) 91 92 AfterEach(func() { 93 couchProcess.Signal(syscall.SIGTERM) 94 Eventually(couchProcess.Wait(), network.EventuallyTimeout).Should(Receive()) 95 }) 96 97 When("running health checks on Couch DB", func() { 98 It("returns appropriate response codes", func() { 99 By("returning 200 when able to reach Couch DB") 100 statusCode, status := doHealthCheck(authClient, healthURL) 101 Expect(statusCode).To(Equal(http.StatusOK)) 102 Expect(status.Status).To(Equal("OK")) 103 104 By("terminating CouchDB") 105 couchProcess.Signal(syscall.SIGTERM) 106 Eventually(couchProcess.Wait(), network.EventuallyTimeout).Should(Receive()) 107 108 By("waiting for termination to complete") 109 Eventually(func() bool { 110 if c, err := net.Dial("tcp", couchDB.Address()); err == nil { 111 c.Close() 112 return false 113 } 114 return true 115 }, network.EventuallyTimeout).Should(BeTrue()) 116 117 By("returning 503 when unable to reach Couch DB") 118 Eventually(func() int { 119 statusCode, _ := doHealthCheck(authClient, healthURL) 120 return statusCode 121 }, network.EventuallyTimeout).Should(Equal(http.StatusServiceUnavailable)) 122 statusCode, status = doHealthCheck(authClient, healthURL) 123 Expect(statusCode).To(Equal(http.StatusServiceUnavailable)) 124 Expect(status.Status).To(Equal("Service Unavailable")) 125 Expect(status.FailedChecks[0].Component).To(Equal("couchdb")) 126 Expect(status.FailedChecks[0].Reason).To(MatchRegexp(fmt.Sprintf(`failed to connect to couch db \[http error calling couchdb: Head "?http://%s"?: dial tcp %s: .*\]`, couchAddr, couchAddr))) 127 }) 128 }) 129 }) 130 }) 131 132 func doHealthCheck(client *http.Client, url string) (int, *healthz.HealthStatus) { 133 resp, err := client.Get(url) 134 Expect(err).NotTo(HaveOccurred()) 135 136 bodyBytes, err := ioutil.ReadAll(resp.Body) 137 Expect(err).NotTo(HaveOccurred()) 138 resp.Body.Close() 139 140 // This occurs when a request to the health check server times out, no body is 141 // returned when a timeout occurs 142 if len(bodyBytes) == 0 { 143 return resp.StatusCode, nil 144 } 145 146 healthStatus := &healthz.HealthStatus{} 147 err = json.Unmarshal(bodyBytes, &healthStatus) 148 Expect(err).NotTo(HaveOccurred()) 149 150 return resp.StatusCode, healthStatus 151 }