Browse Source
* WIP for automated integration test * See if it runs under a workflow * Support running test locally as well as a workflow * Use already downloaded repo to build. Do not re-clone * Add comments * Update to support new default config file * Split out different test suites * Add test for chat * Always run test with config-default and ignore local config file * Remove the build workflow because the end to end test does that nowpull/397/head
10 changed files with 5395 additions and 41 deletions
@ -0,0 +1,16 @@ |
|||||||
|
name: Automated end to end tests |
||||||
|
|
||||||
|
on: |
||||||
|
push: |
||||||
|
# branches: |
||||||
|
# - master |
||||||
|
pull_request: |
||||||
|
branches: master |
||||||
|
|
||||||
|
jobs: |
||||||
|
Jest: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v2 |
||||||
|
- name: Setup and run |
||||||
|
run: cd test/automated && ./run.sh |
@ -1,41 +0,0 @@ |
|||||||
name: Build Owncast |
|
||||||
|
|
||||||
on: |
|
||||||
push: |
|
||||||
branches: |
|
||||||
- master |
|
||||||
pull_request: |
|
||||||
branches: master |
|
||||||
|
|
||||||
jobs: |
|
||||||
build: |
|
||||||
strategy: |
|
||||||
matrix: |
|
||||||
go-version: [~1.13, ^1] |
|
||||||
os: [ubuntu-latest, macos-latest] |
|
||||||
runs-on: ${{ matrix.os }} |
|
||||||
|
|
||||||
steps: |
|
||||||
- name: Install go |
|
||||||
uses: actions/setup-go@v2 |
|
||||||
with: |
|
||||||
go-version: ${{ matrix.go-version }} |
|
||||||
|
|
||||||
- uses: actions/checkout@v2 |
|
||||||
|
|
||||||
- name: Build |
|
||||||
run: go build -o owncast *.go |
|
||||||
|
|
||||||
docker-build: |
|
||||||
runs-on: ubuntu-latest |
|
||||||
steps: |
|
||||||
- uses: actions/checkout@v2 |
|
||||||
|
|
||||||
- name: Copy default config file |
|
||||||
run: cp config-default.yaml config.yaml |
|
||||||
|
|
||||||
- name: Build Docker image |
|
||||||
run: docker build -t owncast . |
|
||||||
|
|
||||||
- name: Run Docker image |
|
||||||
run: docker run -d -p 8080:8080 -p 1935:1935 owncast |
|
@ -0,0 +1,49 @@ |
|||||||
|
var request = require('supertest'); |
||||||
|
request = request('http://127.0.0.1:8080'); |
||||||
|
|
||||||
|
test('stream details are correct', (done) => { |
||||||
|
request.get('/api/admin/status').auth('admin', 'abc123').expect(200) |
||||||
|
.then((res) => { |
||||||
|
expect(res.body.broadcaster.streamDetails.width).toBe(320); |
||||||
|
expect(res.body.broadcaster.streamDetails.height).toBe(180); |
||||||
|
expect(res.body.broadcaster.streamDetails.framerate).toBe(24); |
||||||
|
expect(res.body.broadcaster.streamDetails.videoBitrate).toBe(1269); |
||||||
|
expect(res.body.broadcaster.streamDetails.videoCodec).toBe('H.264'); |
||||||
|
expect(res.body.broadcaster.streamDetails.audioCodec).toBe('AAC'); |
||||||
|
expect(res.body.online).toBe(true); |
||||||
|
done(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
test('admin configuration is correct', (done) => { |
||||||
|
request.get('/api/admin/serverconfig').auth('admin', 'abc123').expect(200) |
||||||
|
.then((res) => { |
||||||
|
expect(res.body.instanceDetails.name).toBe('Owncast'); |
||||||
|
expect(res.body.instanceDetails.title).toBe('Owncast'); |
||||||
|
expect(res.body.instanceDetails.summary).toBe('This is brief summary of whom you are or what your stream is. You can edit this description in your config file.'); |
||||||
|
expect(res.body.instanceDetails.logo).toBe('/img/logo.svg'); |
||||||
|
expect(res.body.instanceDetails.tags).toStrictEqual(['music', 'software', 'streaming']); |
||||||
|
|
||||||
|
expect(res.body.videoSettings.segmentLengthSeconds).toBe(4); |
||||||
|
expect(res.body.videoSettings.numberOfPlaylistItems).toBe(5); |
||||||
|
|
||||||
|
expect(res.body.videoSettings.videoQualityVariants[0].framerate).toBe(24); |
||||||
|
expect(res.body.videoSettings.videoQualityVariants[0].encoderPreset).toBe('veryfast'); |
||||||
|
|
||||||
|
expect(res.body.videoSettings.numberOfPlaylistItems).toBe(5); |
||||||
|
|
||||||
|
expect(res.body.yp.enabled).toBe(false); |
||||||
|
expect(res.body.streamKey).toBe('abc123'); |
||||||
|
done(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('correct number of log entries exist', (done) => { |
||||||
|
request.get('/api/admin/logs').auth('admin', 'abc123').expect(200) |
||||||
|
.then((res) => { |
||||||
|
expect(res.body).toHaveLength(4); |
||||||
|
done(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
@ -0,0 +1,49 @@ |
|||||||
|
const { test } = require('@jest/globals'); |
||||||
|
var request = require('supertest'); |
||||||
|
request = request('http://127.0.0.1:8080'); |
||||||
|
|
||||||
|
const WebSocket = require('ws'); |
||||||
|
var ws; |
||||||
|
|
||||||
|
const id = Math.random().toString(36).substring(7); |
||||||
|
const username = 'user' + Math.floor(Math.random() * 100); |
||||||
|
const message = Math.floor(Math.random() * 100) + ' test 123'; |
||||||
|
const messageRaw = message + ' *and some markdown too*'; |
||||||
|
const messageMarkdown = '<p>' + message + ' <em>and some markdown too</em></p>' |
||||||
|
const date = new Date().toISOString(); |
||||||
|
|
||||||
|
const testMessage = { |
||||||
|
author: username, |
||||||
|
body: messageRaw, |
||||||
|
id: id, |
||||||
|
type: 'CHAT', |
||||||
|
visible: true, |
||||||
|
timestamp: date, |
||||||
|
}; |
||||||
|
|
||||||
|
test('can send a chat message', (done) => { |
||||||
|
ws = new WebSocket('ws://127.0.0.1:8080/entry', { |
||||||
|
origin: 'http://localhost', |
||||||
|
}); |
||||||
|
|
||||||
|
function onOpen() { |
||||||
|
ws.send(JSON.stringify(testMessage), function() { |
||||||
|
ws.close(); |
||||||
|
done(); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
ws.on('open', onOpen); |
||||||
|
}); |
||||||
|
|
||||||
|
test('can fetch chat messages', (done) => { |
||||||
|
request.get('/api/chat').expect(200) |
||||||
|
.then((res) => { |
||||||
|
expect(res.body[0].author).toBe(testMessage.author); |
||||||
|
expect(res.body[0].body).toBe(messageMarkdown); |
||||||
|
expect(res.body[0].date).toBe(testMessage.date); |
||||||
|
expect(res.body[0].type).toBe(testMessage.type); |
||||||
|
|
||||||
|
done(); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,21 @@ |
|||||||
|
var request = require('supertest'); |
||||||
|
request = request('http://127.0.0.1:8080'); |
||||||
|
|
||||||
|
test('service is online', (done) => { |
||||||
|
request.get('/api/status').expect(200) |
||||||
|
.then((res) => { |
||||||
|
expect(res.body.online).toBe(true); |
||||||
|
done(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
test('frontend configuration is correct', (done) => { |
||||||
|
request.get('/api/config').expect(200) |
||||||
|
.then((res) => { |
||||||
|
expect(res.body.title).toBe('Owncast'); |
||||||
|
expect(res.body.logo).toBe('/img/logo.svg'); |
||||||
|
expect(res.body.socialHandles[0].platform).toBe('github'); |
||||||
|
expect(res.body.socialHandles[0].url).toBe('http://github.com/owncast/owncast'); |
||||||
|
done(); |
||||||
|
}); |
||||||
|
}); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,18 @@ |
|||||||
|
{ |
||||||
|
"name": "owncast-test-automation", |
||||||
|
"version": "1.0.0", |
||||||
|
"description": "", |
||||||
|
"main": "index.js", |
||||||
|
"scripts": { |
||||||
|
"test": "jest" |
||||||
|
}, |
||||||
|
"author": "", |
||||||
|
"license": "ISC", |
||||||
|
"dependencies": { |
||||||
|
"supertest": "^6.0.1", |
||||||
|
"websocket": "^1.0.32" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"jest": "^26.6.3" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
TEMP_DB=$(mktemp) |
||||||
|
|
||||||
|
# Install the node test framework |
||||||
|
npm install --silent > /dev/null |
||||||
|
|
||||||
|
# Download a specific version of ffmpeg |
||||||
|
if [ ! -d "ffmpeg" ]; then |
||||||
|
mkdir ffmpeg |
||||||
|
pushd ffmpeg > /dev/null |
||||||
|
curl -sL https://github.com/vot/ffbinaries-prebuilt/releases/download/v4.2.1/ffmpeg-4.2.1-linux-64.zip --output ffmpeg.zip > /dev/null |
||||||
|
unzip -o ffmpeg.zip > /dev/null |
||||||
|
PATH=$PATH:$(pwd) |
||||||
|
popd > /dev/null |
||||||
|
fi |
||||||
|
|
||||||
|
pushd ../.. > /dev/null |
||||||
|
|
||||||
|
# Build and run owncast from source |
||||||
|
go build -o owncast main.go pkged.go |
||||||
|
./owncast -database $TEMP_DB -configFile config-default.yaml & |
||||||
|
SERVER_PID=$! |
||||||
|
|
||||||
|
popd > /dev/null |
||||||
|
sleep 5 |
||||||
|
|
||||||
|
# Start streaming the test file over RTMP to |
||||||
|
# the local owncast instance. |
||||||
|
ffmpeg -hide_banner -loglevel panic -re -i test.mp4 -vcodec libx264 -profile:v main -sc_threshold 0 -b:v 1300k -acodec copy -f flv rtmp://127.0.0.1/live/abc123 & |
||||||
|
FFMPEG_PID=$! |
||||||
|
|
||||||
|
function finish { |
||||||
|
rm $TEMP_DB |
||||||
|
kill $SERVER_PID $FFMPEG_PID |
||||||
|
} |
||||||
|
trap finish EXIT |
||||||
|
|
||||||
|
echo "Waiting..." |
||||||
|
sleep 15 |
||||||
|
|
||||||
|
# Run the tests against the instance. |
||||||
|
npm test |
Binary file not shown.
Loading…
Reference in new issue