unit PSQLDumpTest;
{$I PSQLDAC.inc}
{$IFDEF DUNITX}
  {$M+}
{$ENDIF}
{

  Delphi DUnit Test Case
  ----------------------
  This unit contains a skeleton test case class generated by the Test Case Wizard.
  Modify the generated code to correctly setup and call the methods from the unit
  being tested.

}

interface

uses
  Db, PSQLDump, PSQLTypes, SysUtils, PSQLDbTables, Classes
  {$IFDEF DELPHI_15}, IOUtils{$ELSE}, FileCtrl{$ENDIF}
  {$IFNDEF DUNITX}
  ,TestFramework, Math, TestExtensions, TestHelper
  {$ELSE}
  , DUnitX.TestFramework, TestXHelper
  {$ENDIF};

type

  {$IFDEF DUNITX}[TestFixture]{$ENDIF}
  TestTPSQLDump = class({$IFNDEF DUNITX}TTestCase{$ELSE}TTestXCase{$ENDIF})
  private
    FPSQLDump: TPSQLDump;
  public
    {$IFNDEF DUNITX}
    procedure SetUp; override;
    procedure TearDown; override;
    {$ELSE}
    [Setup]
    procedure SetUp;
    [TearDown]
    procedure TearDown;
    {$ENDIF}
    procedure TestDumpToFileLogFile(ALogFileName: string = '');
    procedure LoadLibrary(Sender: TObject; var FileName: string);
  published
    procedure TestDumpToStream;
    procedure TestDumpToStreamStrings;
    procedure TestDumpToStreamLogFile;
    procedure TestDumpToFileStrings;
    //specific routines
    procedure TestDumpCompressed;
    procedure TestDumpTar;
    procedure TestDumpDirectory;
    procedure TestDumpPlain;
    procedure TestDumpPlainCompressed;
    procedure TestDumpNonASCIIName;
    procedure TestDumpSections;
    {$IFDEF DUNITX}
    [SetupFixture]
    procedure SetupFixture;
    [TearDownFixture]
    procedure TearDownFixture;
    {$ENDIF}
  end;

  // Test methods for class TPSQLRestore
  {$IFDEF DUNITX}[TestFixture]{$ENDIF}
  TestTPSQLRestore = class({$IFNDEF DUNITX}TTestCase{$ELSE}TTestXCase{$ENDIF})
  private
    FPSQLRestore: TPSQLRestore;
  public
    {$IFNDEF DUNITX}
    procedure SetUp; override;
    procedure TearDown; override;
    {$ELSE}
    [Setup]
    procedure SetUp;
    [TearDown]
    procedure TearDown;
    {$ENDIF}
    procedure LoadLibrary(Sender: TObject; var FileName: string);
  published
    procedure TestRestoreFromFileToDB;
    procedure TestRestoreFromFileToFile;
    procedure TestRestoreFromDirectoryToFile;
  end;

var
  DumpPath: string; //= 'TestOut\';
  DumpFileName: string; //= 'TestDumpToFile.backup';

implementation

procedure TestTPSQLDump.LoadLibrary(Sender: TObject; var FileName: string);
begin
  //FileName := 'pg_dump-9.2.9.dll';
end;

procedure TestTPSQLDump.SetUp;
begin
  FPSQLDump := TPSQLDump.Create(nil);
  FPSQLDump.Database := TestDBSetup.Database;
  FPSQLDump.Options := [doVerbose];
  FPSQLDump.OnLibraryLoad := LoadLibrary;
  DumpPath := {$IFDEF DUNITX}
                        TPath.GetDocumentsPath + PathDelim
                     {$ELSE}
                     'TestOutput\'
                     {$ENDIF};
  DumpFileName:= DumpPath + 'TestDumpToFile.backup';
end;

procedure TestTPSQLDump.TearDown;
begin
  FPSQLDump.Free;
  FPSQLDump := nil;
end;

procedure TestTPSQLDump.TestDumpToStream;
var
  Stream: TStream;
begin
  Stream := TMemoryStream.Create;
  try
    FPSQLDump.DumpToStream(Stream);
    Check(Stream.Size > 0, 'Dump stream empty');
  finally
    Stream.Free;
  end;
end;

procedure TestTPSQLDump.TestDumpToStreamStrings;
var
  Log: TStrings;
  Stream: TStream;
begin
  Stream := TMemoryStream.Create;
  try
    Log := TStringList.Create;
    try
      FPSQLDump.DumpToStream(Stream, Log);
      Check(Stream.Size > 0, 'Dump stream empty');
      Check(Log.Count > 0, 'Dump log empty');
      Log.SaveToFile(DumpPath + 'TestDumpToStream1.log');
    finally
      Log.Free;
    end;
  finally
    Stream.Free;
  end;
end;

procedure TestTPSQLDump.TestDumpToStreamLogFile;
var
  LogFileName: string;
  Stream: TStream;
begin
  Stream := TMemoryStream.Create;
  try
    LogFileName := DumpPath + 'TestDumpToStream2.log';
    FPSQLDump.DumpToStream(Stream, LogFileName);
    Check(Stream.Size > 0, 'Dump stream empty');
    Check(FileExists(LogFileName), 'Log file empty');
  finally
    Stream.Free;
  end;
end;

{$IFDEF DUNITX}
procedure TestTPSQLDump.SetupFixture;
begin
end;

procedure TestTPSQLDump.TearDownFixture;
begin
end;
{$ENDIF}

procedure TestTPSQLDump.TestDumpCompressed;
begin
  FPSQLDump.DumpFormat := dfCompressedArchive;
  FPSQLDump.CompressLevel := 9;
  FPSQLDump.RewriteFile := True;
  TestDumpToFileLogFile(DumpPath + 'CompressedDump.log');
end;

procedure TestTPSQLDump.TestDumpDirectory;
begin
  DumpFileName := DumpPath + 'TestDumpToFile';
  {$IFDEF DELPHI_5}
  if DirectoryExists(DumpFileName) then
    RemoveDirectory(PAnsiChar(DumpFileName));
  {$ELSE}
  if TDirectory.Exists(DumpFileName) then
    TDirectory.Delete(DumpFileName, True);
  {$ENDIF}
  FPSQLDump.DumpFormat := dfDirectory;
  FPSQLDump.Jobs := 4;
  TestDumpToFileLogFile(DumpPath + 'DirectoryDump.log');
  FPSQLDump.Jobs := 0;
end;

procedure TestTPSQLDump.TestDumpNonASCIIName;
var TempDb: TPSQLDatabase;
    DoesDbExist: boolean;
begin
  TestDBSetup.Database.SelectString('SELECT TRUE FROM pg_database WHERE datname = ''МояУкраїнськаБазочка''', DoesDbExist);
  if not DoesDbExist then
    TestDBSetup.Database.Execute('CREATE DATABASE "МояУкраїнськаБазочка"');
  TempDb := TPSQLDatabase.Create(nil);
  try
    TempDb.Assign(TestDBSetup.Database);
    TempDb.DatabaseName := 'МояУкраїнськаБазочка';
    DumpFileName := DumpPath + 'МійУкраїнськийДамп.backup';
    FPSQLDump.Database := TempDB;
    FPSQLDump.DumpFormat := dfCompressedArchive;
    TestDumpToFileLogFile(DumpPath + 'МійУкраїнськийДамп.log');
  finally
    TempDb.Close;
    TempDb.Free;
  end;
end;

procedure TestTPSQLDump.TestDumpPlain;
begin
  DumpFileName := DumpPath + 'TestDumpToFile.sql';
  FPSQLDump.DumpFormat := dfPlain;
  FPSQLDump.CompressLevel := 0;
  FPSQLDump.RewriteFile := True;
  TestDumpToFileLogFile(DumpPath + 'PlainDump.log');
end;

procedure TestTPSQLDump.TestDumpPlainCompressed;
begin
  DumpFileName := DumpPath + 'TestDumpToFile.gz';
  FPSQLDump.DumpFormat := dfPlain;
  FPSQLDump.CompressLevel := 6;
  FPSQLDump.RewriteFile := True;
  TestDumpToFileLogFile(DumpPath + 'PlainCompressedDump.log');
end;

procedure TestTPSQLDump.TestDumpSections;
begin
  DumpFileName := DumpPath + 'TestDumpSection.backup';
  FPSQLDump.DumpFormat := dfCompressedArchive;
  FPSQLDump.CompressLevel := 6;
  FPSQLDump.RewriteFile := True;
  FPSQLDump.Sections := [drsPreData, drsPostData];
  TestDumpToFileLogFile(DumpPath + 'SectionCompressedDump.log');
end;

procedure TestTPSQLDump.TestDumpTar;
begin
  DumpFileName := DumpPath + 'TestDumpToFile.tar.gz';
  FPSQLDump.DumpFormat := dfTarArchive;
  FPSQLDump.CompressLevel := 6;
  FPSQLDump.RewriteFile := True;
  TestDumpToFileLogFile(DumpPath + 'TarDump.log');
end;

procedure TestTPSQLDump.TestDumpToFileStrings;
var
  Log: TStrings;
begin
  Log := TStringList.Create;
  try
    FPSQLDump.DumpToFile(DumpFileName, Log);
    Check(FileExists(DumpFileName), 'Dump file empty');
    Check(Log.Count > 0, 'Dump log empty');
  finally
    Log.SaveToFile(DumpPath + 'TestDumpToFile.log');
    Log.Free;
  end;
end;

procedure TestTPSQLDump.TestDumpToFileLogFile(ALogFileName: string = '');
var
  LogFileName: string;
begin
  if ALogFileName = '' then
    LogFileName := DumpPath + 'TestDumpToFile1.log'
  else
    LogFileName := ALogFileName;
  FPSQLDump.DumpToFile({DumpPath +} DumpFileName, LogFileName);
  Check(FileExists({DumpPath +} DumpFileName) or DirectoryExists({DumpPath +} DumpFileName), 'Dump file empty');
  Check(FileExists(LogFileName), 'Log file empty');
end;

procedure TestTPSQLRestore.LoadLibrary(Sender: TObject; var FileName: string);
begin
  //FileName := 'pg_restore-9.2.9.dll';
end;

procedure TestTPSQLRestore.SetUp;
begin
  FPSQLRestore := TPSQLRestore.Create(nil);
  FPSQLRestore.Database := TestDBSetup.Database;
  FPSQLRestore.Options := [roVerbose];
  FPSQLRestore.OnLibraryLoad := LoadLibrary;
  DumpPath := {$IFDEF DUNITX}
                        TPath.GetDocumentsPath + PathDelim
                     {$ELSE}
                     'TestOutput\'
                     {$ENDIF};
  DumpFileName:= DumpPath + 'TestDumpToFile.backup';
end;

procedure TestTPSQLRestore.TearDown;
begin
  FPSQLRestore.Free;
  FPSQLRestore := nil;
end;

procedure TestTPSQLRestore.TestRestoreFromDirectoryToFile;
var
  LogFileName: string;
  FileName: string;
begin
  LogFileName := DumpPath + 'RestoreFromDirToFile.log';
  FileName := DumpPath + 'TestDumpToFile';
  FPSQLRestore.RestoreFormat := rfDirectory;
  FPSQLRestore.OutputFileName := DumpPath + 'RestoreFromDirToFileOutput.sql';
  FPSQLRestore.RestoreFromFile(FileName, LogFileName);
  Check(DirectoryExists(FileName), 'Dump directory is empty');
  Check(FileExists(FPSQLRestore.OutputFileName), 'Output file is empty');
  Check(FileExists(LogFileName), 'Log file is empty');
end;

procedure TestTPSQLRestore.TestRestoreFromFileToDB;
var
  Log: TStrings;
  FileName: string;
begin
  TestDBSetup.Database.Execute('CREATE DATABASE restore_test TEMPLATE template0;');
  Log := TStringList.Create;
  try
    FileName := DumpFileName;
    FPSQLRestore.DBName := 'restore_test';
    FPSQLRestore.RestoreFromFile(FileName, Log);
  finally
    TestDBSetup.Database.Execute('DROP DATABASE restore_test;');
    Log.SaveToFile(DumpPath + 'RestoreFromFile.log');
    Log.Free;
  end;
end;

procedure TestTPSQLRestore.TestRestoreFromFileToFile;
var
  LogFileName: string;
  FileName: string;
begin
  LogFileName := DumpPath + 'RestoreFromFileToFile.log';
  FileName := DumpFileName;
  FPSQLRestore.OutputFileName := DumpPath + 'RestoreFromFileToFileOutput.sql';
  FPSQLRestore.RestoreFromFile(FileName, LogFileName);
  Check(FileExists(DumpFileName), 'Dump file empty');
  Check(FileExists(FPSQLRestore.OutputFileName), 'Output file empty');
  Check(FileExists(LogFileName), 'Log file empty');
end;

initialization

{$IFDEF DUNITX}
  TDUnitX.RegisterTestFixture(TestTPSQLDump);
  TDUnitX.RegisterTestFixture(TestTPSQLRestore);
{$ENDIF}

end.
