Uploaded image for project: 'CouchDB'
  1. CouchDB
  2. COUCHDB-731

Improved Query Server tests

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Trivial
    • Resolution: Won't Fix
    • None
    • None
    • Test Suite
    • None
    • New Contributors Level (Easy)

    Description

      In the process of writing a ruby version of the query server, I wrote a few more tests for the javascript and erlang ones to help determine the proper behavior of certain cases. The ones pertaining to handling syntax errors will fail for erlang, but pass on javascript; apparently this is by design. Anyway, here they are, my hope is that other people attempting an implementation of the query server find them useful.

      diff --git a/test/view_server/query_server_spec.rb b/test/view_server/query_server_spec.rb
      index 1de8e5b..c427e35 100644
      — a/test/view_server/query_server_spec.rb
      +++ b/test/view_server/query_server_spec.rb

      @@ -508,34 +623,70 @@ describe "query server normal case" do
      [{:title => "Best ever", :body => "Doc body"}, {}]).should ==
      ["resp",

      {"body" => "Best ever - Doc body"}

      ]
      end

      • it "should run map funs" do
      • @qs.reset!
      • @qs.run(["add_fun", functions["emit-twice"][LANGUAGE]]).should == true
        + it "should clear map functions on reset" do
        @qs.run(["add_fun", functions["emit-once"][LANGUAGE]]).should == true
      • rows = @qs.run(["map_doc", {:a => "b"}])
      • rows[0][0].should == ["foo", "b"]
      • rows[0][1].should == ["bar", "b"]
      • rows[1][0].should == ["baz", "b"]
        + @qs.run(["map_doc", {:a => "b"}]).size.should be > 0
        + @qs.run(["reset"])
        + @qs.run(["map_doc", {:a => "b"}]).size.should == 0
        end
        +
        + describe "map functions" do
        + before do
        + @qs.reset!
        + end
        + it "should run map funs" do
        + @qs.run(["add_fun", functions["emit-twice"][LANGUAGE]]).should == true
        + @qs.run(["add_fun", functions["emit-once"][LANGUAGE]]).should == true
        + rows = @qs.run(["map_doc", {:a => "b"}])
        + rows[0][0].should == ["foo", "b"]
        + rows[0][1].should == ["bar", "b"]
        + rows[1][0].should == ["baz", "b"]
        + end
        +
        + it "should return error on invalid expressions" do
        + response = @qs.run(["add_fun", functions["map-invalid-expression"][LANGUAGE]])
        + response.should be_kind_of Array
        + response[0].should == 'error'
        + response[1].should == 'compilation_error'
        + end
        +
        + it "should return error on non-function expressions" do
        + response = @qs.run(["add_fun", functions["map-non-function-expression"][LANGUAGE]])
        + response.should be_kind_of Array
        + response[0].should == 'error'
        + response[1].should == 'compilation_error'
        + end
        +
        + it "has access to the logger" do
        + @qs.run(["add_fun", functions["map-logging"][LANGUAGE]])
        + @qs.rrun(["map_doc", {:a => "b"}])
        + response = JSON.parse @qs.rgets
        + response.should == ["log", " {\"a\":\"b\"}

        "]
        + response = @qs.jsgets
        + response.should == [[[ "logged", "b" ]]]
        + end
        + end
        +
        describe "reduce" do
        before(:all) do
        @fun = functions["reduce-values-length"][LANGUAGE]
        + @fun2 = functions["reduce-values-sum"][LANGUAGE]
        @qs.reset!
        end
        it "should reduce" do
        kvs = (0...10).collect

        {|i|[i,i*2]}
      • @qs.run(["reduce", [@fun], kvs]).should == [true, [10]]
        + @qs.run(["reduce", [@fun, @fun2], kvs]).should == [true, [10, 90]]
        end
        end
        describe "rereduce" do
        before(:all) do
        @fun = functions["reduce-values-sum"][LANGUAGE]
        + @fun2 = functions["reduce-values-length"][LANGUAGE]
        @qs.reset!
        end
        it "should rereduce" do
        vs = (0...10).collect {|i|i}
      • @qs.run(["rereduce", [@fun], vs]).should == [true, [45]]
        + @qs.run(["rereduce", [@fun, @fun2], vs]).should == [true, [45, 10]]
        end
        end

      @@ -648,6 +799,15 @@ describe "query server normal case" do
      doc.should ==

      {"foo" => "gnarly", "world" => "hello"}

      resp["body"].should == "hello doc"
      end
      + # TODO: fails in erlang, passes in javascript. does it matter or not?
      + it "should reject GET requests" do
      + err, name, msg = @qs.ddoc_run(@ddoc,
      + ["updates","basic"],
      + [

      {"foo" => "gnarly"}

      ,

      {"method" => "GET"}

      ]
      + )
      + err.should == "error"
      + name.should == "method_not_allowed"
      + end
      end

      1. end
        @@ -655,99 +815,100 @@ describe "query server normal case" do
      2. _END_

      describe "ddoc list" do

      • before(:all) do
      • @ddoc = {
      • "_id" => "foo",
      • "lists" => { - "simple" => functions["list-simple"][LANGUAGE], - "headers" => functions["show-sends"][LANGUAGE], - "rows" => functions["show-while-get-rows"][LANGUAGE], - "buffer-chunks" => functions["show-while-get-rows-multi-send"][LANGUAGE], - "chunky" => functions["list-chunky"][LANGUAGE] - }

        + before(:all) do
        + @ddoc = {
        + "_id" => "foo",
        + "lists" =>

        { + "simple" => functions["list-simple"][LANGUAGE], + "headers" => functions["show-sends"][LANGUAGE], + "rows" => functions["show-while-get-rows"][LANGUAGE], + "buffer-chunks" => functions["show-while-get-rows-multi-send"][LANGUAGE], + "chunky" => functions["list-chunky"][LANGUAGE] }
      • @qs.teach_ddoc(@ddoc)
      • end
      • describe "example list" do
      • it "should run normal" do
      • @qs.ddoc_run(@ddoc,
      • ["lists","simple"],
      • [ {"foo"=>"bar"}, {"q" => "ok"}]
        - ).should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        - @qs.run(["list_row", {"key"=>"baz"}]).should == ["chunks", ["baz"]]
        - @qs.run(["list_row", {"key"=>"bam"}]).should == ["chunks", ["bam"]]
        - @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
        - @qs.run(["list_row", {"key"=>"fooz"}]).should == ["chunks", ["fooz"]]
        - @qs.run(["list_row", {"key"=>"foox"}]).should == ["chunks", ["foox"]]
        - @qs.run(["list_end"]).should == ["end" , ["early"]]
        - end
        + }
        + @qs.teach_ddoc(@ddoc)
        + end
        +
        + describe "example list" do
        + it "should run normal" do
        + @qs.ddoc_run(@ddoc,
        + ["lists","simple"],
        + [{"foo"=>"bar"}

        ,

        {"q" => "ok"}]
        + ).should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        + @qs.run(["list_row", {"key"=>"baz"}]).should == ["chunks", ["baz"]]
        + @qs.run(["list_row", {"key"=>"bam"}]).should == ["chunks", ["bam"]]
        + @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
        + @qs.run(["list_row", {"key"=>"fooz"}]).should == ["chunks", ["fooz"]]
        + @qs.run(["list_row", {"key"=>"foox"}]).should == ["chunks", ["foox"]]
        + @qs.run(["list_end"]).should == ["end" , ["early"]]
        end
        -
        - describe "headers" do
        - it "should do headers proper" do
        - @qs.ddoc_run(@ddoc, ["lists","headers"],
        - [{"total_rows"=>1000}, {"q" => "ok"}

        ]

      • ).should == ["start", ["first chunk", 'second "chunk"'],
      • {"headers"=>{"Content-Type"=>"text/plain"}}]
      • @qs.rrun(["list_end"])
      • @qs.jsgets.should == ["end", ["tail"]]
      • end
        + end
        +
        + describe "headers" do
        + it "should do headers proper" do
        + @qs.ddoc_run(@ddoc, ["lists","headers"],
        + [ {"total_rows"=>1000}

        ,

        {"q" => "ok"}]
        + ).should == ["start", ["first chunk", 'second "chunk"'],
        + {"headers"=>{"Content-Type"=>"text/plain"}}]
        + @qs.rrun(["list_end"])
        + @qs.jsgets.should == ["end", ["tail"]]
        end
        + end

        - describe "with rows" do
        - it "should list em" do
        - @qs.ddoc_run(@ddoc, ["lists","rows"],
        - [{"foo"=>"bar"}, {"q" => "ok"}

        ]).

      • should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
      • @qs.rrun(["list_row", {"key"=>"baz"}])
        - @qs.get_chunks.should == ["baz"]
        - @qs.rrun(["list_row", {"key"=>"bam"}])
        - @qs.get_chunks.should == ["bam"]
        - @qs.rrun(["list_end"])
        - @qs.jsgets.should == ["end", ["tail"]]
        - end
        - it "should work with zero rows" do
        - @qs.ddoc_run(@ddoc, ["lists","rows"],
        - [{"foo"=>"bar"}, {"q" => "ok"}]).
        - should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        - @qs.rrun(["list_end"])
        - @qs.jsgets.should == ["end", ["tail"]]
        - end
        - end
        -
        - describe "should buffer multiple chunks sent for a single row." do
        - it "should should buffer em" do
        - @qs.ddoc_run(@ddoc, ["lists","buffer-chunks"],
        - [{"foo"=>"bar"}, {"q" => "ok"}]
        ).
        - should == ["start", ["bacon"], {"headers"=>{}}]
        - @qs.rrun(["list_row", {"key"=>"baz"}

        ])

      • @qs.get_chunks.should == ["baz", "eggs"]
      • @qs.rrun(["list_row", {"key"=>"bam"}])
        - @qs.get_chunks.should == ["bam", "eggs"]
        - @qs.rrun(["list_end"])
        - @qs.jsgets.should == ["end", ["tail"]]
        - end
        + describe "with rows" do
        + it "should list em" do
        + @qs.ddoc_run(@ddoc, ["lists","rows"],
        + [{"foo"=>"bar"}, {"q" => "ok"}]).
        + should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        + @qs.rrun(["list_row", {"key"=>"baz"}])
        + @qs.get_chunks.should == ["baz"]
        + @qs.rrun(["list_row", {"key"=>"bam"}

        ])
        + @qs.get_chunks.should == ["bam"]
        + @qs.rrun(["list_end"])
        + @qs.jsgets.should == ["end", ["tail"]]
        end

      • it "should end after 2" do
      • @qs.ddoc_run(@ddoc, ["lists","chunky"],
        + it "should work with zero rows" do
        + @qs.ddoc_run(@ddoc, ["lists","rows"],
        [ {"foo"=>"bar"}, {"q" => "ok"}]).
        should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        -
        - @qs.run(["list_row", {"key"=>"baz"}]).
        - should == ["chunks", ["baz"]]
        -
        - @qs.run(["list_row", {"key"=>"bam"}]).
        - should == ["chunks", ["bam"]]
        -
        - @qs.run(["list_row", {"key"=>"foom"}]).
        - should == ["end", ["foom", "early tail"]]
        - # here's where js has to discard quit properly
        - @qs.run(["reset"]).
        - should == true
        + @qs.rrun(["list_end"])
        + @qs.jsgets.should == ["end", ["tail"]]
        + end
        + end
        +
        + describe "should buffer multiple chunks sent for a single row." do
        + it "should should buffer em" do
        + @qs.ddoc_run(@ddoc, ["lists","buffer-chunks"],
        + [{"foo"=>"bar"}

        ,

        {"q" => "ok"}]).
        + should == ["start", ["bacon"], {"headers"=>{}}]
        + @qs.rrun(["list_row", {"key"=>"baz"}])
        + @qs.get_chunks.should == ["baz", "eggs"]
        + @qs.rrun(["list_row", {"key"=>"bam"}])
        + @qs.get_chunks.should == ["bam", "eggs"]
        + @qs.rrun(["list_end"])
        + @qs.jsgets.should == ["end", ["tail"]]
        end
        end
        +
        + it "should end after 2" do
        + @qs.ddoc_run(@ddoc, ["lists","chunky"],
        + [{"foo"=>"bar"}, {"q" => "ok"}

        ]).
        + should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        +
        + @qs.run(["list_row",

        {"key"=>"baz"}]).
        + should == ["chunks", ["baz"]]
        +
        + @qs.run(["list_row", {"key"=>"bam"}]).
        + should == ["chunks", ["bam"]]
        +
        + @qs.run(["list_row", {"key"=>"foom"}]).
        + should == ["end", ["foom", "early tail"]]
        + # here's where js has to discard quit properly
        + @qs.run(["reset"]).
        + should == true
        + end
        end
        +end



        @@ -762,58 +923,60 @@ def should_have_exited qs
        end
        end

        -describe "query server that exits" do
        - before(:each) do
        - @qs = QueryServerRunner.run
        - @ddoc = {
        - "_id" => "foo",
        - "lists" => { - "capped" => functions["list-capped"][LANGUAGE], - "raw" => functions["list-raw"][LANGUAGE] - },
        - "shows" => {
        - "fatal" => functions["fatal"][LANGUAGE]
        +if LANGUAGE=='js'
        + describe "query server that exits" do
        + before(:each) do
        + @qs = QueryServerRunner.run
        + @ddoc = {
        + "_id" => "foo",
        + "lists" => { + "capped" => functions["list-capped"][LANGUAGE], + "raw" => functions["list-raw"][LANGUAGE] + },
        + "shows" => { + "fatal" => functions["fatal"][LANGUAGE] + }
        }
        - }
        - @qs.teach_ddoc(@ddoc)
        - end
        - after(:each) do
        - @qs.close
        - end
        + @qs.teach_ddoc(@ddoc)
        + end
        + after(:each) do
        + @qs.close
        + end

        - describe "only goes to 2 list" do
        - it "should exit if erlang sends too many rows" do
        - @qs.ddoc_run(@ddoc, ["lists","capped"],
        - [{"foo"=>"bar"}, {"q" => "ok"}]).
        - should == ["start", ["bacon"], {"headers"=>{}}]
        - @qs.run(["list_row", {"key"=>"baz"}

        ]).should == ["chunks", ["baz"]]

      • @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
        - @qs.run(["list_row", {"key"=>"fooz"}]).should == ["end", ["fooz", "early"]]
        - e = @qs.run(["list_row", {"key"=>"foox"}])
        - e[0].should == "error"
        - e[1].should == "unknown_command"
        - should_have_exited @qs
        + describe "only goes to 2 list" do
        + it "should exit if erlang sends too many rows" do
        + @qs.ddoc_run(@ddoc, ["lists","capped"],
        + [{"foo"=>"bar"}, {"q" => "ok"}]).
        + should == ["start", ["bacon"], {"headers"=>{}}]
        + @qs.run(["list_row", {"key"=>"baz"}]).should == ["chunks", ["baz"]]
        + @qs.run(["list_row", {"key"=>"foom"}

        ]).should == ["chunks", ["foom"]]
        + @qs.run(["list_row",

        {"key"=>"fooz"}

        ]).should == ["end", ["fooz", "early"]]
        + e = @qs.run(["list_row",

        {"key"=>"foox"}

        ])
        + e[0].should == "error"
        + e[1].should == "unknown_command"
        + should_have_exited @qs
        + end
        end

      • end
      • describe "raw list" do
      • it "should exit if it gets a non-row in the middle" do
      • @qs.ddoc_run(@ddoc, ["lists","raw"],
      • [ {"foo"=>"bar"}, {"q" => "ok"}]).
        - should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        - e = @qs.run(["reset"])
        - e[0].should == "error"
        - e[1].should == "list_error"
        - should_have_exited @qs
        + describe "raw list" do
        + it "should exit if it gets a non-row in the middle" do
        + @qs.ddoc_run(@ddoc, ["lists","raw"],
        + [{"foo"=>"bar"}

        ,

        {"q" => "ok"}]).
        + should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
        + e = @qs.run(["reset"])
        + e[0].should == "error"
        + e[1].should == "list_error"
        + should_have_exited @qs
        + end
        end
        - end
        -
        - describe "fatal error" do
        - it "should exit" do
        - @qs.ddoc_run(@ddoc, ["shows","fatal"],
        - [{"foo"=>"bar"}, {"q" => "ok"}

        ]).

      • should == ["error", "error_key", "testing"]
      • should_have_exited @qs
        +
        + describe "fatal error" do
        + it "should exit" do
        + @qs.ddoc_run(@ddoc, ["shows","fatal"],
        + [ {"foo"=>"bar"}

        ,

        {"q" => "ok"}

        ]).
        + should == ["error", "error_key", "testing"]
        + should_have_exited @qs
        + end
        end
        end
        end
        @@ -821,4 +984,4 @@ end
        describe "thank you for using the tests" do
        it "for more info run with QS_TRACE=true or see query_server_spec.rb file header" do
        end
        -end
        \ No newline at end of file
        +end

      Attachments

        Activity

          People

            tilgovi Randall Leeds
            mattly Matt Lyon
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: