Allow HLS test to wait for stream changes
This commit is contained in:
7
.github/workflows/hls-tests.yml
vendored
7
.github/workflows/hls-tests.yml
vendored
@@ -28,5 +28,10 @@ jobs:
|
|||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: '1.18.8'
|
go-version: '1.18.8'
|
||||||
|
|
||||||
- name: Run HLS tests
|
- name: Run HLS tests
|
||||||
run: cd test/automated/hls && ./run.sh
|
uses: nick-fields/retry@v2
|
||||||
|
with:
|
||||||
|
timeout_minutes: 10
|
||||||
|
max_attempts: 3
|
||||||
|
command: cd test/automated/hls && ./run.sh
|
||||||
|
|||||||
@@ -11,112 +11,112 @@ const HLS_FETCH_ITERATIONS = 5;
|
|||||||
jest.setTimeout(40000);
|
jest.setTimeout(40000);
|
||||||
|
|
||||||
async function getPlaylist(urlString) {
|
async function getPlaylist(urlString) {
|
||||||
const response = await fetch(urlString);
|
const response = await fetch(urlString);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
const body = await response.text();
|
const body = await response.text();
|
||||||
|
|
||||||
var parser = new m3u8Parser.Parser();
|
var parser = new m3u8Parser.Parser();
|
||||||
|
|
||||||
parser.push(body);
|
parser.push(body);
|
||||||
parser.end();
|
parser.end();
|
||||||
|
|
||||||
return parser.manifest;
|
return parser.manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeUrl(urlString, baseUrl) {
|
function normalizeUrl(urlString, baseUrl) {
|
||||||
let parsedString = url.parse(urlString);
|
let parsedString = url.parse(urlString);
|
||||||
if (!parsedString.host) {
|
if (!parsedString.host) {
|
||||||
const testInstanceRoot = url.parse(baseUrl);
|
const testInstanceRoot = url.parse(baseUrl);
|
||||||
parsedString.protocol = testInstanceRoot.protocol;
|
parsedString.protocol = testInstanceRoot.protocol;
|
||||||
parsedString.host = testInstanceRoot.host;
|
parsedString.host = testInstanceRoot.host;
|
||||||
|
|
||||||
const filename = baseUrl.substring(baseUrl.lastIndexOf('/') + 1);
|
const filename = baseUrl.substring(baseUrl.lastIndexOf('/') + 1);
|
||||||
parsedString.pathname =
|
parsedString.pathname =
|
||||||
testInstanceRoot.pathname.replace(filename, '') + urlString;
|
testInstanceRoot.pathname.replace(filename, '') + urlString;
|
||||||
}
|
}
|
||||||
return url.format(parsedString).toString();
|
return url.format(parsedString).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over an array of video segments and make sure they return back
|
// Iterate over an array of video segments and make sure they return back
|
||||||
// valid status.
|
// valid status.
|
||||||
async function validateSegments(segments) {
|
async function validateSegments(segments) {
|
||||||
for (let segment of segments) {
|
for (let segment of segments) {
|
||||||
const res = await fetch(segment);
|
const res = await fetch(segment);
|
||||||
expect(res.status).toBe(200);
|
expect(res.status).toBe(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('fetch and parse HLS', () => {
|
describe('fetch and parse HLS', () => {
|
||||||
const masterPlaylistUrl = `${TEST_OWNCAST_INSTANCE}${HLS_SUBDIRECTORY}${PLAYLIST_NAME}`;
|
const masterPlaylistUrl = `${TEST_OWNCAST_INSTANCE}${HLS_SUBDIRECTORY}${PLAYLIST_NAME}`;
|
||||||
var masterPlaylist;
|
var masterPlaylist;
|
||||||
var mediaPlaylistUrl;
|
var mediaPlaylistUrl;
|
||||||
|
|
||||||
test('fetch master playlist', async (done) => {
|
test('fetch master playlist', async (done) => {
|
||||||
try {
|
try {
|
||||||
masterPlaylist = await getPlaylist(masterPlaylistUrl);
|
masterPlaylist = await getPlaylist(masterPlaylistUrl);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('error fetching and parsing master playlist', e);
|
console.error('error fetching and parsing master playlist', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('verify there is a media playlist', () => {
|
test('verify there is a media playlist', () => {
|
||||||
// Master playlist should have at least one media playlist.
|
// Master playlist should have at least one media playlist.
|
||||||
expect(masterPlaylist.playlists.length).toBe(1);
|
expect(masterPlaylist.playlists.length).toBe(1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mediaPlaylistUrl = normalizeUrl(
|
mediaPlaylistUrl = normalizeUrl(
|
||||||
masterPlaylist.playlists[0].uri,
|
masterPlaylist.playlists[0].uri,
|
||||||
masterPlaylistUrl
|
masterPlaylistUrl
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('error fetching and parsing media playlist', e);
|
console.error('error fetching and parsing media playlist', e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('verify there are segments', async (done) => {
|
test('verify there are segments', async (done) => {
|
||||||
let playlist;
|
let playlist;
|
||||||
try {
|
try {
|
||||||
playlist = await getPlaylist(mediaPlaylistUrl);
|
playlist = await getPlaylist(mediaPlaylistUrl);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('error verifying segments in media playlist', e);
|
console.error('error verifying segments in media playlist', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
const segments = playlist.segments;
|
const segments = playlist.segments;
|
||||||
expect(segments.length).toBeGreaterThan(0);
|
expect(segments.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Iterate over segments and make sure they change.
|
// Iterate over segments and make sure they change.
|
||||||
// Use the reported duration of the segment to wait to
|
// Use the reported duration of the segment to wait to
|
||||||
// fetch another just like a real HLS player would do.
|
// fetch another just like a real HLS player would do.
|
||||||
var lastSegmentUrl;
|
var lastSegmentUrl;
|
||||||
for (let i = 0; i < HLS_FETCH_ITERATIONS; i++) {
|
for (let i = 0; i < HLS_FETCH_ITERATIONS; i++) {
|
||||||
test('fetch and monitor media playlist segments ' + i, async (done) => {
|
test('fetch and monitor media playlist segments ' + i, async (done) => {
|
||||||
await new Promise((r) => setTimeout(r, 3000));
|
await new Promise((r) => setTimeout(r, 5000));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var playlist = await getPlaylist(mediaPlaylistUrl);
|
var playlist = await getPlaylist(mediaPlaylistUrl);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('error updating media playlist', mediaPlaylistUrl, e);
|
console.error('error updating media playlist', mediaPlaylistUrl, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
const segments = playlist.segments;
|
const segments = playlist.segments;
|
||||||
const segment = segments[segments.length - 1];
|
const segment = segments[segments.length - 1];
|
||||||
expect(segment.uri).not.toBe(lastSegmentUrl);
|
expect(segment.uri).not.toBe(lastSegmentUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var segmentUrl = normalizeUrl(segment.uri, mediaPlaylistUrl);
|
var segmentUrl = normalizeUrl(segment.uri, mediaPlaylistUrl);
|
||||||
await validateSegments([segmentUrl]);
|
await validateSegments([segmentUrl]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('unable to validate HLS segment', segmentUrl, e);
|
console.error('unable to validate HLS segment', segmentUrl, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastSegmentUrl = segment.uri;
|
lastSegmentUrl = segment.uri;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ start_owncast
|
|||||||
|
|
||||||
start_stream
|
start_stream
|
||||||
|
|
||||||
|
sleep 10
|
||||||
|
|
||||||
# Run tests against a fresh install with no settings.
|
# Run tests against a fresh install with no settings.
|
||||||
npm test
|
npm test
|
||||||
|
|
||||||
@@ -21,8 +23,8 @@ kill_with_kids "$STREAM_PID"
|
|||||||
|
|
||||||
# Determine if we should continue testing with S3 configuration.
|
# Determine if we should continue testing with S3 configuration.
|
||||||
if [[ -z "${S3_BUCKET}" ]]; then
|
if [[ -z "${S3_BUCKET}" ]]; then
|
||||||
echo "No S3 configuration is set. Skipping S3 tests!"
|
echo "No S3 configuration is set. Skipping S3 tests!"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Update the server config to use S3 for storage.
|
# Update the server config to use S3 for storage.
|
||||||
@@ -30,5 +32,7 @@ update_storage_config
|
|||||||
|
|
||||||
start_stream
|
start_stream
|
||||||
|
|
||||||
|
sleep 10
|
||||||
|
|
||||||
# Re-run the HLS test against the external storage configuration.
|
# Re-run the HLS test against the external storage configuration.
|
||||||
npm test
|
npm test
|
||||||
|
|||||||
Reference in New Issue
Block a user