github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/integration-tests/framework.go (about) 1 package integration_tests 2 3 import ( 4 "fmt" 5 "time" 6 7 . "github.com/onsi/ginkgo" 8 . "github.com/onsi/gomega" 9 ) 10 11 // ItOnAWS runs a spec if the AWS details have been provided 12 func ItOnAWS(description string, f func(infrastructureProvisioner)) { 13 Context("when using AWS infrastructure [aws]", func() { 14 It(description, func() { 15 awsClient, ok := AWSClientFromEnvironment() 16 if !ok { 17 Skip("AWS environment variables were not defined") 18 } 19 f(awsClient) 20 }) 21 }) 22 } 23 24 // ItOnPacket runs a spec if the Packet.Net details have been provided 25 func ItOnPacket(description string, f func(infrastructureProvisioner)) { 26 Context("when using Packet.net infrastructure [packet]", func() { 27 It(description, func() { 28 packetClient, ok := packetClientFromEnv() 29 if !ok { 30 Skip("Packet environment variables were not defined") 31 } 32 f(packetClient) 33 }) 34 }) 35 } 36 37 type infraDependentTest func(nodes provisionedNodes, sshKey string) 38 39 // WithInfrastructure runs the spec with the requested infrastructure 40 func WithInfrastructure(nodeCount NodeCount, distro linuxDistro, provisioner infrastructureProvisioner, f infraDependentTest) { 41 By(fmt.Sprintf("Provisioning nodes: %+v", nodeCount)) 42 start := time.Now() 43 nodes, err := provisioner.ProvisionNodes(nodeCount, distro) 44 if !leaveIt() { 45 defer provisioner.TerminateNodes(nodes) 46 } 47 Expect(err).ToNot(HaveOccurred()) 48 fmt.Println("Provisioning infrastructure took", time.Since(start)) 49 50 By("Waiting until nodes are SSH-accessible") 51 start = time.Now() 52 sshKey := provisioner.SSHKey() 53 err = waitForSSH(nodes, sshKey) 54 Expect(err).ToNot(HaveOccurred()) 55 fmt.Println("Waiting for SSH took", time.Since(start)) 56 57 f(nodes, sshKey) 58 } 59 60 // WithInfrastructureAndDNS runs the spec with the requested infrastructure and DNS 61 func WithInfrastructureAndDNS(nodeCount NodeCount, distro linuxDistro, provisioner infrastructureProvisioner, f infraDependentTest) { 62 By(fmt.Sprintf("Provisioning nodes and DNS: %+v", nodeCount)) 63 start := time.Now() 64 nodes, err := provisioner.ProvisionNodes(nodeCount, distro) 65 if !leaveIt() { 66 defer provisioner.TerminateNodes(nodes) 67 } 68 Expect(err).ToNot(HaveOccurred()) 69 fmt.Println("Provisioning infrastructure took", time.Since(start)) 70 71 By("Waiting until nodes are SSH-accessible") 72 start = time.Now() 73 sshKey := provisioner.SSHKey() 74 err = waitForSSH(nodes, sshKey) 75 Expect(err).ToNot(HaveOccurred()) 76 fmt.Println("Waiting for SSH took", time.Since(start)) 77 78 By("Configuring DNS entries") 79 start = time.Now() 80 var masterIPs []string 81 for _, node := range nodes.master { 82 masterIPs = append(masterIPs, node.PrivateIP) 83 } 84 dnsRecord, err := provisioner.ConfigureDNS(masterIPs) 85 nodes.dnsRecord = dnsRecord 86 Expect(err).ToNot(HaveOccurred()) 87 if !leaveIt() { 88 By("Removing DNS entries") 89 defer provisioner.RemoveDNS(dnsRecord) 90 } 91 fmt.Println("Configuring DNS entries took", time.Since(start)) 92 93 f(nodes, sshKey) 94 } 95 96 type miniInfraDependentTest func(node NodeDeets, sshKey string) 97 98 // WithMiniInfrastructure runs the spec with a Minikube-like infrastructure setup. 99 func WithMiniInfrastructure(distro linuxDistro, provisioner infrastructureProvisioner, f miniInfraDependentTest) { 100 By("Provisioning minikube node") 101 start := time.Now() 102 nodes, err := provisioner.ProvisionNodes(NodeCount{Worker: 1}, distro) 103 if !leaveIt() { 104 defer provisioner.TerminateNodes(nodes) 105 } 106 Expect(err).ToNot(HaveOccurred()) 107 fmt.Println("Provisioning node took", time.Since(start)) 108 109 By("Waiting until nodes are SSH-accessible") 110 start = time.Now() 111 sshKey := provisioner.SSHKey() 112 err = waitForSSH(nodes, sshKey) 113 Expect(err).ToNot(HaveOccurred()) 114 fmt.Println("Waiting for SSH took", time.Since(start)) 115 116 f(nodes.worker[0], sshKey) 117 } 118 119 // WithMiniInfrastructureAndBlockDevice runs the spec with the requested infrastructure and an additiona block device 120 // The block will be under /dev/xvdb on AWS 121 func WithMiniInfrastructureAndBlockDevice(distro linuxDistro, provisioner infrastructureProvisioner, f miniInfraDependentTest) { 122 By("Provisioning minikube node") 123 start := time.Now() 124 nodes, err := provisioner.ProvisionNodes(NodeCount{Worker: 1}, distro, []string{"block_device"}...) 125 if !leaveIt() { 126 defer provisioner.TerminateNodes(nodes) 127 } 128 Expect(err).ToNot(HaveOccurred()) 129 fmt.Println("Provisioning node took", time.Since(start)) 130 131 By("Waiting until nodes are SSH-accessible") 132 start = time.Now() 133 sshKey := provisioner.SSHKey() 134 err = waitForSSH(nodes, sshKey) 135 Expect(err).ToNot(HaveOccurred()) 136 fmt.Println("Waiting for SSH took", time.Since(start)) 137 138 f(nodes.worker[0], sshKey) 139 } 140 141 // SubDescribe allows you to define specifications inside another spec. 142 // We have found the need for this because Gingko does not support 143 // serializing a subset of tests when running in parallel. This means 144 // that we must define multiple specs inside a parent It() block. 145 // Use this when it is truly needed. 146 // 147 // Example: 148 // Describe("the foo service", func() { 149 // It("should be deployed successfully", func() { 150 // // some assertions here... 151 // sub := SubDescribe("should return 200", func() error { 152 // // call service and return error if not 200 153 // }) 154 // }) 155 // }) 156 func SubDescribe(name string) *subTest { 157 return &subTest{name: name} 158 } 159 160 type subTest struct { 161 name string 162 specs []string 163 errors []error 164 } 165 166 func (sub *subTest) It(name string, f func() error) { 167 By(fmt.Sprintf("Running spec: %s - %s", sub.name, name)) 168 sub.specs = append(sub.specs, name) 169 sub.errors = append(sub.errors, f()) 170 } 171 172 func (sub *subTest) Check() { 173 var failed bool 174 for _, e := range sub.errors { 175 if e != nil { 176 failed = true 177 break 178 } 179 } 180 if failed { 181 // Print report and fail test 182 sub.printReport() 183 Fail("Failed: " + sub.name) 184 } 185 } 186 187 func (sub *subTest) printReport() { 188 fmt.Println(sub.name) 189 for i, spec := range sub.specs { 190 if sub.errors[i] != nil { 191 fmt.Printf("%s: FAILED: %v\n", spec, sub.errors[i]) 192 } else { 193 fmt.Printf("%s: PASSED\n", spec) 194 } 195 } 196 }