Imported Upstream version 1.41.0
[platform/upstream/grpc.git] / tools / interop_matrix / client_matrix.py
1 #!/usr/bin/env python2.7
2 # Copyright 2017 gRPC authors.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # Defines languages, runtimes and releases for backward compatibility testing
17
18 from collections import OrderedDict
19
20
21 def get_github_repo(lang):
22     return {
23         'dart': 'https://github.com/grpc/grpc-dart.git',
24         'go': 'https://github.com/grpc/grpc-go.git',
25         'java': 'https://github.com/grpc/grpc-java.git',
26         'node': 'https://github.com/grpc/grpc-node.git',
27         # all other languages use the grpc.git repo.
28     }.get(lang, 'https://github.com/grpc/grpc.git')
29
30
31 def get_release_tags(lang):
32     """Returns list of known releases for given language."""
33     return list(LANG_RELEASE_MATRIX[lang].keys())
34
35
36 def get_runtimes_for_lang_release(lang, release):
37     """Get list of valid runtimes for given release of lang."""
38     runtimes = list(LANG_RUNTIME_MATRIX[lang])
39     release_info = LANG_RELEASE_MATRIX[lang].get(release)
40     if release_info and release_info.runtimes:
41         runtimes = list(release_info.runtimes)
42     return runtimes
43
44
45 def should_build_docker_interop_image_from_release_tag(lang):
46     # All dockerfile definitions live in grpc/grpc repository.
47     # For language that have a separate repo, we need to use
48     # dockerfile definitions from head of grpc/grpc.
49     if lang in ['go', 'java', 'node']:
50         return False
51     return True
52
53
54 # Dictionary of default runtimes per language
55 LANG_RUNTIME_MATRIX = {
56     'cxx': ['cxx'],  # This is actually debian8.
57     'go': ['go1.8', 'go1.11', 'go1.16'],
58     'java': ['java'],
59     'python': ['python', 'pythonasyncio'],
60     'node': ['node'],
61     'ruby': ['ruby'],
62     'php': ['php7'],
63     'csharp': ['csharp', 'csharpcoreclr'],
64 }
65
66
67 class ReleaseInfo:
68     """Info about a single release of a language"""
69
70     def __init__(self, patch=[], runtimes=[], testcases_file=None):
71         self.patch = patch
72         self.runtimes = runtimes
73         self.testcases_file = testcases_file
74
75
76 # Dictionary of known releases for given language.
77 LANG_RELEASE_MATRIX = {
78     'cxx':
79         OrderedDict([
80             ('v1.0.1', ReleaseInfo(testcases_file='cxx__v1.0.1')),
81             ('v1.1.4', ReleaseInfo(testcases_file='cxx__v1.0.1')),
82             ('v1.2.5', ReleaseInfo(testcases_file='cxx__v1.0.1')),
83             ('v1.3.9', ReleaseInfo(testcases_file='cxx__v1.0.1')),
84             ('v1.4.2', ReleaseInfo(testcases_file='cxx__v1.0.1')),
85             ('v1.6.6', ReleaseInfo(testcases_file='cxx__v1.0.1')),
86             ('v1.7.2', ReleaseInfo(testcases_file='cxx__v1.0.1')),
87             ('v1.8.0', ReleaseInfo(testcases_file='cxx__v1.0.1')),
88             ('v1.9.1', ReleaseInfo(testcases_file='cxx__v1.0.1')),
89             ('v1.10.1', ReleaseInfo(testcases_file='cxx__v1.0.1')),
90             ('v1.11.1', ReleaseInfo(testcases_file='cxx__v1.0.1')),
91             ('v1.12.0', ReleaseInfo(testcases_file='cxx__v1.0.1')),
92             ('v1.13.0', ReleaseInfo(testcases_file='cxx__v1.0.1')),
93             ('v1.14.1', ReleaseInfo(testcases_file='cxx__v1.0.1')),
94             ('v1.15.0', ReleaseInfo(testcases_file='cxx__v1.0.1')),
95             ('v1.16.0', ReleaseInfo(testcases_file='cxx__v1.0.1')),
96             ('v1.17.1', ReleaseInfo(testcases_file='cxx__v1.0.1')),
97             ('v1.18.0', ReleaseInfo(testcases_file='cxx__v1.0.1')),
98             ('v1.19.0', ReleaseInfo(testcases_file='cxx__v1.0.1')),
99             ('v1.20.0', ReleaseInfo(testcases_file='cxx__v1.31.1')),
100             ('v1.21.4', ReleaseInfo(testcases_file='cxx__v1.31.1')),
101             ('v1.22.0', ReleaseInfo(testcases_file='cxx__v1.31.1')),
102             ('v1.22.1', ReleaseInfo(testcases_file='cxx__v1.31.1')),
103             ('v1.23.0', ReleaseInfo(testcases_file='cxx__v1.31.1')),
104             ('v1.24.0', ReleaseInfo(testcases_file='cxx__v1.31.1')),
105             ('v1.25.0', ReleaseInfo(testcases_file='cxx__v1.31.1')),
106             ('v1.26.0', ReleaseInfo(testcases_file='cxx__v1.31.1')),
107             ('v1.27.3', ReleaseInfo(testcases_file='cxx__v1.31.1')),
108             ('v1.30.0', ReleaseInfo(testcases_file='cxx__v1.31.1')),
109             ('v1.31.1', ReleaseInfo(testcases_file='cxx__v1.31.1')),
110             ('v1.32.0', ReleaseInfo()),
111             ('v1.33.2', ReleaseInfo()),
112             ('v1.34.0', ReleaseInfo()),
113             ('v1.35.0', ReleaseInfo()),
114             ('v1.36.3', ReleaseInfo()),
115             ('v1.37.0', ReleaseInfo()),
116             ('v1.38.0', ReleaseInfo()),
117             ('v1.39.0', ReleaseInfo()),
118         ]),
119     'go':
120         OrderedDict([
121             ('v1.0.5',
122              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
123             ('v1.2.1',
124              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
125             ('v1.3.0',
126              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
127             ('v1.4.2',
128              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
129             ('v1.5.2',
130              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
131             ('v1.6.0',
132              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
133             ('v1.7.4',
134              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
135             ('v1.8.2',
136              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
137             ('v1.9.2',
138              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
139             ('v1.10.1',
140              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
141             ('v1.11.3',
142              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
143             ('v1.12.2',
144              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
145             ('v1.13.0',
146              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
147             ('v1.14.0',
148              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
149             ('v1.15.0',
150              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
151             ('v1.16.0',
152              ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')),
153             ('v1.17.0',
154              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')),
155             ('v1.18.0',
156              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')),
157             ('v1.19.0',
158              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')),
159             ('v1.20.0',
160              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
161             ('v1.21.3',
162              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
163             ('v1.22.3',
164              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
165             ('v1.23.1',
166              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
167             ('v1.24.0',
168              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
169             ('v1.25.0',
170              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
171             ('v1.26.0',
172              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
173             ('v1.27.1',
174              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
175             ('v1.28.0',
176              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
177             ('v1.29.0',
178              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
179             ('v1.30.0',
180              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
181             ('v1.31.1',
182              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
183             ('v1.32.0',
184              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
185             ('v1.33.1',
186              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
187             ('v1.34.0', ReleaseInfo(runtimes=['go1.11'])),
188             ('v1.35.0', ReleaseInfo(runtimes=['go1.11'])),
189             ('v1.36.0', ReleaseInfo(runtimes=['go1.11'])),
190             ('v1.37.0', ReleaseInfo(runtimes=['go1.11'])),
191             # NOTE: starting from release v1.38.0, use runtimes=['go1.16']
192             ('v1.38.1', ReleaseInfo(runtimes=['go1.16'])),
193             ('v1.39.1', ReleaseInfo(runtimes=['go1.16'])),
194             ('v1.40.0', ReleaseInfo(runtimes=['go1.16'])),
195         ]),
196     'java':
197         OrderedDict([
198             ('v1.0.3',
199              ReleaseInfo(runtimes=['java_oracle8'],
200                          testcases_file='java__v1.0.3')),
201             ('v1.1.2',
202              ReleaseInfo(runtimes=['java_oracle8'],
203                          testcases_file='java__v1.0.3')),
204             ('v1.2.0',
205              ReleaseInfo(runtimes=['java_oracle8'],
206                          testcases_file='java__v1.0.3')),
207             ('v1.3.1',
208              ReleaseInfo(runtimes=['java_oracle8'],
209                          testcases_file='java__v1.0.3')),
210             ('v1.4.0',
211              ReleaseInfo(runtimes=['java_oracle8'],
212                          testcases_file='java__v1.0.3')),
213             ('v1.5.0',
214              ReleaseInfo(runtimes=['java_oracle8'],
215                          testcases_file='java__v1.0.3')),
216             ('v1.6.1',
217              ReleaseInfo(runtimes=['java_oracle8'],
218                          testcases_file='java__v1.0.3')),
219             ('v1.7.1', ReleaseInfo(testcases_file='java__v1.0.3')),
220             ('v1.8.0',
221              ReleaseInfo(runtimes=['java_oracle8'],
222                          testcases_file='java__v1.0.3')),
223             ('v1.9.1',
224              ReleaseInfo(runtimes=['java_oracle8'],
225                          testcases_file='java__v1.0.3')),
226             ('v1.10.1',
227              ReleaseInfo(runtimes=['java_oracle8'],
228                          testcases_file='java__v1.0.3')),
229             ('v1.11.0',
230              ReleaseInfo(runtimes=['java_oracle8'],
231                          testcases_file='java__v1.0.3')),
232             ('v1.12.1', ReleaseInfo(testcases_file='java__v1.0.3')),
233             ('v1.13.2', ReleaseInfo(testcases_file='java__v1.0.3')),
234             ('v1.14.0',
235              ReleaseInfo(runtimes=['java_oracle8'],
236                          testcases_file='java__v1.0.3')),
237             ('v1.15.1', ReleaseInfo(testcases_file='java__v1.0.3')),
238             ('v1.16.1',
239              ReleaseInfo(runtimes=['java_oracle8'],
240                          testcases_file='java__v1.0.3')),
241             ('v1.17.2', ReleaseInfo(testcases_file='java__v1.0.3')),
242             ('v1.18.0',
243              ReleaseInfo(runtimes=['java_oracle8'],
244                          testcases_file='java__v1.0.3')),
245             ('v1.19.0',
246              ReleaseInfo(runtimes=['java_oracle8'],
247                          testcases_file='java__v1.0.3')),
248             ('v1.20.0', ReleaseInfo(runtimes=['java_oracle8'])),
249             ('v1.21.1', ReleaseInfo()),
250             ('v1.22.2', ReleaseInfo()),
251             ('v1.23.0', ReleaseInfo()),
252             ('v1.24.0', ReleaseInfo()),
253             ('v1.25.0', ReleaseInfo()),
254             ('v1.26.1', ReleaseInfo()),
255             ('v1.27.2', ReleaseInfo()),
256             ('v1.28.1', ReleaseInfo()),
257             ('v1.29.0', ReleaseInfo()),
258             ('v1.30.2', ReleaseInfo()),
259             ('v1.31.2', ReleaseInfo()),
260             ('v1.32.3', ReleaseInfo()),
261             ('v1.33.1', ReleaseInfo()),
262             ('v1.34.1', ReleaseInfo()),
263             ('v1.35.1', ReleaseInfo()),
264             ('v1.36.1', ReleaseInfo()),
265             ('v1.37.1', ReleaseInfo()),
266             ('v1.38.1', ReleaseInfo()),
267             ('v1.39.0', ReleaseInfo()),
268             ('v1.40.1', ReleaseInfo()),
269         ]),
270     'python':
271         OrderedDict([
272             ('v1.0.x',
273              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
274             ('v1.1.4',
275              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
276             ('v1.2.5',
277              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
278             ('v1.3.9',
279              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
280             ('v1.4.2',
281              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
282             ('v1.6.6',
283              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
284             ('v1.7.2',
285              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
286             ('v1.8.1',
287              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
288             ('v1.9.1',
289              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
290             ('v1.10.1',
291              ReleaseInfo(runtimes=['python'], testcases_file='python__v1.0.x')),
292             ('v1.11.1',
293              ReleaseInfo(runtimes=['python'],
294                          testcases_file='python__v1.11.1')),
295             ('v1.12.0',
296              ReleaseInfo(runtimes=['python'],
297                          testcases_file='python__v1.11.1')),
298             ('v1.13.0',
299              ReleaseInfo(runtimes=['python'],
300                          testcases_file='python__v1.11.1')),
301             ('v1.14.1',
302              ReleaseInfo(runtimes=['python'],
303                          testcases_file='python__v1.11.1')),
304             ('v1.15.0',
305              ReleaseInfo(runtimes=['python'],
306                          testcases_file='python__v1.11.1')),
307             ('v1.16.0',
308              ReleaseInfo(runtimes=['python'],
309                          testcases_file='python__v1.11.1')),
310             ('v1.17.1',
311              ReleaseInfo(runtimes=['python'],
312                          testcases_file='python__v1.11.1')),
313             ('v1.18.0', ReleaseInfo(runtimes=['python'])),
314             ('v1.19.0', ReleaseInfo(runtimes=['python'])),
315             ('v1.20.0', ReleaseInfo(runtimes=['python'])),
316             ('v1.21.4', ReleaseInfo(runtimes=['python'])),
317             ('v1.22.0', ReleaseInfo(runtimes=['python'])),
318             ('v1.22.1', ReleaseInfo(runtimes=['python'])),
319             ('v1.23.0', ReleaseInfo(runtimes=['python'])),
320             ('v1.24.0', ReleaseInfo(runtimes=['python'])),
321             ('v1.25.0', ReleaseInfo(runtimes=['python'])),
322             ('v1.26.0', ReleaseInfo(runtimes=['python'])),
323             ('v1.27.3', ReleaseInfo(runtimes=['python'])),
324             ('v1.30.0', ReleaseInfo(runtimes=['python'])),
325             ('v1.31.1', ReleaseInfo(runtimes=['python'])),
326             ('v1.32.0', ReleaseInfo(runtimes=['python'])),
327             ('v1.33.2', ReleaseInfo(runtimes=['python'])),
328             ('v1.34.0', ReleaseInfo(runtimes=['python'])),
329             ('v1.35.0', ReleaseInfo(runtimes=['python'])),
330             ('v1.36.3', ReleaseInfo(runtimes=['python'])),
331             ('v1.37.0', ReleaseInfo(runtimes=['python'])),
332             ('v1.38.0', ReleaseInfo(runtimes=['python'])),
333             ('v1.39.0', ReleaseInfo(runtimes=['python'])),
334         ]),
335     'node':
336         OrderedDict([
337             ('v1.0.1', ReleaseInfo(testcases_file='node__v1.0.1')),
338             ('v1.1.4', ReleaseInfo(testcases_file='node__v1.1.4')),
339             ('v1.2.5', ReleaseInfo(testcases_file='node__v1.1.4')),
340             ('v1.3.9', ReleaseInfo(testcases_file='node__v1.1.4')),
341             ('v1.4.2', ReleaseInfo(testcases_file='node__v1.1.4')),
342             ('v1.6.6', ReleaseInfo(testcases_file='node__v1.1.4')),
343             # TODO: https://github.com/grpc/grpc-node/issues/235.
344             # ('v1.7.2', ReleaseInfo()),
345             ('v1.8.4', ReleaseInfo()),
346             ('v1.9.1', ReleaseInfo()),
347             ('v1.10.0', ReleaseInfo()),
348             ('v1.11.3', ReleaseInfo()),
349             ('v1.12.4', ReleaseInfo()),
350         ]),
351     'ruby':
352         OrderedDict([
353             ('v1.0.1',
354              ReleaseInfo(patch=[
355                  'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile',
356                  'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh',
357              ],
358                          testcases_file='ruby__v1.0.1')),
359             ('v1.1.4', ReleaseInfo(testcases_file='ruby__v1.1.4')),
360             ('v1.2.5', ReleaseInfo(testcases_file='ruby__v1.1.4')),
361             ('v1.3.9', ReleaseInfo(testcases_file='ruby__v1.1.4')),
362             ('v1.4.2', ReleaseInfo(testcases_file='ruby__v1.1.4')),
363             ('v1.6.6', ReleaseInfo(testcases_file='ruby__v1.1.4')),
364             ('v1.7.2', ReleaseInfo(testcases_file='ruby__v1.1.4')),
365             ('v1.8.0', ReleaseInfo(testcases_file='ruby__v1.1.4')),
366             ('v1.9.1', ReleaseInfo(testcases_file='ruby__v1.1.4')),
367             ('v1.10.1', ReleaseInfo(testcases_file='ruby__v1.1.4')),
368             ('v1.11.1', ReleaseInfo(testcases_file='ruby__v1.1.4')),
369             ('v1.12.0', ReleaseInfo(testcases_file='ruby__v1.1.4')),
370             ('v1.13.0', ReleaseInfo(testcases_file='ruby__v1.1.4')),
371             ('v1.14.1', ReleaseInfo(testcases_file='ruby__v1.1.4')),
372             ('v1.15.0', ReleaseInfo(testcases_file='ruby__v1.1.4')),
373             ('v1.16.0', ReleaseInfo(testcases_file='ruby__v1.1.4')),
374             ('v1.17.1', ReleaseInfo(testcases_file='ruby__v1.1.4')),
375             ('v1.18.0',
376              ReleaseInfo(patch=[
377                  'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh',
378              ])),
379             ('v1.19.0', ReleaseInfo()),
380             ('v1.20.0', ReleaseInfo()),
381             ('v1.21.4', ReleaseInfo()),
382             ('v1.22.0', ReleaseInfo()),
383             ('v1.22.1', ReleaseInfo()),
384             ('v1.23.0', ReleaseInfo()),
385             ('v1.24.0', ReleaseInfo()),
386             ('v1.25.0', ReleaseInfo()),
387             # TODO: https://github.com/grpc/grpc/issues/18262.
388             # If you are not encountering the error in above issue
389             # go ahead and upload the docker image for new releases.
390             ('v1.26.0', ReleaseInfo()),
391             ('v1.27.3', ReleaseInfo()),
392             ('v1.30.0', ReleaseInfo()),
393             ('v1.31.1', ReleaseInfo()),
394             ('v1.32.0', ReleaseInfo()),
395             ('v1.33.2', ReleaseInfo()),
396             ('v1.34.0', ReleaseInfo()),
397             ('v1.35.0', ReleaseInfo()),
398             ('v1.36.3', ReleaseInfo()),
399             ('v1.37.0', ReleaseInfo()),
400             ('v1.38.0', ReleaseInfo()),
401             ('v1.39.0', ReleaseInfo()),
402         ]),
403     'php':
404         OrderedDict([
405             ('v1.0.1', ReleaseInfo(testcases_file='php__v1.0.1')),
406             ('v1.1.4', ReleaseInfo(testcases_file='php__v1.0.1')),
407             ('v1.2.5', ReleaseInfo(testcases_file='php__v1.0.1')),
408             ('v1.3.9', ReleaseInfo(testcases_file='php__v1.0.1')),
409             ('v1.4.2', ReleaseInfo(testcases_file='php__v1.0.1')),
410             ('v1.6.6', ReleaseInfo(testcases_file='php__v1.0.1')),
411             ('v1.7.2', ReleaseInfo(testcases_file='php__v1.0.1')),
412             ('v1.8.0', ReleaseInfo(testcases_file='php__v1.0.1')),
413             ('v1.9.1', ReleaseInfo(testcases_file='php__v1.0.1')),
414             ('v1.10.1', ReleaseInfo(testcases_file='php__v1.0.1')),
415             ('v1.11.1', ReleaseInfo(testcases_file='php__v1.0.1')),
416             ('v1.12.0', ReleaseInfo(testcases_file='php__v1.0.1')),
417             ('v1.13.0', ReleaseInfo(testcases_file='php__v1.0.1')),
418             ('v1.14.1', ReleaseInfo(testcases_file='php__v1.0.1')),
419             ('v1.15.0', ReleaseInfo(testcases_file='php__v1.0.1')),
420             ('v1.16.0', ReleaseInfo(testcases_file='php__v1.0.1')),
421             ('v1.17.1', ReleaseInfo(testcases_file='php__v1.0.1')),
422             ('v1.18.0', ReleaseInfo()),
423             # v1.19 and v1.20 were deliberately omitted here because of an issue.
424             # See https://github.com/grpc/grpc/issues/18264
425             ('v1.21.4', ReleaseInfo()),
426             ('v1.22.0', ReleaseInfo()),
427             ('v1.22.1', ReleaseInfo()),
428             ('v1.23.0', ReleaseInfo()),
429             ('v1.24.0', ReleaseInfo()),
430             ('v1.25.0', ReleaseInfo()),
431             ('v1.26.0', ReleaseInfo()),
432             ('v1.27.3', ReleaseInfo()),
433             ('v1.30.0', ReleaseInfo()),
434             ('v1.31.1', ReleaseInfo()),
435             ('v1.32.0', ReleaseInfo()),
436             ('v1.33.2', ReleaseInfo()),
437             ('v1.34.0', ReleaseInfo()),
438             ('v1.35.0', ReleaseInfo()),
439             ('v1.36.3', ReleaseInfo()),
440             ('v1.37.0', ReleaseInfo()),
441             ('v1.38.0', ReleaseInfo()),
442             ('v1.39.0', ReleaseInfo()),
443         ]),
444     'csharp':
445         OrderedDict([
446             ('v1.0.1',
447              ReleaseInfo(patch=[
448                  'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile',
449                  'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile',
450              ],
451                          testcases_file='csharp__v1.1.4')),
452             ('v1.1.4', ReleaseInfo(testcases_file='csharp__v1.1.4')),
453             ('v1.2.5', ReleaseInfo(testcases_file='csharp__v1.1.4')),
454             ('v1.3.9', ReleaseInfo(testcases_file='csharp__v1.3.9')),
455             ('v1.4.2', ReleaseInfo(testcases_file='csharp__v1.3.9')),
456             ('v1.6.6', ReleaseInfo(testcases_file='csharp__v1.3.9')),
457             ('v1.7.2', ReleaseInfo(testcases_file='csharp__v1.3.9')),
458             ('v1.8.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
459             ('v1.9.1', ReleaseInfo(testcases_file='csharp__v1.3.9')),
460             ('v1.10.1', ReleaseInfo(testcases_file='csharp__v1.3.9')),
461             ('v1.11.1', ReleaseInfo(testcases_file='csharp__v1.3.9')),
462             ('v1.12.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
463             ('v1.13.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
464             ('v1.14.1', ReleaseInfo(testcases_file='csharp__v1.3.9')),
465             ('v1.15.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
466             ('v1.16.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
467             ('v1.17.1', ReleaseInfo(testcases_file='csharp__v1.3.9')),
468             ('v1.18.0', ReleaseInfo(testcases_file='csharp__v1.18.0')),
469             ('v1.19.0', ReleaseInfo(testcases_file='csharp__v1.18.0')),
470             ('v1.20.0', ReleaseInfo()),
471             ('v1.21.4', ReleaseInfo()),
472             ('v1.22.0', ReleaseInfo()),
473             ('v1.22.1', ReleaseInfo()),
474             ('v1.23.0', ReleaseInfo()),
475             ('v1.24.0', ReleaseInfo()),
476             ('v1.25.0', ReleaseInfo()),
477             ('v1.26.0', ReleaseInfo()),
478             ('v1.27.3', ReleaseInfo()),
479             ('v1.30.0', ReleaseInfo()),
480             ('v1.31.1', ReleaseInfo()),
481             ('v1.32.0', ReleaseInfo()),
482             ('v1.33.2', ReleaseInfo()),
483             ('v1.34.0', ReleaseInfo()),
484             ('v1.35.0', ReleaseInfo()),
485             ('v1.36.3', ReleaseInfo()),
486             ('v1.37.0', ReleaseInfo()),
487             ('v1.38.1', ReleaseInfo()),
488             ('v1.39.1', ReleaseInfo()),
489         ]),
490 }