go.undefinedlabs.com/scopeagent@v0.4.2/instrumentation/nethttp/nethttp_test.go (about)

     1  package nethttp
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"testing"
    10  
    11  	"go.undefinedlabs.com/scopeagent"
    12  	"go.undefinedlabs.com/scopeagent/agent"
    13  	testing2 "go.undefinedlabs.com/scopeagent/instrumentation/testing"
    14  	"go.undefinedlabs.com/scopeagent/tracer"
    15  )
    16  
    17  var r *tracer.InMemorySpanRecorder
    18  
    19  func TestMain(m *testing.M) {
    20  	PatchHttpDefaultClient(WithPayloadInstrumentation(), WithStacktrace())
    21  
    22  	// Test tracer
    23  	r = tracer.NewInMemoryRecorder()
    24  	testing2.PatchTestingLogger()
    25  	os.Exit(scopeagent.Run(m, agent.WithRecorders(r)))
    26  }
    27  
    28  func TestHttpClient(t *testing.T) {
    29  	testCtx := scopeagent.GetContextFromTest(t)
    30  	r.Reset()
    31  
    32  	req, err := http.NewRequest("GET", "https://www.google.com/", nil)
    33  	if err != nil {
    34  		t.Fatalf("%+v", err)
    35  	}
    36  	req = req.WithContext(testCtx)
    37  	resp, err := http.DefaultClient.Do(req)
    38  	if err != nil {
    39  		t.Fatalf("%+v", err)
    40  	}
    41  	if resp.StatusCode != 200 {
    42  		t.Fatalf("server returned %d status code", resp.StatusCode)
    43  	}
    44  	resp.Body.Close()
    45  
    46  	spans := r.GetSpans()
    47  	if len(spans) != 1 {
    48  		t.Fatalf("there aren't the right number of spans: %d", len(spans))
    49  	}
    50  	checkTags(t, spans[0].Tags, map[string]string{
    51  		"component":     "net/http",
    52  		"http.method":   "GET",
    53  		"http.url":      "https://www.google.com/",
    54  		"peer.hostname": "www.google.com",
    55  		"peer.port":     "443",
    56  	})
    57  }
    58  
    59  func TestHttpServer(t *testing.T) {
    60  	testCtx := scopeagent.GetContextFromTest(t)
    61  	r.Reset()
    62  
    63  	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
    64  		_, err := fmt.Fprintf(w, "Hello world")
    65  		if err != nil {
    66  			w.WriteHeader(500)
    67  			return
    68  		}
    69  	})
    70  	server := httptest.NewServer(Middleware(nil, MWPayloadInstrumentation()))
    71  
    72  	url := fmt.Sprintf("%s/hello", server.URL)
    73  	req, err := http.NewRequest("POST", url, bytes.NewReader([]byte("Hello world request")))
    74  	if err != nil {
    75  		t.Fatalf("%+v", err)
    76  	}
    77  	req = req.WithContext(testCtx)
    78  	resp, err := http.DefaultClient.Do(req)
    79  	if err != nil {
    80  		t.Fatalf("%+v", err)
    81  	}
    82  	if resp.StatusCode != 200 {
    83  		t.Fatalf("server returned %d status code", resp.StatusCode)
    84  	}
    85  	resp.Body.Close()
    86  	server.Close()
    87  
    88  	spans := r.GetSpans()
    89  	if len(spans) != 2 {
    90  		t.Fatalf("there aren't the right number of spans: %d", len(spans))
    91  	}
    92  	checkTags(t, spans[0].Tags, map[string]string{
    93  		"component":             "net/http",
    94  		"http.method":           "POST",
    95  		"http.url":              "/hello",
    96  		"span.kind":             "server",
    97  		"http.status_code":      "200",
    98  		"http.request_payload":  "Hello world request",
    99  		"http.response_payload": "Hello world",
   100  	})
   101  	checkTags(t, spans[1].Tags, map[string]string{
   102  		"component":             "net/http",
   103  		"http.method":           "POST",
   104  		"http.url":              url,
   105  		"peer.ipv4":             "127.0.0.1",
   106  		"span.kind":             "client",
   107  		"http.request_payload":  "Hello world request",
   108  		"http.response_payload": "Hello world",
   109  	})
   110  }
   111  
   112  func checkTags(t *testing.T, tags map[string]interface{}, expected map[string]string) {
   113  	for eK, eV := range expected {
   114  		if ok, aV := checkTag(tags, eK, eV); !ok {
   115  			if aV == "" {
   116  				t.Fatalf("the tag with key = '%s' was not found in the span tags", eK)
   117  			} else {
   118  				t.Fatalf("the tag with key = '%s' has a different value in the span tags. Expected = '%s', Actual = '%s'", eK, eV, aV)
   119  			}
   120  		}
   121  	}
   122  	t.Log("all tags ok.")
   123  }
   124  
   125  func checkTag(tags map[string]interface{}, key string, expectedValue string) (bool, string) {
   126  	if val, ok := tags[key]; ok {
   127  		sVal := fmt.Sprint(val)
   128  		return expectedValue == sVal, sVal
   129  	}
   130  	return false, ""
   131  }