Skip to content

Commit c7221ee

Browse files
authored
chore: fix e2e tests to run in isolation (#166)
* chore: fix e2e tests to run in isolation * concurrent run
1 parent 28541c2 commit c7221ee

File tree

1 file changed

+60
-48
lines changed

1 file changed

+60
-48
lines changed

e2e/e2e.js

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag
1010
governing permissions and limitations under the License.
1111
*/
1212

13-
/* ************* NOTE 1: these tests must be run sequentially, jest does it by default within a SINGLE file ************* */
13+
/* ************* NOTE 1: these tests must be able to run concurrently across multiple instances ************* */
1414
/* ************* NOTE 2: requires env vars TEST_AUTH_1, TEST_NS_1 and TEST_AUTH_2, TEST_NS_2 for 2 different namespaces. ************* */
1515

1616
const path = require('node:path')
@@ -20,20 +20,24 @@ require('dotenv').config({ path: path.join(__dirname, '.env') })
2020

2121
const { MAX_TTL_SECONDS } = require('../lib/constants')
2222
const stateLib = require('../index')
23+
const { randomInt } = require('node:crypto')
2324

24-
const testKey = 'e2e_test_state_key'
25-
const testKey2 = 'e2e_test_state_key2'
25+
const uniquePrefix = `${Date.now()}.${randomInt(10)}`
26+
const testKey = `${uniquePrefix}__e2e_test_state_key`
27+
const testKey2 = `${uniquePrefix}__e2e_test_state_key2`
2628

27-
jest.setTimeout(120000) // 2 minutes per test
29+
jest.setTimeout(60000) // 1 minute per test
2830

2931
const initStateEnv = async (n = 1) => {
3032
delete process.env.__OW_API_KEY
3133
delete process.env.__OW_NAMESPACE
3234
process.env.__OW_API_KEY = process.env[`TEST_AUTH_${n}`]
3335
process.env.__OW_NAMESPACE = process.env[`TEST_NAMESPACE_${n}`]
3436
const state = await stateLib.init()
35-
// make sure we cleanup the namespace, note that delete might fail as it is an op under test
36-
await state.deleteAll()
37+
// // make sure we cleanup the namespace, note that delete might fail as it is an op under test
38+
// await state.delete(`${uniquePrefix}*`)
39+
await state.delete(testKey)
40+
await state.delete(testKey2)
3741
return state
3842
}
3943

@@ -70,25 +74,38 @@ describe('e2e tests using OpenWhisk credentials (as env vars)', () => {
7074
}))
7175
})
7276

