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
23 changes: 0 additions & 23 deletions src/renderer/components/services/upload-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,29 +373,6 @@ webModule.factory(UPLOAD_MGR_FACTORY_NAME, [
progs = JSON.parse(data);
} catch (e) {}

Object.entries(progs).forEach(([jobId, job]) => {
if (!job.uploadedParts) {
job.uploadedParts = [];
}
job.uploadedParts = job.uploadedParts.
filter(part => part && part.PartNumber && part.ETag).
map((part) => {
return { partNumber: part.PartNumber, etag: part.ETag };
});
if (job.from && job.from.size && job.from.mtime) {
if (fs.existsSync(job.from.path)) {
const fileStat = fs.statSync(job.from.path);
if (fileStat.size === job.from.size && job.from.mtime === fileStat.mtimeMs) {
return;
}
}
}
job.uploadedParts = [];
if (job.prog) {
delete job.prog.loaded;
}
});

Object.entries(progs)
.forEach(([jobId, briefJob]) => {
if (!briefJob.from || !briefJob.from.size || !briefJob.from.mtime) {
Expand Down
65 changes: 63 additions & 2 deletions src/renderer/models/job/download-job.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ jest.mock("electron", () => ({

import { ipcRenderer } from "electron";
import * as AppConfig from "@/const/app-config";
import { IpcJobEvent, Status } from "./types";

import { EventKey, IpcJobEvent, Status } from "./types";
import { downloadOptionsFromResumeJob } from "./_mock-helpers_/data";

import DownloadJob from "./download-job";

describe("test models/job/download-job.ts", () => {
describe("test models/job/download-job.ts", () => {
describe("test stop", () => {
it("stop", () => {
const downloadJob = new DownloadJob(downloadOptionsFromResumeJob);
Expand Down Expand Up @@ -90,4 +91,64 @@ describe("test models/job/download-job.ts", () => {
downloadJob.stop();
});
});

describe("test resume download job", () => {
it("getInfoForSave()", () => {
const downloadJob = new DownloadJob(downloadOptionsFromResumeJob);

// stat
const fakeProgressTotal = 1024;
const fakeProgressResumable = true;
downloadJob.startDownload(null, {
key: EventKey.Stat,
data: {
progressTotal: fakeProgressTotal,
progressResumable: fakeProgressResumable,
},
});
expect(downloadJob.prog.total).toBe(fakeProgressTotal);
expect(downloadJob.prog.resumable).toBe(fakeProgressResumable);

// progress
const fakeProgressLoaded = 512;
downloadJob.startDownload(null, {
key: EventKey.Progress,
data: {
progressLoaded: fakeProgressLoaded,
progressResumable: fakeProgressResumable,
},
});
expect(downloadJob.prog.loaded).toBe(fakeProgressLoaded);
expect(downloadJob.prog.resumable).toBe(fakeProgressResumable);

// part downloaded
const lastDownloadedSize = downloadJob.prog.loaded;
const fakeDownloadedSize = 512;
downloadJob.startDownload(null, {
key: EventKey.PartDownloaded,
data: {
size: fakeDownloadedSize,
},
});
expect(downloadJob.prog.loaded).toBe(lastDownloadedSize + fakeDownloadedSize);

// info should in disk
expect(downloadJob.getInfoForSave())
.toEqual({
storageClasses: downloadOptionsFromResumeJob.storageClasses,
region: downloadOptionsFromResumeJob.region,
to: downloadOptionsFromResumeJob.to,
from: downloadOptionsFromResumeJob.from,
backendMode: downloadOptionsFromResumeJob.backendMode,

prog: {
loaded: downloadJob.prog.loaded,
total: fakeProgressTotal,
resumable: fakeProgressResumable,
},
status: Status.Waiting,
message: "",
});
});
})
});
7 changes: 5 additions & 2 deletions src/renderer/models/job/download-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,17 +335,20 @@ export default class DownloadJob extends Base {

getInfoForSave() {
return {
// read-only info
storageClasses: this.options.storageClasses,
region: this.options.region,
to: this.options.to,
from: this.options.from,
backendMode: this.options.backendMode,
domain: this.options.domain,

// real-time info
prog: {
loaded: this.prog.loaded,
total: this.prog.total,
resumable: this.prog.resumable
},
backendMode: this.options.backendMode,
domain: this.options.domain,
status: this.status,
message: this.message,
};
Expand Down
87 changes: 85 additions & 2 deletions src/renderer/models/job/upload-job.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ jest.mock("electron", () => ({
import { ipcRenderer } from "electron";
import * as AppConfig from "@/const/app-config"

import { IpcJobEvent, Status } from "./types";
import { EventKey, IpcJobEvent, Status } from "./types";
import { uploadOptionsFromNewJob } from "./_mock-helpers_/data";

import UploadJob from "./upload-job";

describe("test models/job/upload-job.ts", () => {
describe("test models/job/upload-job.ts", () => {
describe("test stop", () => {
it("stop", () => {
const uploadJob = new UploadJob(uploadOptionsFromNewJob);
Expand Down Expand Up @@ -94,4 +94,87 @@ describe("test models/job/upload-job.ts", () => {
uploadJob.stop();
});
});

describe("test resume upload job", () => {
it("getInfoForSave()", () => {
const uploadJob = new UploadJob(uploadOptionsFromNewJob);
uploadJob.on('partcomplete', (data) => {
uploadJob.uploadedId = data.uploadId;
uploadJob.uploadedParts[data.part.partNumber] = data.part;
return false;
})

// stat
const fakeProgressTotal = 1024;
const fakeProgressResumable = true;
uploadJob.startUpload(null, {
key: EventKey.Stat,
data: {
progressTotal: fakeProgressTotal,
progressResumable: fakeProgressResumable,
},
});
expect(uploadJob.prog.total).toBe(fakeProgressTotal);
expect(uploadJob.prog.resumable).toBe(fakeProgressResumable);

// progress
const fakeProgressLoaded = 512;
uploadJob.startUpload(null, {
key: EventKey.Progress,
data: {
progressLoaded: fakeProgressLoaded,
progressResumable: fakeProgressResumable,
},
});
expect(uploadJob.prog.loaded).toBe(fakeProgressLoaded);
expect(uploadJob.prog.resumable).toBe(fakeProgressResumable);

// part uploaded
const fakeUploadedId = 'fakeUploadId';
const fakeUploadedPart = {
partNumber: 0,
etag: 'fakeETag',
};
uploadJob.startUpload(null, {
key: EventKey.PartUploaded,
data: {
uploadId: fakeUploadedId,
part: fakeUploadedPart,
},
});
expect(uploadJob.uploadedParts.length).toBe(1);
expect(uploadJob.uploadedId).toBe(fakeUploadedId);
expect(uploadJob.uploadedParts).toEqual([
fakeUploadedPart,
]);

// info should in disk
expect(uploadJob.getInfoForSave({}))
.toEqual({
from: uploadOptionsFromNewJob.from,

backendMode: uploadOptionsFromNewJob.backendMode,
overwrite: uploadOptionsFromNewJob.overwrite,
to: uploadOptionsFromNewJob.to,
region: uploadOptionsFromNewJob.region,
storageClassName: uploadOptionsFromNewJob.storageClassName,
storageClasses: uploadOptionsFromNewJob.storageClasses,

prog: {
loaded: fakeProgressLoaded,
total: fakeProgressTotal,
resumable: fakeProgressResumable,
},
status: Status.Waiting,
uploadedId: fakeUploadedId,
uploadedParts: [
{
PartNumber: fakeUploadedPart.partNumber,
ETag: fakeUploadedPart.etag,
},
],
message: "",
});
});
});
});
34 changes: 21 additions & 13 deletions src/renderer/models/job/upload-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,29 +355,37 @@ export default class UploadJob extends Base {
getInfoForSave({
from
}: {
from: {
size: number,
mtime: number,
from?: {
size?: number,
mtime?: number,
}
}) {
return {
storageClasses: this.options.storageClasses,
region: this.options.region,
to: this.options.to,
from: {
...this.options.from,
...from,
},
prog: this.options.prog,
status: this.options.status,
message: this.options.message,
uploadedId: this.options.uploadedId,
uploadedParts: this.options.uploadedParts.map((part) => {
return { PartNumber: part.partNumber, ETag: part.etag };
}),

// read-only info
storageClasses: this.options.storageClasses,
region: this.options.region,
to: this.options.to,
overwrite: this.options.overwrite,
storageClassName: this.options.storageClassName,
backendMode: this.options.backendMode,

// real-time info
prog: {
loaded: this.prog.loaded,
total: this.prog.total,
resumable: this.prog.resumable
},
status: this.status,
message: this.message,
uploadedId: this.uploadedId,
uploadedParts: this.uploadedParts.map((part) => {
return { PartNumber: part.partNumber, ETag: part.etag };
}),
};
}
}
Expand Down