Skip to content

Instantly share code, notes, and snippets.

@jodosha
Last active August 6, 2023 08:17
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save jodosha/885dd981c657f599952b9c5df8f6b812 to your computer and use it in GitHub Desktop.
How To Test Go HTTPS services

How To Test Go HTTPS services

Usage

➜ mkdir -p $GOPATH/src/github.com/jodosha && cd $GOPATH/src/github.com/jodosha
➜ git clone https://gist.github.com/jodosha/885dd981c657f599952b9c5df8f6b812 microservice && cd microservice
➜ chmod +x certificate.sh && ./certificate.sh
➜ go test -v
#!/bin/bash
go run $GOROOT/src/crypto/tls/generate_cert.go --rsa-bits 1024 --host 127.0.0.1,::1,localhost --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
package microservice
import (
"fmt"
"net/http"
)
func NewServer(port string) *http.Server {
addr := fmt.Sprintf(":%s", port)
mux := http.NewServeMux()
mux.HandleFunc("/", handler)
return &http.Server{
Addr: addr,
Handler: mux,
}
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
package microservice
import (
"bytes"
"crypto/tls"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
"time"
)
var (
port = "8080"
httpsPort = "8081"
)
//
// Unit Tests
//
func TestHandler(t *testing.T) {
expected := []byte("Hello World")
req, err := http.NewRequest("GET", buildUrl("/"), nil)
if err != nil {
t.Fatal(err)
}
res := httptest.NewRecorder()
handler(res, req)
if res.Code != http.StatusOK {
t.Errorf("Response code was %v; want 200", res.Code)
}
if bytes.Compare(expected, res.Body.Bytes()) != 0 {
t.Errorf("Response body was '%v'; want '%v'", expected, res.Body)
}
}
//
// Integration Tests
//
func TestHTTPServer(t *testing.T) {
srv := NewServer(port)
go srv.ListenAndServe()
defer srv.Close()
time.Sleep(100 * time.Millisecond)
res, err := http.Get(buildUrl("/"))
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
t.Errorf("Response code was %v; want 200", res.StatusCode)
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
expected := []byte("Hello World")
if bytes.Compare(expected, body) != 0 {
t.Errorf("Response body was '%v'; want '%v'", expected, body)
}
}
func TestHTTPSServer(t *testing.T) {
srv := NewServer(httpsPort)
go srv.ListenAndServeTLS("cert.pem", "key.pem")
defer srv.Close()
time.Sleep(100 * time.Millisecond)
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
res, err := client.Get(buildSecureUrl("/"))
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
t.Errorf("Response code was %v; want 200", res.StatusCode)
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
expected := []byte("Hello World")
if bytes.Compare(expected, body) != 0 {
t.Errorf("Response body was '%v'; want '%v'", expected, body)
}
}
//
// Private Helpers
//
func buildUrl(path string) string {
return urlFor("http", port, path)
}
func buildSecureUrl(path string) string {
return urlFor("https", httpsPort, path)
}
func urlFor(scheme string, serverPort string, path string) string {
return scheme + "://localhost:" + serverPort + path
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment