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:
|
||||
push:
|
||||
@ -64,40 +64,3 @@ jobs:
|
||||
|
||||
- name: '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
|
||||
jest.setTimeout(ONE_MINUTE_IN_MILLISECONDS)
|
||||
import { Docker } from '../services/Docker'
|
||||
|
||||
jest.setTimeout(Docker.MAXIMUM_TIMEOUT_MILLISECONDS)
|
||||
|
@ -1,9 +1,12 @@
|
||||
import execa from 'execa'
|
||||
import ora from 'ora'
|
||||
import ms from 'ms'
|
||||
|
||||
class Docker {
|
||||
export class Docker {
|
||||
static CONTAINER_TAG = 'programming-challenges'
|
||||
static SIGSEGV_EXIT_CODE = 139
|
||||
static MAXIMUM_TIMEOUT = '1 minute'
|
||||
static MAXIMUM_TIMEOUT_MILLISECONDS = ms(Docker.MAXIMUM_TIMEOUT)
|
||||
|
||||
public async build (): Promise<void> {
|
||||
const loader = ora('Building the Docker image').start()
|
||||
@ -23,13 +26,22 @@ class Docker {
|
||||
input
|
||||
}
|
||||
)
|
||||
let isValid = true
|
||||
const timeout = setTimeout(() => {
|
||||
subprocess.kill()
|
||||
isValid = false
|
||||
}, Docker.MAXIMUM_TIMEOUT_MILLISECONDS)
|
||||
try {
|
||||
const { stdout, stderr } = await subprocess
|
||||
if (stderr.length !== 0) {
|
||||
throw new Error(stderr)
|
||||
}
|
||||
clearTimeout(timeout)
|
||||
return stdout
|
||||
} 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) {
|
||||
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",
|
||||
"ora": "5.4.1",
|
||||
"replace-in-file": "6.3.2",
|
||||
"table": "6.7.3",
|
||||
"table": "6.7.5",
|
||||
"typanion": "3.7.1",
|
||||
"validate-npm-package-name": "3.0.0"
|
||||
},
|
||||
@ -52,15 +52,17 @@
|
||||
"@types/date-and-time": "0.13.0",
|
||||
"@types/jest": "27.0.3",
|
||||
"@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",
|
||||
"editorconfig-checker": "4.0.2",
|
||||
"get-stream": "6.0.1",
|
||||
"jest": "27.4.2",
|
||||
"jest": "27.4.3",
|
||||
"markdownlint-cli": "0.30.0",
|
||||
"mock-fs": "5.1.2",
|
||||
"ms": "2.1.3",
|
||||
"rimraf": "3.0.2",
|
||||
"ts-jest": "27.0.7",
|
||||
"ts-jest": "27.1.0",
|
||||
"ts-standard": "11.0.0",
|
||||
"typescript": "4.5.2"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user