Files
UnrealEngineUWP/Engine/Source/Developer/ScreenShotComparison/Private/Models/ScreenComparisonModel.cpp
Nick Darnell 5c3f60e315 Copying //UE4/Dev-Automation to //UE4/Dev-Main (Source: //UE4/Dev-Automation @ 3376875)
#lockdown Nick.Penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 3340659 on 2017/03/09 by nick.bullard

	Submitting Template map with update to lighting. The direction of the light was not optimal for looking down X+ for screenshots, which is what the SSF actor does be default.

Change 3340686 on 2017/03/09 by Nick.Bullard

	Updating Animaton/SetVertexColor map to use Template map setup.

Change 3364139 on 2017/03/24 by Nick.Darnell

	Automation - Removing the option to disable taking screenshots, doesn't make sense to have that any more.  Screenshot comparison in an intergal part of the tests now.
	Automation - The system now waits for the asset registry to finish loading assets before running tests.

Change 3364149 on 2017/03/24 by Nick.Darnell

	Automation - Fixing a bug with the source control not reverting the state of screenshots before marking them for delete.

Change 3364588 on 2017/03/24 by Nick.Darnell

	Removing the allow screenshots option.

Change 3364591 on 2017/03/24 by Nick.Darnell

	Automation - Making the camera functional test actor respect the delay.

Change 3364598 on 2017/03/24 by Nick.Darnell

	Automation - Disabling Noisy rendering features now actually disables TAA, instead of enabling FXAA.

Change 3364723 on 2017/03/25 by Nick.Darnell

	Automation - Fixing the client functional test runner to pass object and package path so that in the editor we can reliably load a particular map with object path, but for actually opening the map we can use the package path when running the test since that is what works at editor and in a cooked game.

Change 3366600 on 2017/03/27 by Nick.Bullard

	Adding FuntionalTest map back as selection in New Map window

Change 3367590 on 2017/03/28 by Nick.Darnell

	Automation - Fixing a bug with initial tolerence levels.  They showed as 'Low' in the UI, but the values were in fact all set to 0.  So new screenshot tests had zero tolerence for pixel differences.

	Automation - Adding some documentation to Functional Test.

Change 3367602 on 2017/03/28 by Nick.Darnell

	Automation - Forcing more things to stream in before the screenshots are taken.

Change 3367604 on 2017/03/28 by Nick.Darnell

	Automation - Adding some flare to how disabled functional test actors appear in the editor.

Change 3368024 on 2017/03/28 by mason.seay

	Added new test to map.  Disabled since it hasn't ran at all

Change 3368109 on 2017/03/28 by mason.seay

	Updating authorship on test actors

Change 3369701 on 2017/03/29 by Nick.Bullard

	Removing old Ground Truth images. Investigating why new copies were made rather than replacing original.

Change 3373253 on 2017/03/30 by Samuel.Proctor

	Test updates for Containers. Adding coverage for native containers

Change 3373294 on 2017/03/30 by Nick.Darnell

	Automation - Fixing a bug with Tolerence levels set via blueprints, now properly configuring the tolerence amounts before the screenshot is taken.

Change 3374355 on 2017/03/31 by Samuel.Proctor

	Added testing scenarios to the test actors and fixed a few typos.

[CL 3376906 by Nick Darnell in Main branch]
2017-04-03 13:59:25 -04:00

