@@ -15,7 +15,11 @@ import { promisify } from 'util';
1515import path from 'path' ;
1616import os from 'os' ;
1717import type { MongoLogEntryFromFile } from './repl-helpers' ;
18- import { readReplLogFile , setTemporaryHomeDirectory } from './repl-helpers' ;
18+ import {
19+ readReplLogFile ,
20+ setTemporaryHomeDirectory ,
21+ useTmpdir ,
22+ } from './repl-helpers' ;
1923import { bson } from '@mongosh/service-provider-core' ;
2024import type { Server as HTTPServer } from 'http' ;
2125import { createServer as createHTTPServer } from 'http' ;
@@ -1356,7 +1360,9 @@ describe('e2e', function () {
13561360 let logBasePath : string ;
13571361 let historyPath : string ;
13581362 let readConfig : ( ) => Promise < any > ;
1359- let readLogFile : < T extends MongoLogEntryFromFile > ( ) => Promise < T [ ] > ;
1363+ let readLogFile : < T extends MongoLogEntryFromFile > (
1364+ customBasePath ?: string
1365+ ) => Promise < T [ ] > ;
13601366 let startTestShell : ( ...extraArgs : string [ ] ) => Promise < TestShell > ;
13611367
13621368 beforeEach ( function ( ) {
@@ -1393,11 +1399,16 @@ describe('e2e', function () {
13931399 }
13941400 readConfig = async ( ) =>
13951401 EJSON . parse ( await fs . readFile ( configPath , 'utf8' ) ) ;
1396- readLogFile = async < T extends MongoLogEntryFromFile > ( ) : Promise < T [ ] > => {
1402+ readLogFile = async < T extends MongoLogEntryFromFile > (
1403+ customBasePath ?: string
1404+ ) : Promise < T [ ] > => {
13971405 if ( ! shell . logId ) {
13981406 throw new Error ( 'Shell does not have a logId associated with it' ) ;
13991407 }
1400- const logPath = path . join ( logBasePath , `${ shell . logId } _log` ) ;
1408+ const logPath = path . join (
1409+ customBasePath ?? logBasePath ,
1410+ `${ shell . logId } _log`
1411+ ) ;
14011412 return readReplLogFile < T > ( logPath ) ;
14021413 } ;
14031414 startTestShell = async ( ...extraArgs : string [ ] ) => {
@@ -1557,6 +1568,112 @@ describe('e2e', function () {
15571568 ) . to . have . lengthOf ( 1 ) ;
15581569 } ) ;
15591570
1571+ describe ( 'with custom log location' , function ( ) {
1572+ const customLogDir = useTmpdir ( ) ;
1573+
1574+ it ( 'fails with relative or invalid paths' , async function ( ) {
1575+ const globalConfig = path . join ( homedir , 'globalconfig.conf' ) ;
1576+ await fs . writeFile (
1577+ globalConfig ,
1578+ `mongosh:\n logLocation: "./some-relative-path"`
1579+ ) ;
1580+
1581+ shell = this . startTestShell ( {
1582+ args : [ '--nodb' ] ,
1583+ env : {
1584+ ...env ,
1585+ MONGOSH_GLOBAL_CONFIG_FILE_FOR_TESTING : globalConfig ,
1586+ } ,
1587+ forceTerminal : true ,
1588+ } ) ;
1589+ await shell . waitForPrompt ( ) ;
1590+ shell . assertContainsOutput ( 'Ignoring config option "logLocation"' ) ;
1591+ shell . assertContainsOutput (
1592+ 'must be a valid absolute path or empty'
1593+ ) ;
1594+
1595+ expect (
1596+ await shell . executeLine (
1597+ 'config.set("logLocation", "[123123123123]")'
1598+ )
1599+ ) . contains (
1600+ 'Cannot set option "logLocation": logLocation must be a valid absolute path or empty'
1601+ ) ;
1602+ } ) ;
1603+
1604+ it ( 'gets created according to logLocation, if set' , async function ( ) {
1605+ const globalConfig = path . join ( homedir , 'globalconfig.conf' ) ;
1606+ await fs . writeFile (
1607+ globalConfig ,
1608+ `mongosh:\n logLocation: "${ customLogDir . path } "`
1609+ ) ;
1610+
1611+ shell = this . startTestShell ( {
1612+ args : [ '--nodb' ] ,
1613+ env : {
1614+ ...env ,
1615+ MONGOSH_GLOBAL_CONFIG_FILE_FOR_TESTING : globalConfig ,
1616+ } ,
1617+ forceTerminal : true ,
1618+ } ) ;
1619+ await shell . waitForPrompt ( ) ;
1620+ expect (
1621+ await shell . executeLine ( 'config.get("logLocation")' )
1622+ ) . contains ( customLogDir . path ) ;
1623+
1624+ try {
1625+ await readLogFile ( ) ;
1626+ expect . fail ( 'expected to throw' ) ;
1627+ } catch ( error ) {
1628+ expect ( ( error as Error ) . message ) . includes (
1629+ 'no such file or directory'
1630+ ) ;
1631+ }
1632+
1633+ expect (
1634+ ( await readLogFile ( customLogDir . path ) ) . some (
1635+ ( log ) => log . attr ?. input === 'config.get("logLocation")'
1636+ )
1637+ ) . is . true ;
1638+ } ) ;
1639+
1640+ it ( 'setting location while running mongosh does not have an immediate effect on logging' , async function ( ) {
1641+ expect (
1642+ await shell . executeLine ( 'config.get("logLocation")' )
1643+ ) . does . not . contain ( customLogDir . path ) ;
1644+ const oldLogId = shell . logId ;
1645+
1646+ const oldLogEntries = await readLogFile ( ) ;
1647+ await shell . executeLine (
1648+ `config.set("logLocation", "${ customLogDir . path } ")`
1649+ ) ;
1650+
1651+ await shell . waitForPrompt ( ) ;
1652+ expect (
1653+ await shell . executeLine ( 'config.get("logLocation")' )
1654+ ) . contains ( customLogDir . path ) ;
1655+
1656+ expect ( shell . logId ) . equals ( oldLogId ) ;
1657+
1658+ const currentLogEntries = await readLogFile ( ) ;
1659+
1660+ try {
1661+ await readLogFile ( customLogDir . path ) ;
1662+ expect . fail ( 'expected to throw' ) ;
1663+ } catch ( error ) {
1664+ expect ( ( error as Error ) . message ) . includes (
1665+ 'no such file or directory'
1666+ ) ;
1667+ }
1668+ expect (
1669+ currentLogEntries . some (
1670+ ( log ) => log . attr ?. input === 'config.get("logLocation")'
1671+ )
1672+ ) . is . true ;
1673+ expect ( currentLogEntries . length - oldLogEntries . length ) . equals ( 2 ) ;
1674+ } ) ;
1675+ } ) ;
1676+
15601677 it ( 'creates a log file that keeps track of session events' , async function ( ) {
15611678 expect ( await shell . executeLine ( 'print(123 + 456)' ) ) . to . include ( '579' ) ;
15621679 const log = await readLogFile ( ) ;
0 commit comments