Documentation
¶
Index ¶
- Constants
- Variables
- func CreateCustomerJWT(clientID, username, email string) string
- func CreateEnvironmentJWT(clientID, clientIP, deviceID string) string
- func CreateExternalJWT(clientID, username, email string, userID string) string
- func CreateInternalJWT(clientID, username, email string) string
- func CreateMultiStrategyTestSet() map[string]string
- func CreateResolveEntitiesRequest(entities ...*entity.Entity) *entityresolutionV2.ResolveEntitiesRequest
- func CreateTestEntityByClientID(clientID string) *entity.Entity
- func CreateTestEntityByEmail(email string) *entity.Entity
- func CreateTestEntityByUsername(username string) *entity.Entity
- func CreateTestJWT(clientID, username, email string) string
- func CreateTestJWTWithClaims(clientID, username, email string, additionalClaims map[string]interface{}) string
- func CreateTestToken(ephemeralID, clientID, username, email string) *entity.Token
- func ValidateEntityChainFlexible(chains []*entity.EntityChain, rule FlexibleChainValidationRule) error
- func ValidateEntityRepresentation(repr *entityresolutionV2.EntityRepresentation, originalID string, ...) error
- func WaitForContainer(_ context.Context, checkFunc func() error, maxRetries int, delay time.Duration) error
- type ChainContractTestSuite
- type ContainerConfig
- type ContainerManager
- func (cm *ContainerManager) GetHost() string
- func (cm *ContainerManager) GetMappedPort(ctx context.Context, containerPort string) (int, error)
- func (cm *ContainerManager) IsRunning() bool
- func (cm *ContainerManager) Start(ctx context.Context) error
- func (cm *ContainerManager) Stop(ctx context.Context) error
- type ContainerTestSuite
- func (suite *ContainerTestSuite) AddContainer(name string, config ContainerConfig)
- func (suite *ContainerTestSuite) GetContainer(name string) (*ContainerManager, bool)
- func (suite *ContainerTestSuite) GetContainerPort(ctx context.Context, containerName, containerPort string) (int, error)
- func (suite *ContainerTestSuite) StartAll(ctx context.Context) error
- func (suite *ContainerTestSuite) StopAll(ctx context.Context) error
- type ContractExpected
- type ContractInput
- type ContractTestCase
- type ContractTestDataSet
- type ContractTestSuite
- type ERSImplementation
- type ERSTestAdapter
- type EntityChainValidationRule
- type EntityValidationRule
- type FlexibleChainValidationRule
- type FlexibleEntityChainExpectation
- func ExpectBasicUserChain(ephemeralID string) FlexibleEntityChainExpectation
- func ExpectClientChain(ephemeralID string) FlexibleEntityChainExpectation
- func ExpectEnvironmentChain(ephemeralID string) FlexibleEntityChainExpectation
- func ExpectMultiStrategyChain(ephemeralID string, expectedStrategies int) FlexibleEntityChainExpectation
- type MockTestDataInjector
- type TestClient
- type TestConfig
- type TestDataGenerator
- func (g *TestDataGenerator) CreateBasicScenario() *ContractTestDataSet
- func (g *TestDataGenerator) CreateEdgeCaseScenario() *ContractTestDataSet
- func (g *TestDataGenerator) CreateVariedTestDataSet(scenario TestDataScenario) *ContractTestDataSet
- func (g *TestDataGenerator) GenerateTestClients(scenario TestDataScenario) []TestClient
- func (g *TestDataGenerator) GenerateTestTokens(scenario TestDataScenario, users []TestUser, clients []TestClient) []*entity.Token
- func (g *TestDataGenerator) GenerateTestUsers(scenario TestDataScenario) []TestUser
- func (g *TestDataGenerator) GetStandardScenarios() []TestDataScenario
- type TestDataInjector
- type TestDataScenario
- type TestGroup
- type TestUser
Constants ¶
const (
// AnonymousUser represents an anonymous or unknown user
AnonymousUser = "anonymous"
)
Variables ¶
var ( // Test users for all ERS implementations TestUsers = []TestUser{ { Username: "alice", Email: "alice@opentdf.test", DisplayName: "Alice Smith", Password: "password123", Groups: []string{"users", "admins"}, DN: "uid=alice,ou=users,dc=opentdf,dc=test", }, { Username: "bob", Email: "bob@opentdf.test", DisplayName: "Bob Johnson", Password: "password456", Groups: []string{"users"}, DN: "uid=bob,ou=users,dc=opentdf,dc=test", }, { Username: "charlie", Email: "charlie@opentdf.test", DisplayName: "Charlie Brown", Password: "password789", Groups: []string{"users", "managers"}, DN: "uid=charlie,ou=users,dc=opentdf,dc=test", }, } // Test clients for all ERS implementations TestClients = []TestClient{ { ClientID: "test-client-1", DisplayName: "Test Client 1", Description: "First test client", DN: "cn=test-client-1,ou=clients,dc=opentdf,dc=test", }, { ClientID: "test-client-2", DisplayName: "Test Client 2", Description: "Second test client", DN: "cn=test-client-2,ou=clients,dc=opentdf,dc=test", }, { ClientID: "opentdf-sdk", DisplayName: "OpenTDF SDK", Description: "OpenTDF SDK client", DN: "cn=opentdf-sdk,ou=clients,dc=opentdf,dc=test", }, } // Test groups for all ERS implementations TestGroups = []TestGroup{ { Name: "users", DisplayName: "All Users", Description: "Basic user group", Members: []string{"alice", "bob", "charlie"}, DN: "cn=users,ou=groups,dc=opentdf,dc=test", }, { Name: "admins", DisplayName: "Administrators", Description: "Administrative users", Members: []string{"alice"}, DN: "cn=admins,ou=groups,dc=opentdf,dc=test", }, { Name: "managers", DisplayName: "Managers", Description: "Management users", Members: []string{"charlie"}, DN: "cn=managers,ou=groups,dc=opentdf,dc=test", }, } )
Test data available to all adapters for consistent contract testing
Functions ¶
func CreateCustomerJWT ¶
CreateCustomerJWT creates a JWT for customer audience routing
func CreateEnvironmentJWT ¶
CreateEnvironmentJWT creates a JWT with environment context for environment entity routing
func CreateExternalJWT ¶
CreateExternalJWT creates a JWT for external audience routing (uses database lookup)
func CreateInternalJWT ¶
CreateInternalJWT creates a JWT for internal audience routing (uses JWT claims provider)
func CreateMultiStrategyTestSet ¶
CreateMultiStrategyTestSet creates a set of JWTs for testing different routing scenarios
func CreateResolveEntitiesRequest ¶
func CreateResolveEntitiesRequest(entities ...*entity.Entity) *entityresolutionV2.ResolveEntitiesRequest
CreateResolveEntitiesRequest creates a v2 ResolveEntitiesRequest for testing
func CreateTestEntityByClientID ¶
CreateTestEntityByClientID creates a test entity for client ID-based resolution
func CreateTestEntityByEmail ¶
CreateTestEntityByEmail creates a test entity for email-based resolution
func CreateTestEntityByUsername ¶
CreateTestEntityByUsername creates a test entity for username-based resolution
func CreateTestJWT ¶
CreateTestJWT creates a proper JWT token for token-based testing using actual parameters
func CreateTestJWTWithClaims ¶
func CreateTestJWTWithClaims(clientID, username, email string, additionalClaims map[string]interface{}) string
CreateTestJWTWithClaims creates a JWT token with additional custom claims for multi-strategy testing
func CreateTestToken ¶
CreateTestToken creates a test entity.Token with the given ephemeral ID and JWT
func ValidateEntityChainFlexible ¶
func ValidateEntityChainFlexible(chains []*entity.EntityChain, rule FlexibleChainValidationRule) error
ValidateEntityChainFlexible performs flexible validation with detailed reporting
func ValidateEntityRepresentation ¶
func ValidateEntityRepresentation(repr *entityresolutionV2.EntityRepresentation, originalID string, expectedFields map[string]interface{}) error
ValidateEntityRepresentation validates that an EntityRepresentation contains expected data
Types ¶
type ChainContractTestSuite ¶
type ChainContractTestSuite struct {
TestCases []ContractTestCase
}
ChainContractTestSuite holds implementation-agnostic multi-entity chain validation tests
func NewChainContractTestSuite ¶
func NewChainContractTestSuite() *ChainContractTestSuite
NewChainContractTestSuite creates a test suite focused on implementation-agnostic multi-entity chain validation
func (*ChainContractTestSuite) RunChainContractTests ¶
func (suite *ChainContractTestSuite) RunChainContractTests(t *testing.T, implementation ERSImplementation, _ string)
RunChainContractTests executes multi-entity chain tests against an ERS implementation
type ContainerConfig ¶
type ContainerConfig struct {
Image string
ExposedPorts []string
Env map[string]string
Cmd []string
WaitStrategy wait.Strategy
Timeout time.Duration
}
ContainerConfig holds configuration for a test container
type ContainerManager ¶
type ContainerManager struct {
Container tc.Container
Config ContainerConfig
}
ContainerManager provides standardized container lifecycle management
func NewContainerManager ¶
func NewContainerManager(config ContainerConfig) *ContainerManager
NewContainerManager creates a new container manager with the given configuration
func (*ContainerManager) GetHost ¶
func (cm *ContainerManager) GetHost() string
GetHost returns the container host (typically localhost)
func (*ContainerManager) GetMappedPort ¶
GetMappedPort returns the host port mapped to the container port
func (*ContainerManager) IsRunning ¶
func (cm *ContainerManager) IsRunning() bool
IsRunning returns true if the container is currently running
type ContainerTestSuite ¶
type ContainerTestSuite struct {
// contains filtered or unexported fields
}
ContainerTestSuite provides a standardized way to manage multiple containers for testing
func NewContainerTestSuite ¶
func NewContainerTestSuite() *ContainerTestSuite
NewContainerTestSuite creates a new container test suite
func (*ContainerTestSuite) AddContainer ¶
func (suite *ContainerTestSuite) AddContainer(name string, config ContainerConfig)
AddContainer adds a container to the test suite
func (*ContainerTestSuite) GetContainer ¶
func (suite *ContainerTestSuite) GetContainer(name string) (*ContainerManager, bool)
GetContainer returns a container manager by name
func (*ContainerTestSuite) GetContainerPort ¶
func (suite *ContainerTestSuite) GetContainerPort(ctx context.Context, containerName, containerPort string) (int, error)
GetContainerPort returns the mapped port for a container
type ContractExpected ¶
type ContractExpected struct {
EntityCount int // Expected number of entities returned
ShouldError bool // Whether the call should return an error
ErrorCode connect.Code // Expected error code if ShouldError is true
EntityValidation []EntityValidationRule // Rules for validating returned entities
ChainValidation []EntityChainValidationRule // Rules for validating entity chains
}
ContractExpected defines the expected output for a contract test
type ContractInput ¶
type ContractInput struct {
Entities []*entity.Entity
Tokens []*entity.Token // For CreateEntityChainsFromTokens tests
}
ContractInput defines the input data for a contract test
type ContractTestCase ¶
type ContractTestCase struct {
Name string
Description string
Input ContractInput
Expected ContractExpected
}
ContractTestCase represents a single test case in the contract
type ContractTestDataSet ¶
type ContractTestDataSet struct {
Users []TestUser
Clients []TestClient
}
ContractTestDataSet defines the standard test data that all ERS implementations should support
func NewContractTestDataSet ¶
func NewContractTestDataSet() *ContractTestDataSet
NewContractTestDataSet creates the standard test data set for contract testing
type ContractTestSuite ¶
type ContractTestSuite struct {
TestCases []ContractTestCase
}
ContractTestSuite holds all the contract tests for ERS implementations
func NewContractTestSuite ¶
func NewContractTestSuite() *ContractTestSuite
NewContractTestSuite creates a new contract test suite with standard test cases
func (*ContractTestSuite) RunContractTests ¶
func (suite *ContractTestSuite) RunContractTests(t *testing.T, implementation ERSImplementation, implementationName string)
RunContractTests executes all contract tests against the given ERS implementation
func (*ContractTestSuite) RunContractTestsWithAdapter ¶
func (suite *ContractTestSuite) RunContractTestsWithAdapter(t *testing.T, adapter ERSTestAdapter)
RunContractTestsWithAdapter executes all contract tests against the given ERS adapter This is the preferred way to run contract tests as it handles data setup/teardown
type ERSImplementation ¶
type ERSImplementation interface {
ResolveEntities(ctx context.Context, req *connect.Request[entityresolutionV2.ResolveEntitiesRequest]) (*connect.Response[entityresolutionV2.ResolveEntitiesResponse], error)
CreateEntityChainsFromTokens(ctx context.Context, req *connect.Request[entityresolutionV2.CreateEntityChainsFromTokensRequest]) (*connect.Response[entityresolutionV2.CreateEntityChainsFromTokensResponse], error)
}
ERSImplementation defines the interface that all ERS implementations must satisfy for contract testing
type ERSTestAdapter ¶
type ERSTestAdapter interface {
// GetScopeName returns the human-readable name for this ERS scope (e.g., "LDAP", "SQL")
GetScopeName() string
// SetupTestData injects the provided test data into the backend data store
// Each implementation handles this differently:
// - LDAP: Creates LDAP entries via LDAP operations
// - SQL: Inserts rows into database tables
// - Claims: Sets up JWT signing keys and test claims
SetupTestData(ctx context.Context, testDataSet *ContractTestDataSet) error
// CreateERSService creates and returns a configured ERS service instance
// ready for testing with the injected test data
CreateERSService(ctx context.Context) (ERSImplementation, error)
// TeardownTestData cleans up any test data and resources
// This is called after tests complete to ensure clean state
TeardownTestData(ctx context.Context) error
}
ERSTestAdapter defines the interface that each scope (ldap, sql, etc.) must implement to participate in contract testing. This allows each scope to define: 1. How to inject test data into their specific backend 2. How to create their concrete ERS service implementation
type EntityChainValidationRule ¶
type EntityChainValidationRule struct {
EphemeralID string // Expected ephemeral ID
EntityCount int // Expected number of entities in the chain
EntityTypes []string // Expected entity types in order
EntityCategories []string // Expected entity categories in order (CATEGORY_ENVIRONMENT, CATEGORY_SUBJECT)
RequireConsistentOrdering bool // Whether entity order must be consistent across implementations
}
EntityChainValidationRule defines how to validate a returned entity chain
type EntityValidationRule ¶
type EntityValidationRule struct {
Index int // Which entity in the response to validate
EphemeralID string // Expected ephemeral ID
RequiredFields map[string]interface{} // Fields that must be present with specific values
ForbiddenFields []string // Fields that must not be present
MinFieldCount int // Minimum number of fields in additional properties
}
EntityValidationRule defines how to validate a returned entity
type FlexibleChainValidationRule ¶
type FlexibleChainValidationRule struct {
Description string
Expectations []FlexibleEntityChainExpectation
AllowPartialSuccess bool // Some chains can fail if others succeed
MinSuccessCount int // Minimum number of successful chains
}
FlexibleChainValidationRule provides comprehensive validation
func CreateFlexibleValidationFromLegacy ¶
func CreateFlexibleValidationFromLegacy(legacyRules []EntityChainValidationRule) FlexibleChainValidationRule
CreateFlexibleValidationFromLegacy converts legacy validation rules to flexible ones
type FlexibleEntityChainExpectation ¶
type FlexibleEntityChainExpectation struct {
EphemeralID string
MinEntityCount int // At least this many entities
MaxEntityCount int // At most this many entities (0 = no limit)
RequiredEntityTypes []string // Must contain these entity types
RequiredClaims []string // Must contain these claim keys
RequiredCategories []string // Must contain these categories
ForbiddenClaims []string // Must NOT contain these claim keys
AllowImplementationGaps bool // Accept implementation differences
}
FlexibleEntityChainExpectation provides range-based and conditional expectations
func ExpectBasicUserChain ¶
func ExpectBasicUserChain(ephemeralID string) FlexibleEntityChainExpectation
ExpectBasicUserChain creates expectation for a user-based entity chain
func ExpectClientChain ¶
func ExpectClientChain(ephemeralID string) FlexibleEntityChainExpectation
ExpectClientChain creates expectation for a client-based entity chain
func ExpectEnvironmentChain ¶
func ExpectEnvironmentChain(ephemeralID string) FlexibleEntityChainExpectation
ExpectEnvironmentChain creates expectation for environment entities
func ExpectMultiStrategyChain ¶
func ExpectMultiStrategyChain(ephemeralID string, expectedStrategies int) FlexibleEntityChainExpectation
ExpectMultiStrategyChain creates expectation for multi-strategy entity resolution
type MockTestDataInjector ¶
type MockTestDataInjector struct {
// contains filtered or unexported fields
}
MockTestDataInjector provides a no-op implementation for testing
func NewMockTestDataInjector ¶
func NewMockTestDataInjector(logger any) *MockTestDataInjector
NewMockTestDataInjector creates a new mock test data injector
func (*MockTestDataInjector) CleanupTestData ¶
func (m *MockTestDataInjector) CleanupTestData(_ context.Context) error
CleanupTestData is a no-op for the mock injector
func (*MockTestDataInjector) InjectTestData ¶
func (m *MockTestDataInjector) InjectTestData(_ context.Context, _ *ContractTestDataSet) error
InjectTestData is a no-op for the mock injector
func (*MockTestDataInjector) ValidateTestData ¶
func (m *MockTestDataInjector) ValidateTestData(_ context.Context, _ *ContractTestDataSet) error
ValidateTestData is a no-op for the mock injector
type TestClient ¶
TestClient represents a test client entity
func GetTestClient ¶
func GetTestClient(clientID string) *TestClient
GetTestClient finds a test client by client ID
type TestConfig ¶
type TestConfig struct {
// Service Endpoints
KeycloakURL string
KeycloakPort int
PostgresHost string
PostgresPort int
LDAPHost string
LDAPPort int
// Authentication
AdminUser string
AdminPassword string
Realm string
ClientID string
ClientSecret string
// Test Behavior
ContainerStartupTimeout time.Duration
ContainerRunTimeout time.Duration
TestDataVariation bool // Enable varied test data generation
JWTValidityDuration time.Duration
// Test Data
EmailDomains []string
TestUserCount int
TestClientCount int
}
TestConfig provides environment-aware configuration for integration tests
func GetTestConfig ¶
func GetTestConfig() *TestConfig
GetTestConfig returns environment-aware test configuration with sensible defaults
func (*TestConfig) KeycloakConfig ¶
func (tc *TestConfig) KeycloakConfig() map[string]interface{}
KeycloakConfig returns Keycloak-specific configuration
func (*TestConfig) PostgresConnectionString ¶
func (tc *TestConfig) PostgresConnectionString(dbname, username, password string) string
PostgresConnectionString returns a connection string for PostgreSQL
type TestDataGenerator ¶
type TestDataGenerator struct {
// contains filtered or unexported fields
}
TestDataGenerator provides flexible test data generation
func NewTestDataGenerator ¶
func NewTestDataGenerator(config *TestConfig) *TestDataGenerator
NewTestDataGenerator creates a new test data generator
func (*TestDataGenerator) CreateBasicScenario ¶
func (g *TestDataGenerator) CreateBasicScenario() *ContractTestDataSet
Scenario-specific helpers
func (*TestDataGenerator) CreateEdgeCaseScenario ¶
func (g *TestDataGenerator) CreateEdgeCaseScenario() *ContractTestDataSet
func (*TestDataGenerator) CreateVariedTestDataSet ¶
func (g *TestDataGenerator) CreateVariedTestDataSet(scenario TestDataScenario) *ContractTestDataSet
CreateVariedTestDataSet creates a test data set based on scenario
func (*TestDataGenerator) GenerateTestClients ¶
func (g *TestDataGenerator) GenerateTestClients(scenario TestDataScenario) []TestClient
GenerateTestClients creates varied test clients based on scenario
func (*TestDataGenerator) GenerateTestTokens ¶
func (g *TestDataGenerator) GenerateTestTokens(scenario TestDataScenario, users []TestUser, clients []TestClient) []*entity.Token
GenerateTestTokens creates tokens that will trigger specific strategies
func (*TestDataGenerator) GenerateTestUsers ¶
func (g *TestDataGenerator) GenerateTestUsers(scenario TestDataScenario) []TestUser
GenerateTestUsers creates varied test users based on scenario
func (*TestDataGenerator) GetStandardScenarios ¶
func (g *TestDataGenerator) GetStandardScenarios() []TestDataScenario
GetStandardScenarios returns common test scenarios
type TestDataInjector ¶
type TestDataInjector interface {
InjectTestData(ctx context.Context, dataSet *ContractTestDataSet) error
CleanupTestData(ctx context.Context) error
ValidateTestData(ctx context.Context, dataSet *ContractTestDataSet) error
}
TestDataInjector interface defines methods for injecting test data into different backends
type TestDataScenario ¶
type TestDataScenario struct {
Name string
UserCount int
ClientCount int
EmailDomains []string
// JWT claim variations
IncludeClientID bool
IncludeEmail bool
IncludeUsername bool
IncludeEmptyUsers bool // Test edge case with missing claims
// Strategy testing
StrategyTypes []string // Which strategies should be triggered
}
TestDataScenario defines a test scenario with specific characteristics