sharedtest

package
v6.9.1 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2023 License: Apache-2.0 Imports: 37 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 main core package, core/relayenv, or core/streams. 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)},
		},
	},
	{
		Kind: ldstoreimpl.Segments(),
		Items: []ldstoretypes.KeyedItemDescriptor{
			{Key: Segment1.Key, Item: SegmentDesc(Segment1)},
		},
	},
}
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(lduser.KeyAttribute, 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 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 added in v6.2.0

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

BuildRequestWithAuth creates a GET request with an Authorization header.

func CallHandlerAndAwaitStatus added in v6.1.6

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 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 ExpectNoStreamChEvent added in v6.4.2

func ExpectNoStreamChEvent(t *testing.T, ch <-chan eventsource.Event, timeout time.Duration)

ExpectNoStreamChEvent causes a test failure if an event is seen on an SSE stream channel.

func ExpectNoStreamEvent added in v6.2.0

func ExpectNoStreamEvent(t *testing.T, stream *eventsource.Stream, timeout time.Duration)

ExpectNoStreamEvent causes a test failure if an event is seen on an SSE stream.

func ExpectNoTestRequests

func ExpectNoTestRequests(t *testing.T, ch <-chan httphelpers.HTTPRequestInfo, timeout time.Duration)

ExpectNoTestRequests causes a test failure if an httphelpers request-capturing channel is not empty.

func ExpectStreamChEvent added in v6.4.2

func ExpectStreamChEvent(t *testing.T, ch <-chan eventsource.Event, timeout time.Duration) eventsource.Event

ExpectStreamChEvent is a shortcut for reading from an SSE stream channel with a timeout.

func ExpectStreamEvent added in v6.2.0

func ExpectStreamEvent(t *testing.T, stream *eventsource.Stream, timeout time.Duration) eventsource.Event

ExpectStreamEvent is a shortcut for reading from an SSE stream with a timeout.

func ExpectTestRequest

func ExpectTestRequest(t *testing.T, ch <-chan httphelpers.HTTPRequestInfo, timeout time.Duration) httphelpers.HTTPRequestInfo

ExpectTestRequest is a shortcut for reading from an httphelpers request-capturing channel with a timeout.

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 added in v6.4.0

func MakeBasicHTTPConfig() httpconfig.HTTPConfig

func MakeEnvConfigs

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

func MakeEvalBody

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

func MakeSDKEvalEndpointRequest added in v6.2.0

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

func MakeSDKStreamEndpointRequest added in v6.2.0

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) interfaces.DataStore

func NewInMemoryStore

func NewInMemoryStore() interfaces.DataStore

func SegmentDesc

func SegmentDesc(segment ldmodel.Segment) ldstoretypes.ItemDescriptor

func ToBase64 added in v6.2.0

func ToBase64(s string) string

ToBase64 is a shortcut for base64 encoding.

func UpsertFlag

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

func UpsertSegment

func UpsertSegment(store interfaces.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

func WithTempDir added in v6.1.0

func WithTempDir(fn func(path string))

WithTempDir creates a temporary directory, calls the function with its path, then removes it.

Types

type BodyMatcher

type BodyMatcher func(t *testing.T, body []byte)

func ExpectBody

func ExpectBody(expectedBody string) BodyMatcher

func ExpectJSONBody

func ExpectJSONBody(expectedBody string) BodyMatcher

func ExpectJSONEntity

func ExpectJSONEntity(entity interface{}) BodyMatcher

type DataSourceThatNeverStarts added in v6.1.7

type DataSourceThatNeverStarts struct{}

func (DataSourceThatNeverStarts) Close added in v6.1.7

func (d DataSourceThatNeverStarts) Close() error

func (DataSourceThatNeverStarts) IsInitialized added in v6.1.7

func (d DataSourceThatNeverStarts) IsInitialized() bool

func (DataSourceThatNeverStarts) Start added in v6.1.7

func (d DataSourceThatNeverStarts) Start(chan<- struct{})

type DataSourceThatStartsWithoutInitializing added in v6.1.7

type DataSourceThatStartsWithoutInitializing struct{}

func (DataSourceThatStartsWithoutInitializing) Close added in v6.1.7

func (DataSourceThatStartsWithoutInitializing) IsInitialized added in v6.1.7

func (DataSourceThatStartsWithoutInitializing) Start added in v6.1.7

func (d DataSourceThatStartsWithoutInitializing) Start(closeWhenReady chan<- struct{})

type ExistingDataSourceFactory added in v6.1.7

type ExistingDataSourceFactory struct{ Instance interfaces.DataSource }

func (ExistingDataSourceFactory) CreateDataSource added in v6.1.7

type ExistingDataStoreFactory

type ExistingDataStoreFactory struct {
	Instance interfaces.DataStore
}

func (ExistingDataStoreFactory) CreateDataStore

type NoOpSDKBigSegmentStore added in v6.4.2

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 added in v6.4.2

func (m *NoOpSDKBigSegmentStore) Close() error

func (*NoOpSDKBigSegmentStore) GetMetadata added in v6.4.2

func (*NoOpSDKBigSegmentStore) GetUserMembership added in v6.4.2

func (m *NoOpSDKBigSegmentStore) GetUserMembership(
	userHash string,
) (interfaces.BigSegmentMembership, error)

type ReceivedItemUpdate

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

type SDKContextImpl

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

func (SDKContextImpl) GetBasic

func (SDKContextImpl) GetHTTP

func (SDKContextImpl) GetLogging

type SDKRequestVariant added in v6.2.0

type SDKRequestVariant int

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

const (
	// Evalx indicates that a client-side request wants the "evalx" format rather than the older
	// value-only format.
	Evalx SDKRequestVariant = 2

	// 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 config.SDKCredential

func (UnsupportedSDKCredential) GetAuthorizationHeaderValue

func (k UnsupportedSDKCredential) GetAuthorizationHeaderValue() 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.
Package testsuites contains shared test suites that should be run against every version of Relay to validate the behavior of the core code.
Package testsuites contains shared test suites that should be run against every version of Relay to validate the behavior of the core code.

Jump to

Keyboard shortcuts

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