From 84ac0256dc629e7fc0add1024bce2b77eda86d7c Mon Sep 17 00:00:00 2001 From: Chris Elder Date: Tue, 14 Mar 2017 09:09:03 -0400 Subject: [PATCH] FAB-2775 Add query unit tests to CouchDB layer Add query tests to the CouchDB unit tests. Change-Id: Ia98cecf55c1991b7e21529bd5e38f4624c340669 Signed-off-by: Chris Elder --- core/ledger/util/couchdb/couchdb_test.go | 301 +++++++++++++++++++++++ 1 file changed, 301 insertions(+) diff --git a/core/ledger/util/couchdb/couchdb_test.go b/core/ledger/util/couchdb/couchdb_test.go index 2f2450c84ab..51be8bdc463 100644 --- a/core/ledger/util/couchdb/couchdb_test.go +++ b/core/ledger/util/couchdb/couchdb_test.go @@ -112,6 +112,36 @@ func TestDBCreateSaveWithoutRevision(t *testing.T) { } } +func TestDBCreateEnsureFullCommit(t *testing.T) { + + if ledgerconfig.IsCouchDBEnabled() == true { + + database := "testdbensurefullcommit" + err := cleanup(database) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to cleanup Error: %s", err)) + defer cleanup(database) + + if err == nil { + //create a new instance and database object + couchInstance, err := CreateCouchInstance(connectURL, username, password) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance")) + db := CouchDatabase{couchInstance: *couchInstance, dbName: database} + + //create a new database + _, errdb := db.CreateDatabaseIfNotExist() + testutil.AssertNoError(t, errdb, fmt.Sprintf("Error when trying to create database")) + + //Save the test document + _, saveerr := db.SaveDoc("2", "", &CouchDoc{JSONValue: assetJSON, Attachments: nil}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Ensure a full commit + _, commiterr := db.EnsureFullCommit() + testutil.AssertNoError(t, commiterr, fmt.Sprintf("Error when trying to ensure a full commit")) + + } + } +} func TestDBBadDatabaseName(t *testing.T) { if ledgerconfig.IsCouchDBEnabled() == true { @@ -471,3 +501,274 @@ func TestCouchDBVersion(t *testing.T) { testutil.AssertError(t, err, fmt.Sprintf("Error should have been thrown for invalid version")) } + +func TestRichQuery(t *testing.T) { + + if ledgerconfig.IsCouchDBEnabled() == true { + + byteJSON01 := []byte(`{"asset_name":"marble01","color":"blue","size":1,"owner":"jerry"}`) + byteJSON02 := []byte(`{"asset_name":"marble02","color":"red","size":2,"owner":"tom"}`) + byteJSON03 := []byte(`{"asset_name":"marble03","color":"green","size":3,"owner":"jerry"}`) + byteJSON04 := []byte(`{"asset_name":"marble04","color":"purple","size":4,"owner":"tom"}`) + byteJSON05 := []byte(`{"asset_name":"marble05","color":"blue","size":5,"owner":"jerry"}`) + byteJSON06 := []byte(`{"asset_name":"marble06","color":"white","size":6,"owner":"tom"}`) + byteJSON07 := []byte(`{"asset_name":"marble07","color":"white","size":7,"owner":"tom"}`) + byteJSON08 := []byte(`{"asset_name":"marble08","color":"white","size":8,"owner":"tom"}`) + byteJSON09 := []byte(`{"asset_name":"marble09","color":"white","size":9,"owner":"tom"}`) + byteJSON10 := []byte(`{"asset_name":"marble10","color":"white","size":10,"owner":"tom"}`) + byteJSON11 := []byte(`{"asset_name":"marble11","color":"green","size":11,"owner":"tom"}`) + byteJSON12 := []byte(`{"asset_name":"marble12","color":"green","size":12,"owner":"frank"}`) + + attachment1 := &Attachment{} + attachment1.AttachmentBytes = []byte(`marble01 - test attachment`) + attachment1.ContentType = "application/octet-stream" + attachment1.Name = "data" + attachments1 := []Attachment{} + attachments1 = append(attachments1, *attachment1) + + attachment2 := &Attachment{} + attachment2.AttachmentBytes = []byte(`marble02 - test attachment`) + attachment2.ContentType = "application/octet-stream" + attachment2.Name = "data" + attachments2 := []Attachment{} + attachments2 = append(attachments2, *attachment2) + + attachment3 := &Attachment{} + attachment3.AttachmentBytes = []byte(`marble03 - test attachment`) + attachment3.ContentType = "application/octet-stream" + attachment3.Name = "data" + attachments3 := []Attachment{} + attachments3 = append(attachments3, *attachment3) + + attachment4 := &Attachment{} + attachment4.AttachmentBytes = []byte(`marble04 - test attachment`) + attachment4.ContentType = "application/octet-stream" + attachment4.Name = "data" + attachments4 := []Attachment{} + attachments4 = append(attachments4, *attachment4) + + attachment5 := &Attachment{} + attachment5.AttachmentBytes = []byte(`marble05 - test attachment`) + attachment5.ContentType = "application/octet-stream" + attachment5.Name = "data" + attachments5 := []Attachment{} + attachments5 = append(attachments5, *attachment5) + + attachment6 := &Attachment{} + attachment6.AttachmentBytes = []byte(`marble06 - test attachment`) + attachment6.ContentType = "application/octet-stream" + attachment6.Name = "data" + attachments6 := []Attachment{} + attachments6 = append(attachments6, *attachment6) + + attachment7 := &Attachment{} + attachment7.AttachmentBytes = []byte(`marble07 - test attachment`) + attachment7.ContentType = "application/octet-stream" + attachment7.Name = "data" + attachments7 := []Attachment{} + attachments7 = append(attachments7, *attachment7) + + attachment8 := &Attachment{} + attachment8.AttachmentBytes = []byte(`marble08 - test attachment`) + attachment8.ContentType = "application/octet-stream" + attachment7.Name = "data" + attachments8 := []Attachment{} + attachments8 = append(attachments8, *attachment8) + + attachment9 := &Attachment{} + attachment9.AttachmentBytes = []byte(`marble09 - test attachment`) + attachment9.ContentType = "application/octet-stream" + attachment9.Name = "data" + attachments9 := []Attachment{} + attachments9 = append(attachments9, *attachment9) + + attachment10 := &Attachment{} + attachment10.AttachmentBytes = []byte(`marble10 - test attachment`) + attachment10.ContentType = "application/octet-stream" + attachment10.Name = "data" + attachments10 := []Attachment{} + attachments10 = append(attachments10, *attachment10) + + attachment11 := &Attachment{} + attachment11.AttachmentBytes = []byte(`marble11 - test attachment`) + attachment11.ContentType = "application/octet-stream" + attachment11.Name = "data" + attachments11 := []Attachment{} + attachments11 = append(attachments11, *attachment11) + + attachment12 := &Attachment{} + attachment12.AttachmentBytes = []byte(`marble12 - test attachment`) + attachment12.ContentType = "application/octet-stream" + attachment12.Name = "data" + attachments12 := []Attachment{} + attachments12 = append(attachments12, *attachment12) + + database := "testrichquery" + err := cleanup(database) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to cleanup Error: %s", err)) + defer cleanup(database) + + if err == nil { + //create a new instance and database object -------------------------------------------------------- + couchInstance, err := CreateCouchInstance(connectURL, username, password) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance")) + db := CouchDatabase{couchInstance: *couchInstance, dbName: database} + + //create a new database + _, errdb := db.CreateDatabaseIfNotExist() + testutil.AssertNoError(t, errdb, fmt.Sprintf("Error when trying to create database")) + + //Save the test document + _, saveerr := db.SaveDoc("marble01", "", &CouchDoc{JSONValue: byteJSON01, Attachments: attachments1}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble02", "", &CouchDoc{JSONValue: byteJSON02, Attachments: attachments2}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble03", "", &CouchDoc{JSONValue: byteJSON03, Attachments: attachments3}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble04", "", &CouchDoc{JSONValue: byteJSON04, Attachments: attachments4}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble05", "", &CouchDoc{JSONValue: byteJSON05, Attachments: attachments5}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble06", "", &CouchDoc{JSONValue: byteJSON06, Attachments: attachments6}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble07", "", &CouchDoc{JSONValue: byteJSON07, Attachments: attachments7}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble08", "", &CouchDoc{JSONValue: byteJSON08, Attachments: attachments8}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble09", "", &CouchDoc{JSONValue: byteJSON09, Attachments: attachments9}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble10", "", &CouchDoc{JSONValue: byteJSON10, Attachments: attachments10}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble11", "", &CouchDoc{JSONValue: byteJSON11, Attachments: attachments11}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Save the test document + _, saveerr = db.SaveDoc("marble12", "", &CouchDoc{JSONValue: byteJSON12, Attachments: attachments12}) + testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) + + //Test query with invalid JSON ------------------------------------------------------------------- + queryString := "{\"selector\":{\"owner\":}}" + + _, err = db.QueryDocuments(queryString) + testutil.AssertError(t, err, fmt.Sprintf("Error should have been thrown for bad json")) + + //Test query with object ------------------------------------------------------------------- + queryString = "{\"selector\":{\"owner\":{\"$eq\":\"jerry\"}}}" + + queryResult, err := db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 3 results for owner="jerry" + testutil.AssertEquals(t, len(*queryResult), 3) + + //Test query with implicit operator -------------------------------------------------------------- + queryString = "{\"selector\":{\"owner\":\"jerry\"}}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 3 results for owner="jerry" + testutil.AssertEquals(t, len(*queryResult), 3) + + //Test query with specified fields ------------------------------------------------------------------- + queryString = "{\"selector\":{\"owner\":{\"$eq\":\"jerry\"}},\"fields\": [\"owner\",\"asset_name\",\"color\",\"size\"]}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 3 results for owner="jerry" + testutil.AssertEquals(t, len(*queryResult), 3) + + //Test query with a leading operator ------------------------------------------------------------------- + queryString = "{\"selector\":{\"$or\":[{\"owner\":{\"$eq\":\"jerry\"}},{\"owner\": {\"$eq\": \"frank\"}}]}}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 4 results for owner="jerry" or owner="frank" + testutil.AssertEquals(t, len(*queryResult), 4) + + //Test query implicit and explicit operator ------------------------------------------------------------------ + queryString = "{\"selector\":{\"color\":\"green\",\"$or\":[{\"owner\":\"tom\"},{\"owner\":\"frank\"}]}}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 2 results for color="green" and (owner="jerry" or owner="frank") + testutil.AssertEquals(t, len(*queryResult), 2) + + //Test query with a leading operator ------------------------------------------------------------------------- + queryString = "{\"selector\":{\"$and\":[{\"size\":{\"$gte\":2}},{\"size\":{\"$lte\":5}}]}}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 4 results for size >= 2 and size <= 5 + testutil.AssertEquals(t, len(*queryResult), 4) + + //Test query with leading and embedded operator ------------------------------------------------------------- + queryString = "{\"selector\":{\"$and\":[{\"size\":{\"$gte\":3}},{\"size\":{\"$lte\":10}},{\"$not\":{\"size\":7}}]}}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 7 results for size >= 3 and size <= 10 and not 7 + testutil.AssertEquals(t, len(*queryResult), 7) + + //Test query with leading operator and array of objects ---------------------------------------------------------- + queryString = "{\"selector\":{\"$and\":[{\"size\":{\"$gte\":2}},{\"size\":{\"$lte\":10}},{\"$nor\":[{\"size\":3},{\"size\":5},{\"size\":7}]}]}}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 6 results for size >= 2 and size <= 10 and not 3,5 or 7 + testutil.AssertEquals(t, len(*queryResult), 6) + + //Test a range query --------------------------------------------------------------------------------------------- + queryResult, err = db.ReadDocRange("marble02", "marble06", 10000, 0) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a range query")) + + //There should be 4 results + testutil.AssertEquals(t, len(*queryResult), 4) + + //Test query with for tom ------------------------------------------------------------------- + queryString = "{\"selector\":{\"owner\":{\"$eq\":\"tom\"}}}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 8 results for owner="tom" + testutil.AssertEquals(t, len(*queryResult), 8) + + //Test query with for tom with limit ------------------------------------------------------------------- + queryString = "{\"selector\":{\"owner\":{\"$eq\":\"tom\"}},\"limit\":2}" + + queryResult, err = db.QueryDocuments(queryString) + testutil.AssertNoError(t, err, fmt.Sprintf("Error when attempting to execute a query")) + + //There should be 2 results for owner="tom" with a limit of 2 + testutil.AssertEquals(t, len(*queryResult), 2) + + } + } +}