@@ -462,6 +462,44 @@ func TestQueryServerPropertyReturnsColumnName(t *testing.T) {
462462 }
463463}
464464
465+ func TestSqlCmdOutputAndError (t * testing.T ) {
466+ s , outfile , errfile := setupSqlcmdWithFileErrorOutput (t )
467+ defer os .Remove (outfile .Name ())
468+ defer os .Remove (errfile .Name ())
469+ s .Query = "select $(X"
470+ err := s .Run (true , false )
471+ if assert .NoError (t , err , "s.Run(once = true)" ) {
472+ bytes , err := os .ReadFile (errfile .Name ())
473+ if assert .NoError (t , err , "os.ReadFile" ) {
474+ assert .Equal (t , "Sqlcmd: Error: Syntax error at line 1." + SqlcmdEol , string (bytes ), "Expected syntax error not received for query execution" )
475+ }
476+ }
477+ s .Query = "select '1'"
478+ err = s .Run (true , false )
479+ if assert .NoError (t , err , "s.Run(once = true)" ) {
480+ bytes , err := os .ReadFile (outfile .Name ())
481+ if assert .NoError (t , err , "os.ReadFile" ) {
482+ assert .Equal (t , "1" + SqlcmdEol + SqlcmdEol + "(1 row affected)" + SqlcmdEol , string (bytes ), "Unexpected output for query execution" )
483+ }
484+ }
485+
486+ s , outfile , errfile = setupSqlcmdWithFileErrorOutput (t )
487+ defer os .Remove (outfile .Name ())
488+ defer os .Remove (errfile .Name ())
489+ dataPath := "testdata" + string (os .PathSeparator )
490+ err = s .IncludeFile (dataPath + "testerrorredirection.sql" , false )
491+ if assert .NoError (t , err , "IncludeFile testerrorredirection.sql false" ) {
492+ bytes , err := os .ReadFile (outfile .Name ())
493+ if assert .NoError (t , err , "os.ReadFile outfile" ) {
494+ assert .Equal (t , "1" + SqlcmdEol + SqlcmdEol + "(1 row affected)" + SqlcmdEol , string (bytes ), "Unexpected output for sql file execution in outfile" )
495+ }
496+ bytes , err = os .ReadFile (errfile .Name ())
497+ if assert .NoError (t , err , "os.ReadFile errfile" ) {
498+ assert .Equal (t , "Sqlcmd: Error: Syntax error at line 3." + SqlcmdEol , string (bytes ), "Expected syntax error not found in errfile" )
499+ }
500+ }
501+ }
502+
465503// runSqlCmd uses lines as input for sqlcmd instead of relying on file or console input
466504func runSqlCmd (t testing.TB , s * Sqlcmd , lines []string ) error {
467505 t .Helper ()
@@ -509,6 +547,28 @@ func setupSqlcmdWithFileOutput(t testing.TB) (*Sqlcmd, *os.File) {
509547 return s , file
510548}
511549
550+ func setupSqlcmdWithFileErrorOutput (t testing.TB ) (* Sqlcmd , * os.File , * os.File ) {
551+ t .Helper ()
552+ v := InitializeVariables (true )
553+ v .Set (SQLCMDMAXVARTYPEWIDTH , "0" )
554+ s := New (nil , "" , v )
555+ s .Connect = newConnect (t )
556+ s .Format = NewSQLCmdDefaultFormatter (true )
557+ outfile , err := os .CreateTemp ("" , "sqlcmdout" )
558+ assert .NoError (t , err , "os.CreateTemp" )
559+ errfile , err := os .CreateTemp ("" , "sqlcmderr" )
560+ assert .NoError (t , err , "os.CreateTemp" )
561+ s .SetOutput (outfile )
562+ s .SetError (errfile )
563+ err = s .ConnectDb (nil , true )
564+ if err != nil {
565+ os .Remove (outfile .Name ())
566+ os .Remove (errfile .Name ())
567+ }
568+ assert .NoError (t , err , "s.ConnectDB" )
569+ return s , outfile , errfile
570+ }
571+
512572// Assuming public Azure, use AAD when SQLCMDUSER environment variable is not set
513573func canTestAzureAuth () bool {
514574 server := os .Getenv (SQLCMDSERVER )
0 commit comments