Skip to main content

Synchronizing Test Executions Across Multiple Ports

ioBuster allows running a test across multiple ports for parellel execution. However, there are times users would like to synchronize test executions across all test ports running in a task, and utility.sync can be handy for this sceniario.

Introduction to utility.sync

Prerequisite

  • NFS server
  • Installed NFS clients and created an NFS mount on all host machiens

Please read Configure NFS to understand more details of setting up NFS server and client.

Usage

utility.sync function should be called in SyncSandbox.

utility.createSyncSandbox(() => {
utility.sync('hello sync')
})

Case 1: I want all test machines wait specific point.

utility.createSyncSandbox(() => {
doSomething()
utility.sync('wait here 1', () => {
console.log('do something')
})
doNextThing()
})

Case 2: I want all test machines wait specific point but only one function is called.

utility.createSyncSandbox(() => {
doSomething()
utility.sync(
'wait here 1',
() => {
console.log('do something')
},
{ exclusiveCount: 1 }
)
doNextThing()
})

Limitation

When using utility.sync all high-level functions must be executed using utility.createSyncSandbox. This ensures all exceptions will be caught properly, and it prevents unexpected hangs when utility.sync is used.

doThrowSomething()
utility.createSyncSandbox(() => {
utility.sync('wait here 1', () => {})
})

If doThrowSomething function throws an exception, other ports waiting on utility.createSyncSandbox will wait forever because other ports don't know if doThrowSomething threw an exception.

doThrowSomething()
utility.createSyncSandbox(
() => {
utility.sync('wait here 1', () => {})
},
{ timeout: 600 }
)

You can add timeout option for preventing unexpected hangs.

If you pass the function to utility.createSyncSandbox, utility.createSyncSandbox can handle exceptions properly.

utility.createSyncSandbox(
() => {
doThrowSomething()
utility.sync('wait here 1', () => {})
},
{ timeout: 600 }
)

Even though doThrowSomething function throws an exception, utility.createSyncSandbox can handle the exception and other ports can continue the journey except the port that had an exception.

Do NOT catch an exception for utility.sync or utility.createSyncSandbox. We can NOT guarantee of synchronization.

YOU SHOULD NOT DO THIS!

try {
utility.createSyncSandbox(() => {
utility.sync('boring', () => {})
})
} catch (e) {
// SHOULD NOT DO THIS
}
doWeirdThing()

YOU SHOULD NOT DO THIS!

utility.createSyncSandbox(() => {
try {
utility.sync('boring', () => {
throw something
})
} catch (e) {
// SHOULD NOT DO THIS!
}

try {
someThrowThing()
} catch (e) {
// it is OK
}

utility.sync('wait here', () => {})
// doWeirdThing() will be called immediately.
doWeirdThing()
})