sharedtest

package
v8.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2024 License: Apache-2.0 Imports: 39 Imported by: 0

Documentation

Overview

Package sharedtest provides helper code and test data that may be used by tests in all Relay components and distributions.

Non-test code should never import this package or any of its subpackages.

To avoid circular references, code in this package cannot reference the relayenv or streams package. Any helpers that need to do so must be in a subpackage.

Index

Constants

View Source
const (
	// The "undefined" values are well-formed, but do not match any environment in our test data.
	UndefinedSDKKey    = config.SDKKey("sdk-99999999-9999-4999-8999-999999999999")
	UndefinedMobileKey = config.MobileKey("mob-99999999-9999-4999-8999-999999999999")
	UndefinedEnvID     = config.EnvironmentID("999999999999999999999999")

	// The "malformed" values contain an unsupported authorization scheme.
	MalformedSDKKey    = config.SDKKey("fake_key sdk-99999999-9999-4999-8999-999999999999")
	MalformedMobileKey = config.MobileKey("fake_key mob-99999999-9999-4999-8999-999999999999")
)
View Source
const SimpleUserJSON = `{"key":"userkey"}`

SimpleUserJSON is a basic user.

Variables

View Source
var AllData = []ldstoretypes.Collection{
	{
		Kind: ldstoreimpl.Features(),
		Items: []ldstoretypes.KeyedItemDescriptor{
			{Key: Flag1ServerSide.Flag.Key, Item: FlagDesc(Flag1ServerSide.Flag)},
			{Key: Flag2ServerSide.Flag.Key, Item: FlagDesc(Flag2ServerSide.Flag)},
			{Key: Flag3ServerSideNotMobile.Flag.Key, Item: FlagDesc(Flag3ServerSideNotMobile.Flag)},
			{Key: Flag4ClientSide.Flag.Key, Item: FlagDesc(Flag4ClientSide.Flag)},
			{Key: Flag5ClientSide.Flag.Key, Item: FlagDesc(Flag5ClientSide.Flag)},
			{Key: Flag6ClientSideNotMobile.Flag.Key, Item: FlagDesc(Flag6ClientSideNotMobile.Flag)},
			{Key: Flag7Mobile.Flag.Key, Item: FlagDesc(Flag7Mobile.Flag)},
			{Key: Flag8ContextAware.Flag.Key, Item: FlagDesc(Flag8ContextAware.Flag)},
		},
	},
	{
		Kind: ldstoreimpl.Segments(),
		Items: []ldstoretypes.KeyedItemDescriptor{
			{Key: Segment1.Key, Item: SegmentDesc(Segment1)},
		},
	},
}
View Source
var BasicUserForTestFlags = ldcontext.New("me")
View Source
var EnvClientSide = TestEnv{
	Name: "ProjectName JSClientSideEnv",
	Config: config.EnvConfig{
		SDKKey: config.SDKKey("sdk-98e2b0b4-2688-4a59-9810-1e0e3d7e42d1"),
		EnvID:  config.EnvironmentID("507f1f77bcf86cd799439011"),
	},
}
View Source
var EnvClientSideSecureMode = TestEnv{
	Name: "ProjectName JSClientSideSecureModeEnv",
	Config: config.EnvConfig{
		SDKKey:     config.SDKKey("sdk-98e2b0b4-2688-4a59-9810-1e0e3d7e42d9"),
		EnvID:      config.EnvironmentID("507f1f77bcf86cd799439019"),
		SecureMode: true,
	},
}
View Source
var EnvMain = TestEnv{
	Name: "ProjectName ServerSideEnv",
	Config: config.EnvConfig{
		SDKKey: config.SDKKey("sdk-98e2b0b4-2688-4a59-9810-1e0e3d7e42d0"),
	},
}
View Source
var EnvMobile = TestEnv{
	Name: "ProjectName MobileEnv",
	Config: config.EnvConfig{
		SDKKey:    config.SDKKey("sdk-98e2b0b4-2688-4a59-9810-1e0e3d7e42d2"),
		MobileKey: config.MobileKey("mob-98e2b0b4-2688-4a59-9810-1e0e3d7e42db"),
	},
}
View Source
var EnvWithAllCredentials = TestEnv{
	Name: "ProjectName EnvWithAllCredentials",
	Config: config.EnvConfig{
		SDKKey:    config.SDKKey("sdk-98e2b0b4-2688-4a59-9810-2e1e4d8e52e9"),
		MobileKey: config.MobileKey("mob-98e2b0b4-2688-4a59-9810-1e0e3d7e42ec"),
		EnvID:     config.EnvironmentID("507f1f77bcf86cd79943902a"),
	},
}
View Source
var EnvWithTTL = TestEnv{
	Name: "ProjectName ServerSideEnvWithTTL",
	Config: config.EnvConfig{
		SDKKey: config.SDKKey("sdk-98e2b0b4-2688-4a59-9810-1e0e3d7e42d5"),
		TTL:    ct.NewOptDuration(10 * time.Minute),
	},
}
View Source
var Flag1ServerSide = TestFlag{
	Flag:              ldbuilders.NewFlagBuilder("some-flag-key").OffVariation(0).Variations(ldvalue.Bool(true)).Version(2).Build(),
	ExpectedValue:     true,
	ExpectedVariation: 0,
	ExpectedReason:    map[string]interface{}{"kind": "OFF"},
}
View Source
var Flag2ServerSide = TestFlag{
	Flag:              ldbuilders.NewFlagBuilder("another-flag-key").On(true).FallthroughVariation(0).Variations(ldvalue.Int(3)).Version(1).Build(),
	ExpectedValue:     3,
	ExpectedVariation: 0,
	ExpectedReason:    map[string]interface{}{"kind": "FALLTHROUGH"},
}
View Source
var Flag3ServerSideNotMobile = TestFlag{
	Flag:           ldbuilders.NewFlagBuilder("off-variation-key").Version(3).ClientSideUsingMobileKey(false).Build(),
	ExpectedValue:  nil,
	ExpectedReason: map[string]interface{}{"kind": "OFF"},
}
View Source
var Flag4ClientSide = TestFlag{
	Flag: ldbuilders.NewFlagBuilder("client-flag-key").OffVariation(0).Variations(ldvalue.Int(5)).Version(2).
		ClientSideUsingEnvironmentID(true).Build(),
	ExpectedValue:     5,
	ExpectedVariation: 0,
	ExpectedReason:    map[string]interface{}{"kind": "OFF"},
}
View Source
var Flag5ClientSide = TestFlag{
	Flag: ldbuilders.NewFlagBuilder("fallthrough-experiment-flag-key").On(true).FallthroughVariation(0).Variations(ldvalue.Int(3)).
		TrackEventsFallthrough(true).ClientSideUsingEnvironmentID(true).Version(1).Build(),
	ExpectedValue:  3,
	ExpectedReason: map[string]interface{}{"kind": "FALLTHROUGH"},
	IsExperiment:   true,
}
View Source
var Flag6ClientSideNotMobile = TestFlag{
	Flag: ldbuilders.NewFlagBuilder("rule-match-experiment-flag-key").On(true).
		AddRule(ldbuilders.NewRuleBuilder().ID("rule-id").Variation(0).TrackEvents(true).
			Clauses(ldbuilders.Negate(ldbuilders.Clause(ldattr.KeyAttr, ldmodel.OperatorIn, ldvalue.String("not-a-real-user-key"))))).
		Variations(ldvalue.Int(4)).ClientSideUsingEnvironmentID(true).ClientSideUsingMobileKey(false).Version(1).Build(),
	ExpectedValue:  4,
	ExpectedReason: map[string]interface{}{"kind": "RULE_MATCH", "ruleIndex": 0, "ruleId": "rule-id"},
	IsExperiment:   true,
}
View Source
var Flag7Mobile = TestFlag{
	Flag: ldbuilders.NewFlagBuilder("mobile-flag-key").OffVariation(0).Variations(ldvalue.Int(5)).Version(2).
		ClientSideUsingMobileKey(true).Build(),
	ExpectedValue:     5,
	ExpectedVariation: 0,
	ExpectedReason:    map[string]interface{}{"kind": "OFF"},
}
View Source
var Flag8ContextAware = TestFlag{

	Flag: ldbuilders.NewFlagBuilder("context-aware-flag-key").
		On(true).
		FallthroughVariation(0).
		Variations(ldvalue.String("wrong"), ldvalue.String("right")).
		AddRule(
			ldbuilders.NewRuleBuilder().Variation(1).ID("r").Clauses(
				ldbuilders.ClauseWithKind("user", "key", "in", ldvalue.String(BasicUserForTestFlags.Key())),
			),
		).
		ClientSideUsingEnvironmentID(true).
		ClientSideUsingMobileKey(true).
		Version(1).Build(),
	ExpectedValue:     "right",
	ExpectedVariation: 1,
	ExpectedReason:    map[string]interface{}{"kind": "RULE_MATCH", "ruleId": "r", "ruleIndex": 0},
}
View Source
var Segment1 = ldbuilders.NewSegmentBuilder("segment-key").Build()

