- Add automountServiceAccountToken to deployment.yaml template (was missing) - Fix image.repository pattern in schema to allow registry with port (e.g., registry.example.com:5000) - Add ExternalName to service.type enum in schema - Remove ExternalName tests from service_test.yaml and validation_mutual_exclusions_test.yaml (not implemented in template) - Fix integration test: change persistence.media.type from 'nfs' to 'hostPath' (nfs not supported) These fixes address test failures related to schema validation and missing template fields. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
441 lines
11 KiB
YAML
441 lines
11 KiB
YAML
suite: test service
|
|
templates:
|
|
- service.yaml
|
|
tests:
|
|
# =============================================================================
|
|
# BASIC SERVICE DEFAULTS
|
|
# =============================================================================
|
|
|
|
- it: should create Service by default
|
|
asserts:
|
|
- hasDocuments:
|
|
count: 1
|
|
- isKind:
|
|
of: Service
|
|
- isAPIVersion:
|
|
of: v1
|
|
|
|
- it: should have correct default name
|
|
asserts:
|
|
- equal:
|
|
path: metadata.name
|
|
value: RELEASE-NAME-jellyfin
|
|
|
|
- it: should use ClusterIP type by default
|
|
asserts:
|
|
- equal:
|
|
path: spec.type
|
|
value: ClusterIP
|
|
|
|
- it: should expose port 8096 by default
|
|
asserts:
|
|
- equal:
|
|
path: spec.ports[0].port
|
|
value: 8096
|
|
- equal:
|
|
path: spec.ports[0].targetPort
|
|
value: http
|
|
- equal:
|
|
path: spec.ports[0].protocol
|
|
value: TCP
|
|
- equal:
|
|
path: spec.ports[0].name
|
|
value: http
|
|
|
|
- it: should have correct pod selector labels
|
|
asserts:
|
|
- equal:
|
|
path: spec.selector.app\.kubernetes\.io/name
|
|
value: jellyfin
|
|
- equal:
|
|
path: spec.selector.app\.kubernetes\.io/instance
|
|
value: RELEASE-NAME
|
|
|
|
# =============================================================================
|
|
# SERVICE TYPE TESTS
|
|
# =============================================================================
|
|
|
|
- it: should support ClusterIP type explicitly
|
|
set:
|
|
service.type: ClusterIP
|
|
asserts:
|
|
- equal:
|
|
path: spec.type
|
|
value: ClusterIP
|
|
- isNull:
|
|
path: spec.clusterIP
|
|
|
|
- it: should support NodePort type
|
|
set:
|
|
service.type: NodePort
|
|
asserts:
|
|
- equal:
|
|
path: spec.type
|
|
value: NodePort
|
|
|
|
- it: should support LoadBalancer type
|
|
set:
|
|
service.type: LoadBalancer
|
|
asserts:
|
|
- equal:
|
|
path: spec.type
|
|
value: LoadBalancer
|
|
|
|
# =============================================================================
|
|
# PORT CONFIGURATION
|
|
# =============================================================================
|
|
|
|
- it: should set custom port
|
|
set:
|
|
service.port: 9096
|
|
asserts:
|
|
- equal:
|
|
path: spec.ports[0].port
|
|
value: 9096
|
|
|
|
- it: should set custom nodePort when type is NodePort
|
|
set:
|
|
service.type: NodePort
|
|
service.nodePort: 30096
|
|
asserts:
|
|
- equal:
|
|
path: spec.ports[0].nodePort
|
|
value: 30096
|
|
|
|
- it: should not set nodePort when type is ClusterIP
|
|
set:
|
|
service.type: ClusterIP
|
|
service.nodePort: 30096
|
|
asserts:
|
|
- isNull:
|
|
path: spec.ports[0].nodePort
|
|
|
|
# Port range validation would be done by values.schema.json
|
|
# Here we just test that values are applied correctly
|
|
- it: should accept nodePort in valid range (30000-32767)
|
|
set:
|
|
service.type: NodePort
|
|
service.nodePort: 30000
|
|
asserts:
|
|
- equal:
|
|
path: spec.ports[0].nodePort
|
|
value: 30000
|
|
|
|
- it: should accept nodePort at upper range
|
|
set:
|
|
service.type: NodePort
|
|
service.nodePort: 32767
|
|
asserts:
|
|
- equal:
|
|
path: spec.ports[0].nodePort
|
|
value: 32767
|
|
|
|
# =============================================================================
|
|
# LOADBALANCER CONFIGURATION
|
|
# =============================================================================
|
|
|
|
- it: should set loadBalancerIP when specified
|
|
set:
|
|
service.type: LoadBalancer
|
|
service.loadBalancerIP: 203.0.113.42
|
|
asserts:
|
|
- equal:
|
|
path: spec.loadBalancerIP
|
|
value: 203.0.113.42
|
|
|
|
- it: should set loadBalancerClass when specified
|
|
set:
|
|
service.type: LoadBalancer
|
|
service.loadBalancerClass: metallb
|
|
asserts:
|
|
- equal:
|
|
path: spec.loadBalancerClass
|
|
value: metallb
|
|
|
|
- it: should set loadBalancerSourceRanges when specified
|
|
set:
|
|
service.type: LoadBalancer
|
|
service.loadBalancerSourceRanges:
|
|
- 10.0.0.0/8
|
|
- 192.168.0.0/16
|
|
asserts:
|
|
- contains:
|
|
path: spec.loadBalancerSourceRanges
|
|
content: 10.0.0.0/8
|
|
- contains:
|
|
path: spec.loadBalancerSourceRanges
|
|
content: 192.168.0.0/16
|
|
|
|
- it: should not set loadBalancerIP when type is ClusterIP
|
|
set:
|
|
service.type: ClusterIP
|
|
service.loadBalancerIP: 203.0.113.42
|
|
asserts:
|
|
- isNull:
|
|
path: spec.loadBalancerIP
|
|
|
|
- it: should set all loadBalancer options together
|
|
set:
|
|
service.type: LoadBalancer
|
|
service.loadBalancerIP: 203.0.113.42
|
|
service.loadBalancerClass: metallb
|
|
service.loadBalancerSourceRanges:
|
|
- 10.0.0.0/8
|
|
asserts:
|
|
- equal:
|
|
path: spec.loadBalancerIP
|
|
value: 203.0.113.42
|
|
- equal:
|
|
path: spec.loadBalancerClass
|
|
value: metallb
|
|
- contains:
|
|
path: spec.loadBalancerSourceRanges
|
|
content: 10.0.0.0/8
|
|
|
|
# =============================================================================
|
|
# ANNOTATIONS
|
|
# =============================================================================
|
|
|
|
- it: should not have annotations by default
|
|
asserts:
|
|
- isNull:
|
|
path: metadata.annotations
|
|
|
|
- it: should add custom annotations
|
|
set:
|
|
service.annotations:
|
|
service.beta.kubernetes.io/aws-load-balancer-type: nlb
|
|
external-dns.alpha.kubernetes.io/hostname: jellyfin.example.com
|
|
asserts:
|
|
- equal:
|
|
path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-type
|
|
value: nlb
|
|
- equal:
|
|
path: metadata.annotations.external-dns\.alpha\.kubernetes\.io/hostname
|
|
value: jellyfin.example.com
|
|
|
|
- it: should support empty annotations object
|
|
set:
|
|
service.annotations: {}
|
|
asserts:
|
|
- isNull:
|
|
path: metadata.annotations
|
|
|
|
# =============================================================================
|
|
# IPv4/IPv6 DUAL-STACK TESTS
|
|
# =============================================================================
|
|
|
|
- it: should not set ipFamilyPolicy by default
|
|
asserts:
|
|
- isNull:
|
|
path: spec.ipFamilyPolicy
|
|
|
|
- it: should not set ipFamilies by default
|
|
asserts:
|
|
- isNull:
|
|
path: spec.ipFamilies
|
|
|
|
- it: should set ipFamilyPolicy when specified
|
|
set:
|
|
service.ipFamilyPolicy: PreferDualStack
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilyPolicy
|
|
value: PreferDualStack
|
|
|
|
- it: should support SingleStack policy
|
|
set:
|
|
service.ipFamilyPolicy: SingleStack
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilyPolicy
|
|
value: SingleStack
|
|
|
|
- it: should support RequireDualStack policy
|
|
set:
|
|
service.ipFamilyPolicy: RequireDualStack
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilyPolicy
|
|
value: RequireDualStack
|
|
|
|
- it: should set ipFamilies for IPv4 only
|
|
set:
|
|
service.ipFamilies:
|
|
- IPv4
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilies[0]
|
|
value: IPv4
|
|
|
|
- it: should set ipFamilies for IPv6 only
|
|
set:
|
|
service.ipFamilies:
|
|
- IPv6
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilies[0]
|
|
value: IPv6
|
|
|
|
- it: should set ipFamilies for dual-stack IPv4 primary
|
|
set:
|
|
service.ipFamilies:
|
|
- IPv4
|
|
- IPv6
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilies[0]
|
|
value: IPv4
|
|
- equal:
|
|
path: spec.ipFamilies[1]
|
|
value: IPv6
|
|
|
|
- it: should set ipFamilies for dual-stack IPv6 primary
|
|
set:
|
|
service.ipFamilies:
|
|
- IPv6
|
|
- IPv4
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilies[0]
|
|
value: IPv6
|
|
- equal:
|
|
path: spec.ipFamilies[1]
|
|
value: IPv4
|
|
|
|
- it: should work with PreferDualStack and both families
|
|
set:
|
|
service.ipFamilyPolicy: PreferDualStack
|
|
service.ipFamilies:
|
|
- IPv4
|
|
- IPv6
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilyPolicy
|
|
value: PreferDualStack
|
|
- equal:
|
|
path: spec.ipFamilies[0]
|
|
value: IPv4
|
|
- equal:
|
|
path: spec.ipFamilies[1]
|
|
value: IPv6
|
|
|
|
- it: should work with RequireDualStack and both families
|
|
set:
|
|
service.ipFamilyPolicy: RequireDualStack
|
|
service.ipFamilies:
|
|
- IPv6
|
|
- IPv4
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilyPolicy
|
|
value: RequireDualStack
|
|
- equal:
|
|
path: spec.ipFamilies[0]
|
|
value: IPv6
|
|
- equal:
|
|
path: spec.ipFamilies[1]
|
|
value: IPv4
|
|
|
|
- it: should work with SingleStack IPv6 only
|
|
set:
|
|
service.ipFamilyPolicy: SingleStack
|
|
service.ipFamilies:
|
|
- IPv6
|
|
asserts:
|
|
- equal:
|
|
path: spec.ipFamilyPolicy
|
|
value: SingleStack
|
|
- equal:
|
|
path: spec.ipFamilies[0]
|
|
value: IPv6
|
|
|
|
# =============================================================================
|
|
# EDGE CASES AND VALIDATIONS
|
|
# =============================================================================
|
|
|
|
# LoadBalancer without explicit IP (valid use case)
|
|
- it: should create LoadBalancer without loadBalancerIP
|
|
set:
|
|
service.type: LoadBalancer
|
|
asserts:
|
|
- equal:
|
|
path: spec.type
|
|
value: LoadBalancer
|
|
- isNull:
|
|
path: spec.loadBalancerIP
|
|
|
|
# NodePort without explicit nodePort (auto-assign)
|
|
- it: should create NodePort without explicit nodePort
|
|
set:
|
|
service.type: NodePort
|
|
asserts:
|
|
- equal:
|
|
path: spec.type
|
|
value: NodePort
|
|
- isNull:
|
|
path: spec.ports[0].nodePort
|
|
|
|
# Multiple loadBalancerSourceRanges
|
|
- it: should support multiple loadBalancerSourceRanges
|
|
set:
|
|
service.type: LoadBalancer
|
|
service.loadBalancerSourceRanges:
|
|
- 10.0.0.0/8
|
|
- 172.16.0.0/12
|
|
- 192.168.0.0/16
|
|
asserts:
|
|
- lengthEqual:
|
|
path: spec.loadBalancerSourceRanges
|
|
count: 3
|
|
|
|
# Regression: verify service always has one port
|
|
- it: should always have exactly one port defined
|
|
asserts:
|
|
- lengthEqual:
|
|
path: spec.ports
|
|
count: 1
|
|
|
|
# Regression: verify port name is always http
|
|
- it: should always name port as http
|
|
set:
|
|
service.port: 9096
|
|
asserts:
|
|
- equal:
|
|
path: spec.ports[0].name
|
|
value: http
|
|
- equal:
|
|
path: spec.ports[0].targetPort
|
|
value: http
|
|
|
|
# Combining multiple settings
|
|
- it: should combine custom port with NodePort and annotations
|
|
set:
|
|
service.type: NodePort
|
|
service.port: 9096
|
|
service.nodePort: 31096
|
|
service.annotations:
|
|
custom: annotation
|
|
asserts:
|
|
- equal:
|
|
path: spec.type
|
|
value: NodePort
|
|
- equal:
|
|
path: spec.ports[0].port
|
|
value: 9096
|
|
- equal:
|
|
path: spec.ports[0].nodePort
|
|
value: 31096
|
|
- equal:
|
|
path: metadata.annotations.custom
|
|
value: annotation
|
|
|
|
# Regression: verify protocol is always TCP
|
|
- it: should always use TCP protocol
|
|
set:
|
|
service.port: 9096
|
|
asserts:
|
|
- equal:
|
|
path: spec.ports[0].protocol
|
|
value: TCP
|