Skip to content
This repository has been archived by the owner on Sep 30, 2022. It is now read-only.

Commit

Permalink
Essential app.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-danilenko committed Mar 13, 2022
1 parent f970595 commit 9fc0e98
Show file tree
Hide file tree
Showing 27 changed files with 1,163 additions and 111 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
@@ -0,0 +1,5 @@
Dockerfile
docker-compose.yml
node_modules
dist
*.md
16 changes: 16 additions & 0 deletions .env
@@ -0,0 +1,16 @@
# Web app port.
PORT=8080
TIMEOUT=10000
REQUESTS_CONCURRENCY=500

# Print summary table with results.
LOG_SUMMARY_TABLE=true

# Log response status codes to console during load testings.
LOG_RESPONSE_SUCCESS=false
LOG_RESPONSE_TIMEOUT=false
LOG_RESPONSE_ERROR=false

# API endpoints definition.
API_ENDPOINT_HOSTS='https://hutin-puy.nadom.app/hosts.json'
API_ENDPOINT_PROXIES='https://hutin-puy.nadom.app/proxy.json'
44 changes: 44 additions & 0 deletions .github/workflows/docker-image.yml
@@ -0,0 +1,44 @@
name: Docker Image CI

on:
push:
branches:
- master # Master branch will always be tagged as `image:latest`.
tags:
- v** # All `v*` tags will be applied to image. Git tag `v1.0` will create/update `image:1.0` image tag.
# Build and push image only when .py files was changed or Dockerfile itself.
paths:
- 'Dockerfile'
- '**.ts'
- '**.json'
- '**rc'
- '**.lock'
- '**.env**'
env:
IMAGE_NAME: ua-loadtest # Needs to be equal to repository name for ghcr registry.

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build and push image
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# Change all uppercase to lowercase.
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
# Strip git ref prefix from version.
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# Strip "v" prefix from tag name.
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# Use Docker `latest` tag convention.
[ "$VERSION" == "master" ] && VERSION=latest
# Print information.
echo IMAGE_ID=$IMAGE_ID
echo VERSION=$VERSION
# Build and push
docker build . --file Dockerfile --tag $IMAGE_NAME
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION
4 changes: 4 additions & 0 deletions .prettierrc
@@ -1,6 +1,10 @@
{
"singleQuote": true,
"trailingComma": "all",
"importOrder": ["^typeorm(.*)", "^@nestjs/(.*)$", "module$", "controller$", "service$", "entity$", "dto$", "^[./]"],
"importOrderSeparation": false,
"importOrderSortSpecifiers": true,
"importOrderParserPlugins": ["typescript", "decorators-legacy"],
"useTabs": false,
"printWidth": 120
}
11 changes: 11 additions & 0 deletions Dockerfile
@@ -0,0 +1,11 @@
FROM node:16-alpine

WORKDIR /app

COPY package.json yarn.lock /app/
RUN yarn install --frozen-lockfile

COPY . .
RUN yarn build

ENTRYPOINT ["yarn", "start:prod"]
102 changes: 49 additions & 53 deletions README.md
@@ -1,73 +1,69 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
</p>
<h1 align="center">🇺🇦 Ukraine national load-testing</h1>

