github.com/newrelic/go-agent@v3.26.0+incompatible/internal/utilization/provider_test.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package utilization
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"errors"
    10  	"net/http"
    11  	"testing"
    12  )
    13  
    14  // Cross agent test types common to each provider's set of test cases.
    15  type testCase struct {
    16  	TestName            string                  `json:"testname"`
    17  	URIs                map[string]jsonResponse `json:"uri"`
    18  	EnvVars             map[string]envResponse  `json:"env_vars"`
    19  	ExpectedVendorsHash vendors                 `json:"expected_vendors_hash"`
    20  	ExpectedMetrics     map[string]metric       `json:"expected_metrics"`
    21  }
    22  
    23  type envResponse struct {
    24  	Response string `json:"response"`
    25  	Timeout  bool   `json:"timeout"`
    26  }
    27  
    28  type jsonResponse struct {
    29  	Response json.RawMessage `json:"response"`
    30  	Timeout  bool            `json:"timeout"`
    31  }
    32  
    33  type metric struct {
    34  	CallCount int `json:"call_count"`
    35  }
    36  
    37  var errTimeout = errors.New("timeout")
    38  
    39  type mockTransport struct {
    40  	t         *testing.T
    41  	responses map[string]jsonResponse
    42  }
    43  
    44  type mockBody struct {
    45  	bytes.Reader
    46  	closed bool
    47  	t      *testing.T
    48  }
    49  
    50  func (m *mockTransport) RoundTrip(r *http.Request) (*http.Response, error) {
    51  	for match, response := range m.responses {
    52  		if r.URL.String() == match {
    53  			return m.respond(response)
    54  		}
    55  	}
    56  
    57  	m.t.Errorf("Unknown request URI: %s", r.URL.String())
    58  	return nil, nil
    59  }
    60  
    61  func (m *mockTransport) respond(resp jsonResponse) (*http.Response, error) {
    62  	if resp.Timeout {
    63  		return nil, errTimeout
    64  	}
    65  
    66  	return &http.Response{
    67  		Status:     "200 OK",
    68  		StatusCode: 200,
    69  		Body: &mockBody{
    70  			t:      m.t,
    71  			Reader: *bytes.NewReader(resp.Response),
    72  		},
    73  	}, nil
    74  }
    75  
    76  // This function is included simply so that http.Client doesn't complain.
    77  func (m *mockTransport) CancelRequest(r *http.Request) {}
    78  
    79  func (m *mockBody) Close() error {
    80  	if m.closed {
    81  		m.t.Error("Close of already closed connection!")
    82  	}
    83  
    84  	m.closed = true
    85  	return nil
    86  }
    87  
    88  func (m *mockBody) ensureClosed() {
    89  	if !m.closed {
    90  		m.t.Error("Connection was not closed")
    91  	}
    92  }
    93  
    94  func TestNormaliseValue(t *testing.T) {
    95  	testCases := []struct {
    96  		name     string
    97  		input    string
    98  		expected string
    99  		isError  bool
   100  	}{
   101  		{
   102  			name:     "Valid - empty",
   103  			input:    "",
   104  			expected: "",
   105  			isError:  false,
   106  		},
   107  		{
   108  			name:     "Valid - symbols",
   109  			input:    ". /-_",
   110  			expected: ". /-_",
   111  			isError:  false,
   112  		},
   113  		{
   114  			name:     "Valid - string",
   115  			input:    "simplesentence",
   116  			expected: "simplesentence",
   117  			isError:  false,
   118  		},
   119  		{
   120  			name: "Invalid - More than 255",
   121  			input: `256256256256256256256256256256256256256256256256256256256256
   122  			256256256256256256256256256256256256256256256256256256256256256256256256
   123  			256256256256256256256256256256256256256256256256256256256256256256256256
   124  			2562562562562562562562562562562562562562562562562562`,
   125  			expected: "",
   126  			isError:  true,
   127  		},
   128  	}
   129  
   130  	for _, tc := range testCases {
   131  		actual, err := normalizeValue(tc.input)
   132  
   133  		if tc.isError && err == nil {
   134  			t.Fatalf("%s: expected error; got nil", tc.name)
   135  		} else if !tc.isError {
   136  			if err != nil {
   137  				t.Fatalf("%s: expected not error; got: %v", tc.name, err)
   138  			}
   139  			if tc.expected != actual {
   140  				t.Fatalf("%s: expected: %s; got: %s", tc.name, tc.expected, actual)
   141  			}
   142  		}
   143  	}
   144  }