8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-25 00:43:03 +01:00
firebird-mirror/src/jrd/qatest.cpp
alexpeshkoff 1591a54e5e Thread cleanup:
1. Added macros to declare thread entrypoints
2. THD_mutex_* functions use Firebird::Mutex
3. Thread local storage use fb_tls.h
2004-06-08 13:41:08 +00:00

233 lines
5.7 KiB
C++

/*
* PROGRAM: InterBase Access Method
* MODULE: qatest.c
* DESCRIPTION: Entry points for QA testibility library
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
/*
QA Testability Module
Rich Damon in QA requested the addition of a system UDF that would
enable automated tested of certain error conditions. Previously
this was done with a user UDF, but with NLM no longer supporting
user UDF's we are including it in the system.
I have therefore extended the BUILTIN_entrypoint() method to include
a system UDF entry, QATEST_entrypoint, which will do various
nasty things to the system when invoked.
-------------
THIS FUNCTION IS NOT TO BE DOCUMENTED OR USED BY CUSTOMERS
-------------
To use the UDF, it must be declared to a database, thusly:
declare external function QAPOKE
int, int
returns int by value
entry_point "DEBUG_CRASH_TESTS"
module_name "TEST1";
Note the special magic values for entry_point & module_name. Any
number of parameters can be declared as part of the UDF definition and
will be passed to the entrypoint - the first parameter selects the
subfunction to invoke.
Currently defined subfunctions, and expected parameters, are:
0 QATEST_testing (SLONG)
Tests that the mechanism is working properly.
returns 2*arg1;
1 QATEST_delete_database (void)
Deletes the current database file.
Returns 0 on success
Returns -1 if database doesn't have a file (when can this happen?)
2 QATEST_delete_shadow (ULONG)
Deletes shadow #arg1.
Returns 0 on success
Returns -1 if shadowing not enabled
Returns -2 if shadow #arg1 not found.
999 QATEST_exit (void)
Performs exit() on the server.
Note that this will crash an NLM server - and is not suitable
for fully automated testing on that platform.
Code for the UDF is in jrd/qatest.c.
The R&D TCS test case is QATEST_METHOD, which exercises all the
defined APIs for this function.
1994-July-14 David Schnepper
*/
#include "firebird.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../jrd/common.h"
#include "../jrd/jrd.h"
#include "../jrd/sdw.h"
#include "../jrd/os/pio.h"
#include "gen/iberror.h"
#include "../jrd/err_proto.h"
#include "../jrd/flu_proto.h"
#include "../jrd/sch_proto.h"
#include "../jrd/thd.h"
#include "../jrd/thread_proto.h"
#ifdef WIN_NT
#include <windows.h>
#ifdef TEXT
#undef TEXT
#endif
#define TEXT char
#endif
const int QATEST_testing = 0;
const int QATEST_delete_database = 1;
const int QATEST_delete_shadow = 2;
const int QATEST_exit = 999;
int QATEST_entrypoint(ULONG * function, void *arg1, void *arg2, void *arg3)
{
/**************************************
*
* Q A T E S T _ e n t r y p o i n t
*
**************************************
*
* Functional description
*
* Perform various random nastiness to the system in order
* to test database recovery.
*
* These entrypoints are *NOT* designed for customer use!
*
**************************************/
thread_db* tdbb;
char filename[MAXPATHLEN];
Shadow* shadow;
#ifdef WIN_NT
HANDLE desc;
#endif
jrd_file* file;
switch (*function) {
case QATEST_testing:
/* Parameter 1: SLONG *testvalue */
/* Entrypoint for testing the QA entrypoint method */
return 2 * (*(SLONG*) arg1);
case QATEST_delete_database:
/* Parameters: NONE */
/* Close current database file & delete */
tdbb = JRD_get_thread_data();
if (!(file = tdbb->tdbb_attachment->att_database->dbb_file))
return -1;
#ifdef WIN_NT
desc =
(HANDLE) ((file->fil_flags & FIL_force_write) ?
file->fil_force_write_desc : file->fil_desc);
CloseHandle(desc);
desc = INVALID_HANDLE_VALUE;
#else
close(file->fil_desc);
#endif
strncpy((char *) filename, file->fil_string, file->fil_length);
filename[file->fil_length] = 0;
#ifdef WIN_NT
DeleteFile(filename);
#else
unlink(filename);
#endif
return 0;
case QATEST_delete_shadow:
/* Parameter 1: ULONG *shadow_number */
/* Close & delete specified shadow file */
tdbb = JRD_get_thread_data();
if (!(shadow = tdbb->tdbb_attachment->att_database->dbb_shadow))
return -1;
for (; shadow; shadow = shadow->sdw_next)
if (shadow->sdw_number == *(ULONG *) arg1) {
#ifdef WIN_NT
desc =
(HANDLE) ((shadow->sdw_file->fil_flags & FIL_force_write)
? shadow->
sdw_file->fil_force_write_desc : shadow->
sdw_file->fil_desc);
CloseHandle(desc);
desc = INVALID_HANDLE_VALUE;
#else
close(shadow->sdw_file->fil_desc);
#endif
strncpy((char *) filename, shadow->sdw_file->fil_string,
shadow->sdw_file->fil_length);
filename[shadow->sdw_file->fil_length] = 0;
#ifdef WIN_NT
DeleteFile(filename);
#else
unlink(filename);
#endif
return 0;
}
return -2;
case QATEST_exit:
/* Parameters: NONE */
/* do a process exit - very nasty - crashes MU server */
exit(1);
return 0;
default:
sprintf(filename, "Unknown QATEST_entrypoint #%lu", /* TXNN */
*function);
THREAD_ENTER();
ERR_post(isc_random,
isc_arg_string, ERR_cstring(filename), 0);
THREAD_EXIT();
return 0;
}
}