@@ -47,8 +47,7 @@ stages:
4747 } | { read xs; exit $xs; }
4848 } 4>&1
4949
50- ls -la "$REPORT_DIR"
51- mv coverage-all.out "$COVERAGE_OUT"
50+ cp "$COVERAGE_OUT" "$REPORT_DIR"
5251 ls -la "$REPORT_DIR"
5352 retryCountOnTaskFailure: 3
5453 displayName: "Run Unit Tests - Linux"
@@ -62,15 +61,50 @@ stages:
6261 GOCOV_BIN="$BIN_INSTALL_DIR/gocov"
6362 GOCOV_XML_BIN="$BIN_INSTALL_DIR/gocov-xml"
6463
65- $GOCOV_BIN convert "$COVERAGE_OUT" > "$REPORT_DIR"/linux-coverage.json
66- $GOCOV_XML_BIN < "$REPORT_DIR"/linux-coverage.json > "$REPORT_DIR"/linux-coverage.gocov.xml
67-
68- echo "##vso[task.setvariable variable=JUNIT_XML;isOutput=true]$(cat $REPORT_XML | base64 -w 0)"
69- echo "##vso[task.setvariable variable=COVERAGE_OUT_JSON;isOutput=true]$(cat $REPORT_DIR/linux-coverage.json | base64 -w 0)"
70- echo "##vso[task.setvariable variable=COVERAGE_OUT_XML;isOutput=true]$(cat $REPORT_DIR/linux-coverage.xml | base64 -w 0)"
71- echo "##vso[task.setvariable variable=GOCOV_OUT_XML;isOutput=true]$(cat $REPORT_DIR/linux-coverage.gocov.xml | base64 -w 0)"
72- name: report
64+ $GOCOV_BIN convert "$COVERAGE_OUT" > "$REPORT_DIR"/linux-coverage.gocov.json
65+ $GOCOV_XML_BIN < "$REPORT_DIR"/linux-coverage.gocov.json > "$REPORT_DIR"/linux-coverage.gocov.xml
66+
67+ - task : UsePythonVersion@0
68+ inputs :
69+ versionSpec : ' 3.x' # string. Required. Version spec. Default: 3.x.
70+ addToPath : true
71+
72+ - task : PythonScript@0
7373 displayName : " Generate Test Reporting"
74+ name : report
75+ inputs :
76+ arguments : $(Build.SourcesDirectory)
77+ scriptSource : ' inline'
78+ script : |
79+ import os
80+ import zlib
81+
82+ def output_var(var_name, is_output, var_value):
83+ os.environ[var_name] = val
84+ print(f"##vso[task.setvariable variable={var_name};isOutput={is_output}]{var_value}")
85+
86+ def encode_and_compress(file_path):
87+ with open(file_path, 'rb') as file:
88+ compressed_data = zlib.compress(file.read(), level=9)
89+ return compressed_data.hex()
90+
91+ report_dir = os.environ['REPORT_DIR']
92+ report_dir = os.path.realpath(report_dir)
93+
94+ convert_vars = [
95+ { 'var_name': 'LINUX_GOCOV_OUT', 'file_path': f'{report_dir}/linux-coverage.out' },
96+ { 'var_name': 'LINUX_COVERAGE_OUT_XML', 'file_path': f'{report_dir}/linux-coverage.gocov.xml' },
97+ { 'var_name': 'LINUX_COVERAGE_OUT_JSON', 'file_path': f'{report_dir}/linux-coverage.gocov.json' },
98+ { 'var_name': 'LINUX_JUNIT_XML', 'file_path': f'{report_dir}/report.xml' }
99+ ]
100+
101+ def decompress_and_decode(compressed_string):
102+ encoded_string = zlib.decompress(compressed_string)
103+ return encoded_string
104+
105+ for item in convert_vars:
106+ val = encode_and_compress(item['file_path'])
107+ output_var(item['var_name'], True, val)
74108
75109
76110 - job : windows
@@ -82,6 +116,7 @@ stages:
82116 variables :
83117 ob_outputDirectory : $(Build.ArtifactStagingDirectory)/windows-unittest
84118
119+ INPUT_TEST_MODULES : ' ./npm/... ./cni/... ./platform/...'
85120 REPORT_DIR : $(Build.ArtifactStagingDirectory)/windows-unittest
86121 REPORT_XML : report.xml
87122 GOCOV_OUT : windows-gocov.out
@@ -92,18 +127,18 @@ stages:
92127 - task : GoTool@0
93128 inputs :
94129 version : ' $(GOVERSION)'
95-
130+
96131 - task : UsePythonVersion@0
97132 inputs :
98133 versionSpec : ' 3.x' # string. Required. Version spec. Default: 3.x.
99134 addToPath : true
100-
135+
101136 - task : PythonScript@0
102137 displayName : " Run Unit Tests - Windows"
103138 retryCountOnTaskFailure : 3
104139 inputs :
105140 scriptSource : ' inline'
106- arguments : $(Build.SourcesDirectory)
141+ arguments : $(Build.SourcesDirectory) $(INPUT_TEST_MODULES)
107142 script : |
108143 import os
109144 import subprocess
@@ -112,14 +147,15 @@ stages:
112147 # Set environment variables and directories
113148 cwd = sys.argv[1]
114149 cwd = os.path.realpath(cwd)
150+ gotest_packages = sys.argv[2]
115151 bin_install_dir = os.path.join(cwd, 'bin')
116152 os.environ['GOBIN'] = bin_install_dir
117153
118154 report_dir = os.environ['REPORT_DIR']
119155 report_dir = os.path.realpath(report_dir)
120156
121157 log_file = os.path.join(report_dir, 'test.stdout.log')
122-
158+
123159 coverage_file = os.environ['COVERAGE_OUT']
124160 coverage_out = os.path.join(report_dir, coverage_file)
125161
@@ -140,8 +176,10 @@ stages:
140176 subprocess.run('make tools', shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
141177
142178 # Function to run the test and capture output
143- def run_test():
144- cmd_gotest = f"go test -timeout 30m -covermode atomic -coverprofile={coverage_out} ./npm/... ./cni/... ./platform/..."
179+ def run_test(packages_to_test) :
180+ go_pkgs = ' '.join(packages_to_test) if isinstance(packages_to_test, list) else packages_to_test
181+
182+ cmd_gotest = f"go test -timeout 30m -covermode atomic -coverprofile={coverage_out} {go_pkgs}"
145183 cmd_junitreport = f'{junit_report_bin} -set-exit-code -in {log_file} -out {junit_xml} -iocopy'
146184 cmd_gocover = f'go tool cover -func={coverage_out}'
147185
@@ -154,14 +192,15 @@ stages:
154192 print(cmd_gocover)
155193 gocover_process = subprocess.run(cmd_gocover, shell=True, text=True, stdout=open(gocover_out, "w"), cwd=cwd)
156194
157- test_exit_code = gotest_process.returncode
158- sys.exit(test_exit_code)
195+ return gotest_process.returncode
159196
160197 # Run the test function
161- run_test()
162-
198+ return_code = run_test(gotest_packages )
199+
163200 # List report directory contents again
164201 print(os.listdir(report_dir))
202+
203+ sys.exit(return_code)
165204
166205 - task : PythonScript@0
167206 displayName : " Generate Test Reporting"
@@ -170,17 +209,17 @@ stages:
170209 arguments : $(Build.SourcesDirectory)
171210 scriptSource : ' inline'
172211 script : |
173- import base64
174212 import os
175213 import subprocess
176214 import sys
215+ import zlib
177216
178217 # Define the necessary variables
179218 cwd = sys.argv[1]
180219 cwd = os.path.realpath(cwd)
181220 bin_install_dir = os.path.join(cwd, 'bin')
182221 os.environ['GOBIN'] = bin_install_dir
183-
222+
184223 report_dir = os.environ['REPORT_DIR']
185224 report_dir = os.path.realpath(report_dir)
186225
@@ -215,27 +254,32 @@ stages:
215254 with open(coverage_json, 'r') as json_file :
216255 subprocess.run([gocov_xml_bin], stdin=json_file, stdout=xml_file, check=True)
217256
218- # Encoding function to convert long multi-line files to single line for setting vso variable.
219- def encode_file_to_base64(file_path):
257+
258+ def output_var(var_name, is_output, var_value) :
259+ os.environ[var_name] = val
260+ print(f"##vso[task.setvariable variable={var_name};isOutput={is_output}]{var_value}")
261+
262+ def encode_and_compress(file_path) :
220263 with open(file_path, 'rb') as file :
221- encoded_string = base64.b64encode(file.read()).decode('utf-8')
222- return encoded_string
264+ compressed_data = zlib.compress(file.read(), level=9)
265+ return compressed_data.hex()
266+
223267
224268 # coverage json
225- coverage_out_json_content = encode_file_to_base64 (coverage_json)
226- print(f"##vso[task.setvariable variable= COVERAGE_OUT_JSON;isOutput=true]{coverage_out_json_content}" )
269+ coverage_json_content = encode_and_compress (coverage_json)
270+ output_var(' COVERAGE_OUT_JSON', True, coverage_json_content )
227271
228272 # coverage xml
229- coverage_xml_content = encode_file_to_base64(coverage_json )
230- print(f"##vso[task.setvariable variable= COVERAGE_OUT_XML;isOutput=true]{ coverage_xml_content}" )
273+ coverage_xml_content = encode_and_compress(coverage_xml )
274+ output_var(' COVERAGE_OUT_XML', True, coverage_xml_content)
231275
232276 # go cover
233- gocover_out_content = encode_file_to_base64 (gocover_out)
234- print(f"##vso[task.setvariable variable= GOCOV_OUT;isOutput=true]{ gocover_out_content}" )
277+ gocover_out_content = encode_and_compress (gocover_out)
278+ output_var(' GOCOV_OUT', True, gocover_out_content)
235279
236280 # junit xml
237- junit_xml_content = encode_file_to_base64 (junit_xml)
238- print(f"##vso[task.setvariable variable= JUNIT_XML;isOutput=true]{ junit_xml_content}" )
281+ junit_xml_content = encode_and_compress (junit_xml)
282+ output_var(' JUNIT_XML', True, junit_xml_content)
239283
240284
241285 - job : coverage
@@ -259,26 +303,60 @@ stages:
259303 LINUX_GOCOV_OUT : $[ dependencies.linux.outputs['report.GOCOV_OUT_XML'] ]
260304 LINUX_JUNIT_XML : $[ dependencies.linux.outputs['report.JUNIT_XML'] ]
261305 steps :
262- - script : |
263- mkdir "$COV_DIR"
264- echo "$LINUX_COVERAGE_OUT_XML" | base64 -d > "$COV_DIR"/linux-coverage.xml
265- echo "$LINUX_COVERAGE_OUT_JSON" | base64 -d > "$COV_DIR"/linux-coverage.json
266- echo "$LINUX_GOCOV_OUT" | base64 -d > "$COV_DIR"/linux-coverage.gocov.xml
267- echo "$LINUX_JUNIT_XML" | base64 -d > "$COV_DIR"/linux-coverage.junit.xml
306+ - task : UsePythonVersion@0
307+ inputs :
308+ versionSpec : ' 3.x' # string. Required. Version spec. Default: 3.x.
309+ addToPath : true
310+
311+ - task : PythonScript@0
312+ displayName : " Write Test Output Artifacts"
313+ retryCountOnTaskFailure : 3
314+ inputs :
315+ scriptSource : ' inline'
316+ arguments : $(Build.ArtifactStagingDirectory)/out
317+ script : |
318+ import os
319+ import subprocess
320+ import sys
321+ import zlib
322+
323+ # Define the necessary variables
324+ cwd = sys.argv[1]
325+ cwd = os.path.realpath(cwd)
326+
327+ report_dir = os.environ['REPORT_DIR']
328+ report_dir = os.path.realpath(report_dir)
329+
330+ # Create the report directory if it doesn't exist
331+ os.makedirs(report_dir, exist_ok=True)
332+
333+ def decompress_and_decode(compressed_string) :
334+ encoded_string = zlib.decompress(compressed_string)
335+ return encoded_string
268336
269- echo "$WINDOWS_COVERAGE_OUT_XML" | base64 -d > "$COV_DIR"/windows-coverage.xml
270- echo "$WINDOWS_COVERAGE_OUT_JSON" | base64 -d > "$COV_DIR"/windows-coverage.json
271- echo "$WINDOWS_GOCOV_OUT" | base64 -d > "$COV_DIR"/windows-coverage.gocov.xml
272- echo "$WINDOWS_JUNIT_XML" | base64 -d > "$COV_DIR"/windows-coverage.junit.xml
273- env:
274- COV_DIR: $(Build.ArtifactStagingDirectory)/coverage
337+ convert_vars = [
338+ { var_name: 'LINUX_GOCOV_OUT', file_path: f'{report_dir}/coverage-all.out' },
339+ { var_name: 'LINUX_COVERAGE_OUT_XML', file_path: f'{report_dir}/coverage-all.xml' },
340+ { var_name: 'LINUX_COVERAGE_OUT_JSON', file_path: f'{report_dir}/coverage-all.json' },
341+ { var_name: 'LINUX_JUNIT_XML', file_path: f'{report_dir}/coverage-all.junit.xml' },
342+ { var_name: 'WINDOWS_COVERAGE_OUT_XML', file_path: f'{report_dir}/windows-coverage.xml' },
343+ { var_name: 'WINDOWS_COVERAGE_OUT_JSON', file_path: f'{report_dir}/windows-coverage.json' },
344+ { var_name: 'WINDOWS_GOCOV_OUT', file_path: f'{report_dir}/windows-coverage.out' },
345+ { var_name: 'WINDOWS_JUNIT_XML', file_path: f'{report_dir}/windows-coverage.junit.xml' }
346+ ]
347+ for item in convert_vars :
348+ with open(item['file_path'], 'wb') as file_io :
349+ print(f'Retrieving variable value from env var {item["var_name"]}')
350+ var_value = bytes.fromhex(os.environ[item['var_name']])
351+ print(f'Decompressing data and writing variable value to file {item["file_path"]}')
352+ file_io.write(decompress_and_decode(var_value))
275353
276354 - task : PublishTestResults@2
277355 displayName : " Publish Test Results"
278356 inputs :
279357 testResultsFormat : ' JUnit'
280358 testResultsFiles : # string. Required. Test results files. Default: **/TEST-*.xml.
281- searchFolder : coverage /**/*.junit.xml
359+ searchFolder : $(Build.ArtifactStagingDirectory)/out /**/*.junit.xml
282360 failTaskOnFailedTests : true
283361 failTaskOnMissingResultsFile : false
284362 # testRunTitle: # Name of the test runs
@@ -293,7 +371,7 @@ stages:
293371 - task : PublishCodeCoverageResults@2
294372 displayName : " Publish Code Coverage Report"
295373 inputs :
296- summaryFileLocation : coverage /*
374+ summaryFileLocation : $(Build.ArtifactStagingDirectory)/out /*
297375
298376 - task : BuildQualityChecks@8
299377 displayName : " Check Code Coverage Regression"
0 commit comments