Skip to content

Commit

Permalink
Add test case for image generation (#42693)
Browse files Browse the repository at this point in the history
This PR adds a basic test case to ensure Next.js and Edge Runtime
changes don't break the image generation feature, as well as record the
usage.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [x] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
  • Loading branch information
shuding committed Nov 10, 2022
1 parent 9d30e77 commit f612acf
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -90,6 +90,7 @@
"@typescript-eslint/eslint-plugin": "4.29.1",
"@typescript-eslint/parser": "4.29.1",
"@vercel/fetch": "6.1.1",
"@vercel/og": "0.0.20",
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/floating-point-hex-parser": "1.11.1",
"@webassemblyjs/helper-api-error": "1.11.1",
Expand Down
20 changes: 20 additions & 0 deletions packages/next/build/webpack/plugins/middleware-plugin.ts
Expand Up @@ -27,6 +27,7 @@ import {
} from '../../analysis/get-page-static-info'
import { Telemetry } from '../../../telemetry/storage'
import { traceGlobals } from '../../../trace/shared'
import { EVENT_BUILD_FEATURE_USAGE } from '../../../telemetry/events'

export interface EdgeFunctionDefinition {
env: string[]
Expand Down Expand Up @@ -686,6 +687,25 @@ function getExtractMetadata(params: {
for (const module of modules) {
const buildInfo = getModuleBuildInfo(module)

/**
* Check if it uses the image generation feature.
*/
if (!dev) {
const resource = module.resource
const hasOGImageGeneration =
resource &&
/[\\/]node_modules[\\/]@vercel[\\/]og[\\/]dist[\\/]index.js$/.test(
resource
)
telemetry.record({
eventName: EVENT_BUILD_FEATURE_USAGE,
payload: {
featureName: 'vercelImageGeneration',
invocationCount: hasOGImageGeneration ? 1 : 0,
},
})
}

/**
* When building for production checks if the module is using `eval`
* and in such case produces a compilation error. The module has to
Expand Down
1 change: 1 addition & 0 deletions packages/next/telemetry/events/build.ts
Expand Up @@ -153,6 +153,7 @@ export type EventBuildFeatureUsage = {
| `swc/target/${SWC_TARGET_TRIPLE}`
| 'turbotrace'
| 'build-lint'
| 'vercelImageGeneration'
invocationCount: number
}
export function eventBuildFeatureUsage(
Expand Down
80 changes: 77 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions test/integration/image-generation/app/pages/api/image.jsx
@@ -0,0 +1,9 @@
import { ImageResponse } from '@vercel/og'

export default async () => {
return new ImageResponse(<div tw="w-full h-full text-5xl">hello</div>)
}

export const config = {
runtime: 'experimental-edge',
}
42 changes: 42 additions & 0 deletions test/integration/image-generation/test/index.test.ts
@@ -0,0 +1,42 @@
/* eslint-env jest */
import {
fetchViaHTTP,
findPort,
killApp,
nextBuild,
nextStart,
} from 'next-test-utils'
import { join } from 'path'

const appDir = join(__dirname, '../app')

describe('Image Generation', () => {
describe('Prod', () => {
let app
let appPort

beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(async () => {
await killApp(app)
})

it('should generate the image without errors', async () => {
const res = await fetchViaHTTP(appPort, '/api/image')
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toBe('image/png')

const buffer = await res.buffer()

// It should be a PNG
expect(
[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a].every(
(b, i) => buffer[i] === b
)
).toBeTrue()
})
})
})
9 changes: 9 additions & 0 deletions test/integration/telemetry/pages/api/og.jsx
@@ -0,0 +1,9 @@
import { ImageResponse } from '@vercel/og'

export default async () => {
return new ImageResponse(<div tw="w-full h-full text-5xl">hello</div>)
}

export const config = {
runtime: 'experimental-edge',
}
19 changes: 17 additions & 2 deletions test/integration/telemetry/test/index.test.js
Expand Up @@ -331,9 +331,9 @@ describe('Telemetry CLI', () => {
const event1 = /NEXT_BUILD_OPTIMIZED[\s\S]+?{([\s\S]+?)}/.exec(stderr).pop()
expect(event1).toMatch(/"staticPropsPageCount": 2/)
expect(event1).toMatch(/"serverPropsPageCount": 2/)
expect(event1).toMatch(/"ssrPageCount": 1/)
expect(event1).toMatch(/"ssrPageCount": 2/)
expect(event1).toMatch(/"staticPageCount": 4/)
expect(event1).toMatch(/"totalPageCount": 9/)
expect(event1).toMatch(/"totalPageCount": 10/)
})

it('detects isSrcDir dir correctly for `next dev`', async () => {
Expand Down Expand Up @@ -970,4 +970,19 @@ describe('Telemetry CLI', () => {
invocationCount: 1,
})
})

it('emits telemetry for usage of @vercel/og', async () => {
const { stderr } = await nextBuild(appDir, [], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
})
const featureUsageEvents = findAllTelemetryEvents(
stderr,
'NEXT_BUILD_FEATURE_USAGE'
)
expect(featureUsageEvents).toContainEqual({
featureName: 'vercelImageGeneration',
invocationCount: 1,
})
})
})

0 comments on commit f612acf

Please sign in to comment.