github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/prober/multihttp/multihttp_test.go (about)

     1  package multihttp
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/grafana/synthetic-monitoring-agent/internal/k6runner"
    11  	"github.com/grafana/synthetic-monitoring-agent/internal/model"
    12  	"github.com/grafana/synthetic-monitoring-agent/internal/testhelper"
    13  	sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
    14  	"github.com/rs/zerolog"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestNewProber(t *testing.T) {
    19  	ctx, cancel := testhelper.Context(context.Background(), t)
    20  	t.Cleanup(cancel)
    21  
    22  	logger := zerolog.New(zerolog.NewTestWriter(t))
    23  
    24  	testcases := map[string]struct {
    25  		check         model.Check
    26  		expectFailure bool
    27  	}{
    28  		"valid": {
    29  			expectFailure: false,
    30  			check: model.Check{
    31  				Check: sm.Check{
    32  					Id:        1,
    33  					Target:    "http://www.example.org",
    34  					Job:       "test",
    35  					Frequency: 10 * 1000,
    36  					Timeout:   10 * 1000,
    37  					Probes:    []int64{1},
    38  					Settings: sm.CheckSettings{
    39  						Multihttp: &sm.MultiHttpSettings{
    40  							Entries: []*sm.MultiHttpEntry{
    41  								{
    42  									Request: &sm.MultiHttpEntryRequest{
    43  										Url: "http://www.example.org",
    44  										QueryFields: []*sm.QueryField{
    45  											{
    46  												Name:  "q",
    47  												Value: "${v}",
    48  											},
    49  										},
    50  									},
    51  								},
    52  							},
    53  						},
    54  					},
    55  				},
    56  			},
    57  		},
    58  		"settings must be valid": {
    59  			expectFailure: true,
    60  			check: model.Check{
    61  				Check: sm.Check{
    62  					Id:        2,
    63  					Target:    "http://www.example.org",
    64  					Job:       "test",
    65  					Frequency: 10 * 1000,
    66  					Timeout:   10 * 1000,
    67  					Probes:    []int64{1},
    68  					Settings: sm.CheckSettings{
    69  						Multihttp: &sm.MultiHttpSettings{
    70  							Entries: []*sm.MultiHttpEntry{
    71  								// This is invalid because the requsest does not have a URL
    72  								{},
    73  							},
    74  						},
    75  					},
    76  				},
    77  			},
    78  		},
    79  		"must contain multihttp settings": {
    80  			expectFailure: true,
    81  			check: model.Check{
    82  				Check: sm.Check{
    83  					Id:        3,
    84  					Target:    "http://www.example.org",
    85  					Job:       "test",
    86  					Frequency: 10 * 1000,
    87  					Timeout:   10 * 1000,
    88  					Probes:    []int64{1},
    89  					Settings: sm.CheckSettings{
    90  						// The settings are valid for ping, but not for multihttp
    91  						Ping: &sm.PingSettings{},
    92  					},
    93  				},
    94  			},
    95  		},
    96  		"header overwrite protection is case-insensitive": {
    97  			expectFailure: false,
    98  			check: model.Check{
    99  				Check: sm.Check{
   100  					Id:        4,
   101  					Target:    "http://www.example.org",
   102  					Job:       "test",
   103  					Frequency: 10 * 1000,
   104  					Timeout:   10 * 1000,
   105  					Probes:    []int64{1},
   106  					Settings: sm.CheckSettings{
   107  						Multihttp: &sm.MultiHttpSettings{
   108  							Entries: []*sm.MultiHttpEntry{
   109  								{
   110  									Request: &sm.MultiHttpEntryRequest{
   111  										Url:     "http://www.example.org",
   112  										Headers: []*sm.HttpHeader{{Name: "X-sM-Id", Value: "9880-9880"}},
   113  									},
   114  								},
   115  							},
   116  						},
   117  					},
   118  				},
   119  			},
   120  		},
   121  	}
   122  
   123  	for name, tc := range testcases {
   124  		t.Run(name, func(t *testing.T) {
   125  			var (
   126  				runner noopRunner
   127  				store  testhelper.NoopSecretStore
   128  			)
   129  
   130  			checkId := tc.check.Id
   131  			reservedHeaders := http.Header{}
   132  			reservedHeaders.Add("x-sm-id", fmt.Sprintf("%d-%d", checkId, checkId))
   133  
   134  			p, err := NewProber(ctx, tc.check, logger, runner, reservedHeaders, store)
   135  			if tc.expectFailure {
   136  				require.Error(t, err)
   137  				return
   138  			}
   139  
   140  			requestHeaders := tc.check.Settings.Multihttp.Entries[0].Request.Headers
   141  			require.Equal(t, len(requestHeaders), 1) // reserved header is present
   142  
   143  			require.Equal(t, requestHeaders[0].Name, "X-Sm-Id")
   144  			require.Equal(t, requestHeaders[0].Value, fmt.Sprintf("%d-%d", checkId, checkId))
   145  
   146  			require.NoError(t, err)
   147  			require.Equal(t, proberName, p.module.Prober)
   148  			require.Equal(t, 10*time.Second, time.Duration(p.module.Script.Settings.Timeout)*time.Millisecond)
   149  			// TODO: check script
   150  		})
   151  	}
   152  }
   153  
   154  type noopRunner struct{}
   155  
   156  func (noopRunner) WithLogger(logger *zerolog.Logger) k6runner.Runner {
   157  	var r noopRunner
   158  	return r
   159  }
   160  
   161  func (noopRunner) Run(ctx context.Context, script k6runner.Script, secretStore k6runner.SecretStore, _ string) (*k6runner.RunResponse, error) {
   162  	return &k6runner.RunResponse{}, nil
   163  }
   164  
   165  func (noopRunner) Versions(_ context.Context) <-chan []string {
   166  	return nil // Blocks forever if read.
   167  }