Files
Xen-Orchestra-xen-orchestra…/@xen-orchestra/vmware-explorer/soap/specs.test.mjs
Florent BEAUCHAMP 3bf50c38ee fix(vmware-explorer): fixes omnibus (#10363)
This branch is a reliability overhaul of the ESXi/vSphere source side of V2V, plus a scope reduction of the package. The SOAP plumbing is rewritten:

    VimClient wraps @vates/node-vsphere-soap in a promise API with one emitter per call (no more cross-talk between concurrent calls, no listener leak) and a pTimeout;
    vim25 faults are now parsed (_parseFault.mjs) so callers get a real fault type instead of task execution failed;
    the library no longer throws from async callbacks (which killed xo-server) and its beforeExit logout hook is per-client instead of removeAllListeners.
    Request specs are built in explicit schema order (soap/specs.mjs) with xsi:type, and property values are normalized (soap/normalize.mjs) so search() and the new #retrieveProperty share one shape.
    search() now paginates, cancels the retrieval and destroys the container view.
    Datastore HTTP downloads get session-cookie reuse, retry with jittered backoff, a headers-only timeout, and range-honouring validation.
    Task waiting polls with backoff and per-operation timeouts (6 h for snapshot consolidation).
    nbdkit servers are memoized by a key that includes the export options, the readiness wait races the process death instead of sleeping 2 s
    the password file is 0600 and unlinked
    the thumbprint is read over TLS in-process instead of two openssl spawns.
    The old VHD-over-datastore readers (VhdEsxi*, Datastore*, openDeltaVmdkAsVhd) are deleted, hence the majo, rleaving the vddk/NBD path with a COWD grain-directory parser as data-map fallback.
    ~1.7k lines of unit tests are added.
2026-09-11 17:36:38 +02:00

90 lines
2.8 KiB
JavaScript

import assert from 'node:assert/strict'
import { describe, it } from 'node:test'
import {
moRef,
objectSpec,
orderedChildren,
propertyFilterSpec,
propertySpec,
retrieveOptions,
traversalSpec,
} from './specs.mjs'
describe('moRef', function () {
it('carries the type of the object', function () {
assert.deepEqual(moRef('VirtualMachine', 'vm-42'), { attributes: { type: 'VirtualMachine' }, $value: 'vm-42' })
})
})
describe('orderedChildren', function () {
const ORDER = Object.freeze(['first', 'second', 'third'])
it('emits the keys in schema order, whatever the order they are given in', function () {
const node = orderedChildren(ORDER, 'SomeType', { third: 3, first: 1 })
// the insertion order of the keys is what the library turns into element order
assert.deepEqual(Object.keys(node), ['attributes', 'first', 'third'])
assert.deepEqual(node, { attributes: { 'xsi:type': 'SomeType' }, first: 1, third: 3 })
})
it('skips the values which are not set', function () {
assert.deepEqual(orderedChildren(ORDER, undefined, { first: undefined, second: null, third: 0 }), { third: 0 })
})
it('refuses an unknown element', function () {
assert.throws(() => orderedChildren(ORDER, 'SomeType', { frist: 1 }), {
code: 'BAD_VIM25_SPEC',
message: 'unknown element(s) for this type: frist',
})
})
it('ignores an unknown element which is not set', function () {
assert.deepEqual(orderedChildren(ORDER, undefined, { frist: undefined }), {})
})
it('omits the type when there is none to declare', function () {
assert.deepEqual(Object.keys(orderedChildren(ORDER, undefined, { first: 1 })), ['first'])
})
})
describe('property collector specs', function () {
it('builds a PropertySpec', function () {
assert.deepEqual(propertySpec({ pathSet: ['config'], type: 'VirtualMachine' }), {
attributes: { 'xsi:type': 'PropertySpec' },
type: 'VirtualMachine',
pathSet: ['config'],
})
})
it('builds an ObjectSpec', function () {
const spec = objectSpec({ skip: false, obj: moRef('Task', 'task-1') })
assert.deepEqual(Object.keys(spec), ['attributes', 'obj', 'skip'])
assert.equal(spec.skip, false)
})
it('builds a TraversalSpec', function () {
assert.deepEqual(Object.keys(traversalSpec({ path: 'view', name: 'traverseEntities', type: 'ContainerView' })), [
'attributes',
'name',
'type',
'path',
])
})
it('builds a PropertyFilterSpec', function () {
assert.deepEqual(
Object.keys(propertyFilterSpec({ objectSet: [objectSpec({ obj: moRef('Task', 'task-1') })], propSet: [] })),
['attributes', 'propSet', 'objectSet']
)
})
it('builds RetrieveOptions', function () {
assert.deepEqual(retrieveOptions({ maxObjects: 100 }), {
attributes: { 'xsi:type': 'RetrieveOptions' },
maxObjects: 100,
})
})
})