Functions

func AddQueryParam

func AddQueryParam(url, query string) string

AddQueryParam is a shortcut for concatenating a query string to a URL that may or may not have one.

func AssertEndpointSupportsOptionsRequest

func AssertEndpointSupportsOptionsRequest(
	t *testing.T,
	handler http.Handler,
	url, usualMethod string,
)

func AssertExpectedCORSHeaders

func AssertExpectedCORSHeaders(t *testing.T, resp *http.Response, endpointMethod string, host string)

func AssertJSONPathMatch

func AssertJSONPathMatch(t *testing.T, expected interface{}, inValue ldvalue.Value, path ...string)

AssertJSONPathMatch checks for a value within a nested JSON data structure.

func AssertNonStreamingHeaders

func AssertNonStreamingHeaders(t *testing.T, h http.Header)

func AssertStreamingContentType

func AssertStreamingContentType(t *testing.T, h http.Header)

func AssertStreamingHeaders

func AssertStreamingHeaders(t *testing.T, h http.Header)

func BuildRequest

func BuildRequest(method, url string, body []byte, headers http.Header) *http.Request

BuildRequest is a simple shortcut for creating a request that may or may not have a body.

func BuildRequestWithAuth

func BuildRequestWithAuth(method, url string, authKey credential.SDKCredential, body []byte) *http.Request

