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

Boilerplate for integration tests (within js-sdk) #519

Merged
merged 10 commits into from
Jan 18, 2025
3 changes: 2 additions & 1 deletion packages/js-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"update-deps": "ncu -u && pnpm i",
"postPublish": "./scripts/post-publish.sh || true",
"test:bun": "bun test tests/runtimes/bun --env-file=.env",
"test:deno": "deno test tests/runtimes/deno/ --allow-net --allow-read --allow-env --unstable-sloppy-imports --trace-leaks"
"test:deno": "deno test tests/runtimes/deno/ --allow-net --allow-read --allow-env --unstable-sloppy-imports --trace-leaks",
"test:integration": "E2B_INTEGRATION_TEST=1 vitest run tests/integration/**"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we do it only based on directory structure? 🙏

Copy link
Contributor Author

@0div 0div Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, I initially tried that, but the way vitest workspace works makes it impossible to exclude the integration tests when when running pnpm test , bc that just picks up everything — maybe i'm missing something tho!

},
"devDependencies": {
"@testing-library/react": "^16.0.1",
Expand Down
77 changes: 77 additions & 0 deletions packages/js-sdk/tests/integration/stress.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { test } from 'vitest'

import Sandbox from '../../src/index.js'
import { isIntegrationTest, wait } from '../setup.js'

const heavyArray = new ArrayBuffer(256 * 1024 * 1024) // 256 MiB = 256 * 1024 * 1024 bytes
const view = new Uint8Array(heavyArray)
for (let i = 0; i < view.length; i++) {
view[i] = Math.floor(Math.random() * 256)
}

const integrationTestTemplate = 'integration-test-v1'
const sanboxCount = 10

test.skipIf(!isIntegrationTest)(
'stress test heavy file writes and reads',
async () => {
const promises: Array<Promise<string | void>> = []
for (let i = 0; i < sanboxCount; i++) {
promises.push(
Sandbox.create(integrationTestTemplate, { timeoutMs: 60 })
.then((sbx) => {
console.log(sbx.sandboxId)
return sbx.files
.write('heavy-file', heavyArray)
.then(() => sbx.files.read('heavy-file'))
})
.catch(console.error)
)
}
await wait(10_000)
await Promise.all(promises)
}
)

test.skipIf(!isIntegrationTest)('stress requests to nextjs app', async ({}) => {
const hostPromises: Array<Promise<string | void>> = []

for (let i = 0; i < sanboxCount; i++) {
hostPromises.push(
Sandbox.create(integrationTestTemplate, { timeoutMs: 60_000 }).then(
(sbx) => {
console.log('created sandbox', sbx.sandboxId)
return new Promise((resolve, reject) => {
try {
resolve(sbx.getHost(3000))
} catch (e) {
console.error('error getting sbx host', e)
reject(e)
}
})
}
)
)
}

await wait(10_000)
const hosts = await Promise.all(hostPromises)

const fetchPromises: Array<Promise<string | void>> = []

for (let i = 0; i < 100; i++) {
for (const host of hosts) {
fetchPromises.push(
new Promise((resolve) => {
fetch('https://' + host)
.then((res) => {
console.log(`response for ${host}: ${res.status}`)
})
.then(resolve)
})
)
}
}

await Promise.all(fetchPromises)
})
5 changes: 5 additions & 0 deletions packages/js-sdk/tests/integration/template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Integration test template

# Build the template

`$ e2b template build -c "cd /basic-nextjs-app/ && sudo npm run dev"`
8 changes: 8 additions & 0 deletions packages/js-sdk/tests/integration/template/e2b.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM e2bdev/code-interpreter:latest

# Create a basic Next.js app
RUN npx -y create-next-app@latest test --yes --ts --use-npm

# Install dependencies
RUN cd basic-nextjs-app && npm install

18 changes: 18 additions & 0 deletions packages/js-sdk/tests/integration/template/e2b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This is a config for E2B sandbox template.
# You can use template ID (2e2z80zhv34yumbrybvn) or template name (integration-test-v1) to create a sandbox:

# Python SDK
# from e2b import Sandbox, AsyncSandbox
# sandbox = Sandbox("integration-test-v1") # Sync sandbox
# sandbox = await AsyncSandbox.create("integration-test-v1") # Async sandbox

# JS SDK
# import { Sandbox } from 'e2b'
# const sandbox = await Sandbox.create('integration-test-v1')

team_id = "b9c07023-d095-4bdc-9634-e25d5530ba47"
memory_mb = 1_024
start_cmd = "npm run dev"
dockerfile = "e2b.Dockerfile"
template_name = "integration-test-v1"
template_id = "2e2z80zhv34yumbrybvn"
1 change: 1 addition & 0 deletions packages/js-sdk/tests/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const sandboxTest = base.extend<SandboxFixture>({
})

export const isDebug = process.env.E2B_DEBUG !== undefined
export const isIntegrationTest = process.env.E2B_INTEGRATION_TEST !== undefined

export async function wait(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms))
Expand Down
35 changes: 19 additions & 16 deletions packages/js-sdk/vitest.workspace.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,19 @@ const env = config()
export default defineWorkspace([
{
test: {
include: [
'tests/**/*.test.ts',
],
exclude: [
'tests/runtimes/**',
],
poolOptions: {
threads: {
minThreads: 1,
maxThreads: 4,
},
},
include: ['tests/**/*.test.ts'],
exclude: ['tests/runtimes/**', 'tests/integration/**'],
isolate: false, // for projects that don't rely on side effects, disabling isolation will improve the speed of the tests
globals: false,
testTimeout: 30000,
testTimeout: 30_000,
environment: 'node',
bail: 1,
server: {},
deps: {
interopDefault: true,
},
env: {
...process.env as Record<string, string>,
...(process.env as Record<string, string>),
...env.parsed,
},
},
Expand All @@ -43,8 +34,8 @@ export default defineWorkspace([
providerOptions: {},
},
env: {
...process.env as Record<string, string>,
...env.parsed,
...(process.env as Record<string, string>),
...env.parsed,
},
},
},
Expand All @@ -55,4 +46,16 @@ export default defineWorkspace([
environment: 'edge-runtime',
},
},
{
test: {
include: ['tests/integration/**/*.test.ts'],
globals: false,
testTimeout: 60_000,
environment: 'node',
env: {
...(process.env as Record<string, string>),
...env.parsed,
},
},
},
])
Loading