Repository: rclone/rclone
File: cmd/test/info/info.go (Go)

Code before:
		}
		if !hash.Equals(hashes[Hash], sum) {
			fs.Infof(r.f, "Streamed file has incorrect hash %v: expecting %q got %q", Hash, hashes[Hash], sum)
			r.canStream = false
			return
		}
	}
	if int64(len(contents)) != objR.Size() {
		fs.Infof(r.f, "Streamed file has incorrect file size: expecting %d got %d", len(contents), objR.Size())
		r.canStream = false
		return
	}
	r.canStream = true
}

func readInfo(ctx context.Context, f fs.Fs) error {
	// Generate a unique name for the temporary directory
	tempDirName := "rclone-test-info-" + random.String(8)
	tempDirPath := path.Join(f.Root(), tempDirName)

	// Attempt to create the temporary directory
	err := f.Mkdir(ctx, tempDirPath)
	if err != nil {
		return fmt.Errorf("couldn't create temporary directory: %w", err)
	}

	// Ensure cleanup unless --keep-test-files is specified
	if !keepTestFiles {
		defer func() {
			// Use Purge to recursively delete the temporary directory and its contents
			if doPurge, ok := f.(fs.Purger); ok {
				err := doPurge.Purge(ctx, tempDirPath)
				if err != nil {
					log.Printf("Failed to purge temporary directory: %v", err)
				}
			} else {
				// Fallback cleanup when Purge is not supported
				err := cleanupTempFiles(ctx, f, tempDirPath)
				if err != nil {
					log.Printf("Failed to clean up temporary files: %v", err)
				}
			}
		}()
	}

	// Adjust the fs.Fs to point to the temporary directory for subsequent operations
	tempFs, err := fs.NewFs(ctx, tempDirPath)
	if err != nil {
		return fmt.Errorf("couldn't create fs for temporary directory: %w", err)
	}


Review comment (suggestion):
I think an INFO level message announcing the temporary directory would be helpful here, something like

    fs.Infof(tempDirPath, "Created temporary directory for test files")

And I'd probably put another in the removal code announcing that it is being removed.

    fs.Infof(tempDirPath, "Removed temporary directory for test files")

INFO level messages will show with `-v`.

Code after:

	hashes := hashIn.Sums()
	types := objR.Fs().Hashes().Array()
	for _, Hash := range types {
		sum, err := objR.Hash(r.ctx, Hash)
		if err != nil {
			fs.Infof(r.f, "Streamed file failed when getting hash %v (%v)", Hash, err)
			r.canStream = false
			return
		}
		if !hash.Equals(hashes[Hash], sum) {
			fs.Infof(r.f, "Streamed file has incorrect hash %v: expecting %q got %q", Hash, hashes[Hash], sum)
			r.canStream = false
			return
		}
	}
	if int64(len(contents)) != objR.Size() {
		fs.Infof(r.f, "Streamed file has incorrect file size: expecting %d got %d", len(contents), objR.Size())
		r.canStream = false
		return
	}
	r.canStream = true
}

func readInfo(ctx context.Context, f fs.Fs) error {
	// Ensure cleanup unless --keep-test-files is specified
	if !keepTestFiles {
		defer func() {
			err := operations.Purge(ctx, f, "")
			if err != nil {
				fs.Errorf(f, "Failed to purge temporary directory: %v", err)
			} else {
				fs.Infof(f, "Removed temporary directory for test files: %s", f.Root())
			}
		}()
	}

	r := newResults(ctx, f)
	if checkControl {
		r.checkControls()
	}
	if checkLength {
		for i := range r.maxFileLength {
			r.findMaxLength(i + 1)
		}
	}
	if checkNormalization {
		r.checkUTF8Normalization()
	}
	if checkStreaming {
		r.checkStreaming()