BuildRequestWithAuth creates a GET request with an Authorization header.

func CallHandlerAndAwaitStatus

func CallHandlerAndAwaitStatus(t *testing.T, handler http.Handler, req *http.Request, timeout time.Duration) int

CallHandlerAndAwaitStatus calls an HTTP handler directly with a request and then blocks until the handler has started a response, returning the response status (and cancelling the request). We use this when we don't need to wait for a complete response (or when there's no such thing as a complete response, as in the case of streaming endpoints). It raises a fatal test failure if the timeout elapses before receiving a status.

func DataSourceThatNeverStarts

func DataSourceThatNeverStarts() subsystems.DataSource

func DataSourceThatStartsWithoutInitializing

func DataSourceThatStartsWithoutInitializing() subsystems.DataSource

func DeletedItem

func DeletedItem(version int) ldstoretypes.ItemDescriptor

func DoRequest

func DoRequest(req *http.Request, handler http.Handler) (*http.Response, []byte)

DoRequest is a shortcut for executing an endpoint handler against a request and getting the response.

func ExistingInstance

func ExistingInstance[T any](instance T) subsystems.ComponentConfigurer[T]

func ExpectBody

func ExpectBody(expectedBody string) m.Matcher

func ExpectJSONBody

func ExpectJSONBody(expectedBody string) m.Matcher

