Uploaded image for project: 'Go Driver'
  1. Go Driver
  2. GODRIVER-3384

bucket.DownloadToStream is failing to locate file by ID

    • Type: Icon: Bug Bug
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 1.17.1
    • Component/s: GridFS
    • None
    • Go Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      Testcase:
      I have updated existing testcase present at: https://github.com/mongodb/mongo-go-driver/blob/7355997933f8522a8a17379918b5cb91ff3674cc/mongo/gridfs/gridfs_test.go 

      // Copyright (C) MongoDB, Inc. 2017-present.
      //
      // Licensed under the Apache License, Version 2.0 (the "License"); you may
      // not use this file except in compliance with the License. You may obtain
      // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
      
      package gridfs
      
      import (
          "bytes"
          "context"
          "fmt"
          "testing"
      
          "go.mongodb.org/mongo-driver/event"
          "go.mongodb.org/mongo-driver/internal/assert"
          "go.mongodb.org/mongo-driver/internal/integtest"
          "go.mongodb.org/mongo-driver/mongo"
          "go.mongodb.org/mongo-driver/mongo/options"
          "go.mongodb.org/mongo-driver/mongo/readpref"
          "go.mongodb.org/mongo-driver/mongo/writeconcern"
      )
      
      var (
          connsCheckedOut int
      )
      
      func TestGridFS(t *testing.T) {
          if testing.Short() {
             t.Skip("skipping integration test in short mode")
          }
      
          cs := integtest.ConnString(t)
          poolMonitor := &event.PoolMonitor{
             Event: func(evt *event.PoolEvent) {
                switch evt.Type {
                case event.GetSucceeded:
                   connsCheckedOut++
                case event.ConnectionReturned:
                   connsCheckedOut--
                }
             },
          }
          clientOpts := options.Client().
             ApplyURI(cs.Original).
             SetReadPreference(readpref.Primary()).
             SetWriteConcern(writeconcern.New(writeconcern.WMajority())).
             SetPoolMonitor(poolMonitor).
             // Connect to a single host. For sharded clusters, this will pin to a single mongos, which avoids
             // non-deterministic versioning errors in the server. This has no effect for replica sets because the driver
             // will discover the other hosts during SDAM checks.
             SetHosts(cs.Hosts[:1])
      
          client, err := mongo.Connect(context.Background(), clientOpts)
          assert.Nil(t, err, "Connect error: %v", err)
          db := client.Database("gridfs")
          defer func() {
             sessions := client.NumberSessionsInProgress()
             conns := connsCheckedOut
      
             _ = db.Drop(context.Background())
             _ = client.Disconnect(context.Background())
             assert.Equal(t, 0, sessions, "%v sessions checked out", sessions)
             assert.Equal(t, 0, conns, "%v connections checked out", conns)
          }()
      
          // Unit tests showing the chunk size is set correctly on the bucket and upload stream objects.
          t.Run("ChunkSize", func(t *testing.T) {
             chunkSizeTests := []struct {
                testName   string
                bucketOpts *options.BucketOptions
                uploadOpts *options.UploadOptions
             }{
                {"Default values", nil, nil},
                //{"Options provided without chunk size", options.GridFSBucket(), options.GridFSUpload()},
                //{"Bucket chunk size set", options.GridFSBucket().SetChunkSizeBytes(27), nil},
                //{"Upload stream chunk size set", nil, options.GridFSUpload().SetChunkSizeBytes(27)},
                //{"Bucket and upload set to different values", options.GridFSBucket().SetChunkSizeBytes(27), options.GridFSUpload().SetChunkSizeBytes(31)},
             }
             fileContent := []byte("test")
             if err != nil {
                panic(err)
             }
             for _, tt := range chunkSizeTests {
                t.Run(tt.testName, func(t *testing.T) {
                   bucket, err := NewBucket(db, tt.bucketOpts)
                   assert.Nil(t, err, "NewBucket error: %v", err)
      
                   us, err := bucket.OpenUploadStream("filename", tt.uploadOpts)
                   assert.Nil(t, err, "OpenUploadStream error: %v", err)
      
                   expectedBucketChunkSize := DefaultChunkSize
                   if tt.bucketOpts != nil && tt.bucketOpts.ChunkSizeBytes != nil {
                      expectedBucketChunkSize = *tt.bucketOpts.ChunkSizeBytes
                   }
                   assert.Equal(t, expectedBucketChunkSize, bucket.chunkSize,
                      "expected chunk size %v, got %v", expectedBucketChunkSize, bucket.chunkSize)
      
                   expectedUploadChunkSize := expectedBucketChunkSize
                   if tt.uploadOpts != nil && tt.uploadOpts.ChunkSizeBytes != nil {
                      expectedUploadChunkSize = *tt.uploadOpts.ChunkSizeBytes
                   }
                   assert.Equal(t, expectedUploadChunkSize, us.chunkSize,
                      "expected chunk size %v, got %v", expectedUploadChunkSize, us.chunkSize)
      
                   // upload file
                   var byts int
                   if byts, err = us.Write(fileContent); err != nil {
                      assert.Fail(t, "failed to write a file")
                   }
                   fmt.Printf("New file uploaded with %d bytes written", byts)
      
                   fileBuffer := bytes.NewBuffer(nil)
                   if _, err := bucket.DownloadToStream(us.FileID, fileBuffer); err != nil {
                      assert.Fail(t, "failed to download a file")
                   }
                   fmt.Printf("Downloaded file")
                })
             }
          })
      }
       

      Expected:

      Download should work.

      Actual:

      Failing to download uploaded file. Here is the test output:

      /Users/nb732834/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.darwin-amd64/bin/go tool test2json -t /Users/nb732834/Library/Caches/JetBrains/GoLand2024.2/tmp/GoLand/___1TestGridFS_in_go_mongodb_org_mongo_driver_mongo_gridfs.test -test.v=test2json -test.paniconexit0 -test.run ^\QTestGridFS\E$
      === RUN   TestGridFS
      === RUN   TestGridFS/ChunkSize
      === RUN   TestGridFS/ChunkSize/Default_values
      New file uploaded with 4 bytes written    gridfs_test.go:115: 
                  Error Trace:    /Users/nb732834/lab/mongo/mongo-go-driver/mongo/gridfs/gridfs_test.go:115
                  Error:          failed to download a file
                  Test:           TestGridFS/ChunkSize/Default_values
      Downloaded file--- FAIL: TestGridFS/ChunkSize/Default_values (4.54s)--- FAIL: TestGridFS/ChunkSize (4.54s)--- FAIL: TestGridFS (5.29s)FAILProcess finished with the exit code 1 

            Assignee:
            preston.vasquez@mongodb.com Preston Vasquez
            Reporter:
            nitin.bodke@gmail.com Nitin Bodke
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: