tSQLt ExpectException Not Detecting exception - unit-testing

I was working on building a test to utilize the ExpectException for a error raised during execution of a stored proc, but the test were never passing as I expected them to. So as part of my troubleshooting I made a very simple stored proc:
ALTER PROC testerror AS RAISERROR ('SomeError',16,1);
Then I built a test for this:
ALTER PROCEDURE [uspTest].[test the test]
AS
BEGIN
EXEC testerror
--Assert
EXEC tSQLt.ExpectException #ExpectedMessagePattern = '%SomeError%',
#ExpectedSeverity = 16,
#ExpectedState = 1;
END;
When I run this in tSQLt the test fails with the following output:
Test Procedure: [SSISAdmin].[uspTest].[test the test] on SF5I-ETLTST01
[uspTest].[test the test] failed: (Error)
SomeError[16,1]{testerror,1}
I have also tried passing NULL for the Severity and State based on examples that were in the documentation for the ExpectException as below but it still fails the test:
EXEC tSQLt.ExpectException #ExpectedMessagePattern = '%SomeError%',
#ExpectedSeverity = NULL,
#ExpectedState = NULL;
I am guessing I am doing something wrong, but I am not sure what since this seems like a very simplified test and error message that is being returned.
Any assistance would be appreciated.

After doing some more extensive Googling I found some other examples and then saw that I had written my test wrong. I had treated the ExpectException as an assertion where you execute the stored proc and then assert the results, but with the ExpectException you have to call the ExpectException method first and then execute the stored procedure that generates the error message. To further explain this here is how the test looks when it works as expected:
ALTER PROCEDURE uspTest.[test the test]
AS
BEGIN
EXEC tSQLt.ExpectException #ExpectedMessagePattern = '%SomeError%',
#ExpectedSeverity = NULL,
#ExpectedState = NULL;
EXEC dbo.testerror;
END;

Related

PreparedStatement throwing SQL error 0

I have this line of C++ code calling a procedure (this procedure works, I've tested it using phpmyadmin):
prep_stmt.reset(con->prepareStatement("CALL get_pass(?, #pass)"));
The code compiles fine, but on runtime, it throws this error:
MySQL_Connection::prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) (MySQL error code: 0, SQLState: )
I've been looking into this for hours and I can't seem to find a solution - I guess its something to do with arguments but I'm new to Connector\C++ and all the examples I've seen just have an SQL command as a string. Can anyone help?

Is there a way to let IAR CSPY return an error code defined by executed user program?

I am using IAR EWARM's cspybat to run some unit tests for my embedded code using Unity. I would like an easy way for my build server to determine if the unit tests passed or failed. Is there a way for CSPY to return a nonzero error code if my unit tests fail? I have tried changing the return value in main() with no change. Is there a function I can call to force an error to be returned?
My cspybat batch file looks like this:
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.4\common\bin\cspybat" -f "C:\Work\Sandbox\ST\stmicroeval\_iar_ewarm_project\settings\Project.UnitTest.general.xcl" --backend -f "C:\Work\Sandbox\ST\stmicroeval\_iar_ewarm_project\settings\Project.UnitTest.driver.xcl"
Unfortunately, no.
I've solved this by replacing "exit" with a function that prints a specific pattern, plus the exit code. I then wrapped the call to cspybat into a script that 1) strips the output of the extra output and 2) exits with the desired exit code.
It's late 2020 and they still don't offer a mechanism to do this.
We solved it by including a macro file with the contents:
execUserExit()
{
__message "program exited with __exit_value = ", __exit_value:%d ;
}
And having our own exit variable in the code:
extern "C" int __exit_value=0xff;
That we set prior to calling exit() (though you could just write your own version of exit())
This makes the debugger always print SOMETHING, even if the program crashes on startup.
Then we parse with a python wrapper:
pattern = "__exit_value =\s([\-|0-9|a-f|A-F|x]*)"
retvalue = int(re.findall(pattern,process.stdout)[0])

MariaDB, Syntax error when executing stored procedure in c++ program

First of all, thank you for read this question and apologize for my poor english.
I'm now converting my DB from SQL-Server to MariaDB. I installed MySQL ODBC driver and added 'system DSN'. ( C:\Windows\SysWOW64\odbcad32.exe )
The problem occured at executing a stored procedure.
When I created an procedure in SQLyog, There was no error and execution also runs fine. But When I execute stored procedure in my c++ application syntax error occurs.
Database [MySQL][ODBC 5.3(w) Driver][mysqld-5.5.5-10.0.20-MariaDB]You
have an error in your SQL syntax; check the manual that corresponds to
your MariaDB server version for the right syntax to use near
'get_bookProperty ?' at line 1
My C++ code is...
bool LoadbookProperty::OnExecute(db::IDbProcesser* dbProcesser)
{
const char* bookName = m_bookName.c_str();
dbProcesser->BindParams(bookName);
if (!dbProcesser->Execute("get_bookProperty"))
return false;
char type[PROPERTY_NAME_LEN];
char value[PROPERTY_VALUE_LEN];
dbProcesser->BindCols(type, value);
dbProcesser->FetchWith([this, &type, &value]()
{
m_properties.push_back(std::make_pair(type, value));
});
return true;
}
And my procedure is...
USE bookInfoDB;
-- GetbookProperty
DELIMITER ;;
CREATE PROCEDURE get_bookProperty (
IN pi_bookName VARCHAR(32)
)
this_proc:BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
SELECT bookName, bookPrice FROM bookProperty WHERE bookName = pi_bookName;
END ;;
DELIMITER ;
I really don't know what's the matter. Please help me.
Solved it! The cause is EXECUTION function. When my team used SQL Server, EXECUTION function's string combination was EXEC and no bracket.
(As you all know, SQL Server execute procedure by 'EXEC sp_name arg1 arg2 ...')
But MySQL(and also MariaDB)'s procedure execution syntax is 'CALL sp_name (arg1, arg2 ...). Our programmer have changed EXECTION function's string combination. And? It works perfectly!

C++ and ADODB : Com error 0x800a0e78

I have a C++ library that calls a stored procedure in MSSQL database using ADODB. Everything works fine on development database. But on test database, I am getting Com error 0x800a0e78: This option is not allowed if an object is closed.
The code looks like
ADODB::_CommandPtr cmd = NULL;
ADODB::_RecordsetPtr rs = NULL;
CHECKHR(cmd.CreateInstance( __uuidof( ADODB::Command) ));
cmd->ActiveConnection = m_connexion;
cmd->CommandText = "my_stored_procedure";
cmd->CommandType = ADODB::adCmdStoredProc;
CHECKHR(cmd->Parameters->Refresh());
//input param
cmd->Parameters->GetItem(paramIndex)->put_Value(paramValue);
// output param
cmd->Parameters->GetItem(paramIndex)->PutDirection(ADODB::adParamOutput);
rs = cmd->Execute( NULL, NULL, ADODB::adCmdStoredProc);
while(! rs->ADO_EOF ) { ...
rs->ADO_EOF is where it crashes the program if I use the test database.
note: The stored procedure is same in both the databases and returns same data.
There is one more flow where another SP is called. It works well with the test database. The problem appears only with this particular SP.
I tend to think that it is not a code issue because it works with development database. But I can consistently reproduce the problem with test database.
Please suggest of next actions I should take to resolve this issue
UPDATE
Due to some miracle this C++ exception has gone away after 1 day. But it is so very slow that the execution almost always times out. I do not know how to justify this behavior
UPDATE: 2013-07-18
After so much time, the error has appeared again. This time with development DB with the same SP
[Com error 0x800a0e78 : Operation is not allowed when the object is closed.
on the same line
while(! rs->ADO_EOF ) {
in rs I can see a memory address pointing to ADODB recordset object. But rs->ADO_EOF is generating the said error

SQL Server catch error from extended stored procedure

Hello I have an extended stored procedure that sends an error message.
srv_sendmsg(pSrvProc, SRV_MSG_ERROR, errorNum, SRV_FATAL_SERVER, 1,
NULL, 0, (DBUSMALLINT) __LINE__,
buff,
SRV_NULLTERM);
I've set the severity to SVR_FATAL_SERVER just as a test to see if I can cause the message to throw an exception in the sql.
In my SQL i'm doing:
BEGIN TRY
EXEC dbo.xp_somethingCool
SET #Error = ##ERROR
END TRY
BEGIN CATCH
PRINT 'AN Error occoured!'
SELECT ERROR_NUMBER() AS ErrorNumber
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
I would think that when my xp sends the error message the tsql would catch the error and select the error_number and error_message. Instead what ends up happening is that the xp sends the message and the T-SQL continues on its way like nothing happened. The ##Error variable doesn't get set either.
So I was wondering if there was any trick to getting SQL to catch an error from an XP ?
Thanks,
Raul
You can only test the result from an extended stored proc, and use that to throw an exception.
...
EXEC #rtn = dbo.xp_somethingCool
IF #rtn <> 0
RAISERROR ...
...
In very simple terms, an extended stored proc is not SQL run by the database engine so you can't issue RAISERROR. See KB 190987 for some more info
Never raise anything so high. Anything raised with severity above 16 will abort the batch, so your T-SQL catch block never gets a chance to run. Something as high as SVR_FATAL_SERVER will shutdown the server immedeatly.
You should be able to use RAISERROR to throw an exception.
Per comment: Are you not creating your own extended stored proc? If so, you can use throw or do something like 1/0 to throw an exception.