func ExpectJSONEntity

func ExpectJSONEntity(entity interface{}) m.Matcher

func ExpectNoBody

func ExpectNoBody() m.Matcher

func FlagsMap

func FlagsMap(testFlags []TestFlag) map[string]interface{}

func GetAvailablePort

func GetAvailablePort(t *testing.T) int

GetAvailablePort finds an available port (by creating and then immediately closing a listener) and returns the port number.

func MakeBasicHTTPConfig

func MakeBasicHTTPConfig() httpconfig.HTTPConfig

func MakeEnvConfigs

func MakeEnvConfigs(envs ...TestEnv) map[string]*config.EnvConfig

func MakeEvalBody

func MakeEvalBody(flags []TestFlag, reasons bool) string

func MakeSDKEvalEndpointRequest

func MakeSDKEvalEndpointRequest(baseURL string, kind basictypes.SDKKind, testEnv TestEnv, userJSON string, variant SDKRequestVariant) *http.Request

func MakeSDKStreamEndpointRequest

func MakeSDKStreamEndpointRequest(
	baseURL string,
	kind basictypes.StreamKind,
	testEnv TestEnv,
	userJSON string,
	variant SDKRequestVariant,
) *http.Request

MakeSDKStreamEndpointRequest creates a request to one of the streaming SDK endpoints.

func MakeStoreWithData

func MakeStoreWithData(initialized bool) subsystems.DataStore

func NewInMemoryStore

func NewInMemoryStore() subsystems.DataStore

func SegmentDesc

func SegmentDesc(segment ldmodel.Segment) ldstoretypes.ItemDescriptor

func ToBase64

func ToBase64(s string) string

ToBase64 is a shortcut for base64 encoding.

func UpsertFlag

func UpsertFlag(store subsystems.DataStore, flag ldmodel.FeatureFlag) (bool, error)

func UpsertSegment

func UpsertSegment(store subsystems.DataStore, segment ldmodel.Segment) (bool, error)

func WithListenerForAnyPort

func WithListenerForAnyPort(t *testing.T, fn func(net.Listener, int))

WithListenerForAnyPort creates a listener for an available port, calls the function with the listener and the port number, and then closes the listener.

func WithStreamRequest

func WithStreamRequest(
	t *testing.T,
	req *http.Request,
	handler http.Handler,
	action func(<-chan eventsource.Event),
) *http.Response

WithStreamRequest makes a request that should receive an SSE stream, and calls the given code with a channel that will read from that stream. A nil value is pushed to the channel when the stream closes or encounters an error.

func WithStreamRequestLines

func WithStreamRequestLines(
	t *testing.T,
	req *http.Request,
	handler http.Handler,
	action func(<-chan string),
) *http.Response

Types

type NoOpSDKBigSegmentStore

type NoOpSDKBigSegmentStore struct{}

NoOpSDKBigSegmentStore is a stub implementation of the SDK's BigSegmentStore (not the type of the same name that Relay uses internally).

func (*NoOpSDKBigSegmentStore) Close

func (m *NoOpSDKBigSegmentStore) Close() error

func (*NoOpSDKBigSegmentStore) GetMembership

func (m *NoOpSDKBigSegmentStore) GetMembership(
	contextHash string,
) (subsystems.BigSegmentMembership, error)

func (*NoOpSDKBigSegmentStore) GetMetadata

type ReceivedItemUpdate

type ReceivedItemUpdate struct {
	Kind ldstoretypes.DataKind
	Key  string
	Item ldstoretypes.ItemDescriptor
}

type SDKRequestVariant

type SDKRequestVariant int

SDKRequestVariant represents distinctions between endpoints that are not described in full by basictypes.SDKKind or basictypes.StreamKind.

