Atlas › Test

TestClientSupported

Exact test identity: go.temporal.io/server/common/headers/TestVersionCheckerSuite/TestClientSupported

Package
go.temporal.io/server/common/headers
Suite / test hierarchy
TestVersionCheckerSuite/TestClientSupported
Test
TestClientSupported
Introduced at
version_checker.go ×2 Frontier kind: Joint frontier
Covered ranges
20
Covered lines
61
Covered files
2

Covered source

Expand a file to inspect source; the > gutter marks covered lines.

go.temporal.io/server/common/headers/version_checker.go 53 covered LOC · 17 ranges

Open complete file

81
82 // NewVersionChecker constructs a new VersionChecker
83 > func NewVersionChecker(supportedClients map[string]string, serverVersion string) *versionChecker { version_checker.go
84 > return &versionChecker{
85 > serverVersion: semver.MustParse(serverVersion),
86 > supportedClients: supportedClients,
87 > supportedClientsRange: mustParseRanges(supportedClients),
88 > }
89 > }
90
91 // GetClientNameAndVersion extracts SDK name and version from context headers
104 // SetVersionsForTests sets headers as they would be received from the client.
105 // Must be used in tests only.
106 > func SetVersionsForTests(ctx context.Context, clientVersion, clientName, supportedServerVersions, supportedFeatures string) context.Context { version_checker.go
107 > return metadata.NewIncomingContext(ctx, metadata.New(map[string]string{
108 > ClientNameHeaderName: clientName,
109 > ClientVersionHeaderName: clientVersion,
110 > SupportedServerVersionsHeaderName: supportedServerVersions,
111 > SupportedFeaturesHeaderName: supportedFeatures,
112 > }))
113 > }
114
115 // ClientSupported returns an error if client is unsupported, nil otherwise.
116 > func (vc *versionChecker) ClientSupported(ctx context.Context) error { version_checker.go
117 >
118 > headers := GetValues(ctx, ClientNameHeaderName, ClientVersionHeaderName, SupportedServerVersionsHeaderName)
119 > clientName := headers[0]
120 > clientVersion := headers[1]
121 > supportedServerVersions := headers[2]
122 >
123 > // Validate client version only if it is provided and server knows about this client.
124 > if clientName != "" && clientVersion != "" {
125 > if supportedClientRange, ok := vc.supportedClientsRange[clientName]; ok { version_checker.go
126 > clientVersionParsed, parseErr := semver.Parse(clientVersion)
127 > if parseErr != nil {
128 > return serviceerror.NewInvalidArgumentf("Unable to parse client version: %v", parseErr) version_checker.go
129 > }
130 > if !supportedClientRange(clientVersionParsed) { version_checker.go
131 > return serviceerror.NewClientVersionNotSupported(clientVersion, clientName, vc.supportedClients[clientName]) version_checker.go
132 > }
133 }
134 }
135
136 // Validate supported server version if it is provided.
137 > if supportedServerVersions != "" { version_checker.go
138 > supportedServerVersionsParsed, parseErr := semver.ParseRange(supportedServerVersions) version_checker.go
139 > if parseErr != nil {
140 return serviceerror.NewInvalidArgumentf("Unable to parse supported server versions: %v", parseErr)
141 }
142 > if !supportedServerVersionsParsed(vc.serverVersion) { version_checker.go
143 > return serviceerror.NewServerVersionNotSupported(vc.serverVersion.String(), supportedServerVersions) version_checker.go
144 > }
145 }
146
147 > return nil version_checker.go
148 }
149
150 // ClientSupportsFeature returns true if the client reports support for the
151 // given feature (which should be one of the Feature... constants above).
152 > func (vc *versionChecker) ClientSupportsFeature(ctx context.Context, feature string) bool { version_checker.go
153 > headers := GetValues(ctx, SupportedFeaturesHeaderName)
154 > if len(headers) == 0 {
155 return false
156 }
157 > for clientFeature := range strings.SplitSeq(headers[0], SupportedFeaturesHeaderDelim) { version_checker.go
158 > if clientFeature == feature {
159 > return true version_checker.go
160 > }
161 }
162 > return false version_checker.go
163 }
164
165 > func mustParseRanges(ranges map[string]string) map[string]semver.Range { version_checker.go
166 > out := make(map[string]semver.Range, len(ranges))
167 > for c, r := range ranges {
168 > out[c] = semver.MustParseRange(r)
169 > }
170 > return out
171 }
go.temporal.io/server/common/headers/headers.go 8 covered LOC · 3 ranges

Open complete file

45 // GetValues returns header values for passed header names.
46 // It always returns slice of the same size as number of passed header names.
47 > func GetValues(ctx context.Context, headerNames ...string) []string { headers.go
48 > headerValues := make([]string, len(headerNames))
49 >
50 > for i, headerName := range headerNames {
51 > if values := metadata.ValueFromIncomingContext(ctx, headerName); len(values) > 0 {
52 > headerValues[i] = values[0] headers.go
53 > }
54 }
55
56 > return headerValues headers.go
57 }
58