@vltpkg/vsr 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,351 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
- import { getPackagePackument } from '../src/routes/packages.ts'
3
-
4
- // Mock config
5
- vi.mock('../../config.js', () => ({
6
- DOMAIN: 'https://registry.example.com',
7
- PROXY: true,
8
- PROXY_URL: 'https://registry.npmjs.org'
9
- }))
10
-
11
- // Mock slimManifest function
12
- vi.mock('../src/utils/packages.js', () => ({
13
- slimManifest: (manifest) => {
14
- // Simple implementation to use in tests
15
- if (!manifest) return {}
16
-
17
- const parsed = typeof manifest === 'string' ? JSON.parse(manifest) : manifest
18
-
19
- // Create a simplified version with only essential fields
20
- const slimmed = {
21
- name: parsed.name,
22
- version: parsed.version,
23
- description: parsed.description,
24
- dependencies: parsed.dependencies || {},
25
- peerDependencies: parsed.peerDependencies || {},
26
- peerDependenciesMeta: parsed.peerDependenciesMeta || {},
27
- dist: {
28
- ...(parsed.dist || {}),
29
- tarball: parsed.dist?.tarball || ''
30
- }
31
- }
32
-
33
- // Remove undefined values
34
- Object.keys(slimmed).forEach(key => {
35
- if (key !== 'dist' && slimmed[key] === undefined) {
36
- delete slimmed[key]
37
- }
38
- })
39
-
40
- return slimmed
41
- },
42
- createVersion: ({ pkg, version, manifest }) => manifest
43
- }))
44
-
45
- describe('Packument Response Format', () => {
46
- // Set up mock data and context
47
- const setupTest = () => {
48
- // Mock package data
49
- const mockPublishedPackage = {
50
- name: 'local-package',
51
- tags: { latest: '1.0.0', beta: '1.1.0-beta.1' },
52
- lastUpdated: '2023-01-01T00:00:00.000Z'
53
- }
54
-
55
- // Mock version data with JSON strings
56
- const mockVersions = [
57
- {
58
- spec: 'local-package@1.0.0',
59
- version: '1.0.0',
60
- manifest: JSON.stringify({
61
- name: 'local-package',
62
- version: '1.0.0',
63
- description: 'A locally published package',
64
- dependencies: { 'some-dep': '^1.0.0' },
65
- _id: 'local-package@1.0.0',
66
- _npmUser: { name: 'testuser' },
67
- readme: 'Very long readme content...',
68
- dist: {
69
- shasum: '1234567890abcdef',
70
- integrity: 'sha512-abcdefghijklmnopqrstuvwxyz0123456789',
71
- tarball: 'https://registry.example.com/local-package/-/local-package-1.0.0.tgz'
72
- }
73
- }),
74
- published_at: '2023-01-01T00:00:00.000Z'
75
- },
76
- {
77
- spec: 'local-package@1.1.0-beta.1',
78
- version: '1.1.0-beta.1',
79
- manifest: JSON.stringify({
80
- name: 'local-package',
81
- version: '1.1.0-beta.1',
82
- description: 'A locally published package (beta)',
83
- dependencies: {
84
- 'some-dep': '^1.0.0',
85
- 'another-dep': '^2.0.0'
86
- },
87
- _id: 'local-package@1.1.0-beta.1',
88
- _npmUser: { name: 'testuser' },
89
- readme: 'Very long readme content for beta...',
90
- dist: {
91
- shasum: '0987654321fedcba',
92
- integrity: 'sha512-zyxwvutsrqponmlkjihgfedcba0987654321',
93
- tarball: 'https://registry.example.com/local-package/-/local-package-1.1.0-beta.1.tgz'
94
- }
95
- }),
96
- published_at: '2023-01-15T00:00:00.000Z'
97
- }
98
- ]
99
-
100
- // Set up mock context
101
- const mockContext = {
102
- req: {
103
- param: vi.fn((name) => {
104
- if (name === 'pkg') {
105
- return 'local-package'
106
- }
107
- return undefined
108
- }),
109
- query: vi.fn((name) => {
110
- return null; // Return null for any query param
111
- }),
112
- url: 'https://registry.example.com/local-package'
113
- },
114
- db: {
115
- getPackage: vi.fn(async (name) => {
116
- if (name === 'local-package') {
117
- return { ...mockPublishedPackage }
118
- }
119
- return null
120
- }),
121
- getVersionsByPackage: vi.fn(async (name) => {
122
- if (name === 'local-package') {
123
- return [...mockVersions]
124
- }
125
- return []
126
- }),
127
- getVersion: vi.fn(async (spec) => {
128
- return mockVersions.find(v => v.spec === spec)
129
- }),
130
- upsertPackage: vi.fn(async () => true),
131
- upsertVersion: vi.fn(async () => true)
132
- },
133
- json: vi.fn((data, status = 200) => ({ body: data, status })),
134
- header: vi.fn(),
135
- executionCtx: { waitUntil: vi.fn() },
136
- env: {}
137
- }
138
-
139
- // Mock upstream data
140
- const mockUpstreamData = {
141
- name: 'proxied-package',
142
- _id: 'proxied-package',
143
- _rev: '123-abc',
144
- _attachments: {},
145
- _npmUser: { name: 'upstream-user' },
146
- maintainers: [{ name: 'upstream-user', email: 'user@example.com' }],
147
- 'dist-tags': { latest: '2.0.0', next: '2.1.0-rc.1' },
148
- versions: {
149
- '2.0.0': {
150
- name: 'proxied-package',
151
- version: '2.0.0',
152
- description: 'A proxied package',
153
- dependencies: { 'dep1': '^1.0.0' },
154
- _id: 'proxied-package@2.0.0',
155
- _npmUser: { name: 'upstream-user' },
156
- readme: 'Very long readme content...',
157
- dist: {
158
- shasum: 'abcdef1234567890',
159
- integrity: 'sha512-abcdefghijklmnopqrstuvwxyz0123456789',
160
- tarball: 'https://registry.npmjs.org/proxied-package/-/proxied-package-2.0.0.tgz'
161
- }
162
- },
163
- '2.1.0-rc.1': {
164
- name: 'proxied-package',
165
- version: '2.1.0-rc.1',
166
- description: 'A proxied package (RC)',
167
- dependencies: { 'dep1': '^1.0.0', 'dep2': '^3.0.0' },
168
- _id: 'proxied-package@2.1.0-rc.1',
169
- _npmUser: { name: 'upstream-user' },
170
- readme: 'Very long readme content for RC...',
171
- dist: {
172
- shasum: 'fedcba0987654321',
173
- integrity: 'sha512-zyxwvutsrqponmlkjihgfedcba0987654321',
174
- tarball: 'https://registry.npmjs.org/proxied-package/-/proxied-package-2.1.0-rc.1.tgz'
175
- }
176
- }
177
- },
178
- time: {
179
- modified: '2023-02-01T00:00:00.000Z',
180
- created: '2023-01-01T00:00:00.000Z',
181
- '2.0.0': '2023-01-15T00:00:00.000Z',
182
- '2.1.0-rc.1': '2023-02-01T00:00:00.000Z'
183
- }
184
- }
185
-
186
- // Mock fetch for proxied package
187
- global.fetch = vi.fn(async (url) => {
188
- if (url.includes('proxied-package')) {
189
- return {
190
- ok: true,
191
- status: 200,
192
- json: async () => ({ ...mockUpstreamData })
193
- }
194
- }
195
- return {
196
- ok: false,
197
- status: 404,
198
- json: async () => ({ error: 'Not found' })
199
- }
200
- })
201
-
202
- return {
203
- mockContext,
204
- mockUpstreamData,
205
- mockPublishedPackage,
206
- mockVersions
207
- }
208
- }
209
-
210
- beforeEach(() => {
211
- vi.resetAllMocks()
212
- })
213
-
214
- it('should return consistent packument for local packages with only required fields', async () => {
215
- const { mockContext } = setupTest()
216
-
217
- await getPackagePackument(mockContext)
218
-
219
- expect(mockContext.json).toHaveBeenCalled()
220
- const responseData = mockContext.json.mock.calls[0][0]
221
-
222
- // Verify structure
223
- expect(responseData).toHaveProperty('name', 'local-package')
224
- expect(responseData).toHaveProperty('dist-tags')
225
- expect(responseData).toHaveProperty('versions')
226
- expect(responseData).toHaveProperty('time')
227
-
228
- // Verify dist-tags
229
- expect(responseData['dist-tags']).toEqual({
230
- latest: '1.0.0',
231
- beta: '1.1.0-beta.1'
232
- })
233
-
234
- // Verify versions exist
235
- expect(responseData.versions).toHaveProperty('1.0.0')
236
- expect(responseData.versions).toHaveProperty('1.1.0-beta.1')
237
-
238
- // Check slimming of sensitive data
239
- const version = responseData.versions['1.0.0']
240
- expect(version).toBeDefined()
241
- expect(version).not.toHaveProperty('_id')
242
- expect(version).not.toHaveProperty('_npmUser')
243
- expect(version).not.toHaveProperty('readme')
244
-
245
- // Verify contains required fields
246
- expect(version).toHaveProperty('name', 'local-package')
247
- expect(version).toHaveProperty('version', '1.0.0')
248
- expect(version).toHaveProperty('dist')
249
-
250
- // Verify status
251
- expect(mockContext.json.mock.calls[0][1]).toBe(200)
252
- })
253
-
254
- it('should return consistent packument for proxied packages with only required fields', async () => {
255
- const { mockContext } = setupTest()
256
-
257
- // Change request to fetch proxied package
258
- mockContext.req.param = vi.fn((name) => {
259
- if (name === 'pkg') {
260
- return 'proxied-package'
261
- }
262
- return undefined
263
- })
264
-
265
- // Capture dist-tags for verification
266
- let capturedTags = null
267
- mockContext.db.upsertPackage = vi.fn(async (name, tags) => {
268
- capturedTags = tags
269
- return true
270
- })
271
-
272
- await getPackagePackument(mockContext)
273
-
274
- // Verify response
275
- expect(mockContext.json).toHaveBeenCalled()
276
- const responseData = mockContext.json.mock.calls[0][0]
277
-
278
- // Verify structure
279
- expect(responseData).toHaveProperty('name', 'proxied-package')
280
- expect(responseData).toHaveProperty('dist-tags')
281
- expect(responseData).toHaveProperty('versions')
282
- expect(responseData).toHaveProperty('time')
283
-
284
- // Check that tags were properly stored
285
- expect(capturedTags).toEqual({
286
- latest: '2.0.0',
287
- next: '2.1.0-rc.1'
288
- })
289
-
290
- // Verify no extra fields
291
- expect(responseData).not.toHaveProperty('_id')
292
- expect(responseData).not.toHaveProperty('_rev')
293
- expect(responseData).not.toHaveProperty('_attachments')
294
-
295
- // Verify versions exist
296
- expect(Object.keys(responseData.versions)).toContain('2.0.0')
297
- expect(Object.keys(responseData.versions)).toContain('2.1.0-rc.1')
298
-
299
- // Check version format
300
- const version = responseData.versions['2.0.0']
301
- expect(version).toBeDefined()
302
- expect(version).toHaveProperty('name', 'proxied-package')
303
- expect(version).toHaveProperty('version', '2.0.0')
304
- expect(version).not.toHaveProperty('_id')
305
- expect(version).not.toHaveProperty('_npmUser')
306
- expect(version).not.toHaveProperty('readme')
307
-
308
- // Verify status
309
- expect(mockContext.json.mock.calls[0][1]).toBe(200)
310
- })
311
-
312
- it('should handle background refresh while maintaining consistent response format', async () => {
313
- const { mockContext } = setupTest()
314
-
315
- // Setup stale timestamp
316
- const oldDate = new Date()
317
- oldDate.setDate(oldDate.getDate() - 10)
318
-
319
- // Mock stale package data
320
- mockContext.db.getPackage = vi.fn(async (name) => {
321
- if (name === 'local-package') {
322
- return {
323
- name: 'local-package',
324
- tags: { latest: '1.0.0', beta: '1.1.0-beta.1' },
325
- lastUpdated: oldDate.toISOString()
326
- }
327
- }
328
- return null
329
- })
330
-
331
- await getPackagePackument(mockContext)
332
-
333
- // Verify background refresh was triggered
334
- expect(mockContext.executionCtx.waitUntil).toHaveBeenCalled()
335
-
336
- // Verify response
337
- expect(mockContext.json).toHaveBeenCalled()
338
- const responseData = mockContext.json.mock.calls[0][0]
339
-
340
- // Verify structure
341
- expect(responseData).toEqual(expect.objectContaining({
342
- name: 'local-package',
343
- 'dist-tags': expect.any(Object),
344
- versions: expect.any(Object),
345
- time: expect.any(Object)
346
- }))
347
-
348
- // Verify status
349
- expect(mockContext.json.mock.calls[0][1]).toBe(200)
350
- })
351
- })
@@ -1,144 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
- import * as semver from 'semver'
3
-
4
- // Mock semver to use actual implementation
5
- vi.mock('semver', async () => {
6
- const actual = await vi.importActual('semver')
7
- return {
8
- ...actual
9
- }
10
- })
11
-
12
- // Mock config
13
- vi.mock('../../config.js', () => ({
14
- DOMAIN: 'https://registry.example.com',
15
- PROXY: false // Disable proxy for these tests
16
- }))
17
-
18
- describe('Packument Version Range Filtering', () => {
19
- // Test the versionRange filtering functionality directly
20
- describe('Core semver filtering behavior', () => {
21
-
22
- // Create a realistic set of package versions
23
- const versions = [
24
- '1.0.0', '1.0.1', '1.1.0', '1.2.0', '1.2.3', // Major 1
25
- '2.0.0', '2.0.1', '2.1.0', // Major 2
26
- '3.0.0-beta.1', '3.0.0-beta.2', // Pre-release versions
27
- ]
28
-
29
- // Function to simulate the filtering logic from our implementation
30
- const filterVersionsByRange = (versions, range) => {
31
- if (!semver.validRange(range)) {
32
- throw new Error(`Invalid semver range: ${range}`)
33
- }
34
-
35
- return versions.filter(version => semver.satisfies(version, range))
36
- }
37
-
38
- it('should validate semver ranges correctly', () => {
39
- // Valid ranges
40
- expect(semver.validRange('1.x')).toBeTruthy()
41
- expect(semver.validRange('^2.0.0')).toBeTruthy()
42
- expect(semver.validRange('~2.0.0')).toBeTruthy()
43
- expect(semver.validRange('>=1.2.0 <2.1.0')).toBeTruthy()
44
- expect(semver.validRange('^3.0.0-0')).toBeTruthy()
45
-
46
- // Invalid range
47
- expect(semver.validRange('not-a-valid-range')).toBeNull()
48
- })
49
-
50
- it('should filter by major version (1.x)', () => {
51
- const range = '1.x'
52
- const filtered = filterVersionsByRange(versions, range)
53
-
54
- // Should only include major 1 versions
55
- const expected = ['1.0.0', '1.0.1', '1.1.0', '1.2.0', '1.2.3']
56
- expect(filtered).toEqual(expected)
57
- expect(filtered.length).toBe(5)
58
-
59
- // Shouldn't include major 2 or 3
60
- expect(filtered).not.toContain('2.0.0')
61
- expect(filtered).not.toContain('3.0.0-beta.1')
62
- })
63
-
64
- it('should filter with caret range (^2.0.0)', () => {
65
- const range = '^2.0.0'
66
- const filtered = filterVersionsByRange(versions, range)
67
-
68
- // Should include all 2.x versions
69
- const expected = ['2.0.0', '2.0.1', '2.1.0']
70
- expect(filtered).toEqual(expected)
71
- expect(filtered.length).toBe(3)
72
-
73
- // Shouldn't include major 1 or 3
74
- expect(filtered).not.toContain('1.2.3')
75
- expect(filtered).not.toContain('3.0.0-beta.1')
76
- })
77
-
78
- it('should filter with tilde range (~2.0.0)', () => {
79
- const range = '~2.0.0'
80
- const filtered = filterVersionsByRange(versions, range)
81
-
82
- // Should only include patch versions of 2.0
83
- const expected = ['2.0.0', '2.0.1']
84
- expect(filtered).toEqual(expected)
85
- expect(filtered.length).toBe(2)
86
-
87
- // Shouldn't include minor versions
88
- expect(filtered).not.toContain('2.1.0')
89
- })
90
-
91
- it('should filter with complex range (>=1.2.0 <2.1.0)', () => {
92
- const range = '>=1.2.0 <2.1.0'
93
- const filtered = filterVersionsByRange(versions, range)
94
-
95
- // Should include specified range
96
- const expected = ['1.2.0', '1.2.3', '2.0.0', '2.0.1']
97
- expect(filtered).toEqual(expected)
98
- expect(filtered.length).toBe(4)
99
-
100
- // Verify boundaries are respected
101
- expect(filtered).not.toContain('1.1.0')
102
- expect(filtered).not.toContain('2.1.0')
103
- })
104
-
105
- it('should handle pre-release versions when explicitly included (^3.0.0-0)', () => {
106
- const range = '^3.0.0-0'
107
- const filtered = filterVersionsByRange(versions, range)
108
-
109
- // Should include beta versions
110
- const expected = ['3.0.0-beta.1', '3.0.0-beta.2']
111
- expect(filtered).toEqual(expected)
112
- expect(filtered.length).toBe(2)
113
- })
114
-
115
- it('should reject invalid semver ranges', () => {
116
- const range = 'not-a-valid-range'
117
- expect(() => filterVersionsByRange(versions, range)).toThrow('Invalid semver range')
118
- })
119
- })
120
-
121
- // Test the API integration with minimal mocking
122
- describe('API implementation integration', () => {
123
- it('should correctly integrate with the API', () => {
124
- // Verify that the actual API implementation would correctly:
125
- // 1. Extract the versionRange query parameter
126
- // 2. Validate it using semver.validRange
127
- // 3. Filter versions using semver.satisfies
128
-
129
- // Instead of trying to mock the entire system, we're just
130
- // asserting here that the core semver functionality works
131
- // as expected when integrated with our API filtering logic
132
-
133
- const validRange = semver.validRange('^1.0.0')
134
- expect(validRange).toBeTruthy()
135
-
136
- const version = '1.2.3'
137
- const matchesRange = semver.satisfies(version, '^1.0.0')
138
- expect(matchesRange).toBe(true)
139
-
140
- const doesntMatch = semver.satisfies('2.0.0', '^1.0.0')
141
- expect(doesntMatch).toBe(false)
142
- })
143
- })
144
- })
@@ -1,162 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from 'vitest'
2
- import { unstable_dev } from 'wrangler'
3
-
4
- describe('Performance Tests', () => {
5
- let worker
6
-
7
- beforeAll(async () => {
8
- worker = await unstable_dev('src/index.js', {
9
- experimental: { disableExperimentalWarning: true },
10
- local: true,
11
- port: 1338, // Use different port to avoid conflicts
12
- })
13
- })
14
-
15
- afterAll(async () => {
16
- await worker.stop()
17
- })
18
-
19
- async function measureRequestTime(url, expectJson = true) {
20
- const start = Date.now()
21
- const response = await fetch(url)
22
- const end = Date.now()
23
- const duration = end - start
24
-
25
- let data = null
26
- if (response.ok && expectJson) {
27
- try {
28
- data = await response.json()
29
- } catch (e) {
30
- // Handle non-JSON responses (like tarballs)
31
- data = null
32
- }
33
- }
34
-
35
- return {
36
- duration,
37
- ok: response.ok,
38
- status: response.status,
39
- data
40
- }
41
- }
42
-
43
- it('should be faster than npm registry for packument requests', async () => {
44
- const testPackage = 'lodash'
45
-
46
- // Test npm registry directly
47
- const npmResult = await measureRequestTime(`https://registry.npmjs.org/${testPackage}`)
48
- console.log(`NPM registry time: ${npmResult.duration}ms`)
49
-
50
- // Test our registry (first request - cache miss)
51
- const ourFirstResult = await measureRequestTime(`http://localhost:1338/npm/${testPackage}`)
52
- console.log(`Our registry (first): ${ourFirstResult.duration}ms`)
53
-
54
- // Test our registry (second request - should be cached)
55
- const ourSecondResult = await measureRequestTime(`http://localhost:1338/npm/${testPackage}`)
56
- console.log(`Our registry (cached): ${ourSecondResult.duration}ms`)
57
-
58
- expect(npmResult.ok).toBe(true)
59
- expect(ourFirstResult.ok).toBe(true)
60
- expect(ourSecondResult.ok).toBe(true)
61
-
62
- // Second request should be faster than first (due to caching)
63
- expect(ourSecondResult.duration).toBeLessThan(ourFirstResult.duration)
64
-
65
- // Cached request should be faster than npm (relaxed expectation)
66
- expect(ourSecondResult.duration).toBeLessThan(npmResult.duration * 2) // Allow up to 2x npm time
67
- }, 30000)
68
-
69
- it('should cache tarball requests effectively', async () => {
70
- const testPackage = 'lodash'
71
- const testVersion = '4.17.21'
72
- const tarballUrl = `http://localhost:1338/npm/${testPackage}/-/${testPackage}-${testVersion}.tgz`
73
-
74
- // First tarball request (don't expect JSON)
75
- const firstRequest = await measureRequestTime(tarballUrl, false)
76
- console.log(`Tarball (first): ${firstRequest.duration}ms`)
77
-
78
- // Second tarball request (should be cached)
79
- const secondRequest = await measureRequestTime(tarballUrl, false)
80
- console.log(`Tarball (cached): ${secondRequest.duration}ms`)
81
-
82
- expect(firstRequest.ok).toBe(true)
83
- expect(secondRequest.ok).toBe(true)
84
-
85
- // Second request should be reasonably fast (allow for network variance)
86
- expect(secondRequest.duration).toBeLessThan(firstRequest.duration * 3) // Allow more variance for small requests
87
- }, 30000)
88
-
89
- it('should handle manifest requests efficiently', async () => {
90
- const testPackage = 'express'
91
- const testVersion = '4.18.2'
92
- const manifestUrl = `http://localhost:1338/npm/${testPackage}/${testVersion}`
93
-
94
- // First manifest request
95
- const firstRequest = await measureRequestTime(manifestUrl)
96
- console.log(`Manifest (first): ${firstRequest.duration}ms`)
97
-
98
- // Second manifest request (should be cached)
99
- const secondRequest = await measureRequestTime(manifestUrl)
100
- console.log(`Manifest (cached): ${secondRequest.duration}ms`)
101
-
102
- expect(firstRequest.ok).toBe(true)
103
- expect(secondRequest.ok).toBe(true)
104
-
105
- // Verify the manifest has rewritten tarball URLs to our domain
106
- expect(secondRequest.data.dist.tarball).toContain('localhost')
107
- expect(secondRequest.data.dist.tarball).toContain(testPackage)
108
-
109
- // Second request should be faster or at least not much slower
110
- expect(secondRequest.duration).toBeLessThan(firstRequest.duration * 1.5) // Allow some variance
111
- }, 30000)
112
-
113
- it('should demonstrate racing cache performance', async () => {
114
- const testPackages = ['react', 'vue', 'angular']
115
- const results = []
116
-
117
- for (const pkg of testPackages) {
118
- // Measure cold request (no cache)
119
- const coldResult = await measureRequestTime(`http://localhost:1338/npm/${pkg}`)
120
-
121
- // Measure warm request (potentially cached)
122
- const warmResult = await measureRequestTime(`http://localhost:1338/npm/${pkg}`)
123
-
124
- results.push({
125
- package: pkg,
126
- cold: coldResult.duration,
127
- warm: warmResult.duration,
128
- improvement: ((coldResult.duration - warmResult.duration) / coldResult.duration * 100).toFixed(1)
129
- })
130
-
131
- console.log(`${pkg}: Cold ${coldResult.duration}ms, Warm ${warmResult.duration}ms (${results[results.length-1].improvement}% faster)`)
132
- }
133
-
134
- // At least some packages should show improvement (or at least not be much worse)
135
- const reasonableResults = results.filter(r => parseFloat(r.improvement) > -50) // Allow up to 50% slower due to racing
136
- expect(reasonableResults.length).toBeGreaterThan(0)
137
- }, 60000)
138
-
139
- it('should handle high concurrency efficiently', async () => {
140
- const testPackage = 'uuid'
141
- const concurrency = 10
142
-
143
- // Make concurrent requests
144
- const promises = Array(concurrency).fill().map((_, i) =>
145
- measureRequestTime(`http://localhost:1338/npm/${testPackage}?_t=${i}`)
146
- )
147
-
148
- const start = Date.now()
149
- const results = await Promise.all(promises)
150
- const totalTime = Date.now() - start
151
-
152
- console.log(`${concurrency} concurrent requests completed in ${totalTime}ms`)
153
- console.log(`Average per request: ${(totalTime / concurrency).toFixed(1)}ms`)
154
-
155
- // All requests should succeed
156
- expect(results.every(r => r.ok)).toBe(true)
157
-
158
- // Concurrent requests shouldn't be much slower than sequential
159
- const avgRequestTime = totalTime / concurrency
160
- expect(avgRequestTime).toBeLessThan(5000) // Should average less than 5 seconds per request
161
- }, 60000)
162
- })