mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-20 16:47:50 +02:00
UBERF-8425: Fix get pending workspace on CR (#8009)
This commit is contained in:
@@ -14,7 +14,15 @@
|
||||
//
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
import { Collection, Db } from 'mongodb'
|
||||
import { type WorkspaceMode, type WorkspaceUuid, type PersonUuid, SocialIdType, AccountRole } from '@hcengineering/core'
|
||||
import {
|
||||
type WorkspaceMode,
|
||||
type WorkspaceUuid,
|
||||
type PersonUuid,
|
||||
SocialIdType,
|
||||
AccountRole,
|
||||
type Version,
|
||||
type Data
|
||||
} from '@hcengineering/core'
|
||||
import {
|
||||
MongoDbCollection,
|
||||
AccountMongoDbCollection,
|
||||
@@ -683,7 +691,10 @@ describe('MongoAccountDB', () => {
|
||||
updateOne: jest.fn(),
|
||||
insertOne: jest.fn(),
|
||||
find: jest.fn(),
|
||||
ensureIndices: jest.fn()
|
||||
ensureIndices: jest.fn(),
|
||||
collection: {
|
||||
findOneAndUpdate: jest.fn()
|
||||
}
|
||||
}
|
||||
|
||||
mockWorkspaceMembers = {
|
||||
@@ -856,6 +867,260 @@ describe('MongoAccountDB', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('getPendingWorkspace', () => {
|
||||
const version: Data<Version> = { major: 1, minor: 0, patch: 0 }
|
||||
const processingTimeoutMs = 5000
|
||||
const wsLivenessMs = 300000 // 5 minutes
|
||||
const NOW = 1234567890000 // Fixed timestamp
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(Date, 'now').mockReturnValue(NOW)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('should get pending creation workspace', async () => {
|
||||
await accountDb.getPendingWorkspace('', version, 'create', processingTimeoutMs)
|
||||
|
||||
expect(accountDb.workspace.collection.findOneAndUpdate).toHaveBeenCalledWith(
|
||||
{
|
||||
$and: [
|
||||
{ 'status.mode': { $ne: 'manual-creation' } },
|
||||
{ $or: [{ 'status.mode': { $in: ['pending-creation', 'creating'] } }] },
|
||||
{
|
||||
$or: [{ 'status.processingAttempts': { $exists: false } }, { 'status.processingAttempts': { $lte: 3 } }]
|
||||
},
|
||||
{ $or: [{ region: { $exists: false } }, { region: '' }] },
|
||||
{
|
||||
$or: [
|
||||
{ 'status.lastProcessingTime': { $exists: false } },
|
||||
{ 'status.lastProcessingTime': { $lt: NOW - processingTimeoutMs } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
'status.processingAttempts': 1
|
||||
},
|
||||
$set: {
|
||||
'status.lastProcessingTime': NOW
|
||||
}
|
||||
},
|
||||
{
|
||||
returnDocument: 'after',
|
||||
sort: {
|
||||
'status.lastVisit': -1
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should get workspace pending upgrade', async () => {
|
||||
await accountDb.getPendingWorkspace('', version, 'upgrade', processingTimeoutMs, wsLivenessMs)
|
||||
|
||||
expect(accountDb.workspace.collection.findOneAndUpdate).toHaveBeenCalledWith(
|
||||
{
|
||||
$and: [
|
||||
{ 'status.mode': { $ne: 'manual-creation' } },
|
||||
{
|
||||
$or: [
|
||||
{
|
||||
$and: [
|
||||
{
|
||||
$or: [{ 'status.isDisabled': false }, { 'status.isDisabled': { $exists: false } }]
|
||||
},
|
||||
{
|
||||
$or: [{ 'status.mode': 'active' }, { 'status.mode': { $exists: false } }]
|
||||
},
|
||||
{
|
||||
$or: [
|
||||
{ 'status.versionMajor': { $lt: version.major } },
|
||||
{ 'status.versionMajor': version.major, 'status.versionMinor': { $lt: version.minor } },
|
||||
{
|
||||
'status.versionMajor': version.major,
|
||||
'status.versionMinor': version.minor,
|
||||
'status.versionPatch': { $lt: version.patch }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'status.lastVisit': { $gt: NOW - wsLivenessMs }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$or: [{ 'status.isDisabled': false }, { 'status.isDisabled': { $exists: false } }],
|
||||
'status.mode': 'upgrading'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$or: [{ 'status.processingAttempts': { $exists: false } }, { 'status.processingAttempts': { $lte: 3 } }]
|
||||
},
|
||||
{ $or: [{ region: { $exists: false } }, { region: '' }] },
|
||||
{
|
||||
$or: [
|
||||
{ 'status.lastProcessingTime': { $exists: false } },
|
||||
{ 'status.lastProcessingTime': { $lt: NOW - processingTimeoutMs } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
'status.processingAttempts': 1
|
||||
},
|
||||
$set: {
|
||||
'status.lastProcessingTime': NOW
|
||||
}
|
||||
},
|
||||
{
|
||||
returnDocument: 'after',
|
||||
sort: {
|
||||
'status.lastVisit': -1
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should get workspace for all+backup operations', async () => {
|
||||
await accountDb.getPendingWorkspace('', version, 'all+backup', processingTimeoutMs)
|
||||
|
||||
expect(accountDb.workspace.collection.findOneAndUpdate).toHaveBeenCalledWith(
|
||||
{
|
||||
$and: [
|
||||
{ 'status.mode': { $ne: 'manual-creation' } },
|
||||
{
|
||||
$or: [
|
||||
{ 'status.mode': { $in: ['pending-creation', 'creating'] } },
|
||||
{
|
||||
$and: [
|
||||
{
|
||||
$or: [{ 'status.isDisabled': false }, { 'status.isDisabled': { $exists: false } }]
|
||||
},
|
||||
{
|
||||
$or: [{ 'status.mode': 'active' }, { 'status.mode': { $exists: false } }]
|
||||
},
|
||||
{
|
||||
$or: [
|
||||
{ 'status.versionMajor': { $lt: version.major } },
|
||||
{ 'status.versionMajor': version.major, 'status.versionMinor': { $lt: version.minor } },
|
||||
{
|
||||
'status.versionMajor': version.major,
|
||||
'status.versionMinor': version.minor,
|
||||
'status.versionPatch': { $lt: version.patch }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$or: [{ 'status.isDisabled': false }, { 'status.isDisabled': { $exists: false } }],
|
||||
'status.mode': 'upgrading'
|
||||
},
|
||||
{
|
||||
'status.mode': {
|
||||
$in: [
|
||||
'migration-backup',
|
||||
'migration-pending-backup',
|
||||
'migration-clean',
|
||||
'migration-pending-clean'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'status.mode': {
|
||||
$in: [
|
||||
'archiving-pending-backup',
|
||||
'archiving-backup',
|
||||
'archiving-pending-clean',
|
||||
'archiving-clean'
|
||||
]
|
||||
}
|
||||
},
|
||||
{ 'status.mode': { $in: ['pending-restore', 'restoring'] } },
|
||||
{ 'status.mode': { $in: ['pending-deletion', 'deleting'] } }
|
||||
]
|
||||
},
|
||||
{
|
||||
$or: [{ 'status.processingAttempts': { $exists: false } }, { 'status.processingAttempts': { $lte: 3 } }]
|
||||
},
|
||||
{ $or: [{ region: { $exists: false } }, { region: '' }] },
|
||||
{
|
||||
$or: [
|
||||
{ 'status.lastProcessingTime': { $exists: false } },
|
||||
{ 'status.lastProcessingTime': { $lt: NOW - processingTimeoutMs } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
'status.processingAttempts': 1
|
||||
},
|
||||
$set: {
|
||||
'status.lastProcessingTime': NOW
|
||||
}
|
||||
},
|
||||
{
|
||||
returnDocument: 'after',
|
||||
sort: {
|
||||
'status.lastVisit': -1
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should filter by region when specified', async () => {
|
||||
const region = 'us-east-1'
|
||||
await accountDb.getPendingWorkspace(region, version, 'create', processingTimeoutMs)
|
||||
|
||||
expect(accountDb.workspace.collection.findOneAndUpdate).toHaveBeenCalledWith(
|
||||
{
|
||||
$and: [
|
||||
{ 'status.mode': { $ne: 'manual-creation' } },
|
||||
{ $or: [{ 'status.mode': { $in: ['pending-creation', 'creating'] } }] },
|
||||
{
|
||||
$or: [{ 'status.processingAttempts': { $exists: false } }, { 'status.processingAttempts': { $lte: 3 } }]
|
||||
},
|
||||
{ region },
|
||||
{
|
||||
$or: [
|
||||
{ 'status.lastProcessingTime': { $exists: false } },
|
||||
{ 'status.lastProcessingTime': { $lt: NOW - processingTimeoutMs } }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
'status.processingAttempts': 1
|
||||
},
|
||||
$set: {
|
||||
'status.lastProcessingTime': NOW
|
||||
}
|
||||
},
|
||||
{
|
||||
returnDocument: 'after',
|
||||
sort: {
|
||||
'status.lastVisit': -1
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should handle undefined result', async () => {
|
||||
;(accountDb.workspace.collection.findOneAndUpdate as jest.Mock).mockResolvedValue(null)
|
||||
|
||||
const result = await accountDb.getPendingWorkspace('', version, 'create', processingTimeoutMs)
|
||||
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('createWorkspace', () => {
|
||||
it('should create workspace and status', async () => {
|
||||
const workspaceData = {
|
||||
|
||||
@@ -510,6 +510,7 @@ describe('PostgresAccountDB', () => {
|
||||
describe('getPendingWorkspace', () => {
|
||||
const version: Data<Version> = { major: 1, minor: 0, patch: 0 }
|
||||
const processingTimeoutMs = 5000
|
||||
const wsLivenessMs = 300000 // 5 minutes
|
||||
const NOW = 1234567890000 // Fixed timestamp
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -524,6 +525,280 @@ describe('PostgresAccountDB', () => {
|
||||
await accountDb.getPendingWorkspace('', version, 'create', processingTimeoutMs)
|
||||
|
||||
expect(mockClient.unsafe.mock.calls[0][0].replace(/\s+/g, ' ')).toEqual(
|
||||
`SELECT
|
||||
w.uuid,
|
||||
w.name,
|
||||
w.url,
|
||||
w.branding,
|
||||
w.location,
|
||||
w.region,
|
||||
w.created_by,
|
||||
w.created_on,
|
||||
w.billing_account,
|
||||
json_build_object(
|
||||
'mode', s.mode,
|
||||
'processing_progress', s.processing_progress,
|
||||
'version_major', s.version_major,
|
||||
'version_minor', s.version_minor,
|
||||
'version_patch', s.version_patch,
|
||||
'last_processing_time', s.last_processing_time,
|
||||
'last_visit', s.last_visit,
|
||||
'is_disabled', s.is_disabled,
|
||||
'processing_attempts', s.processing_attempts,
|
||||
'processing_message', s.processing_message,
|
||||
'backup_info', s.backup_info
|
||||
) status
|
||||
FROM global_account.workspace as w
|
||||
INNER JOIN global_account.workspace_status as s ON s.workspace_uuid = w.uuid
|
||||
WHERE s.mode IN ('pending-creation', 'creating')
|
||||
AND s.mode <> 'manual-creation'
|
||||
AND (s.processing_attempts IS NULL OR s.processing_attempts <= 3)
|
||||
AND (s.last_processing_time IS NULL OR s.last_processing_time < $1)
|
||||
AND (w.region IS NULL OR w.region = '')
|
||||
ORDER BY s.last_visit DESC
|
||||
LIMIT 1
|
||||
FOR UPDATE SKIP LOCKED`.replace(/\s+/g, ' ')
|
||||
)
|
||||
expect(mockClient.unsafe.mock.calls[0][1]).toEqual([NOW - processingTimeoutMs])
|
||||
})
|
||||
|
||||
it('should get workspace pending upgrade', async () => {
|
||||
await accountDb.getPendingWorkspace('', version, 'upgrade', processingTimeoutMs, wsLivenessMs)
|
||||
|
||||
expect(
|
||||
mockClient.unsafe.mock.calls[0][0].replace(/\s+/g, ' ').replace(/\(\s/g, '(').replace(/\s\)/g, ')')
|
||||
).toEqual(
|
||||
`SELECT
|
||||
w.uuid,
|
||||
w.name,
|
||||
w.url,
|
||||
w.branding,
|
||||
w.location,
|
||||
w.region,
|
||||
w.created_by,
|
||||
w.created_on,
|
||||
w.billing_account,
|
||||
json_build_object(
|
||||
'mode', s.mode,
|
||||
'processing_progress', s.processing_progress,
|
||||
'version_major', s.version_major,
|
||||
'version_minor', s.version_minor,
|
||||
'version_patch', s.version_patch,
|
||||
'last_processing_time', s.last_processing_time,
|
||||
'last_visit', s.last_visit,
|
||||
'is_disabled', s.is_disabled,
|
||||
'processing_attempts', s.processing_attempts,
|
||||
'processing_message', s.processing_message,
|
||||
'backup_info', s.backup_info
|
||||
) status
|
||||
FROM global_account.workspace as w
|
||||
INNER JOIN global_account.workspace_status as s ON s.workspace_uuid = w.uuid
|
||||
WHERE (
|
||||
(
|
||||
(s.is_disabled = FALSE OR s.is_disabled IS NULL)
|
||||
AND (s.mode = 'active' OR s.mode IS NULL)
|
||||
AND (
|
||||
s.version_major < $1
|
||||
OR (s.version_major = $1 AND s.version_minor < $2)
|
||||
OR (s.version_major = $1 AND s.version_minor = $2 AND s.version_patch < $3)
|
||||
)
|
||||
AND s.last_visit > $4
|
||||
)
|
||||
OR
|
||||
(
|
||||
(s.is_disabled = FALSE OR s.is_disabled IS NULL)
|
||||
AND s.mode = 'upgrading'
|
||||
)
|
||||
)
|
||||
AND s.mode <> 'manual-creation'
|
||||
AND (s.processing_attempts IS NULL OR s.processing_attempts <= 3)
|
||||
AND (s.last_processing_time IS NULL OR s.last_processing_time < $5)
|
||||
AND (w.region IS NULL OR w.region = '')
|
||||
ORDER BY s.last_visit DESC
|
||||
LIMIT 1
|
||||
FOR UPDATE SKIP LOCKED`
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/\(\s/g, '(')
|
||||
.replace(/\s\)/g, ')')
|
||||
)
|
||||
expect(mockClient.unsafe.mock.calls[0][1]).toEqual([
|
||||
version.major,
|
||||
version.minor,
|
||||
version.patch,
|
||||
NOW - wsLivenessMs,
|
||||
NOW - processingTimeoutMs
|
||||
])
|
||||
})
|
||||
|
||||
it('should get workspace for all operations', async () => {
|
||||
await accountDb.getPendingWorkspace('', version, 'all', processingTimeoutMs, wsLivenessMs)
|
||||
|
||||
expect(
|
||||
mockClient.unsafe.mock.calls[0][0].replace(/\s+/g, ' ').replace(/\(\s/g, '(').replace(/\s\)/g, ')')
|
||||
).toEqual(
|
||||
`SELECT
|
||||
w.uuid,
|
||||
w.name,
|
||||
w.url,
|
||||
w.branding,
|
||||
w.location,
|
||||
w.region,
|
||||
w.created_by,
|
||||
w.created_on,
|
||||
w.billing_account,
|
||||
json_build_object(
|
||||
'mode', s.mode,
|
||||
'processing_progress', s.processing_progress,
|
||||
'version_major', s.version_major,
|
||||
'version_minor', s.version_minor,
|
||||
'version_patch', s.version_patch,
|
||||
'last_processing_time', s.last_processing_time,
|
||||
'last_visit', s.last_visit,
|
||||
'is_disabled', s.is_disabled,
|
||||
'processing_attempts', s.processing_attempts,
|
||||
'processing_message', s.processing_message,
|
||||
'backup_info', s.backup_info
|
||||
) status
|
||||
FROM global_account.workspace as w
|
||||
INNER JOIN global_account.workspace_status as s ON s.workspace_uuid = w.uuid
|
||||
WHERE (
|
||||
s.mode IN ('pending-creation', 'creating')
|
||||
OR
|
||||
(
|
||||
(
|
||||
(s.is_disabled = FALSE OR s.is_disabled IS NULL)
|
||||
AND (s.mode = 'active' OR s.mode IS NULL)
|
||||
AND (
|
||||
s.version_major < $1
|
||||
OR (s.version_major = $1 AND s.version_minor < $2)
|
||||
OR (s.version_major = $1 AND s.version_minor = $2 AND s.version_patch < $3)
|
||||
)
|
||||
AND s.last_visit > $4
|
||||
)
|
||||
OR
|
||||
(
|
||||
(s.is_disabled = FALSE OR s.is_disabled IS NULL)
|
||||
AND s.mode = 'upgrading'
|
||||
)
|
||||
)
|
||||
)
|
||||
AND s.mode <> 'manual-creation'
|
||||
AND (s.processing_attempts IS NULL OR s.processing_attempts <= 3)
|
||||
AND (s.last_processing_time IS NULL OR s.last_processing_time < $5)
|
||||
AND (w.region IS NULL OR w.region = '')
|
||||
ORDER BY s.last_visit DESC
|
||||
LIMIT 1
|
||||
FOR UPDATE SKIP LOCKED`
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/\(\s/g, '(')
|
||||
.replace(/\s\)/g, ')')
|
||||
)
|
||||
expect(mockClient.unsafe.mock.calls[0][1]).toEqual([
|
||||
version.major,
|
||||
version.minor,
|
||||
version.patch,
|
||||
NOW - wsLivenessMs,
|
||||
NOW - processingTimeoutMs
|
||||
])
|
||||
})
|
||||
|
||||
it('should get workspace for all+backup operations', async () => {
|
||||
await accountDb.getPendingWorkspace('', version, 'all+backup', processingTimeoutMs, wsLivenessMs)
|
||||
|
||||
expect(
|
||||
mockClient.unsafe.mock.calls[0][0].replace(/\s+/g, ' ').replace(/\(\s/g, '(').replace(/\s\)/g, ')')
|
||||
).toEqual(
|
||||
`SELECT
|
||||
w.uuid,
|
||||
w.name,
|
||||
w.url,
|
||||
w.branding,
|
||||
w.location,
|
||||
w.region,
|
||||
w.created_by,
|
||||
w.created_on,
|
||||
w.billing_account,
|
||||
json_build_object(
|
||||
'mode', s.mode,
|
||||
'processing_progress', s.processing_progress,
|
||||
'version_major', s.version_major,
|
||||
'version_minor', s.version_minor,
|
||||
'version_patch', s.version_patch,
|
||||
'last_processing_time', s.last_processing_time,
|
||||
'last_visit', s.last_visit,
|
||||
'is_disabled', s.is_disabled,
|
||||
'processing_attempts', s.processing_attempts,
|
||||
'processing_message', s.processing_message,
|
||||
'backup_info', s.backup_info
|
||||
) status
|
||||
FROM global_account.workspace as w
|
||||
INNER JOIN global_account.workspace_status as s ON s.workspace_uuid = w.uuid
|
||||
WHERE (
|
||||
s.mode IN ('pending-creation', 'creating')
|
||||
OR
|
||||
(
|
||||
(
|
||||
(s.is_disabled = FALSE OR s.is_disabled IS NULL)
|
||||
AND (s.mode = 'active' OR s.mode IS NULL)
|
||||
AND (
|
||||
s.version_major < $1
|
||||
OR (s.version_major = $1 AND s.version_minor < $2)
|
||||
OR (s.version_major = $1 AND s.version_minor = $2 AND s.version_patch < $3)
|
||||
)
|
||||
AND s.last_visit > $4
|
||||
)
|
||||
OR
|
||||
(
|
||||
(s.is_disabled = FALSE OR s.is_disabled IS NULL)
|
||||
AND s.mode = 'upgrading'
|
||||
)
|
||||
)
|
||||
OR
|
||||
s.mode IN (
|
||||
'migration-backup',
|
||||
'migration-pending-backup',
|
||||
'migration-clean',
|
||||
'migration-pending-clean'
|
||||
)
|
||||
OR
|
||||
s.mode IN (
|
||||
'archiving-pending-backup',
|
||||
'archiving-backup',
|
||||
'archiving-pending-clean',
|
||||
'archiving-clean'
|
||||
)
|
||||
OR
|
||||
s.mode IN ('pending-restore', 'restoring')
|
||||
OR
|
||||
s.mode IN ('pending-deletion', 'deleting')
|
||||
)
|
||||
AND s.mode <> 'manual-creation'
|
||||
AND (s.processing_attempts IS NULL OR s.processing_attempts <= 3)
|
||||
AND (s.last_processing_time IS NULL OR s.last_processing_time < $5)
|
||||
AND (w.region IS NULL OR w.region = '')
|
||||
ORDER BY s.last_visit DESC
|
||||
LIMIT 1
|
||||
FOR UPDATE SKIP LOCKED`
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/\(\s/g, '(')
|
||||
.replace(/\s\)/g, ')')
|
||||
)
|
||||
expect(mockClient.unsafe.mock.calls[0][1]).toEqual([
|
||||
version.major,
|
||||
version.minor,
|
||||
version.patch,
|
||||
NOW - wsLivenessMs,
|
||||
NOW - processingTimeoutMs
|
||||
])
|
||||
})
|
||||
|
||||
it('should filter by region when specified', async () => {
|
||||
const region = 'us-east-1'
|
||||
await accountDb.getPendingWorkspace(region, version, 'create', processingTimeoutMs)
|
||||
|
||||
expect(
|
||||
mockClient.unsafe.mock.calls[0][0].replace(/\s+/g, ' ').replace(/\(\s/g, '(').replace(/\s\)/g, ')')
|
||||
).toEqual(
|
||||
`SELECT
|
||||
w.uuid,
|
||||
w.name,
|
||||
@@ -553,29 +828,44 @@ describe('PostgresAccountDB', () => {
|
||||
AND s.mode <> 'manual-creation'
|
||||
AND (s.processing_attempts IS NULL OR s.processing_attempts <= 3)
|
||||
AND (s.last_processing_time IS NULL OR s.last_processing_time < $1)
|
||||
AND (w.region IS NULL OR w.region = '')
|
||||
AND region = $2
|
||||
ORDER BY s.last_visit DESC
|
||||
LIMIT 1
|
||||
FOR UPDATE SKIP LOCKED`.replace(/\s+/g, ' ')
|
||||
FOR UPDATE SKIP LOCKED`
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/\(\s/g, '(')
|
||||
.replace(/\s\)/g, ')')
|
||||
)
|
||||
expect(mockClient.unsafe.mock.calls[0][1]).toEqual([NOW - processingTimeoutMs])
|
||||
expect(mockClient.unsafe.mock.calls[0][1]).toEqual([NOW - processingTimeoutMs, region])
|
||||
})
|
||||
|
||||
// Should also verify update after fetch
|
||||
it('should update processing attempts and time after fetch', async () => {
|
||||
const wsUuid = 'ws1'
|
||||
mockClient.unsafe.mockResolvedValueOnce([{ uuid: wsUuid }]) // Mock the fetch result
|
||||
mockClient.unsafe.mockResolvedValueOnce([{ uuid: wsUuid }])
|
||||
|
||||
await accountDb.getPendingWorkspace('', version, 'create', processingTimeoutMs)
|
||||
|
||||
// Verify the update was called
|
||||
expect(mockClient.unsafe.mock.calls[1][0].replace(/\s+/g, ' ')).toEqual(
|
||||
expect(
|
||||
mockClient.unsafe.mock.calls[1][0].replace(/\s+/g, ' ').replace(/\(\s/g, '(').replace(/\s\)/g, ')')
|
||||
).toEqual(
|
||||
`UPDATE global_account.workspace_status
|
||||
SET processing_attempts = processing_attempts + 1, "last_processing_time" = $1
|
||||
WHERE workspace_uuid = $2`.replace(/\s+/g, ' ')
|
||||
WHERE workspace_uuid = $2`
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/\(\s/g, '(')
|
||||
.replace(/\s\)/g, ')')
|
||||
)
|
||||
expect(mockClient.unsafe.mock.calls[1][1]).toEqual([NOW, wsUuid])
|
||||
})
|
||||
|
||||
it('should handle null result', async () => {
|
||||
mockClient.unsafe.mockResolvedValueOnce([])
|
||||
|
||||
const result = await accountDb.getPendingWorkspace('', version, 'create', processingTimeoutMs)
|
||||
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ export class PostgresAccountDB implements AccountDB {
|
||||
const archivingSql =
|
||||
"s.mode IN ('archiving-pending-backup', 'archiving-backup', 'archiving-pending-clean', 'archiving-clean')"
|
||||
const versionSql =
|
||||
'(s.version_major < $1) OR (s.version_major = $1 AND s.version_minor < $2) OR (s.version_major = $1 AND s.version_minor = $2 AND s.version_patch < $3)'
|
||||
'(s.version_major < $1 OR (s.version_major = $1 AND s.version_minor < $2) OR (s.version_major = $1 AND s.version_minor = $2 AND s.version_patch < $3))'
|
||||
const pendingUpgradeSql = `(((s.is_disabled = FALSE OR s.is_disabled IS NULL) AND (s.mode = 'active' OR s.mode IS NULL) AND ${versionSql} ${wsLivenessMs !== undefined ? 'AND s.last_visit > $4' : ''}) OR ((s.is_disabled = FALSE OR s.is_disabled IS NULL) AND s.mode = 'upgrading'))`
|
||||
let operationSql: string = ''
|
||||
switch (operation) {
|
||||
|
||||
Reference in New Issue
Block a user