4242 collectTestReportsFn = collectTestReports
4343 runCmdFn = runCmd
4444 isManualFn = external .IsManualExecution
45+ installAgentFn = installAgents
4546 getWorkspace = external .GetWrkspcPath
4647)
4748
@@ -69,7 +70,10 @@ type runTestsTask struct {
6970 language string // language of codebase
7071 buildTool string // buildTool used for codebase
7172 packages string // Packages ti will generate callgraph for
73+ namespaces string // Namespaces TI will generate callgraph for, similar to package
7274 annotations string // Annotations to identify tests for instrumentation
75+ buildEnvironment string // Dotnet build environment
76+ frameworkVersion string // Dotnet framework version
7377 runOnlySelectedTests bool // Flag to be used for disabling testIntelligence and running all tests
7478 envVarOutputs []string
7579 environment map [string ]string
@@ -112,6 +116,8 @@ func NewRunTestsTask(step *pb.UnitStep, tmpFilePath string, log *zap.SugaredLogg
112116 runOnlySelectedTests : r .GetRunOnlySelectedTests (),
113117 envVarOutputs : r .GetEnvVarOutputs (),
114118 environment : r .GetEnvironment (),
119+ buildEnvironment : r .GetBuildEnvironment (),
120+ frameworkVersion : r .GetFrameworkVersion (),
115121 cmdContextFactory : exec .OsCommandContextGracefulWithLog (log ),
116122 logMetrics : logMetrics ,
117123 log : log ,
@@ -216,6 +222,55 @@ instrPackages: %s`, dir, r.packages)
216222 return iniFile , nil
217223}
218224
225+ /*
226+ Creates config.yaml file for .NET agent to consume and returns the path to config.yaml file on successful creation.
227+ Args:
228+ None
229+ Returns:
230+ configPath (string): Path to the config.yaml file. Empty string on errors.
231+ err (error): Error if there's one, nil otherwise.
232+ */
233+ func (r * runTestsTask ) createDotNetConfigFile () (string , error ) {
234+ // Create config file
235+ dir := fmt .Sprintf (outDir , r .tmpFilePath )
236+ err := r .fs .MkdirAll (dir , os .ModePerm )
237+ if err != nil {
238+ r .log .Errorw (fmt .Sprintf ("could not create nested directory %s" , dir ), zap .Error (err ))
239+ return "" , err
240+ }
241+
242+ if r .namespaces == "" {
243+ r .log .Errorw ("Dotnet does not support auto detect namespaces" , zap .Error (err ))
244+ }
245+ var data string
246+ var outputFile string
247+
248+ outputFile = fmt .Sprintf ("%s/config.yaml" , r .tmpFilePath )
249+ namespaceArray := strings .Split (r .namespaces , "," )
250+ for idx , s := range namespaceArray {
251+ namespaceArray [idx ] = fmt .Sprintf ("'%s'" , s )
252+ }
253+ data = fmt .Sprintf (`outDir: '%s'
254+ logLevel: 0
255+ writeTo: [COVERAGE_JSON]
256+ instrPackages: [%s]` , dir , strings .Join (namespaceArray , "," ))
257+
258+ r .log .Infow (fmt .Sprintf ("attempting to write %s to %s" , data , outputFile ))
259+ f , err := r .fs .Create (outputFile )
260+ if err != nil {
261+ r .log .Errorw (fmt .Sprintf ("could not create file %s" , outputFile ), zap .Error (err ))
262+ return "" , err
263+ }
264+ _ , err = f .Write ([]byte (data ))
265+ defer f .Close ()
266+ if err != nil {
267+ r .log .Errorw (fmt .Sprintf ("could not write %s to file %s" , data , outputFile ), zap .Error (err ))
268+ return "" , err
269+ }
270+ // Return path to the config.yaml file
271+ return outputFile , nil
272+ }
273+
219274func valid (tests []types.RunnableTest ) bool {
220275 for _ , t := range tests {
221276 if t .Class == "" {
@@ -225,7 +280,7 @@ func valid(tests []types.RunnableTest) bool {
225280 return true
226281}
227282
228- func (r * runTestsTask ) getCmd (ctx context.Context , outputVarFile string ) (string , error ) {
283+ func (r * runTestsTask ) getCmd (ctx context.Context , agentPath , outputVarFile string ) (string , error ) {
229284 // Get the tests that need to be run if we are running selected tests
230285 var selection types.SelectTestsResp
231286 var files []types.File
@@ -273,7 +328,9 @@ func (r *runTestsTask) getCmd(ctx context.Context, outputVarFile string) (string
273328 {
274329 switch r .buildTool {
275330 case "dotnet" :
276- runner = csharp .NewDotnetRunner (r .log , r .fs , r .cmdContextFactory )
331+ runner = csharp .NewDotnetRunner (r .log , r .fs , r .cmdContextFactory , agentPath )
332+ case "nunitconsole" :
333+ runner = csharp .NewNunitConsoleRunner (r .log , r .fs , r .cmdContextFactory , agentPath )
277334 default :
278335 return "" , fmt .Errorf ("build tool: %s is not supported for csharp" , r .buildTool )
279336 }
@@ -287,12 +344,26 @@ func (r *runTestsTask) getCmd(ctx context.Context, outputVarFile string) (string
287344 outputVarCmd += fmt .Sprintf ("\n echo %s $%s >> %s" , o , o , outputVarFile )
288345 }
289346
290- // Create the java agent config file
291- iniFilePath , err := r .createJavaAgentConfigFile (runner )
292- if err != nil {
293- return "" , err
347+ var iniFilePath , agentArg string
348+
349+ switch r .language {
350+ case "java" :
351+ {
352+ // Create the java agent config file
353+ iniFilePath , err = r .createJavaAgentConfigFile (runner )
354+ if err != nil {
355+ return "" , err
356+ }
357+ agentArg = fmt .Sprintf (javaAgentArg , iniFilePath )
358+ }
359+ case "csharp" :
360+ {
361+ iniFilePath , err = r .createDotNetConfigFile ()
362+ if err != nil {
363+ return "" , err
364+ }
365+ }
294366 }
295- agentArg := fmt .Sprintf (javaAgentArg , iniFilePath )
296367
297368 testCmd , err := runner .GetCmd (ctx , selection .Tests , r .args , iniFilePath , isManual , ! r .runOnlySelectedTests )
298369 if err != nil {
@@ -316,8 +387,14 @@ func (r *runTestsTask) execute(ctx context.Context, retryCount int32) (map[strin
316387 ctx , cancel := context .WithTimeout (ctx , time .Second * time .Duration (r .timeoutSecs ))
317388 defer cancel ()
318389
390+ // Install agent artifacts if not present
391+ agentPath , err := installAgentFn (ctx , r .tmpFilePath , r .language , r .buildTool , r .frameworkVersion , r .buildEnvironment , r .log , r .fs )
392+ if err != nil {
393+ return nil , err
394+ }
395+
319396 outputFile := filepath .Join (r .tmpFilePath , fmt .Sprintf ("%s%s" , r .id , outputEnvSuffix ))
320- cmdToExecute , err := r .getCmd (ctx , outputFile )
397+ cmdToExecute , err := r .getCmd (ctx , agentPath , outputFile )
321398 if err != nil {
322399 r .log .Errorw ("could not create run command" , zap .Error (err ))
323400 return nil , err
0 commit comments