🤖 TEST: Test on OSS NFS store (#24)

This commit is contained in:
fengmk2
2021-12-12 17:56:17 +08:00
committed by GitHub
parent bdeadf9c74
commit 22d0e725ae
18 changed files with 243 additions and 125 deletions

View File

@@ -16,7 +16,7 @@ on:
- cron: '0 2 * * *'
jobs:
test-mysql57:
test-mysql57-fs-nfs:
runs-on: ${{ matrix.os }}
services:
@@ -54,3 +54,47 @@ jobs:
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
test-mysql57-oss-nfs:
runs-on: ${{ matrix.os }}
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: cnpmcore_unittest
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5
strategy:
fail-fast: false
matrix:
node-version: [16]
os: [ubuntu-latest]
steps:
- name: Checkout Git Source
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm i -g npminstall && npminstall
- name: Continuous Integration
run: npm run ci
env:
CNPMCORE_NFS_TYPE: oss
CNPMCORE_NFS_OSS_BUCKET: cnpmcore-unittest-github
CNPMCORE_NFS_OSS_ENDPOINT: https://oss-us-west-1.aliyuncs.com
CNPMCORE_NFS_OSS_ID: ${{ secrets.CNPMCORE_NFS_OSS_ID }}
CNPMCORE_NFS_OSS_SECRET: ${{ secrets.CNPMCORE_NFS_OSS_SECRET }}
- name: Code Coverage
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021 cnpm and other contributors.
Copyright (c) 2021-present cnpm and other contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -23,11 +23,28 @@ export class NFSAdapter {
async uploadBytes(storeKey: string, bytes: Uint8Array) {
this.logger.info('[%s:uploadBytes] key: %s, bytes: %d', INSTANCE_NAME, storeKey, bytes.length);
if (this.nfsClientAdapter.client.uploadBytes) {
return await this.nfsClientAdapter.client.uploadBytes(bytes, { key: storeKey });
}
await this.nfsClientAdapter.client.uploadBuffer(bytes, { key: storeKey });
}
async appendBytes(storeKey: string, bytes: Uint8Array) {
await this.nfsClientAdapter.client.appendBuffer(bytes, { key: storeKey });
// will return next store position
async appendBytes(storeKey: string, bytes: Uint8Array, position?: string, headers?: object) {
let result;
// make sure position is undefined by the first time
if (!position) position = undefined;
const options = {
key: storeKey,
position,
headers,
};
if (this.nfsClientAdapter.client.appendBytes) {
result = await this.nfsClientAdapter.client.appendBytes(bytes, options);
} else {
result = await this.nfsClientAdapter.client.appendBuffer(bytes, options);
}
if (result?.nextAppendPosition) return String(result.nextAppendPosition);
}
async uploadFile(storeKey: string, file: string) {

View File

@@ -12,6 +12,7 @@ interface TaskData extends EntityData {
authorIp: string;
data: unknown;
logPath?: string;
logStorePosition?: string;
}
export type SyncPackageTaskOptions = {
@@ -30,6 +31,7 @@ export class Task extends Entity {
authorIp: string;
data: unknown;
logPath: string;
logStorePosition: string;
constructor(data: TaskData) {
super(data);
@@ -41,6 +43,7 @@ export class Task extends Entity {
this.authorIp = data.authorIp;
this.data = data.data;
this.logPath = data.logPath ?? '';
this.logStorePosition = data.logStorePosition ?? '';
}
private static create(data: EasyData<TaskData, 'taskId'>): Task {

View File

@@ -337,14 +337,33 @@ export class PackageSyncerService extends AbstractService {
}
private async appendTaskLog(task: Task, appendLog: string) {
await this.nfsAdapter.appendBytes(task.logPath, Buffer.from(appendLog + '\n'));
const nextPosition = await this.nfsAdapter.appendBytes(
task.logPath,
Buffer.from(appendLog + '\n'),
task.logStorePosition,
{
'Content-Type': 'text/plain; charset=utf-8',
},
);
if (nextPosition) {
task.logStorePosition = nextPosition;
}
task.updatedAt = new Date();
await this.taskRepository.saveTask(task);
}
private async finishTask(task: Task, taskState: TaskState, appendLog: string) {
// console.log(appendLog);
await this.nfsAdapter.appendBytes(task.logPath, Buffer.from(appendLog + '\n'));
const nextPosition = await this.nfsAdapter.appendBytes(
task.logPath,
Buffer.from(appendLog + '\n'),
task.logStorePosition,
{
'Content-Type': 'text/plain; charset=utf-8',
},
);
if (nextPosition) {
task.logStorePosition = nextPosition;
}
task.state = taskState;
await this.taskRepository.saveTaskToHistory(task);
}

View File

@@ -42,6 +42,9 @@ export class HistoryTask extends Bone {
@Attribute(DataTypes.STRING(512))
logPath: string;
@Attribute(DataTypes.STRING(10))
logStorePosition: string;
@Attribute(DataTypes.INTEGER)
attempts: number;
}

View File

@@ -42,6 +42,9 @@ export class Task extends Bone {
@Attribute(DataTypes.STRING(512))
logPath: string;
@Attribute(DataTypes.STRING(10))
logStorePosition: string;
@Attribute(DataTypes.INTEGER)
attempts: number;
}

View File

@@ -1,6 +1,8 @@
import assert from 'assert';
import { join } from 'path';
import { tmpdir } from 'os';
import { EggAppConfig, PowerPartial } from 'egg';
import OSSClient from 'oss-cnpm';
import { patchAjv } from '../app/port/typebox';
export default (/* appInfo: EggAppConfig */) => {
@@ -58,6 +60,22 @@ export default (/* appInfo: EggAppConfig */) => {
client: null,
dir: join(config.dataDir, 'nfs'),
};
// enable oss nfs store by env values
if (process.env.CNPMCORE_NFS_TYPE === 'oss') {
assert(process.env.CNPMCORE_NFS_OSS_BUCKET, 'require env CNPMCORE_NFS_OSS_BUCKET');
assert(process.env.CNPMCORE_NFS_OSS_ENDPOINT, 'require env CNPMCORE_NFS_OSS_ENDPOINT');
assert(process.env.CNPMCORE_NFS_OSS_ID, 'require env CNPMCORE_NFS_OSS_ID');
assert(process.env.CNPMCORE_NFS_OSS_SECRET, 'require env CNPMCORE_NFS_OSS_SECRET');
config.nfs.client = new OSSClient({
bucket: process.env.CNPMCORE_NFS_OSS_BUCKET,
endpoint: process.env.CNPMCORE_NFS_OSS_ENDPOINT,
accessKeyId: process.env.CNPMCORE_NFS_OSS_ID,
accessKeySecret: process.env.CNPMCORE_NFS_OSS_SECRET,
defaultHeaders: {
'Cache-Control': 'max-age=0, s-maxage=60',
},
});
}
config.logger = {
enablePerformanceTimer: true,

View File

@@ -9,5 +9,9 @@ export default () => {
config.orm = {
database: process.env.MYSQL_DATABASE || 'cnpmcore_unittest',
};
config.nfs = {
dir: join(config.dataDir, 'nfs'),
};
return config;
};

View File

@@ -56,6 +56,7 @@
"leoric": "^1.15.0",
"mysql": "^2.18.1",
"mysql2": "^2.3.0",
"oss-cnpm": "^3.0.1",
"semver": "^7.3.5",
"ssri": "^8.0.1",
"type-fest": "^2.5.3",

View File

@@ -203,6 +203,7 @@ CREATE TABLE IF NOT EXISTS `tasks` (
`author_ip` varchar(100) NOT NULL COMMENT 'create task user request ip',
`data` json NULL COMMENT 'task params',
`log_path` varchar(512) NOT NULL COMMENT 'access path',
`log_store_position` varchar(10) NOT NULL COMMENT 'cloud store disk position',
`attempts` int unsigned DEFAULT 0 COMMENT 'task execute attempts times',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_task_id` (`task_id`),
@@ -223,6 +224,7 @@ CREATE TABLE IF NOT EXISTS `history_tasks` (
`author_ip` varchar(100) NOT NULL COMMENT 'create task user request ip',
`data` json NULL COMMENT 'task params',
`log_path` varchar(512) NOT NULL COMMENT 'access path',
`log_store_position` varchar(10) NOT NULL COMMENT 'cloud store disk position',
`attempts` int unsigned DEFAULT 0 COMMENT 'task execute attempts times',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_task_id` (`task_id`)

View File

@@ -1,4 +1,5 @@
import * as fs from 'fs/promises';
import { Readable } from 'stream';
import mysql from 'mysql';
import path from 'path';
import crypto from 'crypto';
@@ -245,4 +246,19 @@ export class TestUtil {
authorization: `Bearer ${token}`,
};
}
static async readStreamToLog(urlOrStream) {
let stream: Readable;
if (typeof urlOrStream === 'string') {
const { res } = await this.app.curl(urlOrStream, { streaming: true });
stream = res;
} else {
stream = urlOrStream;
}
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
return Buffer.concat(chunks).toString();
}
}

View File

@@ -35,11 +35,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
const model = await PackageModel.findOne({ scope: '', name: 'foo' });
assert.equal(model!.isPrivate, false);
@@ -50,12 +46,6 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
// stream = await packageSyncerService.findTaskLog(task) as Readable;
// assert(stream);
// for await (const chunk of stream) {
// process.stdout.write(chunk);
// }
const manifests = await packageManagerService.listPackageFullManifests('', 'foo', undefined);
// console.log(JSON.stringify(manifests, null, 2));
// should have 2 maintainers
@@ -115,11 +105,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
let chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
let log = Buffer.concat(chunks).toString();
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] Add dependency "cnpmcore-test-sync-deprecated" sync task: '));
@@ -132,11 +118,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
chunks = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
log = Buffer.concat(chunks).toString();
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Sync cause by "cnpmcore-test-sync-dependencies" dependencies, parent task: '));
});
@@ -152,11 +134,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] Add dependency "cnpmcore-test-sync-deprecated" sync task: '));
assert(log.includes('][UP] 🚧🚧🚧🚧🚧 Waiting sync "cnpmcore-test-sync-dependencies" task on https://r.cnpmjs.org 🚧'));
@@ -175,11 +153,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes(`][UP] ❌ Sync ${name} fail, create sync task error:`));
@@ -197,11 +171,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes(`][UP] ❌ Sync ${name} fail, missing logId`));
@@ -225,13 +195,9 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes('][UP] 🚧 HTTP [200]'));
@@ -250,11 +216,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes(`][UP] ❌ Sync ${name} fail, timeout`));
@@ -270,11 +232,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes(`❌ Synced ${name} fail, request manifests error`));
@@ -296,11 +254,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes('❌ Invalid maintainers: '));
@@ -333,11 +287,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes('❌ Synced version 1.0.0 fail, missing tarball, dist: '));
@@ -373,11 +323,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
const chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
const log = Buffer.concat(chunks).toString();
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes('❌ All versions sync fail, package not exists'));
@@ -394,11 +340,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
let chunks: any[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
let log = Buffer.concat(chunks).toString();
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🟢 Synced version 2.0.0 success, different meta: {"peerDependenciesMeta":{"bufferutil":{"optional":true},"utf-8-validate":{"optional":true}},"os":["linux"],"cpu":["x64"]}'));
assert(log.includes('Z] 👉👉👉👉👉 Tips: sync test tips here 👈👈👈👈👈'));
@@ -422,11 +364,7 @@ describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task) as Readable;
assert(stream);
chunks = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
log = Buffer.concat(chunks).toString();
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('🟢 Synced version 2.0.0 success, different meta:'));
});

View File

@@ -32,22 +32,37 @@ describe('test/port/controller/DownloadController/showDownloads.test.ts', () =>
.set('user-agent', publisher.ua)
.send(pkg)
.expect(201);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-2.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
if (app.config.nfs.client) {
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect(302);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect(302);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect(302);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-2.0.0.tgz`)
.expect(302);
} else {
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-2.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
}
await app.runSchedule('SavePackageVersionDownloadCounter');
@@ -75,10 +90,16 @@ describe('test/port/controller/DownloadController/showDownloads.test.ts', () =>
.set('user-agent', publisher.ua)
.send(pkg)
.expect(201);
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
if (app.config.nfs.client) {
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect(302);
} else {
await app.httpRequest()
.get(`/${pkg.name}/-/koa-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
.expect(200);
}
await app.runSchedule('SavePackageVersionDownloadCounter');

View File

@@ -59,6 +59,7 @@ describe('test/port/controller/PackageController/downloadVersionTar.test.ts', ()
});
it('should download a version tar with streaming success', async () => {
mock(nfsClientAdapter.client, 'url', 'not-function');
await app.httpRequest()
.get(`/${name}/-/testmodule-download-version-tar-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')
@@ -81,6 +82,7 @@ describe('test/port/controller/PackageController/downloadVersionTar.test.ts', ()
.send(pkg)
.expect(201);
mock(nfsClientAdapter.client, 'url', 'not-function');
await app.httpRequest()
.get(`/${pkg.name}/-/${pkg.name}-1.0.0.tgz`)
.expect('content-type', 'application/octet-stream')

View File

@@ -35,9 +35,10 @@ describe('test/port/controller/PackageController/removeVersion.test.ts', () => {
.expect(200);
const pkgVersion = res.body;
const tarballUrl = new URL(pkgVersion.dist.tarball).pathname;
await app.httpRequest()
.get(`${tarballUrl}`)
.expect(200);
res = await app.httpRequest()
.get(`${tarballUrl}`);
assert(res.status === 200 || res.status === 302);
pkg = await TestUtil.getFullPackage({
name: '@cnpm/foo',
version: '2.0.0',
@@ -57,9 +58,15 @@ describe('test/port/controller/PackageController/removeVersion.test.ts', () => {
.expect(200);
assert.equal(res.body.ok, true);
res = await app.httpRequest()
.get(`${tarballUrl}`)
.expect(404);
assert.equal(res.body.error, '[NOT_FOUND] @cnpm/foo@1.0.0 not found');
.get(`${tarballUrl}`);
if (res.status === 404) {
assert.equal(res.body.error, '[NOT_FOUND] @cnpm/foo@1.0.0 not found');
} else {
// 302
assert.equal(res.status, 302);
const { status } = await app.curl(res.headers.location);
assert.equal(status, 404);
}
res = await app.httpRequest()
.get(`/${pkg.name}`)
@@ -79,7 +86,6 @@ describe('test/port/controller/PackageController/removeVersion.test.ts', () => {
res = await app.httpRequest()
.get(`/${pkg.name}`)
.expect(200);
// console.log(res.body);
assert(!res.body.versions);
assert.equal(res.body.name, pkg.name);
assert(res.body.time.unpublished);

View File

@@ -91,10 +91,15 @@ describe('test/port/controller/PackageSyncController/showSyncTask.test.ts', () =
assert(res.body.logUrl);
res = await app.httpRequest()
.get(`/-/package/${name}/syncs/${taskId}/log`)
.expect(200);
// console.log(res.text);
assert.match(res.text, /🟢🟢🟢🟢🟢/);
.get(`/-/package/${name}/syncs/${taskId}/log`);
let log = '';
if (res.status === 200) {
log = res.text;
} else {
assert.equal(res.status, 302);
log = await TestUtil.readStreamToLog(res.headers.location);
}
assert.match(log, /🟢🟢🟢🟢🟢/);
// check hasInstallScript
res = await app.httpRequest()

View File

@@ -54,26 +54,42 @@ describe('test/port/controller/PackageSyncController/showSyncTaskLog.test.ts', (
const task = await taskRepository.findTask(res.body.id);
// waiting state logUrl is not exists
res = await app.httpRequest()
.get(`/-/package/koa/syncs/${task!.taskId}/log`)
.expect(404);
assert.equal(res.body.error, `[NOT_FOUND] Package "koa" sync task "${task!.taskId}" log not found`);
.get(`/-/package/koa/syncs/${task!.taskId}/log`);
if (res.status === 404) {
assert.equal(res.body.error, `[NOT_FOUND] Package "koa" sync task "${task!.taskId}" log not found`);
} else {
assert.equal(res.status, 302);
const { status } = await app.curl(res.headers.location);
assert.equal(status, 404);
}
task!.state = TaskState.Processing;
await taskRepository.saveTask(task!);
// log file not exists
res = await app.httpRequest()
.get(`/-/package/koa/syncs/${task!.taskId}/log`)
.expect(404);
assert.equal(res.body.error, `[NOT_FOUND] Package "koa" sync task "${task!.taskId}" log not found`);
.get(`/-/package/koa/syncs/${task!.taskId}/log`);
if (res.status === 404) {
assert.equal(res.body.error, `[NOT_FOUND] Package "koa" sync task "${task!.taskId}" log not found`);
} else {
assert.equal(res.status, 302);
const { status } = await app.curl(res.headers.location);
assert.equal(status, 404);
}
// save log file
await nfsAdapter.uploadBytes(task!.logPath, Buffer.from('hello log file 😄\nsencod line here'));
res = await app.httpRequest()
.get(`/-/package/koa/syncs/${task!.taskId}/log`)
.expect('content-type', 'text/plain; charset=utf-8')
.expect(200);
assert.equal(res.text, 'hello log file 😄\nsencod line here');
.get(`/-/package/koa/syncs/${task!.taskId}/log`);
if (res.status === 200) {
assert.equal(res.text, 'hello log file 😄\nsencod line here');
assert.equal(res.headers['content-type'], 'text/plain; charset=utf-8');
} else {
assert.equal(res.status, 302);
assert(res.headers.location);
const log = await TestUtil.readStreamToLog(res.headers.location);
assert.equal(log, 'hello log file 😄\nsencod line here');
}
// mock redirect
mock.data(nfsAdapter.constructor.prototype, 'getDownloadUrlOrStream', 'http://mock.com/some.log');