Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missed points in mc-fus branch #7

Merged
merged 2 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Tasks/AppCenterDistributeV1/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ describe('AppCenterDistribute L0 Suite', function () {
assert(tr.failed, 'task should have failed');
});

it('Negative path: failed when HTTP status is not 2xx', function () {
this.timeout(6000);

let tp = path.join(__dirname, 'L0FailsHttpStatusNot2xx.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);

tr.run();
assert(tr.succeeded, 'task should have succeeded');
});

it('Negative path: cannot continue upload without symbols', function () {
this.timeout(4000);

Expand Down
209 changes: 209 additions & 0 deletions Tasks/AppCenterDistributeV1/Tests/L0FailsHttpStatusNot2xx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@

import ma = require('vsts-task-lib/mock-answer');
import tmrm = require('vsts-task-lib/mock-run');
import path = require('path');
import fs = require('fs');
import azureBlobUploadHelper = require('../azure-blob-upload-helper');

var Readable = require('stream').Readable
var Stats = require('fs').Stats

var nock = require('nock');

let taskPath = path.join(__dirname, '..', 'appcenterdistribute.js');
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);

tmr.setInput('serverEndpoint', 'MyTestEndpoint');
tmr.setInput('appSlug', 'testuser/testapp');
tmr.setInput('app', '/Users/anastasia.kubova/Downloads/test.ipa');
tmr.setInput('releaseNotesSelection', 'releaseNotesInput');
tmr.setInput('releaseNotesInput', 'my release notes');
tmr.setInput('isMandatory', 'True');
tmr.setInput('symbolsType', 'AndroidJava');
tmr.setInput('mappingTxtPath', '/test/path/to/mappings.txt');

process.env['BUILD_BUILDID'] = '2';
process.env['BUILD_SOURCEBRANCH'] = 'refs/heads/master';
process.env['BUILD_SOURCEVERSION'] = 'commitsha';

// upload
nock('https://example.upload.test')
.post('/release_upload')
.reply(201, {
status: 'success'
});

nock('https://example.test')
.post('/v0.1/apps/testuser/testapp/uploads/releases')
.reply(201, {
id: 1,
upload_url: "https://upload.example.test/upload/upload_chunk/00000000-0000-0000-0000-000000000000",
package_asset_id: 1,
upload_domain: 'https://example.upload.test/release_upload',
url_encoded_token: "test"
}).log(console.log);

// finishing upload, commit the package
nock('https://example.test')
.patch("/v0.1/apps/testuser/testapp/uploads/releases/1", {
status: 'committed'
})
.reply(200, {
release_url: 'my_release_location'
});

nock('https://example.upload.test')
.post('/release_upload/upload/set_metadata/1')
.query(true)
.reply(200, {
resume_restart: false,
chunk_list: [1],
chunk_size: 100,
blob_partitions: 1
});

nock('https://example.upload.test')
.post('/release_upload/upload/upload_chunk/1')
.query(true)
.reply(200, {
});

nock('https://example.upload.test')
.post('/release_upload/upload/finished/1')
.query(true)
.reply(200, {
error: false,
state: "Done",
});

nock('https://example.test')
.patch('/v0.1/apps/testuser/testapp/uploads/releases/1', {
upload_status: "uploadFinished",
})
.query(true)
.reply(200, {
upload_status: "uploadFinished",
release_url: 'https://example.upload.test/release_upload',
});

nock('https://example.test')
.get('/v0.1/apps/testuser/testapp/uploads/releases/1')
.query(true)
.reply(500, {
release_distinct_id: 1,
upload_status: "readyToBePublished",
});

nock('https://example.test')
.patch('/v0.1/apps/testuser/testapp/uploads/releases/1', {
upload_status: "committed",
})
.query(true)
.reply(200, {
upload_status: "committed",
release_url: 'https://example.upload.test/release_upload',
});

nock('https://example.test')
.put('/v0.1/apps/testuser/testapp/releases/1')
.query(true)
.reply(200, {
version: '1',
short_version: '1.0',
});

nock('https://example.test')
.patch("/v0.1/apps/testuser/testapp/releases/1", {
})
.reply(201, {
});

nock('https://example.test')
.post("/v0.1/apps/testuser/testapp/releases/1", {
id: "00000000-0000-0000-0000-000000000000"
})
.reply(200);

nock('https://example.test')
.put('/v0.1/apps/testuser/testapp/releases/1', JSON.stringify({
release_notes: 'my release notes'
}))
.reply(200);

// make it available
// JSON.stringify to verify exact match of request body: https://github.com/node-nock/nock/issues/571
nock('https://example.test')
.patch("/my_release_location", JSON.stringify({
status: "available",
release_notes: "my release notes",
mandatory_update: true,
destinations: [{ id: "00000000-0000-0000-0000-000000000000" }],
build: {
id: '2',
branch: 'master',
commit_hash: 'commitsha'
}
}))
.reply(200);

// begin symbol upload
nock('https://example.test')
.post('/v0.1/apps/testuser/testapp/symbol_uploads', {
symbol_type: "AndroidJava"
})
.reply(201, {
symbol_upload_id: 100,
upload_url: 'https://example.upload.test/symbol_upload',
expiration_date: 1234567
});

// finishing symbol upload, commit the symbol
nock('https://example.test')
.patch("/v0.1/apps/testuser/testapp/symbol_uploads/100", {
status: 'committed'
})
.reply(200);

// provide answers for task mock
let a: ma.TaskLibAnswers = <ma.TaskLibAnswers>{
"checkPath" : {
"/Users/anastasia.kubova/Downloads/test.ipa": true,
"/test/path/to/mappings.txt": true
},
"findMatch" : {
"/test/path/to/mappings.txt": [
"/test/path/to/mappings.txt"
],
"/Users/anastasia.kubova/Downloads/test.ipa": [
"/Users/anastasia.kubova/Downloads/test.ipa"
]
}
};
tmr.setAnswers(a);

fs.createReadStream = (s: string) => {
let stream = new Readable;
stream.push(s);
stream.push(null);
return stream;
};

fs.statSync = (s: string) => {
let stat = new Stats;
stat.isFile = () => {
return !s.toLowerCase().endsWith(".dsym");
}
stat.isDirectory = () => {
return s.toLowerCase().endsWith(".dsym");
}
stat.size = 100;
return stat;
}

azureBlobUploadHelper.AzureBlobUploadHelper.prototype.upload = async () => {
return Promise.resolve();
}

tmr.registerMock('azure-blob-upload-helper', azureBlobUploadHelper);
tmr.registerMock('fs', fs);
tmr.run();
23 changes: 16 additions & 7 deletions Tasks/AppCenterDistributeV1/appcenterdistribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function beginReleaseUpload(apiServer: string, apiVersion: string, appSlug: stri
request.post({ url: beginUploadUrl, headers: headers }, (err, res, body) => {
responseHandler(defer, err, res, body, () => {
let response = JSON.parse(body);
if (!response.package_asset_id || (response.statusCode && response.statusCode !== 200)) {
if (!response.package_asset_id || (response.statusCode && (response.statusCode < 200 || response.statusCode >= 300))) {
defer.reject(`failed to create release upload. ${response.message}`)
}

Expand All @@ -120,7 +120,13 @@ function beginReleaseUpload(apiServer: string, apiVersion: string, appSlug: stri
function loadReleaseIdUntilSuccess(apiServer: string, apiVersion: string, appSlug: string, uploadId: string, token: string, userAgent: string): Q.Promise<string> {
let defer = Q.defer<string>();
const timerId = setInterval(async () => {
const response = await getReleaseId(apiServer, apiVersion, appSlug, uploadId, token, userAgent);
let response;
try {
response = await getReleaseId(apiServer, apiVersion, appSlug, uploadId, token, userAgent);
} catch (error) {
clearInterval(timerId);
defer.reject(new Error(`Loading release id failed with: ${error}`));
}
const releaseId = response.release_distinct_id;
tl.debug(`Received release id is ${releaseId}`);
if (response.upload_status === "readyToBePublished" && releaseId) {
Expand All @@ -146,20 +152,20 @@ function uploadRelease(releaseUploadParams: UploadInfo, file: string): Q.Promise
uploadDomain: uploadDomain,
tenant: "distribution",
onProgressChanged: (progress: IProgress) => {
tl.debug("onProgressChanged: " + progress.percentCompleted);
tl.debug("---- onProgressChanged: " + progress.percentCompleted);
},
onMessage: (message: string, properties: LogProperties, level: McFusMessageLevel) => {
tl.debug(`onMessage: ${message} \nMessage properties: ${JSON.stringify(properties)}`);
tl.debug(`---- onMessage: ${message} \nMessage properties: ${JSON.stringify(properties)}`);
if (level === McFusMessageLevel.Error) {
mcFusUploader.cancel();
defer.reject(new Error(`Uploading file error: ${message}`));
}
},
onStateChanged: (status: McFusUploadState): void => {
tl.debug(`onStateChanged: ${status.toString()}`);
tl.debug(`---- onStateChanged: ${status.toString()}`);
},
onCompleted: (uploadStats: IUploadStats) => {
tl.debug("Upload completed, total time: " + uploadStats.totalTimeInSeconds);
tl.debug("---- Upload completed, total time: " + uploadStats.totalTimeInSeconds);
defer.resolve();
},
};
Expand Down Expand Up @@ -211,7 +217,10 @@ function getReleaseId(apiServer: string, apiVersion: string, appSlug: string, re

request.get({ url: getReleaseUrl, headers: headers }, (err, res, body) => {
responseHandler(defer, err, res, body, () => {
defer.resolve(JSON.parse(body));
if (res["status"] < 200 || res["status"] >= 300) {
defer.reject(new Error(`HTTP status ${res["status"]}`));
}
defer.resolve(JSON.parse(body));
});
})

Expand Down
7 changes: 7 additions & 0 deletions Tasks/AppCenterDistributeV2/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ describe('AppCenterDistribute L0 Suite', function () {
assert(tr.failed, 'task should have failed');
});

it('Negative path: failed when HTTP status is not 2xx', function () {
let tp = path.join(__dirname, 'L0FailsHttpStatusNot2xx.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
tr.run();
assert(tr.succeeded, 'task should have succeeded');
});

it('Postiive path: can continue upload without symbols if variable VSMobileCenterUpload.ContinueIfSymbolsNotFound is true', function () {
let tp = path.join(__dirname, 'L0NoSymbolsConditionallyPass.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
Expand Down
Loading