anchor.diff:      qos_reconciliation_dir_test,
       reconcile_qos_using_file_meta_posthooks_test,
       reconcile_with_links_race_test,
  +    reconcile_with_links_race_nested_file_test,
  +    reconcile_with_links_and_file_meta_race_nested_file_test,
   
       reevaluate_impossible_qos_test,
       reevaluate_impossible_qos_race_test,
  
positive.code:         end).
  
  
  unmock_dbsync_changes(Config) ->
      [Worker1 | _] = ?config(op_worker_nodes, Config),
      test_utils:mock_unload(Worker1, dbsync_changes).
  
  
  unmock_file_meta_posthooks(Config) ->
      Workers = ?config(op_worker_nodes, Config),
      test_utils:mock_unload(Workers, file_meta_posthooks).
  
  
  save_file_meta_docs(Config) ->
      [Worker1 | _] = ?config(op_worker_nodes, Config),
      receive
          {file_meta, Doc} ->
              ?assertMatch(ok, rpc:call(Worker1, dbsync_changes, apply, [Doc])),
              save_file_meta_docs(Config)
      after 0 ->
          ok
      end.
  
  
  create_file_with_content(Worker, SessId, ParentGuid, Name) ->
  
negative.code:     {ok, _} = lfm_proxy:write(Worker, H1, 0, ?TEST_DATA),
      ok = lfm_proxy:close(Worker, H1),
      G.
  
  
  mock_fslogic_authz_ensure_authorized(Worker) ->
      test_utils:mock_new(Worker, fslogic_authz, [passthrough]),
      ok = test_utils:mock_expect(Worker, fslogic_authz, ensure_authorized,
          fun(_, FileCtx, _) ->
              FileCtx
          end).
  
  %%%===================================================================
  %%% DBSync mocks
  %%%===================================================================
  
  mock_dbsync_changes(Worker) ->
      test_utils:mock_new(Worker, dbsync_changes, [passthrough]),
      TestPid = self(),
  
      ok = test_utils:mock_expect(Worker, dbsync_changes, apply,
          fun(#document{value = Value} = Doc) ->
              RecordType = element(1, Value),
              TestPid ! {RecordType, Doc},
              ok
          end).
  
  
  unmock_dbsync_changes(Worker) ->
      test_utils:mock_unload(Worker, dbsync_changes).
  
  
  save_matching_docs(Worker, Filters) ->
      save_docs(Worker, Filters, matching).
  
  
  save_not_matching_docs(Worker, Filters) ->
      save_docs(Worker, Filters, not_matching).
  
  
  save_docs(Worker, Filters, Strategy) ->
      LeftOutDocs = save_docs(Worker, Filters, [], Strategy),
      lists:foreach(fun(#document{value = Value} = Doc) ->
          RecordType = element(1, Value),
          self() ! {RecordType, Doc}
      end, LeftOutDocs).
  
  
  save_docs(Worker, Filters, LeftOutDocs, Strategy) ->
      ExpectedMatch = Strategy == matching,
      receive
          {_, Doc} ->
              case matches_doc(Doc, Filters) of
                  ExpectedMatch ->
                      ?assertMatch(ok, rpc:call(Worker, dbsync_changes, apply, [Doc])),
                      save_docs(Worker, Filters, LeftOutDocs, Strategy);
                  _ ->
                      save_docs(Worker, Filters, [Doc | LeftOutDocs], Strategy)
              end
      after 0 ->
          LeftOutDocs
      end.
  
  
  matches_doc(#document{key = Key, value = Value}, Filters) ->
      RecordType = element(1, Value),
      lists:any(fun
          (R) when R =:= RecordType ->
              true;
          ({R, K}) when R =:= RecordType andalso K =:= Key ->
              true;
          ({links, R, LinksKey}) when R =:= RecordType -> 
              matches_link_doc(Value, LinksKey);
          (_) ->
              false
      end, Filters).
  
  
  matches_link_doc(#links_node{key = Key}, Key) -> true;
  matches_link_doc(#links_forest{key = Key}, Key) -> true;
  matches_link_doc(#links_mask{key = Key}, Key) -> true;
  matches_link_doc(_, _) -> false.
  
  
  ensure_docs_received([]) -> ok;
  ensure_docs_received([{RecordType, _} | Tail]) ->
      wait_for_doc(RecordType),
      ensure_docs_received(Tail);
  ensure_docs_received([{links, RecordType, _} | Tail]) ->
      wait_for_doc(RecordType),
      ensure_docs_received(Tail).
  
  
  wait_for_doc(RecordType) ->
      receive {RecordType, _} = Msg ->
          self() ! Msg
      end.
  