Skip to content
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
5 changes: 5 additions & 0 deletions code-push-plugin-testing-framework/script/serverUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ function setupServer(targetPlatform) {
console.log("Application downloading the package.");
res.download(exports.updatePackagePath);
});
app.post("/v0.1/public/codepush/report_status/download", function (req, res) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this handler so that the requests show up in test logs.

console.log("Application reported download status.");
console.log("Body: " + JSON.stringify(req.body));
res.sendStatus(200);
});
app.post("/reportTestMessage", function (req, res) {
console.log("Application reported a test message.");
console.log("Body: " + JSON.stringify(req.body));
Expand Down
30 changes: 22 additions & 8 deletions package-mixins.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NativeEventEmitter } from "react-native";
import log from "./logging";
import { DownloadStatus } from "./lib/acquisition-sdk/acquisition-sdk";

// Reporting this event is important, but avoid blocking install()/restartApp() indefinitely
// on a stalled network request.
Expand Down Expand Up @@ -39,22 +40,35 @@ module.exports = (NativeCodePush) => {
);
}

const downloadStartTime = Date.now();
const reportDownloadStatus = async (status) => {
if (!reportStatusDownload) return;
// Only report a duration on success: on failure, this would be the time until
// the download broke rather than a completed download's duration, and could be misleading.
const downloadDurationMs = status === DownloadStatus.Succeeded ? Date.now() - downloadStartTime : undefined;
try {
await withTimeout(reportStatusDownload({ ...this, downloadDurationMs, status }), REPORT_STATUS_DOWNLOAD_TIMEOUT_MS);
} catch (err) {
log(`Report download status failed: ${err}`);
}
};

// Use the downloaded package info. Native code will save the package info
// so that the client knows what the current package version is.
try {
const updatePackageCopy = Object.assign({}, this);
Object.keys(updatePackageCopy).forEach((key) => (typeof updatePackageCopy[key] === 'function') && delete updatePackageCopy[key]);

const downloadedPackage = await NativeCodePush.downloadUpdate(updatePackageCopy, !!downloadProgressCallback);

if (reportStatusDownload) {
try {
await withTimeout(reportStatusDownload(this), REPORT_STATUS_DOWNLOAD_TIMEOUT_MS);
} catch (err) {
log(`Report download status failed: ${err}`);
}
let downloadedPackage;
try {
downloadedPackage = await NativeCodePush.downloadUpdate(updatePackageCopy, !!downloadProgressCallback);
} catch (err) {
await reportDownloadStatus(DownloadStatus.Failed);
throw err;
}

await reportDownloadStatus(DownloadStatus.Succeeded);

return { ...downloadedPackage, ...local };
} finally {
downloadProgressSubscription && downloadProgressSubscription.remove();
Expand Down
6 changes: 3 additions & 3 deletions src/acquisition-sdk/__tests__/acquisition-sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ describe("Acquisition SDK", () => {
it("reportStatusDownload(...) signals completion", (done: Mocha.Done): void => {
var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);

acquisition.reportStatusDownload(templateCurrentPackage, ((error: Error, parameter: void): void => {
acquisition.reportStatusDownload({ ...templateCurrentPackage, status: acquisitionSdk.DownloadStatus.Succeeded }, ((error: Error, parameter: void): void => {
if (error) {
throw error;
}
Expand Down Expand Up @@ -261,7 +261,7 @@ describe("Acquisition SDK", () => {
(acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled = false;
}));

acquisition.reportStatusDownload(templateCurrentPackage, ((error: Error, parameter: void): void => {
acquisition.reportStatusDownload({ ...templateCurrentPackage, status: acquisitionSdk.DownloadStatus.Succeeded }, ((error: Error, parameter: void): void => {
assert.strictEqual((acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled, true);
acquisition = acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.CustomResponseHttpRequester(invalidJsonResponse), configuration);
(acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled = false;
Expand All @@ -287,7 +287,7 @@ describe("Acquisition SDK", () => {
assert.strictEqual((acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled, false);
}));

acquisition.reportStatusDownload(templateCurrentPackage, ((error: Error, parameter: void): void => {
acquisition.reportStatusDownload({ ...templateCurrentPackage, status: acquisitionSdk.DownloadStatus.Succeeded }, ((error: Error, parameter: void): void => {
assert.strictEqual((acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled, false);
}));

Expand Down
20 changes: 17 additions & 3 deletions src/acquisition-sdk/acquisition-sdk.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Vendored from https://github.com/microsoft/code-push/blob/master/src/script/acquisition-sdk.ts (archived, MIT licensed)

import { UpdateCheckResponse, UpdateCheckRequest, DeploymentStatusReport, DownloadReport } from "./types";
import { UpdateCheckResponse, UpdateCheckRequest, DeploymentStatusReport, DownloadReport, DownloadStatusValue } from "./types";
import { CodePushHttpError, CodePushDeployStatusError, CodePushPackageError } from "./code-push-error"

export namespace Http {
Expand Down Expand Up @@ -35,6 +35,11 @@ export interface RemotePackage extends Package {
downloadUrl: string;
}

export interface DownloadedPackage extends Package {
downloadDurationMs?: number;
status: DownloadStatusValue;
}

export interface NativeUpdateNotification {
updateAppVersion: boolean; // Always true
appVersion: string;
Expand All @@ -59,6 +64,11 @@ export class AcquisitionStatus {
public static DeploymentFailed = "DeploymentFailed";
}

export class DownloadStatus {
public static Succeeded: DownloadStatusValue = "DownloadSucceeded";
public static Failed: DownloadStatusValue = "DownloadFailed";
}

export class AcquisitionManager {
private readonly BASE_URL_PART = "appcenter.ms";
private _appVersion: string;
Expand Down Expand Up @@ -235,7 +245,7 @@ export class AcquisitionManager {
});
}

public reportStatusDownload(downloadedPackage: Package, callback?: Callback<void>): void {
public reportStatusDownload(downloadedPackage: DownloadedPackage, callback?: Callback<void>): void {
if (AcquisitionManager._apiCallsDisabled) {
console.log(`[CodePush] Api calls are disabled, skipping API call`);
callback(/*error*/ null, /*not used*/ null);
Expand All @@ -246,7 +256,11 @@ export class AcquisitionManager {
var body: DownloadReport = {
client_unique_id: this._clientUniqueId,
deployment_key: this._deploymentKey,
Comment thread
ofalvai marked this conversation as resolved.
label: downloadedPackage.label
label: downloadedPackage.label,
package_hash: downloadedPackage.packageHash,
package_size_bytes: downloadedPackage.packageSize,
download_duration_ms: downloadedPackage.downloadDurationMs,
status: downloadedPackage.status
};

this._httpRequester.request(Http.Verb.POST, url, JSON.stringify(body), (error: Error, response: Http.Response): void => {
Expand Down
6 changes: 6 additions & 0 deletions src/acquisition-sdk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ export interface DeploymentStatusReport {
status?: string;
}

export type DownloadStatusValue = "DownloadSucceeded" | "DownloadFailed";

/*in*/
export interface DownloadReport {
client_unique_id: string;
deployment_key: string;
label: string;
package_hash: string;
package_size_bytes: number;
download_duration_ms?: number;
status: DownloadStatusValue;
}

/*out*/
Expand Down