I have a test case (stripped version of bigger application) which fails sporadically on Windows 7 machine when trying to remove directory or file. It is using native Windows APIs. Test performs following steps --
- Create directory.
- Create a sqlite3 db in the directory created by step#1.
- Create a table in the DB.
- Close the DB.
- If any DB journal file is present, delete it.
- Delete the DB file.
- Delete the directory.
If you skip step#1, then test would run fine. If you add delay between step#4 and step#5, then test would run fine.
#include <windows.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <direct.h>
#include <sqlite3.h>
#include <io.h>
using namespace std;
bool sleep_for_sometime = false;
bool create_table = false;
bool runTest()
{
char cwdpath[1024] = {'\0'};
if (_getcwd(cwdpath, 1023) == NULL) return false;
string testpath(cwdpath);
testpath += "/test_dir";
_mkdir(testpath.c_str());
string dbpath = testpath + "/test.db";
sqlite3 *db = NULL;
if (sqlite3_open(dbpath.c_str(), &db) != SQLITE_OK) return false;
// Create table.
if (create_table) {
string sql = "CREATE TABLE COMPANY(" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME TEXT NOT NULL," \
"AGE INT NOT NULL)";
char *zErrMsg = 0;
if (sqlite3_exec(db, sql.c_str(), NULL, 0, &zErrMsg) != SQLITE_OK) {
sqlite3_close(db);
cerr << "Could not create table: " << zErrMsg << endl;
return false;
}
}
sqlite3_close(db);
if (sleep_for_sometime) {
Sleep(100);
}
string journal_file = dbpath + "-journal";
string journal_error = journal_file + " failed";
if (_access(journal_file.c_str(), 06) == 0) {
if (_unlink(journal_file.c_str()) != 0) {
perror(journal_error.c_str());
return false;
}
cout << "journal file --" << journal_file << endl;
}
string db_error = dbpath + " failed";
if (_unlink(dbpath.c_str()) != 0) {
perror(db_error.c_str());
return false;
}
string dir_error = testpath + " failed";
if (_rmdir(testpath.c_str()) != 0) {
perror(dir_error.c_str());
return false;
}
return true;
}
int main(int argc, char **argv)
{
cout << "Usage: ./projtest 1 1" << endl;
cout << "------If you pass two parameter, then always create table and sleep for some time." << endl;
cout << "Usage: ./projtest 1" << endl;
cout << "------If you pass one parameter, then always create table, but don't sleep." << endl;
cout << "Usage: ./projtest" << endl;
cout << "------If you don't pass any parameter, then don't create table and don't sleep." << endl;
if (argc == 3) {
sleep_for_sometime = true;
create_table = true;
} else if (argc == 2) {
create_table = true;
sleep_for_sometime = false;
} else {
create_table = false;
sleep_for_sometime = false;
}
for (int i = 0; i < 500 ; i++) {
if (! runTest()) {
cerr << "Err in runTest trial --" << i+1 << endl;
return 1;
}
}
return 0;
}
Aucun commentaire:
Enregistrer un commentaire