/// <summary>
 /// Tests the typical request.
 /// </summary>
 /// <param name="parametersLine">The parameters line.</param>
 /// <param name="inputFileName">Name of the input file.</param>
 /// <param name="invokeRequestFunc">The invoke request function that returns response length.</param>
 /// <param name="customResponseTester">The response tester.</param>
 /// <param name="folder">The folder.</param>
 /// <param name="storage">The storage.</param>
 protected void TestRequestWithTypedResponse <T>(
     string parametersLine,
     string inputFileName,
     Func <T> invokeRequestFunc,
     ResponseValidatorDelegate <T> customResponseTester,
     string folder  = CloudTestFolder,
     string storage = DefaultStorage)
 {
     TestRequestInternal(
         parametersLine,
         inputFileName,
         null,
         false,
         () =>
     {
         var response = invokeRequestFunc.Invoke();
         return(response);
     },
         customResponseTester,
         folder,
         storage);
 }
        /// <summary>
        /// Tests the typical request.
        /// </summary>
        /// <param name="parametersLine">The parameters line.</param>
        /// <param name="inputFileName">Name of the input file.</param>
        /// <param name="resultFileName">Name of the result file.</param>
        /// <param name="saveResultToStorage">If result should be saved to storage</param>
        /// <param name="invokeRequestFunc">The invoke request function that returns response length.</param>
        /// <param name="customResponseTester">The response tester.</param>
        /// <param name="folder">The folder.</param>
        /// <param name="storage">The storage.</param>
        private void TestRequestInternal <T>(
            string parametersLine,
            string inputFileName,
            string resultFileName,
            bool saveResultToStorage,
            Func <T> invokeRequestFunc,
            ResponseValidatorDelegate <T> customResponseTester,
            string folder  = CloudTestFolder,
            string storage = DefaultStorage)
        {
            Console.WriteLine(GetCallerMethodName());

            if (!string.IsNullOrEmpty(inputFileName) && !CheckFileExistsOnCloud(inputFileName, InputTestFiles))
            {
                throw new ArgumentException(
                          $"Input file {inputFileName} doesn't exist in the specified storage folder: {folder}. Please, upload it first.");
            }

            bool   passed        = false;
            string outPath       = null;
            string referencePath = CloudReferencesFolder;

            try
            {
                Console.WriteLine(parametersLine);

                if (saveResultToStorage)
                {
                    outPath = CloudTempFolder + "/" + resultFileName;

                    // remove output file from the storage (if exists)
                    if (CadApi.ObjectExists(new ObjectExistsRequest(outPath, storage)).Exists ?? false)
                    {
                        CadApi.DeleteFile(new DeleteFileRequest(outPath, storage));
                    }
                }

                var response = invokeRequestFunc.Invoke();

                var download = saveResultToStorage
                                    ? CadApi.DownloadFile(new DownloadFileRequest(outPath, storage))
                                    : response as Stream;

                if (AutoRecoverReference && download != null)
                {
                    var hasToUpload = ForceReferenceOverride;
                    if (!CadApi.ObjectExists(new ObjectExistsRequest(referencePath + "/" + resultFileName, storage)).Exists ?? false)
                    {
                        hasToUpload = true;
                    }
                    else if (ForceReferenceOverride)
                    {
                        hasToUpload = true;
                        CadApi.DeleteFile(new DeleteFileRequest(referencePath + "/" + resultFileName, storage));
                    }

                    if (hasToUpload)
                    {
                        CadApi.UploadFile(new UploadFileRequest(referencePath + "/" + resultFileName, download, storage));
                    }

#if DEBUG
                    if (!string.IsNullOrEmpty(resultFileName) && download != null)
                    {
                        using (var fs = File.OpenWrite(Path.Combine(LocalReferenceFolderFullPath, resultFileName)))
                        {
                            download.CopyTo(fs);
                        }
                    }
#endif
                }

                if (saveResultToStorage)
                {
                    var resultInfo = GetStorageFileInfo(CloudTempFolder, resultFileName, storage);
                    if (resultInfo == null)
                    {
                        throw new ArgumentException(
                                  $"Result file {resultFileName} doesn't exist in the specified storage folder: {folder}. Result isn't present in the storage by an unknown reason.");
                    }
                }

                var referenceInfo = GetStorageFileInfo(referencePath, resultFileName, storage);
                if (!string.IsNullOrEmpty(outPath) && referenceInfo == null)
                {
                    throw new ArgumentException(
                              $"Reference result file {resultFileName} doesn't exist in the specified storage folder: {referencePath}. Please, upload it first.");
                }

                // check resulting image from response stream
                customResponseTester?.Invoke(response, download, referenceInfo);

                passed = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
            finally
            {
                if (saveResultToStorage &&
                    !passed &&
                    this.AutoRecoverReference &&
                    (CadApi.ObjectExists(new ObjectExistsRequest(outPath, storage)).Exists ?? false))
                {
                    CadApi.MoveFile(new MoveFileRequest(outPath, referencePath + "/" + resultFileName, storage, storage));
                }
                else if (saveResultToStorage &&
                         this.RemoveResult &&
                         (CadApi.ObjectExists(new ObjectExistsRequest(outPath, storage)).Exists ?? false))
                {
                    CadApi.DeleteFile(new DeleteFileRequest(outPath, storage));
                }

                Console.WriteLine($"Test passed: {passed}");
            }
        }