mirror of
https://github.com/theoludwig/programming-challenges.git
synced 2024-12-08 00:45:29 +01:00
fix(cli): add timeout for running solutions
This commit is contained in:
parent
938702c23f
commit
0b59c19885
45
.github/workflows/challenges.yml
vendored
Normal file
45
.github/workflows/challenges.yml
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
name: 'challenges'
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-solutions:
|
||||||
|
runs-on: 'ubuntu-latest'
|
||||||
|
steps:
|
||||||
|
- uses: 'actions/checkout@v2'
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: 'Use Docker'
|
||||||
|
uses: 'actions-hub/docker/cli@master'
|
||||||
|
env:
|
||||||
|
SKIP_LOGIN: true
|
||||||
|
|
||||||
|
- name: 'Use Node.js'
|
||||||
|
uses: 'actions/setup-node@v2.5.0'
|
||||||
|
with:
|
||||||
|
node-version: '16.x'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: 'Install'
|
||||||
|
run: 'npm install'
|
||||||
|
|
||||||
|
- name: 'Build'
|
||||||
|
run: 'npm run build'
|
||||||
|
|
||||||
|
- name: 'Install programming-challenges'
|
||||||
|
run: 'npm install --global'
|
||||||
|
|
||||||
|
- uses: 'nrwl/last-successful-commit-action@v1'
|
||||||
|
id: 'last_successful_commit'
|
||||||
|
with:
|
||||||
|
branch: 'master'
|
||||||
|
workflow_id: 'ci.yml'
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: 'Test'
|
||||||
|
run: 'programming-challenges run test --affected --ci --base=${{ steps.last_successful_commit.outputs.commit_hash }}'
|
@ -1,4 +1,4 @@
|
|||||||
name: 'ci'
|
name: 'cli'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -64,40 +64,3 @@ jobs:
|
|||||||
|
|
||||||
- name: 'Test'
|
- name: 'Test'
|
||||||
run: 'npm run test'
|
run: 'npm run test'
|
||||||
|
|
||||||
challenges:
|
|
||||||
runs-on: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- uses: 'actions/checkout@v2'
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: 'Use Docker'
|
|
||||||
uses: 'actions-hub/docker/cli@master'
|
|
||||||
env:
|
|
||||||
SKIP_LOGIN: true
|
|
||||||
|
|
||||||
- name: 'Use Node.js'
|
|
||||||
uses: 'actions/setup-node@v2.5.0'
|
|
||||||
with:
|
|
||||||
node-version: '16.x'
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- name: 'Install'
|
|
||||||
run: 'npm install'
|
|
||||||
|
|
||||||
- name: 'Build'
|
|
||||||
run: 'npm run build'
|
|
||||||
|
|
||||||
- name: 'Install programming-challenges'
|
|
||||||
run: 'npm install --global'
|
|
||||||
|
|
||||||
- uses: 'nrwl/last-successful-commit-action@v1'
|
|
||||||
id: 'last_successful_commit'
|
|
||||||
with:
|
|
||||||
branch: 'master'
|
|
||||||
workflow_id: 'ci.yml'
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: 'Test'
|
|
||||||
run: 'programming-challenges run test --affected --ci --base=${{ steps.last_successful_commit.outputs.commit_hash }}'
|
|
@ -1,7 +0,0 @@
|
|||||||
# sorting-algorithms/python/bubble-sort
|
|
||||||
|
|
||||||
Created by [@Divlo](https://github.com/Divlo) on 29 June 2021.
|
|
||||||
|
|
||||||
| Algorithm | Best Case | Average Case | Worst Case |
|
|
||||||
| ----------------------------------------------------------- | ----------- | ------------ | ----------- |
|
|
||||||
| [Bubble sort](https://wikipedia.org/wiki/Bubble_sort) | O(n) | O(n²) | O(n²) |
|
|
@ -1,24 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def bubble_sort(numbersInput: List[int]) -> List[int]:
|
|
||||||
numbers = list(numbersInput)
|
|
||||||
length = len(numbers)
|
|
||||||
for index_1 in range(length):
|
|
||||||
for index_2 in range(length - index_1 - 1):
|
|
||||||
if numbers[index_2] > numbers[index_2 + 1]:
|
|
||||||
temporary = numbers[index_2]
|
|
||||||
numbers[index_2] = numbers[index_2 + 1]
|
|
||||||
numbers[index_2 + 1] = temporary
|
|
||||||
return numbers
|
|
||||||
|
|
||||||
|
|
||||||
numbers: List[int] = []
|
|
||||||
for value in sys.stdin:
|
|
||||||
numbers.append(int(value.rstrip('\n')))
|
|
||||||
|
|
||||||
numbers = numbers[1:]
|
|
||||||
sorted_numbers = bubble_sort(numbers)
|
|
||||||
for number in sorted_numbers:
|
|
||||||
print(number)
|
|
@ -1,7 +0,0 @@
|
|||||||
# sorting-algorithms/python/insertion-sort
|
|
||||||
|
|
||||||
Created by [@Divlo](https://github.com/Divlo) on 29 June 2021.
|
|
||||||
|
|
||||||
| Algorithm | Best Case | Average Case | Worst Case |
|
|
||||||
| ----------------------------------------------------------- | ----------- | ------------ | ----------- |
|
|
||||||
| [Insertion sort](https://wikipedia.org/wiki/Insertion_sort) | O(n) | O(n²) | O(n²) |
|
|
@ -1,24 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def insertion_sort(numbersInput: List[int]) -> List[int]:
|
|
||||||
numbers = list(numbersInput)
|
|
||||||
for index_1 in range(1, len(numbers)):
|
|
||||||
current = numbers[index_1]
|
|
||||||
index_2 = index_1 - 1
|
|
||||||
while index_2 >= 0 and numbers[index_2] > current:
|
|
||||||
numbers[index_2 + 1] = numbers[index_2]
|
|
||||||
index_2 -= 1
|
|
||||||
numbers[index_2 + 1] = current
|
|
||||||
return numbers
|
|
||||||
|
|
||||||
|
|
||||||
numbers: List[int] = []
|
|
||||||
for value in sys.stdin:
|
|
||||||
numbers.append(int(value.rstrip('\n')))
|
|
||||||
|
|
||||||
numbers = numbers[1:]
|
|
||||||
sorted_numbers = insertion_sort(numbers)
|
|
||||||
for number in sorted_numbers:
|
|
||||||
print(number)
|
|
@ -1,2 +1,3 @@
|
|||||||
const ONE_MINUTE_IN_MILLISECONDS = 60 * 1000
|
import { Docker } from '../services/Docker'
|
||||||
jest.setTimeout(ONE_MINUTE_IN_MILLISECONDS)
|
|
||||||
|
jest.setTimeout(Docker.MAXIMUM_TIMEOUT_MILLISECONDS)
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import ora from 'ora'
|
import ora from 'ora'
|
||||||
|
import ms from 'ms'
|
||||||
|
|
||||||
class Docker {
|
export class Docker {
|
||||||
static CONTAINER_TAG = 'programming-challenges'
|
static CONTAINER_TAG = 'programming-challenges'
|
||||||
static SIGSEGV_EXIT_CODE = 139
|
static SIGSEGV_EXIT_CODE = 139
|
||||||
|
static MAXIMUM_TIMEOUT = '1 minute'
|
||||||
|
static MAXIMUM_TIMEOUT_MILLISECONDS = ms(Docker.MAXIMUM_TIMEOUT)
|
||||||
|
|
||||||
public async build (): Promise<void> {
|
public async build (): Promise<void> {
|
||||||
const loader = ora('Building the Docker image').start()
|
const loader = ora('Building the Docker image').start()
|
||||||
@ -23,13 +26,22 @@ class Docker {
|
|||||||
input
|
input
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
let isValid = true
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
subprocess.kill()
|
||||||
|
isValid = false
|
||||||
|
}, Docker.MAXIMUM_TIMEOUT_MILLISECONDS)
|
||||||
try {
|
try {
|
||||||
const { stdout, stderr } = await subprocess
|
const { stdout, stderr } = await subprocess
|
||||||
if (stderr.length !== 0) {
|
if (stderr.length !== 0) {
|
||||||
throw new Error(stderr)
|
throw new Error(stderr)
|
||||||
}
|
}
|
||||||
|
clearTimeout(timeout)
|
||||||
return stdout
|
return stdout
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
if (!isValid) {
|
||||||
|
throw new Error(`Timeout: time limit exceeded (${Docker.MAXIMUM_TIMEOUT}), try to optimize your solution.`)
|
||||||
|
}
|
||||||
if (error.exitCode === Docker.SIGSEGV_EXIT_CODE) {
|
if (error.exitCode === Docker.SIGSEGV_EXIT_CODE) {
|
||||||
throw new Error('Docker run failed: SIGSEGV indicates a segmentation fault (attempts to access a memory location that it\'s not allowed to access).')
|
throw new Error('Docker run failed: SIGSEGV indicates a segmentation fault (attempts to access a memory location that it\'s not allowed to access).')
|
||||||
}
|
}
|
||||||
|
747
package-lock.json
generated
747
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -42,7 +42,7 @@
|
|||||||
"execa": "5.1.1",
|
"execa": "5.1.1",
|
||||||
"ora": "5.4.1",
|
"ora": "5.4.1",
|
||||||
"replace-in-file": "6.3.2",
|
"replace-in-file": "6.3.2",
|
||||||
"table": "6.7.3",
|
"table": "6.7.5",
|
||||||
"typanion": "3.7.1",
|
"typanion": "3.7.1",
|
||||||
"validate-npm-package-name": "3.0.0"
|
"validate-npm-package-name": "3.0.0"
|
||||||
},
|
},
|
||||||
@ -52,15 +52,17 @@
|
|||||||
"@types/date-and-time": "0.13.0",
|
"@types/date-and-time": "0.13.0",
|
||||||
"@types/jest": "27.0.3",
|
"@types/jest": "27.0.3",
|
||||||
"@types/mock-fs": "4.13.1",
|
"@types/mock-fs": "4.13.1",
|
||||||
"@types/node": "16.11.11",
|
"@types/ms": "0.7.31",
|
||||||
|
"@types/node": "16.11.12",
|
||||||
"@types/validate-npm-package-name": "3.0.3",
|
"@types/validate-npm-package-name": "3.0.3",
|
||||||
"editorconfig-checker": "4.0.2",
|
"editorconfig-checker": "4.0.2",
|
||||||
"get-stream": "6.0.1",
|
"get-stream": "6.0.1",
|
||||||
"jest": "27.4.2",
|
"jest": "27.4.3",
|
||||||
"markdownlint-cli": "0.30.0",
|
"markdownlint-cli": "0.30.0",
|
||||||
"mock-fs": "5.1.2",
|
"mock-fs": "5.1.2",
|
||||||
|
"ms": "2.1.3",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"ts-jest": "27.0.7",
|
"ts-jest": "27.1.0",
|
||||||
"ts-standard": "11.0.0",
|
"ts-standard": "11.0.0",
|
||||||
"typescript": "4.5.2"
|
"typescript": "4.5.2"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user