[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
## 😎 Overview

<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
- The repo contains [Nest.JS](https://nestjs.com) application, which uses russian proxies and do load testing of web resources using API.
- ⚠ The app uses a proxy, but be careful, it is desirable to use a VPN.

## Description
## 🚀 Quick start

[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
### Docker

## Installation
- Install [Docker](https://docker.com)

```bash
$ npm install
```
- Download docker image:

## Running the app
```shell
docker pull ghcr.io/alexander-danilenko/ua-loadtest:latest
```

```bash
# development
$ npm run start
- Launch the container for the 500 threads:

# watch mode
$ npm run start:dev
```shell
docker run --rm ghcr.io/alexander-danilenko/ua-loadtest:latest
```

# production mode
$ npm run start:prod
```
#### Docker environment variables

## Test
See [.env](./.env) file. All these values could be used for the app in a docker container.

```bash
# unit tests
$ npm run test
### Docker Compose

# e2e tests
$ npm run test:e2e
`docker-compose` allows you to easily run containers in parallel without having to keep multiple terminals opened. To run on servers - perfect choice.

# test coverage
$ npm run test:cov
```
- Clone repository:
```shell
git clone https://github.com/alexander-danilenko/ua-loadtest
```

## Support
- Build and run `5` containers **in parallel**:

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
```shell
docker-compose up --build --scale app=5
```

## Stay in touch
- Stop containers: `Ctrl + C`

- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
### Linux and MacOS

## License
- Install Node `v16`: https://nodejs.org/en/download/

Nest is [MIT licensed](LICENSE).
- Clone repository:
```shell
git clone https://github.com/alexander-danilenko/ua-loadtest
```

- Install all the required dependencies:
```shell
yarn install
```

- Build the app:
```shell
yarn build
```

- Run the app in production mode:
```shell
yarn start:prod
```
9 changes: 9 additions & 0 deletions docker-compose.yml
@@ -0,0 +1,9 @@
version: '3'
services:
# To run several containers in parallel use scale argument:
# docker-compose up --build --scale app=5
app:
build: .
restart: always
environment:
LOG_SUMMARY_TABLE: 'false'
22 changes: 17 additions & 5 deletions package.json
@@ -1,17 +1,17 @@
{
"name": "nowar-nestjs",
"name": "ua-loadtest",
"version": "0.0.1",
"description": "",
"author": "",
"author": "Alexander Danilenko <hi@danilenko.in>",
"license": "MIT",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:debug": "nest start --debug 0.0.0.0:9229 --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
Expand All @@ -26,21 +26,33 @@
"@nestjs/config": "^1.2.0",
"@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/schedule": "^1.0.2",
"axios-retry": "^3.2.4",
"class-transformer": "^0.5.1",
"class-validator": "^0.13.2",
"joi": "^17.6.0",
"lodash": "^4.17.21",
"node-os-utils": "^1.3.6",
"piscina": "^3.2.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
"rxjs": "^7.2.0",
"user-agents": "^1.0.951"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
"@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0",
"@trivago/prettier-plugin-sort-imports": "^3.2.0",
"@types/axios": "^0.14.0",
"@types/cron": "^1.7.3",
"@types/express": "^4.17.13",
"@types/jest": "27.4.1",
"@types/lodash": "^4.14.179",
"@types/node": "^16.0.0",
"@types/node-os-utils": "^1.2.0",
"@types/supertest": "^2.0.11",
"@types/user-agents": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
Expand Down
12 changes: 12 additions & 0 deletions src/app.controller.ts
@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { LoadTesterService } from './service/load-tester.service';

@Controller()
export class AppController {
constructor(private readonly appService: LoadTesterService) {}

@Get('/')
async index() {
return this.appService.getStatus();
}
}
26 changes: 26 additions & 0 deletions src/app.module.ts
@@ -0,0 +1,26 @@
import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { ScheduleModule } from '@nestjs/schedule';
import { AppController } from './app.controller';
import { ApiClientService } from './service/api-client.service';
import { LoadTesterService } from './service/load-tester.service';
import { RandomService } from './service/random.service';
import { StatisticsService } from './service/statistics.service';
import { config, mainConfigValidationSchema } from './config';

@Module({
imports: [
ScheduleModule.forRoot(),
HttpModule,
ConfigModule.forRoot({
envFilePath: ['.env.production', '.env.local', '.env'],
validationSchema: mainConfigValidationSchema(),
load: [config],
isGlobal: true,
}),
],
controllers: [AppController],
providers: [ApiClientService, LoadTesterService, RandomService, StatisticsService],
})
export class AppModule {}
12 changes: 0 additions & 12 deletions src/app/app.controller.ts

This file was deleted.

10 changes: 0 additions & 10 deletions src/app/app.module.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/app/app.service.ts

This file was deleted.

0 comments on commit 9fc0e98

Please sign in to comment.