anchor.diff:      "http://" ++ Addr ++ ":" ++ Port ++ "/" ++ ?b2l(DbName).
   
   query_view(DbName, DDoc, View) ->
  +    query_view(DbName, DDoc, View, false).
  +
  +query_view(DbName, DDoc, View, Stale) ->
       {ok, Code, _Headers, Body} = test_request:get(
  -        db_url(DbName) ++ "/_design/" ++ DDoc ++ "/_view/" ++ View),
  +        db_url(DbName) ++ "/_design/" ++ DDoc ++ "/_view/" ++ View
  +        ++ case Stale of
  +               false -> [];
  +               _ -> "?stale=" ++ atom_to_list(Stale)
  +           end),
       ?assertEqual(200, Code),
  -    Body.
  +    {Props} = ejson:decode(Body),
  +    couch_util:get_value(<<"rows">>, Props, []).
  +
  +check_rows_value(Rows, Value) ->
  +    lists:foreach(
  +        fun({Row}) ->
  +            ?assertEqual(Value, couch_util:get_value(<<"value">>, Row))
  +        end, Rows).
   
   view_cleanup(DbName) ->
       {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]),
       couch_mrview:cleanup(Db),
       couch_db:close(Db).
  +
  +get_db_ref_counter(DbName) ->
  +    {ok, #db{fd_ref_counter = Ref} = Db} = couch_db:open_int(DbName, []),
  +    ok = couch_db:close(Db),
  +    Ref.
  +
  +count_db_refs(DbName) ->
  +    Ref = get_db_ref_counter(DbName),
  +    % have to sleep a bit to let couchdb cleanup all refs and leave only
  +    % active ones. otherwise the related tests will randomly fail due to
  +    % count number mismatch
  +    timer:sleep(200),
  +    couch_ref_counter:count(Ref).
   
   count_index_files(DbName) ->
       % call server to fetch the index files
  
positive.code:     view_cleanup(DbName),
      ?_assertEqual(0, count_index_files(DbName)).
  
  
  create_doc(DbName) ->
      {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]),
      Doc666 = couch_doc:from_json_obj({[
          {<<"_id">>, <<"doc666">>},
          {<<"value">>, 999}
  
      ]}),
      {ok, _} = couch_db:update_docs(Db, [Doc666]),
      couch_db:ensure_full_commit(Db),
  
negative.code:     ok = file:rename(DbFile ++ ".backup", DbFile),
      start(),
      ok.
  
  compact_db(DbName) ->
      {ok, Db} = couch_db:open_int(DbName, []),
      {ok, _} = couch_db:start_compact(Db),
      ok = couch_db:close(Db),
      wait_db_compact_done(DbName, 10).
  
  wait_db_compact_done(_DbName, 0) ->
      erlang:error({assertion_failed,
                    [{module, ?MODULE},
                     {line, ?LINE},
                     {reason, "DB compaction failed to finish"}]});
  wait_db_compact_done(DbName, N) ->
      {ok, Db} = couch_db:open_int(DbName, []),
      ok = couch_db:close(Db),
      case is_pid(Db#db.compactor_pid) of
      false ->
          ok;
      true ->
          ok = timer:sleep(?DELAY),
          wait_db_compact_done(DbName, N - 1)
      end.
  
  compact_view_group(DbName, DDocId) when is_list(DDocId) ->
      compact_view_group(DbName, ?l2b("_design/" ++ DDocId));
  compact_view_group(DbName, DDocId) when is_binary(DDocId) ->
      ok = couch_mrview:compact(DbName, DDocId),
      wait_view_compact_done(DbName, DDocId, 10).
  
  wait_view_compact_done(_DbName, _DDocId, 0) ->
      erlang:error({assertion_failed,
                    [{module, ?MODULE},
                     {line, ?LINE},
                     {reason, "DB compaction failed to finish"}]});
  wait_view_compact_done(DbName, DDocId, N) ->
      {ok, Code, _Headers, Body} = test_request:get(
          db_url(DbName) ++ "/" ++ ?b2l(DDocId) ++ "/_info"),
      ?assertEqual(200, Code),
      {Info} = ejson:decode(Body),
      {IndexInfo} = couch_util:get_value(<<"view_index">>, Info),
      CompactRunning = couch_util:get_value(<<"compact_running">>, IndexInfo),
      case CompactRunning of
          false ->
              ok;
          true ->
              ok = timer:sleep(?DELAY),
              wait_view_compact_done(DbName, DDocId, N - 1)
      end.
  