Skip to content
Snippets Groups Projects
BinaryFileTest.h 5.36 KiB
Newer Older
#ifndef BINARYFILETEST_H_
#define BINARYFILETEST_H_

#include <cxxtest/TestSuite.h>
#include "MantidKernel/BinaryFile.h"
#include "MantidKernel/System.h"
#include "MantidKernel/ConfigService.h"
#include <sys/stat.h>

using namespace Mantid::Kernel;

using std::runtime_error;
using std::size_t;
using std::vector;
using std::cout;
using std::endl;

//==========================================================================================
/// Make the code clearer by having this an explicit type
typedef uint32_t PixelType;
/// Type for the DAS time of flight (data file)
typedef uint32_t DasTofType;
/// Structure that matches the form in the binary event list.
struct DasEvent
{
  /// Time of flight.
  DasTofType tof;
  /// Pixel identifier as published by the DAS/DAE/DAQ.
  PixelType pid;
};


/** Creates a dummy file with so many bytes */
static void MakeDummyFile(std::string filename, size_t num_bytes)
{
  char * buffer;
  buffer = new char[num_bytes];
  for (size_t i=0; i < num_bytes; i++)
  {
    // Put 1,2,3 in 32-bit ints
    if (i%4==0)
      buffer[i]=static_cast<char>(i/4);
    else
      buffer[i]=0;
  }

  std::ofstream myFile (filename.c_str(), std::ios::out | std::ios::binary);
  myFile.write (buffer, num_bytes);
//==========================================================================================
class BinaryFileTest: public CxxTest::TestSuite
{
  std::string dummy_file;

public:
  static BinaryFileTest *createSuite() { return new BinaryFileTest(); }
  static void destroySuite(BinaryFileTest *suite) { delete suite; }

  BinaryFileTest()
  {
    dummy_file = "dummy.bin";
  }

  void testFileNotFound()
  {
    TS_ASSERT_THROWS( file.open("nonexistentfile.dat"), std::invalid_argument);
  }

 void testFileWrongSize()
 {

   MakeDummyFile(dummy_file, 3);
   TS_ASSERT_THROWS( file.open(dummy_file), std::runtime_error);
   file.close();
   Poco::File(dummy_file).remove();
 }


 void testOpen()
 {
   MakeDummyFile(dummy_file, 20*8);

   // If this throws, then the file does not exist.
   file.open(dummy_file);
   //Right size?
   size_t num = 20;
   TS_ASSERT_EQUALS(file.getNumElements(), num);
   //Get it
Campbell, Stuart's avatar
Campbell, Stuart committed
   std::vector<DasEvent> * data = 0;
   TS_ASSERT_THROWS_NOTHING( data = file.loadAll() );
   TS_ASSERT_EQUALS(data->size(), num);
   //Check the first event
   TS_ASSERT_EQUALS( data->at(0).tof, 0);
   TS_ASSERT_EQUALS( data->at(0).pid, 1);
   //Check the last event
   TS_ASSERT_EQUALS( data->at(num-1).tof, 38);
   TS_ASSERT_EQUALS( data->at(num-1).pid, 39);

   delete data;
   file.close();
   Poco::File(dummy_file).remove();
 }

 void testLoadAllInto()
 {
   MakeDummyFile(dummy_file, 20*8);
   file.open(dummy_file);

   //Right size?
   size_t num = 20;
   TS_ASSERT_EQUALS(file.getNumElements(), num);
   //Get it
   std::vector<DasEvent> data;
   TS_ASSERT_THROWS_NOTHING( file.loadAllInto(data) );
   TS_ASSERT_EQUALS(data.size(), num);
   //Check the first event
   TS_ASSERT_EQUALS( data.at(0).tof, 0);
   TS_ASSERT_EQUALS( data.at(0).pid, 1);
   //Check the last event
   TS_ASSERT_EQUALS( data.at(num-1).tof, 38);
   TS_ASSERT_EQUALS( data.at(num-1).pid, 39);
   file.close();
   Poco::File(dummy_file).remove();
 }

 void testLoadInBlocks()
 {
   MakeDummyFile(dummy_file, 20*8);
   file.open(dummy_file);

   //Right size?
   size_t num = 20;
   TS_ASSERT_EQUALS(file.getNumElements(), num);
   //Get it
   size_t block_size = 10;
   DasEvent * data = new DasEvent[block_size];
   size_t loaded_size = file.loadBlock(data, block_size);
   //Yes, we loaded that amount
   TS_ASSERT_EQUALS(loaded_size, block_size);

   //Check the first event
   TS_ASSERT_EQUALS( data[0].tof, 0);
   TS_ASSERT_EQUALS( data[0].pid, 1);

   delete [] data;
   //Now try to load a lot more - going past the end
   block_size = 10;
   data = new DasEvent[block_size];
   loaded_size = file.loadBlock(data, block_size);
   TS_ASSERT_EQUALS(loaded_size, 10);

   //Check the last event
   TS_ASSERT_EQUALS( data[ 9].tof, 38);
   TS_ASSERT_EQUALS( data[ 9].pid, 39);
 void testLoadBlockAt()
 {
   MakeDummyFile(dummy_file, 20*8);
   file.open(dummy_file);

   //Right size?
   size_t num = 20;
   TS_ASSERT_EQUALS(file.getNumElements(), num);
   //Get it
   size_t block_size = 10;
   DasEvent * data = new DasEvent[block_size];
   size_t loaded_size = file.loadBlockAt(data, 5, block_size);
   //Yes, we loaded that amount
   TS_ASSERT_EQUALS(loaded_size, block_size);

   //The first event is at index 5
   TS_ASSERT_EQUALS( data[0].tof, 10);
   TS_ASSERT_EQUALS( data[0].pid, 11);

   delete [] data;
   //Now try to load a lot more - going past the end
   block_size = 10;
   data = new DasEvent[block_size];
   loaded_size = file.loadBlock(data, block_size);
   TS_ASSERT_EQUALS(loaded_size, 5);
   delete [] data;
   file.close();
   Poco::File(dummy_file).remove();
 }


  void testCallingDestructorOnUnitializedObject()
  {
    BinaryFile<DasEvent> file2;
  }

  void testReadingNotOpenFile()
  {
    BinaryFile<DasEvent> file2;
    std::vector<DasEvent> data;
    TS_ASSERT_EQUALS(file2.getNumElements(), 0);
    TS_ASSERT_THROWS(file2.loadAll(), std::runtime_error );
    TS_ASSERT_THROWS(file2.loadAllInto( data), std::runtime_error );
    TS_ASSERT_THROWS(file2.loadBlock(buffer, 10), std::runtime_error );