Skip to content

Commit

Permalink
add environment variable options and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanwitt committed Jul 9, 2024
1 parent bbf2536 commit f9d973e
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 46 deletions.
75 changes: 38 additions & 37 deletions src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ export const defaults = Object.freeze({
unpair: false,

// Check
create: false
create: false,
overwrite: false
})

export function validateInteger (opt, name) {
Expand Down Expand Up @@ -89,55 +90,55 @@ export function getOptionsWithDefaults (options) {

const opt = {
// Shared
prefix: options.prefix === '' ? options.prefix : (options.prefix || defaults.prefix),
failSuffix: options.failSuffix || options['fail-suffix'] || defaults.failSuffix,
region: options.region || process.env.AWS_REGION || defaults.region,
quiet: options.quiet || defaults.quiet,
verbose: options.verbose || defaults.verbose,
fifo: options.fifo || defaults.fifo,
sentryDsn: options.sentryDsn || options['sentry-dsn'],
disableLog: options.disableLog || options['disable-log'] || defaults.disableLog,
includeFailed: options.includeFailed || options['include-failed'] || defaults.includeFailed,
includeDead: options.includeDead || options['include-dead'] || defaults.includeDead,
externalDedup: options.externalDedup || options['external-dedup'] || defaults.externalDedup,
dedupPeriod: options.dedupPeriod || options['dedup-period'] || defaults.dedupPeriod,
dedupStats: options.dedupStats || options['dedup-stats'] || defaults.dedupStats,
prefix: options.prefix === '' ? options.prefix : (options.prefix || process.env.QDONE_PREFIX || defaults.prefix),
failSuffix: options.failSuffix || options['fail-suffix'] || process.env.QDONE_FAIL_SUFFIX || defaults.failSuffix,
region: options.region || process.env.QDONE_REGION || process.env.AWS_REGION || defaults.region,
quiet: options.quiet || process.env.QDONE_QUIET === 'true' || defaults.quiet,
verbose: options.verbose || process.env.QDONE_VERBOSE === 'true' || defaults.verbose,
fifo: options.fifo || process.env.QDONE_FIFO === 'true' || defaults.fifo,
sentryDsn: options.sentryDsn || options['sentry-dsn'] || process.env.QDONE_SENTRY_DSN,
disableLog: options.disableLog || options['disable-log'] || process.env.QDONE_DISABLE_LOG === 'true' || defaults.disableLog,
includeFailed: options.includeFailed || options['include-failed'] || process.env.QDONE_INCLUDE_FAILED === 'true' || defaults.includeFailed,
includeDead: options.includeDead || options['include-dead'] || process.env.QDONE_INCLUDE_DEAD === 'true' || defaults.includeDead,
externalDedup: options.externalDedup || options['external-dedup'] || process.env.QDONE_EXTERNAL_DEDUP === 'true' || defaults.externalDedup,
dedupPeriod: options.dedupPeriod || options['dedup-period'] || process.env.QDONE_DEDUP_PERIOD || defaults.dedupPeriod,
dedupStats: options.dedupStats || options['dedup-stats'] || process.env.QDONE_DEDUP_STATS === 'true' || defaults.dedupStats,

// Cache
cacheUri: options.cacheUri || options['cache-uri'] || defaults.cacheUri,
cachePrefix: options.cachePrefix || options['cache-prefix'] || defaults.cachePrefix,
cacheTtlSeconds: options.cacheTtlSeconds || options['cache-ttl-seconds'] || defaults.cacheTtlSeconds,
cacheUri: options.cacheUri || options['cache-uri'] || process.env.QDONE_CACHE_URI || defaults.cacheUri,
cachePrefix: options.cachePrefix || options['cache-prefix'] || process.env.QDONE_CACHE_PREFIX || defaults.cachePrefix,
cacheTtlSeconds: options.cacheTtlSeconds || options['cache-ttl-seconds'] || process.env.QDONE_CACHE_TTL_SECONDS || defaults.cacheTtlSeconds,

// Enqueue
groupId: options.groupId || options['group-id'] || defaults.groupId,
groupId: options.groupId || options['group-id'] || process.env.QDONE_GROUP_ID || defaults.groupId,
groupIdPerMessage: false,
deduplicationId: options.deduplicationId || options['deduplication-id'] || defaults.deduplicationId,
dedupIdPerMessage: options.dedupIdPerMessage || options['dedup-id-per-message'] || defaults.dedupIdPerMessage,
messageRetentionPeriod: options.messageRetentionPeriod || options['message-retention-period'] || defaults.messageRetentionPeriod,
delay: options.delay || defaults.delay,
sendRetries: options['send-retries'] || defaults.sendRetries,
failDelay: options.failDelay || options['fail-delay'] || defaults.failDelay,
deduplicationId: options.deduplicationId || options['deduplication-id'] || process.env.QDONE_DEDUPLICATION_ID || defaults.deduplicationId,
dedupIdPerMessage: options.dedupIdPerMessage || options['dedup-id-per-message'] || process.env.QDONE_DEDUP_ID_PER_MESSAGE === 'true' || defaults.dedupIdPerMessage,
messageRetentionPeriod: options.messageRetentionPeriod || options['message-retention-period'] || process.env.QDONE_MESSAGE_RETENTION_PERIOD || defaults.messageRetentionPeriod,
delay: options.delay || process.env.QDONE_DELAY || defaults.delay,
sendRetries: options.sendRetries || options['send-retries'] || process.env.QDONE_SEND_RETRIES || defaults.sendRetries,
failDelay: options.failDelay || options['fail-delay'] || process.env.QDONE_FAIL_DELAY || defaults.failDelay,
dlq: dlq === false ? false : defaults.dlq,
dlqSuffix: options.dlqSuffix || options['dlq-suffix'] || defaults.dlqSuffix,
dlqAfter: options.dlqAfter || options['dlq-after'] || defaults.dlqAfter,
dlqSuffix: options.dlqSuffix || options['dlq-suffix'] || process.env.QDONE_DLQ_SUFFIX || defaults.dlqSuffix,
dlqAfter: options.dlqAfter || options['dlq-after'] || process.env.QDONE_DLQ_AFTER || defaults.dlqAfter,
tags: options.tags || undefined,

// Worker
waitTime: options.waitTime || options['wait-time'] || defaults.waitTime,
killAfter: options.killAfter || options['kill-after'] || defaults.killAfter,
archive: options.archive || defaults.archive,
activeOnly: options.activeOnly || options['active-only'] || defaults.activeOnly,
maxConcurrentJobs: options.maxConcurrentJobs || defaults.maxConcurrentJobs,
maxMemoryPercent: options.maxMemoryPercent || defaults.maxMemoryPercent,
waitTime: options.waitTime || options['wait-time'] || process.env.QDONE_WAIT_TIME || defaults.waitTime,
killAfter: options.killAfter || options['kill-after'] || process.env.QDONE_KILL_AFTER || defaults.killAfter,
archive: options.archive || process.env.QDONE_ARCHIVE === 'true' || defaults.archive,
activeOnly: options.activeOnly || options['active-only'] || process.env.QDONE_ACTIVE_ONLY === 'true' || defaults.activeOnly,
maxConcurrentJobs: options.maxConcurrentJobs || process.env.QDONE_MAX_CONCURRENT_JOBS || defaults.maxConcurrentJobs,
maxMemoryPercent: options.maxMemoryPercent || process.env.QDONE_MAX_MEMORY_PERCENT || defaults.maxMemoryPercent,

// Idle Queues
idleFor: options.idleFor || options['idle-for'] || defaults.idleFor,
delete: options.delete || defaults.delete,
unpair: options.unpair || defaults.unpair,
idleFor: options.idleFor || options['idle-for'] || process.env.QDONE_IDLE_FOR || defaults.idleFor,
delete: options.delete || process.env.QDONE_DELETE === 'true' || defaults.delete,
unpair: options.unpair || process.env.QDONE_UNPAIR === 'true' || defaults.unpair,

// Check
create: options.create || defaults.create,
overwrite: options.overwrite || defaults.overwrite
create: options.create || process.env.QDONE_CREATE === 'true' || defaults.create,
overwrite: options.overwrite || process.env.QDONE_OVERWRITE === 'true' || defaults.overwrite
}

// Setting this env here means we don't have to in AWS SDK constructors
Expand Down
132 changes: 123 additions & 9 deletions test/defaults.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { jest } from '@jest/globals'
import {
validateInteger,
validateMessageOptions,
getOptionsWithDefaults,
setupAWS,
setupVerbose
setupVerbose,
defaults
} from '../src/defaults.js'

describe('validateInteger', () => {
Expand Down Expand Up @@ -79,14 +81,6 @@ describe('getOptionsWithDefaults', () => {
})
})

describe('setupAWS', () => {
test('AWS_REGION should be set if options include region', () => {
const region = 'us-west-1'
setupAWS({ region })
expect(process.env.AWS_REGION).toEqual(region)
})
})

describe('setupVerbose', () => {
test('if stderr is a TTY then default to verbose', () => {
const originalIsTTY = process.stderr.isTTY
Expand All @@ -105,3 +99,123 @@ describe('setupVerbose', () => {
process.stderr.isTTY = originalIsTTY
})
})

describe('environment variables', () => {
const originalEnv = process.env

beforeEach(() => {
jest.resetModules()
process.env = { ...originalEnv }
})

afterEach(() => {
process.env = originalEnv
})

function testString (envName, apiName, val1, val2) {
test(envName, () => {
expect(getOptionsWithDefaults()[apiName]).toBe(defaults[apiName])
process.env[envName] = val1
expect(getOptionsWithDefaults({})[apiName]).toBe(val1)
expect(getOptionsWithDefaults({ [apiName]: val2 })[apiName]).toBe(val2)
})
}

function testBoolean (envName, apiName) {
test(envName, () => {
expect(getOptionsWithDefaults()[apiName]).toBe(false)
process.env[envName] = true
expect(getOptionsWithDefaults()[apiName]).toBe(false)
process.env[envName] = 'true'
expect(getOptionsWithDefaults()[apiName]).toBe(true)
})
}

function testInteger (envName, apiName, val1, val2) {
test(envName, () => {
expect(getOptionsWithDefaults()[apiName]).toBe(defaults[apiName])
process.env[envName] = val1
expect(getOptionsWithDefaults()[apiName]).toBe(val1)
expect(getOptionsWithDefaults({ [apiName]: val2 })[apiName]).toBe(val2)
process.env[envName] = 'invalid integer'
expect(() => getOptionsWithDefaults()).toThrow('integer')
})
}

testString('QDONE_PREFIX', 'prefix', 'qdone_custom_', 'custom_')
testString('QDONE_FAIL_SUFFIX', 'failSuffix', '_fail_custom', '_custom')

test('QDONE_REGION', () => {
expect(getOptionsWithDefaults().region).toBe('us-east-1')
process.env.AWS_REGION = 'us-east-2'
expect(getOptionsWithDefaults().region).toBe('us-east-2')
process.env.QDONE_REGION = 'us-west-1'
expect(getOptionsWithDefaults().region).toBe('us-west-1')
expect(getOptionsWithDefaults({ region: 'ap-southeast-1' }).region).toBe('ap-southeast-1')
expect(process.env.AWS_REGION).toBe('ap-southeast-1')
})

test('QDONE_QUIET / QDONE_VERBOSE', () => {
expect(getOptionsWithDefaults().quiet).toBe(false)
expect(getOptionsWithDefaults().verbose).toBe(false)
expect(getOptionsWithDefaults({ verbose: true }).verbose).toBe(true)
expect(getOptionsWithDefaults({ verbose: true }).quiet).toBe(false)
expect(getOptionsWithDefaults({ quiet: true }).verbose).toBe(false)
expect(getOptionsWithDefaults({ quiet: true }).quiet).toBe(true)
process.env.QDONE_VERBOSE = true
expect(getOptionsWithDefaults().verbose).toBe(false)
process.env.QDONE_VERBOSE = 'true'
expect(getOptionsWithDefaults().verbose).toBe(true)
expect(getOptionsWithDefaults().quiet).toBe(false)
process.env = originalEnv
process.env.QDONE_QUIET = 'true'
expect(getOptionsWithDefaults().quiet).toBe(true)
expect(getOptionsWithDefaults().verbose).toBe(false)
})

testBoolean('QDONE_FIFO', 'fifo')
testString('QDONE_SENTRY_DSN', 'sentryDsn', 'https://sentry.io/...', 'https://sentry.io/custom/...')
testBoolean('QDONE_DISABLE_LOG', 'disableLog')
testBoolean('QDONE_INCLUDE_FAILED', 'includeFailed')
testBoolean('QDONE_INCLUDE_DEAD', 'includeDead')

test('QDONE_EXTERNAL_DEDUP', () => {
expect(getOptionsWithDefaults().externalDedup).toBe(false)
process.env.QDONE_EXTERNAL_DEDUP = true
expect(getOptionsWithDefaults().externalDedup).toBe(false)
process.env.QDONE_EXTERNAL_DEDUP = 'true'
process.env.QDONE_CACHE_URI = 'redis://...'
expect(getOptionsWithDefaults().externalDedup).toBe(true)
})

testInteger('QDONE_DEDUP_PERIOD', 'dedupPeriod', 60 * 10, 60 * 20)
testBoolean('QDONE_DEDUP_STATS', 'dedupStats')
testString('QDONE_GROUP_ID', 'groupId', 'abcd123', 'xyz456')
testString('QDONE_DEDUPLICATION_ID', 'deduplicationId', 'abcd123', 'xyz456')
testBoolean('QDONE_DEDUP_ID_PER_MESSAGE', 'dedupIdPerMessage')
testInteger('QDONE_MESSAGE_RETENTION_PERIOD', 'messageRetentionPeriod', 1000, 2000)
testInteger('QDONE_DELAY', 'delay', 1000, 2000)
testInteger('QDONE_SEND_RETRIES', 'sendRetries', 10, 20)
testInteger('QDONE_FAIL_DELAY', 'failDelay', 1000, 2000)
testString('QDONE_DLQ_SUFFIX', 'dlqSuffix', '_custom', '_custom_too')
testInteger('QDONE_DLQ_AFTER', 'dlqAfter', 10, 20)
testInteger('QDONE_WAIT_TIME', 'waitTime', 10, 15)
testInteger('QDONE_KILL_AFTER', 'killAfter', 120, 300)
testBoolean('QDONE_ARCHIVE', 'archive')
testBoolean('QDONE_ACTIVE_ONLY', 'activeOnly')
testInteger('QDONE_MAX_CONCURRENT_JOBS', 'maxConcurrentJobs', 1000, 2000)
testInteger('QDONE_MAX_MEMORY_PERCENT', 'maxMemoryPercent', 80, 50)
testInteger('QDONE_IDLE_FOR', 'idleFor', 120, 420)
testBoolean('QDONE_DELETE', 'delete')
testBoolean('QDONE_UNPAIR', 'unpair')
testBoolean('QDONE_CREATE', 'create')
testBoolean('QDONE_OVERWRITE', 'overwrite')
})

describe('setupAWS', () => {
test('AWS_REGION should be set if options include region', () => {
const region = 'us-west-1'
setupAWS({ region })
expect(process.env.AWS_REGION).toEqual(region)
})
})

0 comments on commit f9d973e

Please sign in to comment.