single.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright (C) MongoDB, Inc. 2017-present.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  6. package benchmark
  7. import (
  8. "context"
  9. "errors"
  10. "go.mongodb.org/mongo-driver/internal/testutil"
  11. "go.mongodb.org/mongo-driver/mongo"
  12. "go.mongodb.org/mongo-driver/mongo/options"
  13. "go.mongodb.org/mongo-driver/x/bsonx"
  14. )
  15. const (
  16. singleAndMultiDataDir = "single_and_multi_document"
  17. tweetData = "tweet.json"
  18. smallData = "small_doc.json"
  19. largeData = "large_doc.json"
  20. )
  21. func getClientDB(ctx context.Context) (*mongo.Database, error) {
  22. cs, err := testutil.GetConnString()
  23. if err != nil {
  24. return nil, err
  25. }
  26. client, err := mongo.NewClient(options.Client().ApplyURI(cs.String()))
  27. if err != nil {
  28. return nil, err
  29. }
  30. if err = client.Connect(ctx); err != nil {
  31. return nil, err
  32. }
  33. db := client.Database(testutil.GetDBName(cs))
  34. return db, nil
  35. }
  36. func SingleRunCommand(ctx context.Context, tm TimerManager, iters int) error {
  37. ctx, cancel := context.WithCancel(ctx)
  38. defer cancel()
  39. db, err := getClientDB(ctx)
  40. if err != nil {
  41. return err
  42. }
  43. defer db.Client().Disconnect(ctx)
  44. cmd := bsonx.Doc{{"ismaster", bsonx.Boolean(true)}}
  45. tm.ResetTimer()
  46. for i := 0; i < iters; i++ {
  47. var doc bsonx.Doc
  48. err := db.RunCommand(ctx, cmd).Decode(&doc)
  49. if err != nil {
  50. return err
  51. }
  52. // read the document and then throw it away to prevent
  53. out, err := doc.MarshalBSON()
  54. if len(out) == 0 {
  55. return errors.New("output of ismaster is empty")
  56. }
  57. }
  58. tm.StopTimer()
  59. return nil
  60. }
  61. func SingleFindOneByID(ctx context.Context, tm TimerManager, iters int) error {
  62. ctx, cancel := context.WithCancel(ctx)
  63. defer cancel()
  64. db, err := getClientDB(ctx)
  65. if err != nil {
  66. return err
  67. }
  68. db = db.Client().Database("perftest")
  69. if err = db.Drop(ctx); err != nil {
  70. return err
  71. }
  72. doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, tweetData)
  73. if err != nil {
  74. return err
  75. }
  76. coll := db.Collection("corpus")
  77. for i := 0; i < iters; i++ {
  78. id := int32(i)
  79. res, err := coll.InsertOne(ctx, doc.Set("_id", bsonx.Int32(id)))
  80. if err != nil {
  81. return err
  82. }
  83. if res.InsertedID == nil {
  84. return errors.New("insert failed")
  85. }
  86. }
  87. tm.ResetTimer()
  88. for i := 0; i < iters; i++ {
  89. res := coll.FindOne(ctx, bsonx.Doc{{"_id", bsonx.Int32(int32(i))}})
  90. if res == nil {
  91. return errors.New("find one query produced nil result")
  92. }
  93. }
  94. tm.StopTimer()
  95. if err = db.Drop(ctx); err != nil {
  96. return err
  97. }
  98. return nil
  99. }
  100. func singleInsertCase(ctx context.Context, tm TimerManager, iters int, data string) error {
  101. ctx, cancel := context.WithCancel(ctx)
  102. defer cancel()
  103. db, err := getClientDB(ctx)
  104. if err != nil {
  105. return err
  106. }
  107. defer db.Client().Disconnect(ctx)
  108. db = db.Client().Database("perftest")
  109. if err = db.Drop(ctx); err != nil {
  110. return err
  111. }
  112. doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, data)
  113. if err != nil {
  114. return err
  115. }
  116. err = db.RunCommand(ctx, bsonx.Doc{{"create", bsonx.String("corpus")}}).Err()
  117. if err != nil {
  118. return err
  119. }
  120. coll := db.Collection("corpus")
  121. tm.ResetTimer()
  122. for i := 0; i < iters; i++ {
  123. if _, err = coll.InsertOne(ctx, doc); err != nil {
  124. return err
  125. }
  126. // TODO: should be remove after resolving GODRIVER-468
  127. _ = doc.Delete("_id")
  128. }
  129. tm.StopTimer()
  130. if err = db.Drop(ctx); err != nil {
  131. return err
  132. }
  133. return nil
  134. }
  135. func SingleInsertSmallDocument(ctx context.Context, tm TimerManager, iters int) error {
  136. return singleInsertCase(ctx, tm, iters, smallData)
  137. }
  138. func SingleInsertLargeDocument(ctx context.Context, tm TimerManager, iters int) error {
  139. return singleInsertCase(ctx, tm, iters, largeData)
  140. }