const (
	// ReportMode means a client-side request should be done with REPORT rather than GET.
	ReportMode SDKRequestVariant = 4
)

type StreamRecorder

type StreamRecorder struct {
	*bufio.Writer
	*httptest.ResponseRecorder
}

StreamRecorder is an extension of ResponseRecorder to handle streaming content.

func NewStreamRecorder

func NewStreamRecorder() (StreamRecorder, io.Reader)

func (StreamRecorder) Flush

func (r StreamRecorder) Flush()

func (StreamRecorder) Write

func (r StreamRecorder) Write(data []byte) (int, error)

type TestEnv

type TestEnv struct {
	Name               string
	Config             config.EnvConfig
	ProjName           string
	ProjKey            string
	EnvName            string
	EnvKey             string
	ExpiringSDKKey     config.SDKKey
	ExpiringSDKKeyTime ldtime.UnixMillisecondTime
}

type TestFlag

type TestFlag struct {
	Flag              ldmodel.FeatureFlag
	ExpectedValue     interface{}
	ExpectedVariation int
	ExpectedReason    map[string]interface{}
	IsExperiment      bool
}

type TestMetricsData

type TestMetricsData map[string][]TestMetricsRow

TestMetricsData is a map of OpenCensus view names to row data.

func (TestMetricsData) HasRow

func (d TestMetricsData) HasRow(viewName string, expectedRow TestMetricsRow) bool

HasRow returns true if this row exists for the specified view name.

type TestMetricsExporter

type TestMetricsExporter struct {
	// contains filtered or unexported fields
}

TestMetricsExporter accumulates OpenCensus metrics for tests. It deaggregates the view data to make it easier to test for a specific row that we expect to see in the data.

func NewTestMetricsExporter

func NewTestMetricsExporter() *TestMetricsExporter

NewTestMetricsExporter creates a TestMetricsExporter.

func (*TestMetricsExporter) AwaitData

func (e *TestMetricsExporter) AwaitData(t *testing.T, timeout time.Duration, loggers ldlog.Loggers, fn func(TestMetricsData) bool)

AwaitData waits until matching view data is received.

func (*TestMetricsExporter) AwaitSpan

func (e *TestMetricsExporter) AwaitSpan(t *testing.T, timeout time.Duration) *trace.SpanData

func (*TestMetricsExporter) ExportSpan

func (e *TestMetricsExporter) ExportSpan(s *trace.SpanData)

ExportSpan is called by OpenCensus.

func (*TestMetricsExporter) ExportView

func (e *TestMetricsExporter) ExportView(viewData *view.Data)

ExportView is called by OpenCensus.

func (*TestMetricsExporter) WithExporter

func (e *TestMetricsExporter) WithExporter(fn func())

WithExporter registers the exporter, then calls the function, then unregisters the exporter. It also overrides the default OpenCensus reporting parameters to ensure that data is exported promptly.

type TestMetricsRow

type TestMetricsRow struct {
	Tags  map[string]string
	Count int64
	Sum   float64
}

TestMetricsRow is a simplified version of an OpenCensus view row.

type UnsupportedSDKCredential

type UnsupportedSDKCredential struct{} // implements credential.SDKCredential

func (UnsupportedSDKCredential) Compare

func (UnsupportedSDKCredential) Defined

func (k UnsupportedSDKCredential) Defined() bool

func (UnsupportedSDKCredential) GetAuthorizationHeaderValue

func (k UnsupportedSDKCredential) GetAuthorizationHeaderValue() string

func (UnsupportedSDKCredential) String

func (k UnsupportedSDKCredential) String() string

Directories

Path Synopsis
Package testclient contains test helpers that reference the SDK-related packages.
Package testclient contains test helpers that reference the SDK-related packages.
Package testenv contains test helpers that reference the relayenv package.
Package testenv contains test helpers that reference the relayenv package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL