Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: video play test #526

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added beach.webm
Binary file not shown.
Binary file added beach2.webm
Binary file not shown.
844 changes: 425 additions & 419 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@helia/http": "^2.0.2",
"@helia/interface": "^5.0.0",
"@helia/routers": "^2.1.0",
"@helia/verified-fetch": "^2.3.0",
"@helia/verified-fetch": "^2.3.1",
"@libp2p/crypto": "^5.0.6",
"@libp2p/dcutr": "^2.0.12",
"@libp2p/identify": "^3.0.12",
Expand Down
29 changes: 29 additions & 0 deletions test-e2e/byte-range.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { testPathRouting as test, expect } from './fixtures/config-test-fixtures.js'
import { doRangeRequest } from './fixtures/do-range-request.js'
import { setConfig } from './fixtures/set-sw-config.js'

test.describe('byte-ranges', () => {
test('should be able to get a single character', async ({ page }) => {
Expand Down Expand Up @@ -30,4 +31,32 @@ test.describe('byte-ranges', () => {
expect(byteSize).toBe(872)
expect(bytes).toStrictEqual(tailBytes)
})

test('ttfb video file', async ({ page }) => {
await setConfig({
page,
config: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
gateways: [process.env.KUBO_GATEWAY!],
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
routers: [process.env.KUBO_GATEWAY!],
debug: 'helia*,helia*:trace,libp2p*,libp2p*:trace',
enableWss: true,
enableWebTransport: false,
enableRecursiveGateways: true,
enableGatewayProviders: false
}
})
const { bytes, byteSize, statusCode } = await doRangeRequest({ page, range: 'bytes=0-100', path: '/ipfs/bafybeiaelnma6kc5k2522f3277m4iw72l4kqbblnxmmoyjugjsaxcpeu7i' })

// also fetch from KUBO_GATEWAY to compare
const response = await fetch(`${process.env.KUBO_GATEWAY}/ipfs/bafybeiaelnma6kc5k2522f3277m4iw72l4kqbblnxmmoyjugjsaxcpeu7i`, { headers: { range: 'bytes=0-100' } })

const buffer = await response.arrayBuffer()
const kuboByteSize = buffer.byteLength
const kuboBytes = Array.from(new Uint8Array(buffer))
expect(statusCode).toBe(response.status)
expect(byteSize).toBe(kuboByteSize)
expect(bytes).toStrictEqual(kuboBytes)
})
})
73 changes: 45 additions & 28 deletions test-e2e/fixtures/config-test-fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { test as base, type Page } from '@playwright/test'
import { setConfig, setSubdomainConfig } from './set-sw-config.js'
import { test as base } from '@playwright/test'
import { setConfig } from './set-sw-config.js'
import { waitForServiceWorker } from './wait-for-service-worker.js'

function isNoServiceWorkerProject <T extends typeof base = typeof base> (test: T): boolean {
Expand Down Expand Up @@ -51,10 +51,19 @@ export const testPathRouting = test.extend<{ rootDomain: string, baseURL: string
routers: [process.env.KUBO_GATEWAY],
dnsJsonResolvers: {
'.': 'https://delegated-ipfs.dev/dns-query'
}
},
debug: 'helia*,helia*:trace,libp2p*,libp2p*:trace,*,*:trace',
enableWss: false,
enableWebTransport: false,
enableRecursiveGateways: true,
enableGatewayProviders: false
}
})

await page.evaluate(async () => {
await fetch('/#/ipfs-sw-config-reload')
})

await use(page)
}
})
Expand Down Expand Up @@ -89,38 +98,46 @@ export const testSubdomainRouting = test.extend<{ rootDomain: string, baseURL: s
if (process.env.KUBO_GATEWAY == null || process.env.KUBO_GATEWAY === '') {
throw new Error('KUBO_GATEWAY not set')
}
const kuboGateway = process.env.KUBO_GATEWAY
const oldPageGoto = page.goto.bind(page)
page.goto = async (url: Parameters<Page['goto']>[0], options: Parameters<Page['goto']>[1]): ReturnType<Page['goto']> => {
const response = await oldPageGoto(url, options)
if (['.ipfs.', '.ipns.'].some((part) => url.includes(part))) {
await setSubdomainConfig({
page,
config: {
autoReload: true,
gateways: [kuboGateway],
routers: [kuboGateway],
dnsJsonResolvers: {
'.': 'https://delegated-ipfs.dev/dns-query'
}
}
})
} else {
// already set on root.
}
return response
}
// const kuboGateway = process.env.KUBO_GATEWAY
// const oldPageGoto = page.goto.bind(page)
// page.goto = async (url: Parameters<Page['goto']>[0], options: Parameters<Page['goto']>[1]): ReturnType<Page['goto']> => {
// const response = await oldPageGoto(url, options)
// if (['.ipfs.', '.ipns.'].some((part) => url.includes(part))) {
// await setSubdomainConfig({
// page,
// config: {
// autoReload: true,
// gateways: [kuboGateway],
// routers: [kuboGateway],
// dnsJsonResolvers: {
// '.': 'https://delegated-ipfs.dev/dns-query'
// },
// enableWss: true,
// enableWebTransport: false,
// enableRecursiveGateways: true,
// enableGatewayProviders: false
// }
// })
// } else {
// // already set on root.
// }
// return response
// }

// set config for the initial page
await setConfig({
page,
config: {
autoReload: true,
gateways: [kuboGateway],
routers: [kuboGateway],
gateways: [process.env.KUBO_GATEWAY],
routers: [process.env.KUBO_GATEWAY],
dnsJsonResolvers: {
'.': 'https://delegated-ipfs.dev/dns-query'
}
},
debug: 'helia*,helia*:trace,libp2p*,libp2p*:trace,*,*:trace',
enableWss: false,
enableWebTransport: false,
enableRecursiveGateways: true,
enableGatewayProviders: false
}
})

