anchor.diff:      lists:foreach(fun(Guid) ->
           ExpContent = read_file(SrcNode, SrcNodeSessId, Guid),
           % Read file on DstNode to force rtransfer
  +        api_test_utils:wait_for_file_sync(DstNode, DstNodeSessId, Guid),
           ?assertMatch(ExpContent, read_file(DstNode, DstNodeSessId, Guid), ?ATTEMPTS)
       end, Files);
   sync_files_between_nodes(_TransferType, _SrcNode, _SrcNodeSessId, DstNode, DstNodeSessId, Files) ->
  
positive.code: 
  
  %% @private
  assert_distribution(Node, SessId, ExpSize, ExpProviders, Files) ->
      lists:foreach(fun(FileGuid) ->
          ExpDistribution = [?FILE_DISTRIBUTION(ExpSize, Provider) || Provider <- ExpProviders],
          ?assertEqual(
              {ok, ExpDistribution},
              lfm_proxy:get_file_distribution(Node, SessId, {guid, FileGuid})
          )
      end, Files).
  
  
  
negative.code: 
  
  %%%===================================================================
  %%% Transfer view test functions
  %%%===================================================================
  
  
  create_view_replication(Config) ->
      [P2, _P1] = ?config(op_worker_nodes, Config),
  
      RequiredPrivs = [?SPACE_SCHEDULE_REPLICATION, ?SPACE_QUERY_VIEWS],
  
      TransferDataSpec = #data_spec{
          required = [
              <<"type">>, <<"dataSourceType">>,
              <<"replicatingProviderId">>,
              <<"spaceId">>, <<"viewName">>
          ],
          optional = [<<"callback">>],
          correct_values = #{
              <<"type">> => [<<"replication">>],
              <<"dataSourceType">> => [<<"view">>],
              <<"replicatingProviderId">> => [?GET_DOMAIN_BIN(P2)],
              <<"spaceId">> => [?SPACE_2],
              <<"viewName">> => [?PLACEHOLDER],
              <<"callback">> => [<<"https://localhost">>]
          },
          bad_values = ?TYPE_AND_DATA_SOURCE_TYPE_BAD_VALUES ++ [
              {<<"replicatingProviderId">>, 100, ?ERROR_BAD_VALUE_BINARY(<<"replicatingProviderId">>)},
              {<<"replicatingProviderId">>, <<"NonExistingProvider">>, ?ERROR_SPACE_NOT_SUPPORTED_BY(<<"NonExistingProvider">>)},
              {<<"callback">>, 100, ?ERROR_BAD_VALUE_BINARY(<<"callback">>)}
          ]
      },
  
      ReplicaDataSpec = #data_spec{
          required = [<<"provider_id">>, <<"space_id">>],
          optional = [<<"url">>],
          correct_values = #{
              <<"provider_id">> => [?GET_DOMAIN_BIN(P2)],
              <<"space_id">> => [?SPACE_2],
              <<"url">> => [<<"https://localhost">>]
          },
          bad_values = [
              {<<"provider_id">>, 100, {gs, ?ERROR_BAD_VALUE_BINARY(<<"provider_id">>)}},
              {<<"provider_id">>, <<"NonExistingProvider">>, ?ERROR_SPACE_NOT_SUPPORTED_BY(<<"NonExistingProvider">>)},
              {<<"url">>, 100, {gs, ?ERROR_BAD_VALUE_BINARY(<<"url">>)}}
          ]
      },
  
      create_view_transfer(Config, replication, TransferDataSpec, ReplicaDataSpec, RequiredPrivs).
  
  
  create_view_eviction(Config) ->
      [_P2, P1] = ?config(op_worker_nodes, Config),
  
      RequiredPrivs = [?SPACE_SCHEDULE_EVICTION, ?SPACE_QUERY_VIEWS],
  
      TransferDataSpec = #data_spec{
          required = [
              <<"type">>, <<"dataSourceType">>,
              <<"evictingProviderId">>,
              <<"spaceId">>, <<"viewName">>
          ],
          optional = [<<"callback">>],
          correct_values = #{
              <<"type">> => [<<"eviction">>],
              <<"dataSourceType">> => [<<"view">>],
              <<"evictingProviderId">> => [?GET_DOMAIN_BIN(P1)],
              <<"spaceId">> => [?SPACE_2],
              <<"viewName">> => [?PLACEHOLDER],
              <<"callback">> => [<<"https://localhost">>]
          },
          bad_values = ?TYPE_AND_DATA_SOURCE_TYPE_BAD_VALUES ++ [
              {<<"evictingProviderId">>, 100, ?ERROR_BAD_VALUE_BINARY(<<"evictingProviderId">>)},
              {<<"evictingProviderId">>, <<"NonExistingProvider">>, ?ERROR_SPACE_NOT_SUPPORTED_BY(<<"NonExistingProvider">>)},
              {<<"callback">>, 100, ?ERROR_BAD_VALUE_BINARY(<<"callback">>)}
          ]
      },
  
      ReplicaDataSpec = #data_spec{
          required = [<<"provider_id">>, <<"space_id">>],
          optional = [<<"url">>],
          correct_values = #{
              <<"provider_id">> => [?GET_DOMAIN_BIN(P1)],
              <<"space_id">> => [?SPACE_2],
              <<"url">> => [<<"https://localhost">>]
          },
          bad_values = [
              {<<"provider_id">>, 100, {gs, ?ERROR_BAD_VALUE_BINARY(<<"provider_id">>)}},
              {<<"provider_id">>, <<"NonExistingProvider">>, ?ERROR_SPACE_NOT_SUPPORTED_BY(<<"NonExistingProvider">>)},
              {<<"url">>, 100, {gs, ?ERROR_BAD_VALUE_BINARY(<<"url">>)}}
          ]
      },
  
      create_view_transfer(Config, eviction, TransferDataSpec, ReplicaDataSpec, RequiredPrivs).
  
  
  %% @private
  create_view_transfer(Config, Type, TransferDataSpec, ReplicaDataSpec, RequiredPrivs) ->
      [P2, P1] = Providers = ?config(op_worker_nodes, Config),
  
      set_space_privileges(Providers, ?SPACE_2, ?USER_IN_SPACE_2, privileges:space_admin() -- RequiredPrivs),
      set_space_privileges(Providers, ?SPACE_2, ?USER_IN_BOTH_SPACES, RequiredPrivs),
  
      ?assert(api_test_runner:run_tests(Config, [
          #suite_spec{
              target_nodes = Providers,
              client_spec = ?CLIENT_SPEC_FOR_TRANSFER_SCENARIOS(Config),
              setup_fun = create_setup_view_transfer_env(Type, P1, P2, ?USER_IN_SPACE_2, Config),
              verify_fun = create_verify_transfer_env(Type, P2, ?USER_IN_SPACE_2, P1, P2, Config),
              scenario_templates = [
                  #scenario_template{
                      name = str_utils:format("Transfer (~p) view using gs transfer api", [Type]),
                      type = gs,
                      prepare_args_fun = create_prepare_transfer_create_instance_gs_args_fun(private),
                      validate_result_fun = fun validate_transfer_gs_call_result/2
                  }
              ],
              data_spec = TransferDataSpec
          },
  
          %% TEST DEPRECATED REPLICAS ENDPOINTS
  
          #suite_spec{
              target_nodes = Providers,
              client_spec = ?CLIENT_SPEC_FOR_TRANSFER_SCENARIOS(Config),
              setup_fun = create_setup_view_transfer_env(Type, P1, P2, ?USER_IN_SPACE_2, Config),
              verify_fun = create_verify_transfer_env(Type, P2, ?USER_IN_SPACE_2, P1, P2, Config),
              scenario_templates = [
                  #scenario_template{
                      name = str_utils:format("Transfer (~p) view using /replicas-view/ rest endpoint", [Type]),
                      type = rest,
                      prepare_args_fun = create_prepare_replica_rest_args_fun(Type),
                      validate_result_fun = fun validate_transfer_rest_call_result/2
                  },
                  #scenario_template{
                      name = str_utils:format("Transfer (~p) view using op_replica gs api", [Type]),
                      type = gs,
                      prepare_args_fun = create_prepare_replica_gs_args_fun(Type, private),
                      validate_result_fun = fun validate_transfer_gs_call_result/2
                  }
              ],
              data_spec = ReplicaDataSpec
          }
      ])).
  
  
  %%%===================================================================
  %%% Common transfer helper functions
  %%%===================================================================
  
  