🤖 TEST: Test on OSS NFS store (#24)
This commit is contained in:
46
.github/workflows/nodejs.yml
vendored
46
.github/workflows/nodejs.yml
vendored
@@ -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 }}
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -9,5 +9,9 @@ export default () => {
|
||||
config.orm = {
|
||||
database: process.env.MYSQL_DATABASE || 'cnpmcore_unittest',
|
||||
};
|
||||
|
||||
config.nfs = {
|
||||
dir: join(config.dataDir, 'nfs'),
|
||||
};
|
||||
return config;
|
||||
};
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:'));
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user