github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/usage/usage_test.go (about)

     1  package usage
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"runtime"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/grafana/synthetic-monitoring-agent/internal/feature"
    13  	sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
    14  )
    15  
    16  func TestHTTPUsageReporter_Report(t *testing.T) {
    17  	// Create a test http server that intercepts requests to https://stats.grafana.net
    18  	t.Parallel()
    19  
    20  	var gotReport *report
    21  
    22  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    23  		defer r.Body.Close()
    24  
    25  		if err := json.NewDecoder(r.Body).Decode(&gotReport); err != nil {
    26  			w.WriteHeader(http.StatusBadRequest)
    27  			return
    28  		}
    29  		// Clear these values out as they're dynamic attributes that are not important to validate the result of
    30  		gotReport.UsageStatsId = ""
    31  		gotReport.CreatedAt = ""
    32  		gotReport.Report = ""
    33  
    34  		w.WriteHeader(http.StatusOK)
    35  	}))
    36  
    37  	defer ts.Close()
    38  
    39  	tests := map[string]struct {
    40  		endpoint       string
    41  		features       []string
    42  		probe          sm.Probe
    43  		wantErr        bool
    44  		expectedReport *report
    45  	}{
    46  		"Send over zero features": {
    47  			endpoint: ts.URL,
    48  			features: []string{},
    49  			expectedReport: &report{
    50  				Public:   false,
    51  				ProbeID:  1,
    52  				TenantID: 1,
    53  				Arch:     runtime.GOARCH,
    54  				OS:       runtime.GOOS,
    55  			},
    56  			probe: sm.Probe{
    57  				Id:       1,
    58  				TenantId: 1,
    59  				Public:   false,
    60  			},
    61  		},
    62  		"Send over a single features": {
    63  			endpoint: ts.URL,
    64  			expectedReport: &report{
    65  				Public:   false,
    66  				ProbeID:  1,
    67  				TenantID: 1,
    68  				Arch:     runtime.GOARCH,
    69  				OS:       runtime.GOOS,
    70  				Features: "k6",
    71  			},
    72  			probe: sm.Probe{
    73  				Id:       1,
    74  				TenantId: 1,
    75  				Public:   false,
    76  			},
    77  			features: []string{feature.K6},
    78  		},
    79  		"Send over a full list of features": {
    80  			endpoint: ts.URL,
    81  			expectedReport: &report{
    82  				Public:   false,
    83  				ProbeID:  1,
    84  				TenantID: 1,
    85  				Arch:     runtime.GOARCH,
    86  				OS:       runtime.GOOS,
    87  				Features: "experimental-dns-prober,k6,traceroute",
    88  			},
    89  			probe: sm.Probe{
    90  				Id:       1,
    91  				TenantId: 1,
    92  				Public:   false,
    93  			},
    94  			features: []string{feature.K6, feature.Traceroute, feature.ExperimentalDnsProber},
    95  		},
    96  	}
    97  	for name, tt := range tests {
    98  		t.Run(name, func(t *testing.T) {
    99  			features := feature.NewCollection()
   100  			for _, f := range tt.features {
   101  				_ = features.Set(f)
   102  			}
   103  
   104  			r := NewHTTPReporter(tt.endpoint)
   105  			if err := r.ReportProbe(t.Context(), tt.probe, features); (err != nil) != tt.wantErr {
   106  				t.Errorf("Report() error = %v, wantErr %v", err, tt.wantErr)
   107  			}
   108  
   109  			assert.Equal(t, tt.expectedReport, gotReport)
   110  		})
   111  	}
   112  }
   113  
   114  func TestNoOPUsageReporter_Report(t *testing.T) {
   115  	r := NewNoOPReporter()
   116  	if err := r.ReportProbe(t.Context(), sm.Probe{}, nil); err != nil {
   117  		t.Errorf("Report() error = %v", err)
   118  	}
   119  }
   120  
   121  func Test_hashOfProbe(t *testing.T) {
   122  	tests := map[string]struct {
   123  		p       sm.Probe
   124  		want    string
   125  		wantErr bool
   126  	}{
   127  		"Nil probe should return an error": {
   128  			p:       sm.Probe{},
   129  			want:    "4547005171780583226",
   130  			wantErr: false,
   131  		},
   132  		"Probe with an ID should generate a consistent hash": {
   133  			p: sm.Probe{
   134  				Id: 1,
   135  			},
   136  			want:    "10535204341849580461",
   137  			wantErr: false,
   138  		},
   139  		"Probe with everything set should return a consistent hash": {
   140  			p: sm.Probe{
   141  				Id:     1,
   142  				Region: "test",
   143  				Name:   "Some Name",
   144  				Public: true,
   145  			},
   146  			want:    "1162427638690750921",
   147  			wantErr: false,
   148  		},
   149  		"Probe with everything set but slightly different values should return a different hash value": {
   150  			p: sm.Probe{
   151  				Id:       10,
   152  				Region:   "test",
   153  				Name:     "Some Name",
   154  				Public:   true,
   155  				TenantId: 1,
   156  			},
   157  			want:    "9777170254191072896",
   158  			wantErr: false,
   159  		},
   160  	}
   161  	for name, tt := range tests {
   162  		t.Run(name, func(t *testing.T) {
   163  			got, err := hashOfProbe(tt.p)
   164  			if (err != nil) != tt.wantErr {
   165  				t.Errorf("hashOfProbe() error = %v, wantErr %v", err, tt.wantErr)
   166  			}
   167  
   168  			assert.Equalf(t, tt.want, got, "want=%v, got=%v", tt.want, got)
   169  		})
   170  	}
   171  }