Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 7d570d9

Browse files
committed
Merge pull request #262 from Microsoft/users/achalla/BrowsingCCFix
Browsing support for code coverage
2 parents 85e3e94 + cbf7832 commit 7d570d9

File tree

6 files changed

+74
-28
lines changed

6 files changed

+74
-28
lines changed

src/agent/codecoveragepublisher.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export class CodeCoveragePublisher {
7878
var newReportDirectory = reportDirectory;
7979

8080
if (reportDirectory && reportDirectory.length > 0) {
81-
if (utilities.isPathExists(reportDirectory) && fs.lstatSync(reportDirectory).isDirectory()) {
81+
if (utilities.isDirectoryExists(reportDirectory)) {
8282
reportDirectoryExists = true;
8383
}
8484
else {
@@ -92,11 +92,11 @@ export class CodeCoveragePublisher {
9292
}
9393

9494
// copy the summary file into report directory
95-
shell.cp('-f', summaryFile, newReportDirectory);
95+
shell.cp(summaryFile, newReportDirectory);
9696

9797
_this.command.info("PublishCodeCoverageFiles : Publishing code coverage report '" + newReportDirectory + "'");
98-
99-
_this.uploadArtifact(newReportDirectory, codeCoverageArtifactName, containerId).then(function() {
98+
99+
_this.uploadArtifact(newReportDirectory, codeCoverageArtifactName, containerId, _this.isReportDirectoryBrowsable(newReportDirectory)).then(function() {
100100
try {
101101
_this.command.info("PublishCodeCoverageFiles : Code coverage report published successfully.");
102102

@@ -118,7 +118,7 @@ export class CodeCoveragePublisher {
118118
var rawFilesArtifactName = "Code Coverage Files_" + _this.buildId;
119119

120120
_this.command.info("PublishCodeCoverageFiles : Publishing additional code coverage files '" + rawFilesDirectory + "'");
121-
_this.uploadArtifact(rawFilesDirectory, rawFilesArtifactName, containerId).then(function() {
121+
_this.uploadArtifact(rawFilesDirectory, rawFilesArtifactName, containerId, "False").then(function() {
122122
// clean the temporary additional files folder created.
123123
shell.rm('-rf', rawFilesDirectory);
124124

@@ -171,17 +171,20 @@ export class CodeCoveragePublisher {
171171
// - artifactName: name of teh artifact
172172
// - containerId: containerId
173173
//-----------------------------------------------------
174-
private uploadArtifact(path: string, artifactName: string, containerId: number): Q.Promise<any> {
174+
private uploadArtifact(path: string, artifactName: string, containerId: number, browsable: string): Q.Promise<any> {
175175
var defer = Q.defer();
176+
var properties = {};
177+
properties["browsable"] = browsable;
176178
fc.copyToFileContainer(this.executionContext, path, containerId, "/" + artifactName).then((artifactLocation: string) => {
177179
try {
178180
this.command.info('Associating artifact ' + artifactLocation + ' ...');
179181
var artifact: buildifm.BuildArtifact = <buildifm.BuildArtifact>{
180182
name: artifactName,
181183
resource: {
182184
type: "container",
183-
data: artifactLocation
184-
}
185+
data: artifactLocation,
186+
properties: properties
187+
},
185188
};
186189

187190
this.executionContext.service.postArtifact(this.project, this.buildId, artifact).fail(function(err) {
@@ -201,6 +204,17 @@ export class CodeCoveragePublisher {
201204
return defer.promise;
202205
}
203206

207+
//-----------------------------------------------------
208+
// Finds if the report directory has index.html
209+
// - reportDirectory: string - report directory
210+
//-----------------------------------------------------
211+
private isReportDirectoryBrowsable(reportDirectory: string): string {
212+
var defaultIndexFile = path.join(reportDirectory, "index.html");
213+
if(utilities.isFileExists(defaultIndexFile)){
214+
return "True";
215+
}
216+
return "False";
217+
}
204218

205219
//-----------------------------------------------------
206220
// Read code coverage results from summary file.

src/agent/commands/codecoverage.publish.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class CodeCoveragePublishCommand implements cm.IAsyncCommand {
4545
return defer.promise;
4646
}
4747

48-
if (!utilities.isPathExists(summaryFile) || !fs.lstatSync(summaryFile).isFile()) {
48+
if (!utilities.isFileExists(summaryFile)) {
4949
var err = new Error("Code coverage summary file '" + summaryFile + "' doesnot exist or it is not a valid file.");
5050
defer.reject(err);
5151
return defer.promise;

src/agent/utilities.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,29 @@ export function sortStringArray(list): string[] {
4343
return sortedFiles;
4444
}
4545

46-
// returns true if path exists else fasle.
47-
export function isPathExists(path: string): boolean {
46+
// returns true if path exists and it is a directory else false.
47+
export function isDirectoryExists(path: string): boolean {
48+
try {
49+
return fs.lstatSync(path).isDirectory();
50+
}
51+
catch (error) {
52+
return false;
53+
}
54+
return true;
55+
}
56+
57+
// returns true if path exists and it is a file else false.
58+
export function isFileExists(path: string): boolean {
4859
try {
49-
fs.statSync(path);
60+
return fs.lstatSync(path).isFile();
5061
}
5162
catch (error) {
5263
return false;
5364
}
5465
return true;
5566
}
5667

68+
5769
// TODO: offer these module level context-less helper functions in utilities below
5870
export function ensurePathExists(path: string): Q.Promise<void> {
5971
var defer = Q.defer<void>();

src/test/codecoveragefiles/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<html/>

src/test/lib/feedback.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ export class TestFeedbackChannel extends events.EventEmitter implements cm.IServ
4646
public taskApi: taskm.ITaskApi;
4747
public jobInfo: cm.IJobInfo;
4848
public enabled: boolean;
49-
public containerItems : string[];
50-
public artifactNames : string[];
51-
public failingArtifactName : string;
49+
public containerItems: string[];
50+
public artifactNames: string[];
51+
public failingArtifactName: string;
52+
public browsableArtifacts: string[];
5253

5354
private _webConsole: string[];
5455
private _records: any;
@@ -61,6 +62,7 @@ export class TestFeedbackChannel extends events.EventEmitter implements cm.IServ
6162
this._logPages = {};
6263
this.containerItems = [];
6364
this.artifactNames = [];
65+
this.browsableArtifacts = [];
6466
}
6567

6668
public getWebApi(): webapi.WebApi {
@@ -174,8 +176,12 @@ export class TestFeedbackChannel extends events.EventEmitter implements cm.IServ
174176

175177
public postArtifact(projectId: string, buildId: number, artifact: buildifm.BuildArtifact): Q.Promise<buildifm.BuildArtifact> {
176178
this.artifactNames.push(artifact.name);
177-
if(this.failingArtifactName == artifact.name)
178-
{
179+
180+
if (artifact.resource.properties["browsable"] == "True") {
181+
this.browsableArtifacts.push(artifact.name);
182+
}
183+
184+
if (this.failingArtifactName == artifact.name) {
179185
throw new Error("Error occured while publishing artifact");
180186
}
181187
return Q(artifact);

src/test/publishcodecoveragetests.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe('CodeCoveragePublisherTests', function() {
3030
var reportDirectory = path.join(shell.tempdir(), "report");
3131
shell.mkdir('-p', reportDirectory);
3232
shell.cp('-r', path.resolve(__dirname, './codecoveragefiles'), reportDirectory);
33+
shell.cp('-r', path.resolve(__dirname, './codecoveragefiles/index.html'), reportDirectory);
3334
var testExecutionContext;
3435

3536
it('codecoverage.publish : publish summary fails when code coverage tool is invalid', function(done) {
@@ -370,6 +371,7 @@ describe('CodeCoveragePublisherTests', function() {
370371
assert(testExecutionContext.service.containerItems.length == 1);
371372
assert(testExecutionContext.service.artifactNames.length == 1);
372373
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
374+
assert(testExecutionContext.service.browsableArtifacts.length == 0);
373375
assert(result);
374376
done();
375377
},
@@ -393,9 +395,11 @@ describe('CodeCoveragePublisherTests', function() {
393395
var codeCoveragePublishCommand = new cpc.CodeCoveragePublishCommand(testExecutionContext, command);
394396
codeCoveragePublishCommand.runCommandAsync().then(function(result) {
395397
assert(testExecutionContext.service.jobsCompletedSuccessfully(), 'CodeCoveragePublish Task Failed! Details : ' + testExecutionContext.service.getRecordsString());
396-
assert(testExecutionContext.service.containerItems.length == 7);
398+
assert(testExecutionContext.service.containerItems.length == 9);
397399
assert(testExecutionContext.service.artifactNames.length == 1);
398-
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1")
400+
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
401+
assert(testExecutionContext.service.browsableArtifacts.length == 1);
402+
assert(testExecutionContext.service.browsableArtifacts[0] == "Code Coverage Report_1");
399403
assert(result);
400404
done();
401405
},
@@ -419,10 +423,12 @@ describe('CodeCoveragePublisherTests', function() {
419423
var codeCoveragePublishCommand = new cpc.CodeCoveragePublishCommand(testExecutionContext, command);
420424
codeCoveragePublishCommand.runCommandAsync().then(function(result) {
421425
assert(testExecutionContext.service.jobsCompletedSuccessfully(), 'CodeCoveragePublish Task Failed! Details : ' + testExecutionContext.service.getRecordsString());
422-
assert(testExecutionContext.service.containerItems.length == 9);
426+
assert(testExecutionContext.service.containerItems.length == 11);
423427
assert(testExecutionContext.service.artifactNames.length == 2);
424-
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1")
425-
assert(testExecutionContext.service.artifactNames[1] == "Code Coverage Files_1")
428+
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
429+
assert(testExecutionContext.service.artifactNames[1] == "Code Coverage Files_1");
430+
assert(testExecutionContext.service.browsableArtifacts.length == 1);
431+
assert(testExecutionContext.service.browsableArtifacts[0] == "Code Coverage Report_1");
426432
assert(result);
427433
done();
428434
},
@@ -450,6 +456,7 @@ describe('CodeCoveragePublisherTests', function() {
450456
assert(testExecutionContext.service.artifactNames.length == 2);
451457
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
452458
assert(testExecutionContext.service.artifactNames[1] == "Code Coverage Files_1");
459+
assert(testExecutionContext.service.browsableArtifacts.length == 0);
453460
assert(result);
454461
done();
455462
},
@@ -477,6 +484,7 @@ describe('CodeCoveragePublisherTests', function() {
477484
assert(testExecutionContext.service.artifactNames.length == 2);
478485
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
479486
assert(testExecutionContext.service.artifactNames[1] == "Code Coverage Files_1");
487+
assert(testExecutionContext.service.browsableArtifacts.length == 0);
480488
assert(result);
481489
done();
482490
},
@@ -510,6 +518,7 @@ describe('CodeCoveragePublisherTests', function() {
510518
assert(testExecutionContext.service.artifactNames.length == 2);
511519
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
512520
assert(testExecutionContext.service.artifactNames[1] == "Code Coverage Files_1");
521+
assert(testExecutionContext.service.browsableArtifacts.length == 0);
513522
assert(result);
514523
done();
515524
},
@@ -533,14 +542,16 @@ describe('CodeCoveragePublisherTests', function() {
533542

534543
var codeCoveragePublishCommand = new cpc.CodeCoveragePublishCommand(testExecutionContext, command);
535544
codeCoveragePublishCommand.runCommandAsync().then(function(result) {
536-
assert(false, 'Publish code coverage Task did not fail as expected')
545+
assert(false, 'Publish code coverage Task did not fail as expected');
537546
done();
538547
},
539548
function(err) {
540-
assert(testExecutionContext.service.containerItems.length == 7);
549+
assert(testExecutionContext.service.containerItems.length == 9);
541550
assert(testExecutionContext.service.artifactNames.length == 1);
542-
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1")
543-
assert(err == "Error: Error occured while publishing artifact")
551+
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
552+
assert(testExecutionContext.service.browsableArtifacts.length == 1);
553+
assert(testExecutionContext.service.browsableArtifacts[0] == "Code Coverage Report_1");
554+
assert(err == "Error: Error occured while publishing artifact");
544555
done();
545556
});
546557
})
@@ -563,10 +574,12 @@ describe('CodeCoveragePublisherTests', function() {
563574
done();
564575
},
565576
function(err) {
566-
assert(testExecutionContext.service.containerItems.length == 9);
577+
assert(testExecutionContext.service.containerItems.length == 11);
567578
assert(testExecutionContext.service.artifactNames.length == 2);
568579
assert(testExecutionContext.service.artifactNames[0] == "Code Coverage Report_1");
569-
assert(testExecutionContext.service.artifactNames[1] == "Code Coverage Files_1")
580+
assert(testExecutionContext.service.artifactNames[1] == "Code Coverage Files_1");
581+
assert(testExecutionContext.service.browsableArtifacts.length == 1);
582+
assert(testExecutionContext.service.browsableArtifacts[0] == "Code Coverage Report_1");
570583
assert(err == "Error: Error occured while publishing artifact")
571584
done();
572585
});

0 commit comments

Comments
 (0)