73-
test('key-value basic test on one key with string value: put, get, delete, any, stats, deleteAll', async () => {
77+
test('key-value basic test on one key with string value: put, get, delete, any, stats', async () => {
7478
const state = await initStateEnv()
7579

7680
const testValue = 'a string'
81+
const testValue2 = 'a longer string'
7782

7883
expect(await state.get(testKey)).toEqual(undefined)
7984
expect(await state.put(testKey, testValue)).toEqual(testKey)
8085
expect(await state.get(testKey)).toEqual(expect.objectContaining({ value: testValue, expiration: expect.any(String) }))
81-
expect(await state.delete(testKey)).toEqual(testKey)
82-
expect(await state.get(testKey)).toEqual(undefined)
83-
expect(await state.any()).toEqual(false)
84-
expect(await state.put(testKey, testValue)).toEqual(testKey)
85-
expect(await state.put(testKey2, testValue)).toEqual(testKey2)
86+
87+
expect(await state.any()).toEqual(true)
88+
const stats = await state.stats()
89+
expect(stats).toBeDefined()
90+
expect(stats.keys).toBeGreaterThanOrEqual(1)
91+
expect(stats.bytesKeys).toBeGreaterThanOrEqual(testKey.length)
92+
expect(stats.bytesValues).toBeGreaterThanOrEqual(testValue.length)
93+
94+
expect(await state.put(testKey2, testValue2)).toEqual(testKey2)
95+
8696
expect(await state.any()).toEqual(true)
87-
expect(await state.stats()).toEqual({ bytesKeys: testKey.length + testKey2.length, bytesValues: testValue.length * 2, keys: 2 })
88-
expect(await state.deleteAll()).toEqual(true)
97+
const stats2 = await state.stats()
98+
expect(stats2).toBeDefined()
99+
expect(stats2.keys).toBeGreaterThanOrEqual(2)
100+
expect(stats2.bytesKeys).toBeGreaterThanOrEqual(testKey.length + testKey2.length)
101+
expect(stats2.bytesValues).toBeGreaterThanOrEqual(testValue.length + testValue2.length)
102+
103+
expect(await state.delete(testKey)).toEqual(testKey)
89104
expect(await state.get(testKey)).toEqual(undefined)
90-
expect(await state.any()).toEqual(false)
91-
expect(await state.stats()).toEqual(false)
105+
expect(await state.delete(testKey2)).toEqual(testKey2)
106+
expect(await state.get(testKey2)).toEqual(undefined)
107+
108+
// note we can't test any, stats for empty container and deleteAll in isolation
92109
})
93110

94111
test('time-to-live tests: write w/o ttl, get default ttl, write with ttl, get, get after ttl', async () => {
@@ -131,13 +148,12 @@ describe('e2e tests using OpenWhisk credentials (as env vars)', () => {
131148

132149
test('listKeys test: few < 128 keys, many, and expired entries', async () => {
133150
const state = await initStateEnv()
134-
await state.deleteAll() // cleanup
135151

136152
const genKeyStrings = (n) => {
137153
return (new Array(n).fill(0).map((_, idx) => {
138154
const char = String.fromCharCode(97 + idx % 26)
139155
// list-[a-z]-[0-(N-1)]
140-
return `list-${char}-${idx}`
156+
return `${uniquePrefix}__list_${char}_${idx}`
141157
}))
142158
}
143159
const putKeys = async (keys, ttl) => {
@@ -159,54 +175,61 @@ describe('e2e tests using OpenWhisk credentials (as env vars)', () => {
159175
const keys90 = genKeyStrings(90).sort()
160176
await putKeys(keys90, 60)
161177

162-
let it = state.list()
163-
let ret = await it.next()
164-
expect(ret.value.keys.sort()).toEqual(keys90)
165-
expect(await it.next()).toEqual({ done: true, value: undefined })
178+
let it, ret
179+
180+
// note: when listing all we are not in isolation
181+
it = state.list()
182+
ret = await it.next()
183+
expect(ret.value.keys.length).toBeGreaterThanOrEqual(90)
166184

167-
it = state.list({ match: 'list-*' })
185+
it = state.list({ match: `${uniquePrefix}__list_*` })
168186
ret = await it.next()
169187
expect(ret.value.keys.sort()).toEqual(keys90)
170188
expect(await it.next()).toEqual({ done: true, value: undefined })
171189

172-
it = state.list({ match: 'list-a*' })
190+
it = state.list({ match: `${uniquePrefix}__list_a*` })
173191
ret = await it.next()
174-
expect(ret.value.keys.sort()).toEqual(['list-a-0', 'list-a-26', 'list-a-52', 'list-a-78'])
192+
expect(ret.value.keys.sort()).toEqual([
193+
`${uniquePrefix}__list_a_0`,
194+
`${uniquePrefix}__list_a_26`,
195+
`${uniquePrefix}__list_a_52`,
196+
`${uniquePrefix}__list_a_78`
197+
])
175198
expect(await it.next()).toEqual({ done: true, value: undefined })
176199

177-
it = state.list({ match: 'list-*-1' })
200+
it = state.list({ match: `${uniquePrefix}__list_*_1` })
178201
ret = await it.next()
179-
expect(ret.value.keys.sort()).toEqual(['list-b-1'])
202+
expect(ret.value.keys.sort()).toEqual([`${uniquePrefix}__list_b_1`])
180203
expect(await it.next()).toEqual({ done: true, value: undefined })
181204

182205
// 2. test with many elements and large countHint
183206
const keys900 = genKeyStrings(900)
184207
await putKeys(keys900, 60)
185208

209+
// note: we can't list in isolation without prefix
186210
it = state.list({ countHint: 1000 })
187211
ret = await it.next()
188-
expect(ret.value.keys.length).toEqual(900)
189-
expect(await it.next()).toEqual({ done: true, value: undefined })
212+
expect(ret.value.keys.length).toBeGreaterThanOrEqual(900)
190213

191-
it = state.list({ countHint: 1000, match: 'list-*' })
214+
it = state.list({ countHint: 1000, match: `${uniquePrefix}__li*t_*` })
192215
ret = await it.next()
193216
expect(ret.value.keys.length).toEqual(900)
194217
expect(await it.next()).toEqual({ done: true, value: undefined })
195218

196-
it = state.list({ countHint: 1000, match: 'list-z*' })
219+
it = state.list({ countHint: 1000, match: `${uniquePrefix}__list_z*` })
197220
ret = await it.next()
198221
expect(ret.value.keys.length).toEqual(34)
199222
expect(await it.next()).toEqual({ done: true, value: undefined })
200223

201-
it = state.list({ match: 'list-*-1' })
224+
it = state.list({ match: `${uniquePrefix}__list_*_1` })
202225
ret = await it.next()
203-
expect(ret.value.keys.sort()).toEqual(['list-b-1'])
226+
expect(ret.value.keys.sort()).toEqual([`${uniquePrefix}__list_b_1`])
204227
expect(await it.next()).toEqual({ done: true, value: undefined })
205228

206229
// 3. test with many elements while iterating
207230
let iterations = 0
208231
let retArray = []
209-
for await (const { keys } of state.list()) {
232+
for await (const { keys } of state.list({ match: `${uniquePrefix}__l*st_*` })) {
210233
iterations++
211234
retArray.push(...keys)
212235
}
@@ -215,16 +238,7 @@ describe('e2e tests using OpenWhisk credentials (as env vars)', () => {
215238

216239
iterations = 0
217240
retArray = []
218-
for await (const { keys } of state.list({ match: 'list-*' })) {
219-
iterations++
220-
retArray.push(...keys)
221-
}
222-
expect(iterations).toBeGreaterThan(5) // should be around 9-10
223-
expect(retArray.length).toEqual(900)
224-
225-
iterations = 0
226-
retArray = []
227-
for await (const { keys } of state.list({ match: 'list-z*' })) {
241+
for await (const { keys } of state.list({ match: `${uniquePrefix}__list_z*` })) {
228242
iterations++
229243
retArray.push(...keys)
230244
}
@@ -233,7 +247,7 @@ describe('e2e tests using OpenWhisk credentials (as env vars)', () => {
233247

234248
iterations = 0
235249
retArray = []
236-
for await (const { keys } of state.list({ match: 'list-*-1' })) {
250+
for await (const { keys } of state.list({ match: `${uniquePrefix}__list_*_1` })) {
237251
iterations++
238252
retArray.push(...keys)
239253
}
@@ -244,12 +258,10 @@ describe('e2e tests using OpenWhisk credentials (as env vars)', () => {
244258
await putKeys(keys90, 1)
245259
await waitFor(2000)
246260

247-
it = state.list({ countHint: 1000 })
261+
it = state.list({ countHint: 1000, match: `${uniquePrefix}__list_*` })
248262
ret = await it.next()
249263
expect(ret.value.keys.length).toEqual(810) // 900 - 90
250264
expect(await it.next()).toEqual({ done: true, value: undefined })
251-
252-
await state.deleteAll()
253265
})
254266

255267
test('throw error when get/put with invalid keys', async () => {

0 commit comments

Comments
 (0)