234 lines
6.8 KiB
C++

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "ScreenComparisonModel.h"
#include "ISourceControlModule.h"
#include "ISourceControlOperation.h"
#include "SourceControlOperations.h"
#include "ISourceControlProvider.h"
#include "Paths.h"
DEFINE_LOG_CATEGORY_STATIC(LogScreenshotComparison, Log, All);
FScreenComparisonModel::FScreenComparisonModel(const FComparisonReport& InReport)
: Report(InReport)
, bComplete(false)
{
const FImageComparisonResult& ComparisonResult = Report.Comparison;
FString IncomingImage = Report.ReportFolder / ComparisonResult.ReportIncomingFile;
FString IncomingMetadata = FPaths::ChangeExtension(IncomingImage, TEXT("json"));
FileImports.Add(FFileMapping(IncomingImage, ComparisonResult.IncomingFile));
FileImports.Add(FFileMapping(IncomingMetadata, FPaths::ChangeExtension(ComparisonResult.IncomingFile, TEXT("json"))));
}
bool FScreenComparisonModel::IsComplete() const
{
return bComplete;
}
void FScreenComparisonModel::Complete()
{
FString RelativeReportFolder = Report.ReportFolder;
if ( FPaths::MakePathRelativeTo(RelativeReportFolder, *Report.ReportRootDirectory) )
{
for (;;)
{
FString ParentFolder = FPaths::GetPath(RelativeReportFolder);
if ( ParentFolder.IsEmpty() )
{
break;
}
RelativeReportFolder = ParentFolder;
}
FString ReportTopFolder = Report.ReportRootDirectory / RelativeReportFolder;
if ( IFileManager::Get().DeleteDirectory(*ReportTopFolder, false, true) )
{
bComplete = true;
OnComplete.Broadcast();
}
}
}
TOptional<FAutomationScreenshotMetadata> FScreenComparisonModel::GetMetadata()
{
// Load it.
if ( !Metadata.IsSet() )
{
FString IncomingImage = Report.ReportFolder / Report.Comparison.ReportIncomingFile;
FString IncomingMetadata = FPaths::ChangeExtension(IncomingImage, TEXT("json"));
if ( !IncomingMetadata.IsEmpty() )
{
FString Json;
if ( FFileHelper::LoadFileToString(Json, *IncomingMetadata) )
{
FAutomationScreenshotMetadata LoadedMetadata;
if ( FJsonObjectConverter::JsonObjectStringToUStruct(Json, &LoadedMetadata, 0, 0) )
{
Metadata = LoadedMetadata;
}
}
}
}
return Metadata;
}
bool FScreenComparisonModel::AddNew(IScreenShotManagerPtr ScreenshotManager)
{
// Copy the files from the reports location to the destination location
TArray<FString> SourceControlFiles;
for ( const FFileMapping& Import : FileImports )
{
FString DestFilePath = ScreenshotManager->GetLocalApprovedFolder() / Import.DestinationFile;
IFileManager::Get().Copy(*DestFilePath, *Import.SourceFile, true, true);
SourceControlFiles.Add(DestFilePath);
}
// Add the files to source control
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FMarkForAdd>(), SourceControlFiles) == ECommandResult::Failed )
{
// TODO Error
}
Complete();
return true;
}
bool FScreenComparisonModel::Replace(IScreenShotManagerPtr ScreenshotManager)
{
// Delete all the existing files in this area
RemoveExistingApproved(ScreenshotManager);
// Copy files to the approved
const FString& LocalApprovedFolder = ScreenshotManager->GetLocalApprovedFolder();
const FString ImportIncomingRoot = Report.ReportFolder;
TArray<FString> SourceControlFiles;
for ( const FFileMapping& Import : FileImports )
{
FString DestFilePath = LocalApprovedFolder / Import.DestinationFile;
SourceControlFiles.Add(DestFilePath);
}
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FRevert>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
for ( const FFileMapping& Import : FileImports )
{
FString DestFilePath = LocalApprovedFolder / Import.DestinationFile;
IFileManager::Get().Copy(*DestFilePath, *Import.SourceFile, true, true);
SourceControlFiles.Add(DestFilePath);
}
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FMarkForAdd>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FCheckOut>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
Complete();
return true;
}
bool FScreenComparisonModel::RemoveExistingApproved(IScreenShotManagerPtr ScreenshotManager)
{
TArray<FString> FilesToRemove;
FString PlatformFolder = Report.ReportFolder;
IFileManager::Get().FindFilesRecursive(FilesToRemove, *PlatformFolder, TEXT("*.*"), true, false);
// Copy files to the approved
const FString& LocalApprovedFolder = ScreenshotManager->GetLocalApprovedFolder();
const FString ImportApprovedRoot = Report.ReportFolder / TEXT("");
TArray<FString> SourceControlFiles;
for ( const FString& File : FilesToRemove )
{
FString RelativeFile = File;
FPaths::MakePathRelativeTo(RelativeFile, *ImportApprovedRoot);
FString DestFilePath = LocalApprovedFolder / RelativeFile;
SourceControlFiles.Add(DestFilePath);
}
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FRevert>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
for ( const FString& File : SourceControlFiles )
{
IFileManager::Get().Delete(*File, false, true, false);
}
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FDelete>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
return true;
}
bool FScreenComparisonModel::AddAlternative(IScreenShotManagerPtr ScreenshotManager)
{
// Copy files to the approved
const FString& LocalApprovedFolder = ScreenshotManager->GetLocalApprovedFolder();
const FString ImportIncomingRoot = Report.ReportFolder;
TArray<FString> SourceControlFiles;
for ( const FFileMapping& Import : FileImports )
{
FString DestFilePath = LocalApprovedFolder / Import.DestinationFile;
SourceControlFiles.Add(DestFilePath);
}
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FRevert>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
for ( const FFileMapping& Import : FileImports )
{
FString DestFilePath = LocalApprovedFolder / Import.DestinationFile;
if ( IFileManager::Get().Copy(*DestFilePath, *Import.SourceFile, false, true) == COPY_OK )
{
SourceControlFiles.Add(DestFilePath);
}
else
{
// TODO Error
}
}
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FMarkForAdd>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
if ( SourceControlProvider.Execute(ISourceControlOperation::Create<FCheckOut>(), SourceControlFiles) == ECommandResult::Failed )
{
//TODO Error
}
Complete();
return true;
}