You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: commit_test.go
    path of file: ./repos/lakeFS/esti
    
    the code of the file until where you have to start completion: package esti

import (
	"bytes"
	"context"
	"fmt"
	"mime/multipart"
	"net/http"
	"path/filepath"
	"strings"
	"sync"
	"testing"

	"github.com/go-openapi/swag"
	"github.com/stretchr/testify/require"
	"github.com/thanhpk/randstr"
	"github.com/treeverse/lakefs/pkg/api/apigen"
	"github.com/treeverse/lakefs/pkg/api/apiutil"
)

func TestCommitSingle(t *testing.T) {
	ctx, _, repo := setupTest(t)
	defer tearDownTest(repo)

	const objPath = "1.txt"
	_, objContent := uploadFileRandomData(ctx, t, repo, mainBranch, objPath)
	commitResp, err := client.CommitWithResponse(ctx, repo, mainBranch, &apigen.CommitParams{}, apigen.CommitJSONRequestBody{
		Message: "singleCommit",
	})
	require.NoError(t, err, "failed to commit changes")
	require.NoErrorf(t, verifyResponse(commitResp.HTTPResponse, commitResp.Body),
		"failed to commit changes repo %s branch %s", repo, mainBranch)

	getObjResp, err := client.GetObjectWithResponse(ctx, repo, mainBranch, &apigen.GetObjectParams{Path: objPath})
	require.NoError(t, err, "failed to get object")
	require.NoErrorf(t, verifyResponse(getObjResp.HTTPResponse, getObjResp.Body),
		"failed to get object repo %s branch %s path %s", repo, mainBranch, objPath)

	body := string(getObjResp.Body)
	require.Equalf(t, objContent, body, "path: %s, expected: %s, actual:%s", objPath, objContent, body)
}

// genNames generates n consecutive filenames starting with prefix.
func genNames(n int, prefix string) []string {
	ret := make([]string, n)
	for i := range ret {
		ret[i] = fmt.Sprint(prefix, i+1)
	}
	return ret
}

type Upload struct {
	Repo, Branch, Path string
}

// upload uploads random file data for uploads.
func upload(ctx context.Context, uploads chan Upload) error {
	for u := range uploads {
		_, _, err := uploadFileRandomDataAndReport(ctx, u.Repo, u.Branch, u.Path, false)
		if err != nil {
			return err
		}
	}
	return nil
}

func TestCommitInMixedOrder(t *testing.T) {
	const (
		parallelism = 5
		size        = 100
	)

	ctx, _, repo := setupTest(t)
	defer tearDownTest(repo)
	names1 := genNames(size, "run2/foo")
	uploads := make(chan Upload, size)
	wg := sync.WaitGroup{}
	for i := 0; i < parallelism; i++ {
		wg.Add(1)
		go func() {
			if err := upload(ctx, uploads); err != nil {
				t.Error(err)
			}
			wg.Done()
		}()
	}
	for _, name := range names1 {
		uploads <- Upload{
    
func TestCommitReadOnlyRepo(t *testing.T) {
	ctx := context.Background()
	name := strings.ToLower(t.Name())
	storageNamespace := generateUniqueStorageNamespace(name)
	repoName := makeRepositoryName(name)
	resp, err := client.CreateRepositoryWithResponse(ctx, &apigen.CreateRepositoryParams{}, apigen.CreateRepositoryJSONRequestBody{
		DefaultBranch:    apiutil.Ptr(mainBranch),
		Name:             repoName,
		StorageNamespace: storageNamespace,
		ReadOnly:         swag.Bool(true),
	})
	require.NoErrorf(t, err, "failed to create repository '%s', storage '%s'", name, storageNamespace)
	require.NoErrorf(t, verifyResponse(resp.HTTPResponse, resp.Body),
		"create repository '%s', storage '%s'", name, storageNamespace)
	defer tearDownTest(repoName)

	commitResp, _ := client.CommitWithResponse(ctx, repoName, mainBranch, &apigen.CommitParams{}, apigen.CommitJSONRequestBody{
		Message: "singleCommit",
	})
	if commitResp.StatusCode() != http.StatusForbidden {
		t.Fatalf("expected 403 Forbidden for committing to read-only repo, got %d instead", resp.StatusCode())
	}

	const objPath = "1.txt"
	objContent := randstr.String(randomDataContentLength)
	var b bytes.Buffer
	w := multipart.NewWriter(&b)
	contentWriter, err := w.CreateFormFile("content", filepath.Base(objPath))
	require.NoError(t, err, "failed to upload file", repoName, mainBranch, objPath)
	_, err = contentWriter.Write([]byte(objContent))
	require.NoError(t, err, "failed to upload file", repoName, mainBranch, objPath)
	err = w.Close()
	require.NoError(t, err, "failed to upload file", repoName, mainBranch, objPath)
	uploadResp, err := client.UploadObjectWithBodyWithResponse(ctx, repoName, mainBranch, &apigen.UploadObjectParams{
		Path:  objPath,
		Force: swag.Bool(true),
	}, w.FormDataContentType(), &b)
	require.NoError(t, err, "failed to upload file", repoName, mainBranch, objPath)
	err = verifyResponse(uploadResp.HTTPResponse, uploadResp.Body)
	require.NoError(t, err, "failed to upload file", repoName, mainBranch, objPath)

	commitResp, err = client.CommitWithResponse(ctx, repoName, mainBranch, &apigen.CommitParams{}, apigen.CommitJSONRequestBody{
		Message: "singleCommit",
		Force:   swag.Bool(true),
	})
	require.NoError(t, err, "failed to commit changes")
	require.NoErrorf(t, verifyResponse(commitResp.HTTPResponse, commitResp.Body),
		"failed to commit changes repo %s branch %s", repoName, mainBranch)

	getObjResp, err := client.GetObjectWithResponse(ctx, repoName, mainBranch, &apigen.GetObjectParams{Path: objPath})
	require.NoError(t, err, "failed to get object")
	require.NoErrorf(t, verifyResponse(getObjResp.HTTPResponse, getObjResp.Body),
		"failed to get object repo %s branch %s path %s", repoName, mainBranch, objPath)

	body := string(getObjResp.Body)
	require.Equalf(t, objContent, body, "path: %s, expected: %s, actual:%s", objPath, objContent, body)

}