Skip to content

Commit 7beccd7

Browse files
authored
Boilerplate for integration tests (within js-sdk) (#519)
# Description - [x] nextjs integration test template - [x] `pnpm test:integration` - [x] set of stress tests - [x] adapt vitest workspace
2 parents 4b5d17e + 5c4207b commit 7beccd7

7 files changed

Lines changed: 130 additions & 17 deletions

File tree

packages/js-sdk/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"update-deps": "ncu -u && pnpm i",
3636
"postPublish": "./scripts/post-publish.sh || true",
3737
"test:bun": "bun test tests/runtimes/bun --env-file=.env",
38-
"test:deno": "deno test tests/runtimes/deno/ --allow-net --allow-read --allow-env --unstable-sloppy-imports --trace-leaks"
38+
"test:deno": "deno test tests/runtimes/deno/ --allow-net --allow-read --allow-env --unstable-sloppy-imports --trace-leaks",
39+
"test:integration": "E2B_INTEGRATION_TEST=1 vitest run tests/integration/**"
3940
},
4041
"devDependencies": {
4142
"@testing-library/react": "^16.0.1",
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { test } from 'vitest'
2+
3+
import Sandbox from '../../src/index.js'
4+
import { isIntegrationTest, wait } from '../setup.js'
5+
6+
const heavyArray = new ArrayBuffer(256 * 1024 * 1024) // 256 MiB = 256 * 1024 * 1024 bytes
7+
const view = new Uint8Array(heavyArray)
8+
for (let i = 0; i < view.length; i++) {
9+
view[i] = Math.floor(Math.random() * 256)
10+
}
11+
12+
const integrationTestTemplate = 'integration-test-v1'
13+
const sanboxCount = 10
14+
15+
test.skipIf(!isIntegrationTest)(
16+
'stress test heavy file writes and reads',
17+
async () => {
18+
const promises: Array<Promise<string | void>> = []
19+
for (let i = 0; i < sanboxCount; i++) {
20+
promises.push(
21+
Sandbox.create(integrationTestTemplate, { timeoutMs: 60 })
22+
.then((sbx) => {
23+
console.log(sbx.sandboxId)
24+
return sbx.files
25+
.write('heavy-file', heavyArray)
26+
.then(() => sbx.files.read('heavy-file'))
27+
})
28+
.catch(console.error)
29+
)
30+
}
31+
await wait(10_000)
32+
await Promise.all(promises)
33+
}
34+
)
35+
36+
test.skipIf(!isIntegrationTest)('stress requests to nextjs app', async ({}) => {
37+
const hostPromises: Array<Promise<string | void>> = []
38+
39+
for (let i = 0; i < sanboxCount; i++) {
40+
hostPromises.push(
41+
Sandbox.create(integrationTestTemplate, { timeoutMs: 60_000 }).then(
42+
(sbx) => {
43+
console.log('created sandbox', sbx.sandboxId)
44+
return new Promise((resolve, reject) => {
45+
try {
46+
resolve(sbx.getHost(3000))
47+
} catch (e) {
48+
console.error('error getting sbx host', e)
49+
reject(e)
50+
}
51+
})
52+
}
53+
)
54+
)
55+
}
56+
57+
await wait(10_000)
58+
const hosts = await Promise.all(hostPromises)
59+
60+
const fetchPromises: Array<Promise<string | void>> = []
61+
62+
for (let i = 0; i < 100; i++) {
63+
for (const host of hosts) {
64+
fetchPromises.push(
65+
new Promise((resolve) => {
66+
fetch('https://' + host)
67+
.then((res) => {
68+
console.log(`response for ${host}: ${res.status}`)
69+
})
70+
.then(resolve)
71+
})
72+
)
73+
}
74+
}
75+
76+
await Promise.all(fetchPromises)
77+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Integration test template
2+
3+
# Build the template
4+
5+
`$ e2b template build -c "cd /basic-nextjs-app/ && sudo npm run dev"`
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM e2bdev/code-interpreter:latest
2+
3+
# Create a basic Next.js app
4+
RUN npx -y create-next-app@latest test --yes --ts --use-npm
5+
6+
# Install dependencies
7+
RUN cd basic-nextjs-app && npm install
8+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# This is a config for E2B sandbox template.
2+
# You can use template ID (2e2z80zhv34yumbrybvn) or template name (integration-test-v1) to create a sandbox:
3+
4+
# Python SDK
5+
# from e2b import Sandbox, AsyncSandbox
6+
# sandbox = Sandbox("integration-test-v1") # Sync sandbox
7+
# sandbox = await AsyncSandbox.create("integration-test-v1") # Async sandbox
8+
9+
# JS SDK
10+
# import { Sandbox } from 'e2b'
11+
# const sandbox = await Sandbox.create('integration-test-v1')
12+
13+
team_id = "b9c07023-d095-4bdc-9634-e25d5530ba47"
14+
memory_mb = 1_024
15+
start_cmd = "npm run dev"
16+
dockerfile = "e2b.Dockerfile"
17+
template_name = "integration-test-v1"
18+
template_id = "2e2z80zhv34yumbrybvn"

packages/js-sdk/tests/setup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const sandboxTest = base.extend<SandboxFixture>({
3030
})
3131

3232
export const isDebug = process.env.E2B_DEBUG !== undefined
33+
export const isIntegrationTest = process.env.E2B_INTEGRATION_TEST !== undefined
3334

3435
export async function wait(ms: number) {
3536
return new Promise((resolve) => setTimeout(resolve, ms))

packages/js-sdk/vitest.workspace.mts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,19 @@ const env = config()
55
export default defineWorkspace([
66
{
77
test: {
8-
include: [
9-
'tests/**/*.test.ts',
10-
],
11-
exclude: [
12-
'tests/runtimes/**',
13-
],
14-
poolOptions: {
15-
threads: {
16-
minThreads: 1,
17-
maxThreads: 4,
18-
},
19-
},
8+
include: ['tests/**/*.test.ts'],
9+
exclude: ['tests/runtimes/**', 'tests/integration/**'],
10+
isolate: false, // for projects that don't rely on side effects, disabling isolation will improve the speed of the tests
2011
globals: false,
21-
testTimeout: 30000,
12+
testTimeout: 30_000,
2213
environment: 'node',
2314
bail: 1,
2415
server: {},
2516
deps: {
2617
interopDefault: true,
2718
},
2819
env: {
29-
...process.env as Record<string, string>,
20+
...(process.env as Record<string, string>),
3021
...env.parsed,
3122
},
3223
},
@@ -43,8 +34,8 @@ export default defineWorkspace([
4334
providerOptions: {},
4435
},
4536
env: {
46-
...process.env as Record<string, string>,
47-
...env.parsed,
37+
...(process.env as Record<string, string>),
38+
...env.parsed,
4839
},
4940
},
5041
},
@@ -55,4 +46,16 @@ export default defineWorkspace([
5546
environment: 'edge-runtime',
5647
},
5748
},
49+
{
50+
test: {
51+
include: ['tests/integration/**/*.test.ts'],
52+
globals: false,
53+
testTimeout: 60_000,
54+
environment: 'node',
55+
env: {
56+
...(process.env as Record<string, string>),
57+
...env.parsed,
58+
},
59+
},
60+
},
5861
])

0 commit comments

Comments
 (0)