How to generate a file open failure for unit testing - c++

For completeness, I'm using C++ in Visual Studio 2012 under Windows 7.
I have some basic file reading code:
Defined in class:
std::ifstream iniFileHandle;
Method in question:
FileLoader::FILE_STATUS FileLoader::loadFile(const std::string& fullpathandfilename)
{
if (fullpathandfilename.empty())
{
iniFileStatus = FILE_NOT_SPECIFIED;
}
else // parameter has 'something'...
{
if (!doesFileExist(fullpathandfilename))
{
iniFileStatus = FILE_NOT_FOUND;
}
else // file found...
{
iniFileHandle.open(fullpathandfilename, std::ios::in);
if (!iniFileHandle.is_open()) // something went wrong
{
iniFileStatus = FILE_CANNOT_LOAD; // <== HOW TO TEST?
}
else // file opened!
{
iniFileStatus = FILE_OPEN;
}
}
}
return iniFileStatus;
}
All this works fine but I'm having difficulty getting coverage with Google Unit Tests.
What i'm missing is a way to simulate/create a scenario where is_open() fails.
I've tried:
read only files
the 'exe' being currently run
a file opened in another application
but they all open.
Is this error condition actually possible to occur? If so, how can I mimic the failure so I can test it?

As mentioned in the comments, trying to open a directory will cause is_open() to return false. The cases you tried all succeed because you open the file as read-only (std::ios::in, which is also the default for an ifstream).

I've tried:
a file opened in another application but they all open.
This happens because file is opened in share mode which allows reading for others. You need to open file in exclusive file access mode. To achieve it, if you use MSVS, you could pass the third parameter int _Prot to the ifstream, otherwise you could use CreateFile().
To emulate the problem you could open file exclusively used by Windows, e.g:
c:\pagefile.sys

create a any file, and set its permission as read only, and in your code try to open this file for writing

Related

Stop ofstream from creating a file

I'm trying open a file and check if it exists yet it creates a new file if the given file does not exist. If it is going to automatically create a file, what's the point of the isOpen() then?
int main() {
std::ofstream defaultFile;
defaultFile.open("AAAAA.txt");
std::cout << defaultFile.is_open();//this will always print out "1"
}
what's the point of the isOpen() then?
Creating a file can fail for numerous reasons. One could be that you have no write access in the directory where you try to create the file. In that case
defaultFile.open("AAAAA.txt");
will fail and is_open will return false. If you want to know if the file exists before creating it you can do for example this:
ifstream f(name);
bool exits_and_can_be_opened = f.good();
Taken from here: https://stackoverflow.com/a/12774387/4117728, but note that since C++17 there is the Filesystem library with more straightforward ways to query properties of files.

ofstream not creating file (Node.js addon)

I am attempting to create an addon for Node.js that (among other things) writes content to a file inside my C++ class using ofstream.
std::ofstream license_file;
std::string fileContent(*NanAsciiString(args[0]));
license_file.open(PATH);
//file doesn't yet exist, so create it
if(!license_file) {
printf("ERROR: %s (%s)\n", strerror(errno), PATH);
}
license_file << fileContent;
license_file.close();
This works fine if PATH is set to the same directory as my Node.js code (e.g. ./license.txt).
However, ofstream fails to open/create the file in question if it is located anywhere else. For example, using ~/license.txt does not work (note: I'm running OSX).
The error reported is always No such file or directory -- even after I physically create ~/license.txt.
Any ideas why this works in one directory but not others? If it were a permissions issue I would expect a different error message.
For the record, I've seen about 20 other SO questions about "ofstream fails to create file" but passing additional flags into open() has no effect. I have a feeling this is somehow related to running inside Node/V8.
I think the issue is that you need to find out the user directory in a different way than using ~.

C++ ofstream System.AccessViolation

I have a problem. I'm writing to a log file, but when I do the application throws:
An unhandled exception of type 'System.AccessViolationException' occurred in ****
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
The code (unmanaged) I'm using is this one:
inline bool writeLog(string message)
{
ofstream myfile;
myfile.open(mStrSource.c_str(), ios::in | ios::out | ios::app);
if(!myfile.is_open())
{
throw "Unable to open the file: " + mStrSource;
}
myfile << "TESTE" << endl;
myfile.close();
return true;
};
When receiving this error, the code points to the _Lock() of file fstream:
virtual void __CLR_OR_THIS_CALL _Lock()
{ // lock file instead of stream buffer
if (_Myfile)
_CSTD _lock_file(_Myfile);
}
Other info:
Developed under VS2010 (Incially the project was Winx32 but now it's Winx64) (.NET Framework 4).
The open() method of ofstream creates the file and the file is writable but throws the exception when try's to write on the file.
Thank you guys in advanced.
Check to make sure your application has rights to write to a file in that location. A standard user in Windows cannot access the whole file system (especially for writing). Either require the app to have admin rights (not recommended for "normal" apps) or write to a place that standard users can get to (e.g. My Documents directory).
Also, make sure the file is not opened for exclusive use by another app like Excel or Word. They have a habit of locking files when opening them.
Another thing to look at is during development, sometimes the .NET runtime/VS debugger will leave a file locked that you were working with after a crash. Try closing/reopening Visual Studio to help with that.
Ok guys,
For future notice, the problem was related to the configuration of the project. When I converted the project from vs2008 to vs2010, from .net 3.5 to .net 4 and from x32 to x64 something didn't quite go right.
So I reverted everything back and converted again in a more controlled environment and now i can open/write/close files without a problem.
Thanks anyway guys.

Stream (pointer to a file structure) in File handling giving strange values

i am trying to output a buffer to a file using visual c++.
my code for doing it is-
FILE *stream;
stream=fopen("C:\\Users\\sshekha\\Desktop\\z.txt","r");
//I also tried with "w" mode
//the differencein behavious on executing these two is that when it is in read mode it
//executes the else condition in the code below whereas in "w" mode it executes the "if"
// condition,
//moreover even if i change the path it don't execute the "else" condition-that means this path
//is effective to the code. and the another surprising thing is when i open the file manually
// and then run the code with "r" mode it still executes the "else" part (which it shouldn't
// because the file is already open.)
if( stream == 0 )
{
MessageBox(m_hwndPreview,L" the file is not opened ",L"BTN WND",MB_ICONINFORMATION);
}
else
{
MessageBox(m_hwndPreview,L" the file is opened ",L"BTN WND",MB_ICONINFORMATION);
int check=fputs (HtmlFileContents,stream);
fclose(stream);
return 0;
}
I tried to check the results using different mode in order to understand whats teh probem going on . when i debug it , i get the value of (in Read mode) :
stream = 0x000000005c5c76f0 { _ptr=0x0000000000000000 _cnt=0 _base=0x0000000000000000 ...}
I don't know it gib=ves bad pointer and even then it go to else part of the loop. Why ?
and in write mode
stream = 0x0000000000000000 {_ptr=??? _cnt=??? _base=??? ...}
So go to the if part of the loop.
Moreover my path is correct and i have enough permission to do the task I wish. But why does it give bad pointer ? Why have I these strange values of stream and what should I do to copy the content of my buffer HtmlFileContents in to z.txt ? Any ideas ?
You're opening the file in read-only mode: fopen("C:\\Users\\sshekha\\Desktop\\z.txt","r");. Here "r" says you only intend to read from file. To be able to write contents (i.e. fputs(...)), open the file in write mode like so: fopen("C:\Users\sshekha\Desktop\z.txt","w")(or"a"` if you want to append). For more information, read fopen documentation.
EDIT: I see that you've tried both read and write modes. You're code only shows read-mode and hence my assumption on the read-only problem. Let me do a bit more research and get back.
Please write the following code in your if statement:
perror("The following error occurred:");
if you don't have a console, use this to store the error string:
char* errorCause = strerror(errno); MessageBoxA(m_hwndPreview, errorCause, "BTN WND", MB_ICONINFORMATION);
and let us know what you see as the cause.
EDIT 2: Since you've mentioned that you're using Visual Studio 2010, are you running it as yourself? This stackoverflow answer shows that VS2010 has different options when debugging applications; https://stackoverflow.com/a/3704942/210634
NOTE: That feature is only available on 'Pro' versions.
Here's a working example: https://ideone.com/hVLgc4
If the file is "read only", opening with it with write permissions should fail.
to see if that is the case,under windows:
right click the file
press properties
at the bottom, see if "Read-only" attribute i marked with "v"
(uncheck it if you desire writing to the file)
refer to :
http://msdn.microsoft.com/en-us/library/aa365535(v=vs.85).aspx
on how to change file permissions from your code

ifstream: how to tell if specified file doesn't exist

I want to open a file for reading. However, in the context of this program, it's OK if the file doesn't exist, I just move on. I want to be able to identify when the error is "file not found" and when the error is otherwise. Otherwise means I need to quit and error.
I don't see an obvious way to do this with fstream.
I can do this with C's open() and perror(). I presumed that there was a fstream way to do this as well.
EDIT: I've been notified that this does not necessarily indicate a file does not exist, as it may be flagged due to access permissions or other issues as well.
I know I'm extremely late in answering this, but I figured I'd leave a comment anyway for anyone browsing. You can use ifstream's fail indicator to tell if a file exists.
ifstream myFile("filename.txt");
if(myFile.fail()){
//File does not exist code here
}
//otherwise, file exists
I don't think you can know if "the file doesn't exist". You could use is_open() for generic checking:
ofstream file(....);
if(!file.is_open())
{
// error! maybe the file doesn't exist.
}
If you are using boost you could use boost::filesystem:
#include <boost/filesystem.hpp>
int main()
{
boost::filesystem::path myfile("test.dat");
if( !boost::filesystem::exists(myfile) )
{
// what do you want to do if the file doesn't exist
}
}
Since the result of opening a file is OS-specific, I don't think standard C++ has any way to differentiate the various types of errors. The file either opens or it doesn't.
You can try opening the file for reading, and if it doesn't open (ifstream::is_open() returns false), you know it either doesn't exist or some other error happened. Then again, if you try to open it for writing afterwards and it fails, that might fall under the "something else" category.
A simple way from http://www.cplusplus.com/forum/general/1796/
ifstream ifile(filename);
if (ifile) {
// The file exists, and is open for input
}
You can use stat, which should be portable across platforms and is in the standard C library:
#include <sys/stat.h>
bool FileExists(string filename) {
struct stat fileInfo;
return stat(filename.c_str(), &fileInfo) == 0;
}
If stat returns 0, the file (or directory) exists, otherwise it doesn't. I assume that you'll have to have access permissions on all directories in the file's path. I haven't tested portability, but this page suggests it shouldn't be an issue.
A better way:
std::ifstream stream;
stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
stream.open(fileName, std::ios::binary);
With C++17 you can use std::filesystem::exists.
Let's me give example with real running:
file does't exist:
file exist:
see http://www.cplusplus.com/reference/fstream/ifstream/ for more information about its public function.
Straight way without creating ifstream object.
if (!std::ifstream(filename))
{
// error! file doesn't exist.
}