Expand Down
Binary file not shown.
Binary file not shown.
24 changes: 12 additions & 12 deletions test-e2e/fixtures/set-sw-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ export async function getConfig ({ page }: { page: Page }): Promise<ConfigDb> {
return config
}

export async function setSubdomainConfig ({ page, config }: { page: Page, config: Partial<ConfigDb> }): Promise<void> {
await waitForServiceWorker(page)

await page.evaluate(async (configInPage) => {
// TODO: we shouldn't need this. We should be able to just post a message to the service worker to reload it's config.
window.postMessage({ source: 'helia-sw-config-iframe', target: 'PARENT', action: 'RELOAD_CONFIG', config: configInPage }, { targetOrigin: window.location.origin })
}, {
gateways: [process.env.KUBO_GATEWAY],
routers: [process.env.KUBO_GATEWAY],
...config
})
}
// export async function setSubdomainConfig ({ page, config }: { page: Page, config: Partial<ConfigDb> }): Promise<void> {
// await waitForServiceWorker(page)

// await page.evaluate(async (configInPage) => {
// // TODO: we shouldn't need this. We should be able to just post a message to the service worker to reload it's config.
// window.postMessage({ source: 'helia-sw-config-iframe', target: 'PARENT', action: 'RELOAD_CONFIG', config: configInPage }, { targetOrigin: window.location.origin })
// }, {
// gateways: [process.env.KUBO_GATEWAY],
// routers: [process.env.KUBO_GATEWAY],
// ...config
// })
// }
4 changes: 2 additions & 2 deletions test-e2e/subdomain-detection.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { test, testSubdomainRouting, expect } from './fixtures/config-test-fixtures.js'
import { setConfig, setSubdomainConfig } from './fixtures/set-sw-config.js'
import { setConfig } from './fixtures/set-sw-config.js'
import { waitForServiceWorker } from './fixtures/wait-for-service-worker.js'

test.describe('subdomain-detection', () => {
Expand Down Expand Up @@ -41,7 +41,7 @@ test.describe('subdomain-detection', () => {

test('enabling autoreload automatically loads the subdomain', async ({ page, rootDomain, protocol }) => {
await page.goto(`${protocol}//bafkqablimvwgy3y.ipfs.${rootDomain}/`, { waitUntil: 'networkidle' })
await setSubdomainConfig({
await setConfig({
page,
config: {
autoReload: true,
Expand Down
163 changes: 163 additions & 0 deletions test-e2e/video.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { type ConfigDbWithoutPrivateFields } from '../src/lib/config-db.js'
import { testPathRouting as test, expect } from './fixtures/config-test-fixtures.js'
import { getConfig, setConfig } from './fixtures/set-sw-config.js'
// import { waitForServiceWorker } from './fixtures/wait-for-service-worker.js'

// const cid = 'bafkreifxwh3i3e7etigob52wqjiic2skhka6nblhmkxtodqpw55tekjg5a' // blank video, mpg
// const cid = 'bafkreibux244hbfyljy4ato265ugpqle6rakmpw24disegfe7rjt442ele' // blank video, webm
// const cid = 'bafybeiao6bob2xmjxjw74bzkcpw4txuoa4uhyu4ikgiyrvr2uwykmfukgi' // beach.mp4
// const cid = 'bafybeih6fyvqpookcgm2vfiapxsvaj2pibf5oflssph7zwn5qn57mfiikm' // beach.webm downloaded from https://www.pexels.com/video/drone-footage-of-the-beach-8150514/ and converted to webm (playwright wont render mp4 for some reason)
const cid = 'bafybeiaelnma6kc5k2522f3277m4iw72l4kqbblnxmmoyjugjsaxcpeu7i' // beach2.webm downloaded from https://www.pexels.com/video/scenic-view-of-a-beach-1893629/ and converted to webm (playwright wont render mp4 for some reason)
// const cid = 'bafybeidsp6fva53dexzjycntiucts57ftecajcn5omzfgjx57pqfy3kwbq' // big buck bunny
test.describe('video', () => {
const testConfig: Partial<ConfigDbWithoutPrivateFields> = {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
gateways: [process.env.KUBO_GATEWAY!],
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
routers: [process.env.KUBO_GATEWAY!],
debug: 'helia*,helia*:trace,libp2p*,libp2p*:trace',
enableWss: true,
enableWebTransport: false,
enableRecursiveGateways: true,
enableGatewayProviders: false
}

/**
* We want to load the beach video fixture and ensure it starts playing.
*/
test('time to play video is reasonable', async ({ page }) => {
// eslint-disable-next-line no-console
console.log('process.env.KUBO_GATEWAY', process.env.KUBO_GATEWAY)
await setConfig({ page, config: testConfig })

page.on('request', async (request) => {
// eslint-disable-next-line no-console
console.log('request.url()', request.url(), await request.allHeaders())
})

page.on('response', async (response) => {
// eslint-disable-next-line no-console
console.log('response.url()', response.url(), await response.allHeaders())
})
const response = await page.goto(`http://127.0.0.1:3333/ipfs/${cid}`, { waitUntil: 'commit' })
// const response = await page.goto(`${process.env.KUBO_GATEWAY}/ipfs/${cid}`) // test with kubo gateway directly.
// subdomains
// const response = await page.goto(`${protocol}//${cid}.ipfs.${rootDomain}`, { waitUntil: 'commit' })

// await waitForServiceWorker(page)
const start = performance.now()

const config = await getConfig({ page })
// eslint-disable-next-line no-console
console.log('config', config)

expect(response?.status()).toBe(200)

// expect a video player
await page.waitForSelector('video')
const video = await page.$('video')
if (video == null) {
throw new Error('video element not found')
}

// make sure the video is actually playing
// continuously check if the video is playing
await page.waitForFunction((video) => {
return video.currentTime > 0 && !video.paused && !video.ended && video.readyState > 2
}, video)
const end = performance.now()

const timeToPlay = end - start
expect(timeToPlay).toBeLessThan(1000)
})
})

/* eslint-disable jsdoc/check-alignment */
/**
- **tmp**
- **test: add test for big-buck-bunny ttfb**

## Title

<!---
The title of the PR will be the commit message of the merge commit, so please make sure it is descriptive enough.
We utilize the Conventional Commits specification for our commit messages. See <https://www.conventionalcommits.org/en/v1.0.0/#specification> for more information.
The commit tag types can be of one of the following: feat, fix, deps, refactor, chore, docs. See <https://github.com/ipfs/helia/blob/main/.github/workflows/main.yml#L184-L192>
The title must also be fewer than 72 characters long or it will fail the Semantic PR check. See <https://github.com/ipfs/helia/blob/main/.github/workflows/semantic-pull-request.yml>
--->
test: local-only ttfb for big-buck-bunny

## Description

<!--
Please write a summary of your changes and why you made them.
Please include any relevant issues in here, for example:
Related https://github.com/ipfs/helia/issues/ABCD.
Fixes https://github.com/ipfs/helia/issues/XYZ.
-->

A test to help confirm improved performance for https://github.com/ipfs/helia-verified-fetch/pull/163

## Notes & open questions

<!--
Any notes, remarks or open questions you have to make about the PR which don't need to go into the final commit message.
-->

### Running against main:

```console
> npm i --save @helia/verified-fetch@latest && npm run test:chrome -- -g 'ttfb' --workers=1 --repeat-each=10

# ...

Running 10 tests using 1 worker

✓ 1 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (1.9s)
[WebServer] (node:53174) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
[WebServer] (Use `node --trace-deprecation ...` to show where the warning was created)
✓ 2 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.0s)
✓ 3 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.0s)
✓ 4 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.1s)
✓ 5 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (1.8s)
✓ 6 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.5s)
✓ 7 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.3s)
✓ 8 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.2s)
✓ 9 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.3s)
✓ 10 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.3s)

10 passed (52.3s)
```

### Running with verified-fetch from https://github.com/ipfs/helia-verified-fetch/pull/163

```console
> npm i --save /Users/sgtpooki/code/work/protocol.ai/ipfs/helia-verified-fetch/packages/verified-fetch/helia-verified-fetch-2.3.0.tgz && npm run test:chrome -- -g 'ttfb' --workers=1 --repeat-each=10

# ...

Running 10 tests using 1 worker

✓ 1 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.5s)
[WebServer] (node:54928) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
[WebServer] (Use `node --trace-deprecation ...` to show where the warning was created)
✓ 2 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.0s)
✓ 3 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.6s)
✓ 4 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.3s)
✓ 5 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (1.8s)
✓ 6 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.2s)
✓ 7 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.1s)
✓ 8 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (2.1s)
✓ 9 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (1.5s)
✓ 10 [chromium] › ttfb-big-buck-bunny.test.ts:29:3 › ttfb-time-to-play-video › loads quickly (1.7s)

10 passed (54.3s)
```

## Change checklist

- [ ] I have performed a self-review of my own code
- [ ] I have made corresponding changes to the documentation if necessary (this includes comments as well)
- [ ] I have added tests that prove my fix is effective or that my feature works

*/
Loading