@@ -14,7 +14,11 @@ import { promises as fs, createReadStream } from 'fs';
1414import { promisify } from 'util' ;
1515import path from 'path' ;
1616import os from 'os' ;
17- import { readReplLogfile , setTemporaryHomeDirectory } from './repl-helpers' ;
17+ import {
18+ readReplLogfile ,
19+ setTemporaryHomeDirectory ,
20+ useTmpdir ,
21+ } from './repl-helpers' ;
1822import { bson } from '@mongosh/service-provider-core' ;
1923import type { Server as HTTPServer } from 'http' ;
2024import { createServer as createHTTPServer } from 'http' ;
@@ -1363,7 +1367,7 @@ describe('e2e', function () {
13631367 let logBasePath : string ;
13641368 let historyPath : string ;
13651369 let readConfig : ( ) => Promise < any > ;
1366- let readLogFile : < T = LogEntry > ( ) => Promise < T [ ] > ;
1370+ let readLogFile : < T = LogEntry > ( path ?: string ) => Promise < T [ ] > ;
13671371 let startTestShell : ( ...extraArgs : string [ ] ) => Promise < TestShell > ;
13681372
13691373 beforeEach ( function ( ) {
@@ -1400,11 +1404,14 @@ describe('e2e', function () {
14001404 }
14011405 readConfig = async ( ) =>
14021406 EJSON . parse ( await fs . readFile ( configPath , 'utf8' ) ) ;
1403- readLogFile = async ( ) => {
1407+ readLogFile = async ( customBasePath ?: string ) => {
14041408 if ( ! shell . logId ) {
14051409 throw new Error ( 'Shell does not have a logId associated with it' ) ;
14061410 }
1407- const logPath = path . join ( logBasePath , `${ shell . logId } _log` ) ;
1411+ const logPath = path . join (
1412+ customBasePath ?? logBasePath ,
1413+ `${ shell . logId } _log`
1414+ ) ;
14081415 return readReplLogfile ( logPath ) ;
14091416 } ;
14101417 startTestShell = async ( ...extraArgs : string [ ] ) => {
@@ -1565,6 +1572,112 @@ describe('e2e', function () {
15651572 ) . to . have . lengthOf ( 1 ) ;
15661573 } ) ;
15671574
1575+ describe ( 'with custom log location' , function ( ) {
1576+ const customLogDir = useTmpdir ( ) ;
1577+
1578+ it ( 'fails with relative or invalid paths' , async function ( ) {
1579+ const globalConfig = path . join ( homedir , 'globalconfig.conf' ) ;
1580+ await fs . writeFile (
1581+ globalConfig ,
1582+ `mongosh:\n logLocation: "./some-relative-path"`
1583+ ) ;
1584+
1585+ shell = this . startTestShell ( {
1586+ args : [ '--nodb' ] ,
1587+ env : {
1588+ ...env ,
1589+ MONGOSH_GLOBAL_CONFIG_FILE_FOR_TESTING : globalConfig ,
1590+ } ,
1591+ forceTerminal : true ,
1592+ } ) ;
1593+ await shell . waitForPrompt ( ) ;
1594+ shell . assertContainsOutput ( 'Ignoring config option "logLocation"' ) ;
1595+ shell . assertContainsOutput (
1596+ 'must be a valid absolute path or empty'
1597+ ) ;
1598+
1599+ expect (
1600+ await shell . executeLine (
1601+ 'config.set("logLocation", "[123123123123]")'
1602+ )
1603+ ) . contains (
1604+ 'Cannot set option "logLocation": logLocation must be a valid absolute path or empty'
1605+ ) ;
1606+ } ) ;
1607+
1608+ it ( 'gets created according to logLocation, if set' , async function ( ) {
1609+ const globalConfig = path . join ( homedir , 'globalconfig.conf' ) ;
1610+ await fs . writeFile (
1611+ globalConfig ,
1612+ `mongosh:\n logLocation: "${ customLogDir . path } "`
1613+ ) ;
1614+
1615+ shell = this . startTestShell ( {
1616+ args : [ '--nodb' ] ,
1617+ env : {
1618+ ...env ,
1619+ MONGOSH_GLOBAL_CONFIG_FILE_FOR_TESTING : globalConfig ,
1620+ } ,
1621+ forceTerminal : true ,
1622+ } ) ;
1623+ await shell . waitForPrompt ( ) ;
1624+ expect (
1625+ await shell . executeLine ( 'config.get("logLocation")' )
1626+ ) . contains ( customLogDir . path ) ;
1627+
1628+ try {
1629+ await readLogFile ( ) ;
1630+ expect . fail ( 'expected to throw' ) ;
1631+ } catch ( error ) {
1632+ expect ( ( error as Error ) . message ) . includes (
1633+ 'no such file or directory'
1634+ ) ;
1635+ }
1636+
1637+ expect (
1638+ ( await readLogFile ( customLogDir . path ) ) . some (
1639+ ( log ) => log . attr ?. input === 'config.get("logLocation")'
1640+ )
1641+ ) . is . true ;
1642+ } ) ;
1643+
1644+ it ( 'setting location while running mongosh does not have an immediate effect on logging' , async function ( ) {
1645+ expect (
1646+ await shell . executeLine ( 'config.get("logLocation")' )
1647+ ) . does . not . contain ( customLogDir . path ) ;
1648+ const oldLogId = shell . logId ;
1649+
1650+ const oldLogEntries = await readLogFile ( ) ;
1651+ await shell . executeLine (
1652+ `config.set("logLocation", "${ customLogDir . path } ")`
1653+ ) ;
1654+
1655+ await shell . waitForPrompt ( ) ;
1656+ expect (
1657+ await shell . executeLine ( 'config.get("logLocation")' )
1658+ ) . contains ( customLogDir . path ) ;
1659+
1660+ expect ( shell . logId ) . equals ( oldLogId ) ;
1661+
1662+ const currentLogEntries = await readLogFile ( ) ;
1663+
1664+ try {
1665+ await readLogFile ( customLogDir . path ) ;
1666+ expect . fail ( 'expected to throw' ) ;
1667+ } catch ( error ) {
1668+ expect ( ( error as Error ) . message ) . includes (
1669+ 'no such file or directory'
1670+ ) ;
1671+ }
1672+ expect (
1673+ currentLogEntries . some (
1674+ ( log ) => log . attr ?. input === 'config.get("logLocation")'
1675+ )
1676+ ) . is . true ;
1677+ expect ( currentLogEntries . length - oldLogEntries . length ) . equals ( 2 ) ;
1678+ } ) ;
1679+ } ) ;
1680+
15681681 it ( 'creates a log file that keeps track of session events' , async function ( ) {
15691682 expect ( await shell . executeLine ( 'print(123 + 456)' ) ) . to . include ( '579' ) ;
15701683 const log = await readLogFile ( ) ;
0 commit comments