func TestFromCommit(t *testing.T) { t.Parallel() repo := uniqueString("TestFromCommit") pachClient := getPachClient(t) seed := time.Now().UnixNano() rand := rand.New(rand.NewSource(seed)) err := pfsutil.CreateRepo(pachClient, repo) require.NoError(t, err) commit1, err := pfsutil.StartCommit(pachClient, repo, "") require.NoError(t, err) _, err = pfsutil.PutFile(pachClient, repo, commit1.Id, "file", 0, workload.NewReader(rand, KB)) require.NoError(t, err) err = pfsutil.FinishCommit(pachClient, repo, commit1.Id) require.NoError(t, err) commit2, err := pfsutil.StartCommit(pachClient, repo, commit1.Id) require.NoError(t, err) _, err = pfsutil.PutFile(pachClient, repo, commit2.Id, "file", 0, workload.NewReader(rand, KB)) require.NoError(t, err) err = pfsutil.FinishCommit(pachClient, repo, commit2.Id) require.NoError(t, err) var buffer bytes.Buffer require.NoError(t, pfsutil.GetFile(pachClient, repo, commit2.Id, "file", 0, 0, commit1.Id, nil, &buffer)) require.Equal(t, buffer.Len(), KB) buffer = bytes.Buffer{} require.NoError(t, pfsutil.GetFile(pachClient, repo, commit2.Id, "file", 0, 0, "", nil, &buffer)) require.Equal(t, buffer.Len(), 2*KB) }
func TestJob(t *testing.T) { dataRepo := uniqueString("TestJob.data") pfsClient := getPfsClient(t) require.NoError(t, pfsutil.CreateRepo(pfsClient, dataRepo)) commit, err := pfsutil.StartCommit(pfsClient, dataRepo, "") require.NoError(t, err) _, err = pfsutil.PutFile(pfsClient, dataRepo, commit.Id, "file", 0, strings.NewReader("foo")) require.NoError(t, err) require.NoError(t, pfsutil.FinishCommit(pfsClient, dataRepo, commit.Id)) ppsClient := getPpsClient(t) job, err := ppsutil.CreateJob( ppsClient, "", []string{"cp", path.Join("/pfs", dataRepo, "file"), "/pfs/out/file"}, "", 1, []*pfs.Commit{commit}, "", ) require.NoError(t, err) inspectJobRequest := &pps.InspectJobRequest{ Job: job, BlockOutput: true, BlockState: true, } jobInfo, err := ppsClient.InspectJob(context.Background(), inspectJobRequest) require.NoError(t, err) var buffer bytes.Buffer require.NoError(t, pfsutil.GetFile(pfsClient, jobInfo.OutputCommit.Repo.Name, jobInfo.OutputCommit.Id, "file", 0, 0, nil, &buffer)) require.Equal(t, "foo", buffer.String()) }
func TestJob(t *testing.T) { t.Parallel() dataRepo := uniqueString("TestJob.data") pachClient := getPachClient(t) require.NoError(t, pfsutil.CreateRepo(pachClient, dataRepo)) commit, err := pfsutil.StartCommit(pachClient, dataRepo, "") require.NoError(t, err) _, err = pfsutil.PutFile(pachClient, dataRepo, commit.Id, "file", 0, strings.NewReader("foo\n")) require.NoError(t, err) require.NoError(t, pfsutil.FinishCommit(pachClient, dataRepo, commit.Id)) job, err := ppsutil.CreateJob( pachClient, "", []string{"cp", path.Join("/pfs", dataRepo, "file"), "/pfs/out/file"}, nil, 1, []*pps.JobInput{{Commit: commit}}, "", ) require.NoError(t, err) inspectJobRequest := &pps.InspectJobRequest{ Job: job, BlockOutput: true, BlockState: true, } jobInfo, err := pachClient.InspectJob(context.Background(), inspectJobRequest) require.NoError(t, err) require.Equal(t, pps.JobState_JOB_STATE_SUCCESS.String(), jobInfo.State.String()) commitInfo, err := pfsutil.InspectCommit(pachClient, jobInfo.OutputCommit.Repo.Name, jobInfo.OutputCommit.Id) require.NoError(t, err) require.Equal(t, pfs.CommitType_COMMIT_TYPE_READ, commitInfo.CommitType) var buffer bytes.Buffer require.NoError(t, pfsutil.GetFile(pachClient, jobInfo.OutputCommit.Repo.Name, jobInfo.OutputCommit.Id, "file", 0, 0, "", nil, &buffer)) require.Equal(t, "foo\n", buffer.String()) }
func doWrites(tb testing.TB, apiClient pfs.APIClient, repoName string, commitID string) { var wg sync.WaitGroup defer wg.Wait() for i := 0; i < testSize; i++ { i := i wg.Add(1) go func() { defer wg.Done() _, iErr := pfsutil.PutFile(apiClient, repoName, commitID, fmt.Sprintf("a/b/file%d", i), 0, strings.NewReader(fmt.Sprintf("hello%d", i))) require.NoError(tb, iErr) _, iErr = pfsutil.PutFile(apiClient, repoName, commitID, fmt.Sprintf("a/c/file%d", i), 0, strings.NewReader(fmt.Sprintf("hello%d", i))) require.NoError(tb, iErr) }() } }
func (f *file) Write(ctx context.Context, request *fuse.WriteRequest, response *fuse.WriteResponse) error { written, err := pfsutil.PutFile(f.fs.apiClient, f.fs.repositoryName, f.commitID, f.path, request.Offset, bytes.NewReader(request.Data)) if err != nil { return err } response.Size = written if f.size < request.Offset+int64(written) { f.size = request.Offset + int64(written) } return nil }
func TestGrep(t *testing.T) { t.Skip() t.Parallel() dataRepo := uniqueString("TestGrep.data") pfsClient := getPfsClient(t) require.NoError(t, pfsutil.CreateRepo(pfsClient, dataRepo)) commit, err := pfsutil.StartCommit(pfsClient, dataRepo, "") require.NoError(t, err) for i := 0; i < 100; i++ { _, err = pfsutil.PutFile(pfsClient, dataRepo, commit.Id, fmt.Sprintf("file%d", i), 0, strings.NewReader("foo\nbar\nfizz\nbuzz\n")) require.NoError(t, err) } require.NoError(t, pfsutil.FinishCommit(pfsClient, dataRepo, commit.Id)) ppsClient := getPpsClient(t) job1, err := ppsutil.CreateJob( ppsClient, "", []string{"bash"}, fmt.Sprintf("grep foo /pfs/%s/* >/pfs/out/foo", dataRepo), 1, []*pps.JobInput{{Commit: commit}}, "", ) require.NoError(t, err) job2, err := ppsutil.CreateJob( ppsClient, "", []string{"bash"}, fmt.Sprintf("grep foo /pfs/%s/* >/pfs/out/foo", dataRepo), 4, []*pps.JobInput{{Commit: commit}}, "", ) require.NoError(t, err) inspectJobRequest := &pps.InspectJobRequest{ Job: job1, BlockOutput: true, BlockState: true, } job1Info, err := ppsClient.InspectJob(context.Background(), inspectJobRequest) require.NoError(t, err) inspectJobRequest.Job = job2 job2Info, err := ppsClient.InspectJob(context.Background(), inspectJobRequest) require.NoError(t, err) repo1Info, err := pfsutil.InspectRepo(pfsClient, job1Info.OutputCommit.Repo.Name) require.NoError(t, err) repo2Info, err := pfsutil.InspectRepo(pfsClient, job2Info.OutputCommit.Repo.Name) require.NoError(t, err) require.Equal(t, repo1Info.SizeBytes, repo2Info.SizeBytes) }
func (f *file) Write(ctx context.Context, request *fuse.WriteRequest, response *fuse.WriteResponse) (retErr error) { defer func() { protolog.Info(&FileWrite{&f.Node, errorToString(retErr)}) }() written, err := pfsutil.PutFile(f.fs.apiClient, f.File.Commit.Repo.Name, f.File.Commit.Id, f.File.Path, request.Offset, bytes.NewReader(request.Data)) if err != nil { return err } response.Size = written if f.size < request.Offset+int64(written) { f.size = request.Offset + int64(written) } return nil }
func TestSharding(t *testing.T) { t.Parallel() repo := uniqueString("TestSharding") pachClient := getPachClient(t) err := pfsutil.CreateRepo(pachClient, repo) require.NoError(t, err) commit, err := pfsutil.StartCommit(pachClient, repo, "") require.NoError(t, err) var wg sync.WaitGroup for i := 0; i < NUMFILES; i++ { i := i wg.Add(1) go func() { defer wg.Done() rand := rand.New(rand.NewSource(int64(i))) _, err = pfsutil.PutFile(pachClient, repo, commit.Id, fmt.Sprintf("file%d", i), 0, workload.NewReader(rand, KB)) require.NoError(t, err) }() } wg.Wait() err = pfsutil.FinishCommit(pachClient, repo, commit.Id) require.NoError(t, err) wg = sync.WaitGroup{} for i := 0; i < NUMFILES; i++ { i := i wg.Add(1) go func() { defer wg.Done() var buffer1Shard bytes.Buffer var buffer4Shard bytes.Buffer shard := &pfs.Shard{FileModulus: 1, BlockModulus: 1} err := pfsutil.GetFile(pachClient, repo, commit.Id, fmt.Sprintf("file%d", i), 0, 0, "", shard, &buffer1Shard) require.NoError(t, err) shard.BlockModulus = 4 for blockNumber := uint64(0); blockNumber < 4; blockNumber++ { shard.BlockNumber = blockNumber err := pfsutil.GetFile(pachClient, repo, commit.Id, fmt.Sprintf("file%d", i), 0, 0, "", shard, &buffer4Shard) require.NoError(t, err) } require.Equal(t, buffer1Shard.Len(), buffer4Shard.Len()) }() } wg.Wait() }
func TestBigWrite(t *testing.T) { t.Parallel() protolog.SetLevel(protolog.Level_LEVEL_DEBUG) repo := uniqueString("TestBigWrite") pfsClient := getPfsClient(t) err := pfsutil.CreateRepo(pfsClient, repo) require.NoError(t, err) commit, err := pfsutil.StartCommit(pfsClient, repo, "") require.NoError(t, err) rand := rand.New(rand.NewSource(5)) _, err = pfsutil.PutFile(pfsClient, repo, commit.Id, "file", 0, workload.NewReader(rand, 10000)) require.NoError(t, err) err = pfsutil.FinishCommit(pfsClient, repo, commit.Id) require.NoError(t, err) var buffer bytes.Buffer err = pfsutil.GetFile(pfsClient, repo, commit.Id, "file", 0, 0, nil, &buffer) require.NoError(t, err) }
func TestSharding(t *testing.T) { t.Parallel() repo := uniqueString("TestSharding") pfsClient := getPfsClient(t) err := pfsutil.CreateRepo(pfsClient, repo) require.NoError(t, err) commit, err := pfsutil.StartCommit(pfsClient, repo, "") require.NoError(t, err) var wg sync.WaitGroup for i := 0; i < NUMFILES; i++ { i := i wg.Add(1) go func() { defer wg.Done() rand := rand.New(rand.NewSource(int64(i))) _, err = pfsutil.PutFile(pfsClient, repo, commit.Id, fmt.Sprintf("file%d", i), 0, workload.NewReader(rand, 128*1024*1024)) require.NoError(t, err) }() } wg.Wait() err = pfsutil.FinishCommit(pfsClient, repo, commit.Id) require.NoError(t, err) }
func TestGrep(t *testing.T) { t.Parallel() dataRepo := uniqueString("pachyderm.TestGrep.data") pfsClient := getPfsClient(t) require.NoError(t, pfsutil.CreateRepo(pfsClient, dataRepo)) commit, err := pfsutil.StartCommit(pfsClient, dataRepo, "") require.NoError(t, err) for i := 0; i < 100; i++ { _, err = pfsutil.PutFile(pfsClient, dataRepo, commit.Id, fmt.Sprintf("file%d", i), 0, strings.NewReader("foo\nbar\nfizz\nbuzz\n")) require.NoError(t, err) } require.NoError(t, pfsutil.FinishCommit(pfsClient, dataRepo, commit.Id)) ppsClient := getPpsClient(t) _, err = ppsutil.CreateJob( ppsClient, "", []string{"bash"}, fmt.Sprintf("grep foo /pfs/%s/* >/pfs/out/foo", dataRepo), 1, []*pps.JobInput{{Commit: commit}}, "", ) require.NoError(t, err) }
func testMount(t *testing.T, apiClient pfs.ApiClient, internalAPIClient pfs.InternalApiClient, cluster Cluster) { repositoryName := "testMountRepo" err := pfsutil.CreateRepo(apiClient, repositoryName) require.NoError(t, err) directory := "/compile/testMount" mounter := fuse.NewMounter(apiClient) err = mounter.Mount(repositoryName, directory, "", 0, 1) require.NoError(t, err) _, err = os.Stat(filepath.Join(directory, "scratch")) require.NoError(t, err) commit, err := pfsutil.StartCommit(apiClient, repositoryName, "scratch") require.NoError(t, err) require.NotNil(t, commit) newCommitID := commit.Id _, err = os.Stat(filepath.Join(directory, newCommitID)) require.NoError(t, err) err = ioutil.WriteFile(filepath.Join(directory, newCommitID, "foo"), []byte("foo"), 0666) require.NoError(t, err) _, err = pfsutil.PutFile(apiClient, repositoryName, newCommitID, "bar", 0, strings.NewReader("bar")) require.NoError(t, err) bigValue := make([]byte, 1024*1024) for i := 0; i < 1024*1024; i++ { bigValue[i] = 'a' } err = ioutil.WriteFile(filepath.Join(directory, newCommitID, "big1"), bigValue, 0666) require.NoError(t, err) _, err = pfsutil.PutFile(apiClient, repositoryName, newCommitID, "big2", 0, bytes.NewReader(bigValue)) require.NoError(t, err) err = pfsutil.FinishCommit(apiClient, repositoryName, newCommitID) require.NoError(t, err) fInfo, err := os.Stat(filepath.Join(directory, newCommitID, "foo")) require.NoError(t, err) require.Equal(t, int64(3), fInfo.Size()) data, err := ioutil.ReadFile(filepath.Join(directory, newCommitID, "foo")) require.NoError(t, err) require.Equal(t, "foo", string(data)) data, err = ioutil.ReadFile(filepath.Join(directory, newCommitID, "bar")) require.NoError(t, err) require.Equal(t, "bar", string(data)) data, err = ioutil.ReadFile(filepath.Join(directory, newCommitID, "big1")) require.NoError(t, err) require.Equal(t, bigValue, data) data, err = ioutil.ReadFile(filepath.Join(directory, newCommitID, "big2")) require.NoError(t, err) require.Equal(t, bigValue, data) err = mounter.Unmount(directory) require.NoError(t, err) err = mounter.Wait(directory) require.NoError(t, err) }
func testMount(t *testing.T, apiClient pfs.APIClient, cluster Cluster) { repoName := "testMountRepo" err := pfsutil.CreateRepo(apiClient, repoName) require.NoError(t, err) directory := "/compile/testMount" mounter := fuse.NewMounter("localhost", apiClient) ready := make(chan bool) go func() { err = mounter.Mount(directory, &pfs.Shard{Number: 0, Modulus: 1}, nil, ready) require.NoError(t, err) }() <-ready _, err = os.Stat(filepath.Join(directory, repoName)) require.NoError(t, err) commit, err := pfsutil.StartCommit(apiClient, repoName, "") require.NoError(t, err) require.NotNil(t, commit) newCommitID := commit.Id _, err = os.Stat(filepath.Join(directory, repoName, newCommitID)) require.NoError(t, err) err = ioutil.WriteFile(filepath.Join(directory, repoName, newCommitID, "foo"), []byte("foo"), 0666) require.NoError(t, err) _, err = pfsutil.PutFile(apiClient, repoName, newCommitID, "bar", 0, strings.NewReader("bar")) require.NoError(t, err) bigValue := make([]byte, 1024*1024) for i := 0; i < 1024*1024; i++ { bigValue[i] = 'a' } err = ioutil.WriteFile(filepath.Join(directory, repoName, newCommitID, "big1"), bigValue, 0666) require.NoError(t, err) _, err = pfsutil.PutFile(apiClient, repoName, newCommitID, "big2", 0, bytes.NewReader(bigValue)) require.NoError(t, err) err = pfsutil.FinishCommit(apiClient, repoName, newCommitID) require.NoError(t, err) fInfo, err := os.Stat(filepath.Join(directory, repoName, newCommitID, "foo")) require.NoError(t, err) require.Equal(t, int64(3), fInfo.Size()) data, err := ioutil.ReadFile(filepath.Join(directory, repoName, newCommitID, "foo")) require.NoError(t, err) require.Equal(t, "foo", string(data)) data, err = ioutil.ReadFile(filepath.Join(directory, repoName, newCommitID, "bar")) require.NoError(t, err) require.Equal(t, "bar", string(data)) data, err = ioutil.ReadFile(filepath.Join(directory, repoName, newCommitID, "big1")) require.NoError(t, err) require.Equal(t, bigValue, data) data, err = ioutil.ReadFile(filepath.Join(directory, repoName, newCommitID, "big2")) require.NoError(t, err) require.Equal(t, bigValue, data) err = mounter.Unmount(directory) require.NoError(t, err) }
func Cmds(address string) ([]*cobra.Command, error) { var number int var modulus int shard := func() *pfs.Shard { return &pfs.Shard{Number: uint64(number), Modulus: uint64(modulus)} } createRepo := &cobra.Command{ Use: "create-repo repo-name", Short: "Create a new repo.", Long: "Create a new repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.CreateRepo(apiClient, args[0]) }), } inspectRepo := &cobra.Command{ Use: "inspect-repo repo-name", Short: "Return info about a repo.", Long: "Return info about a repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } repoInfo, err := pfsutil.InspectRepo(apiClient, args[0]) if err != nil { return err } if repoInfo == nil { return fmt.Errorf("repo %s not found", args[0]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintRepoHeader(writer) pretty.PrintRepoInfo(writer, repoInfo) return writer.Flush() }), } listRepo := &cobra.Command{ Use: "list-repo", Short: "Return all repos.", Long: "Reutrn all repos.", Run: pkgcobra.RunFixedArgs(0, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } repoInfos, err := pfsutil.ListRepo(apiClient) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintRepoHeader(writer) for _, repoInfo := range repoInfos { pretty.PrintRepoInfo(writer, repoInfo) } return writer.Flush() }), } deleteRepo := &cobra.Command{ Use: "delete-repo repo-name", Short: "Delete a repo.", Long: "Delete a repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.DeleteRepo(apiClient, args[0]) }), } startCommit := &cobra.Command{ Use: "start-commit repo-name [parent-commit-id]", Short: "Start a new commit.", Long: "Start a new commit with parent-commit-id as the parent.", Run: pkgcobra.RunBoundedArgs(pkgcobra.Bounds{Min: 1, Max: 2}, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } parentCommitID := "" if len(args) == 2 { parentCommitID = args[1] } commit, err := pfsutil.StartCommit(apiClient, args[0], parentCommitID) if err != nil { return err } fmt.Println(commit.Id) return nil }), } finishCommit := &cobra.Command{ Use: "finish-commit repo-name commit-id", Short: "Finish a started commit.", Long: "Finish a started commit. Commit-id must be a writeable commit.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.FinishCommit(apiClient, args[0], args[1]) }), } inspectCommit := &cobra.Command{ Use: "inspect-commit repo-name commit-id", Short: "Return info about a commit.", Long: "Return info about a commit.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } commitInfo, err := pfsutil.InspectCommit(apiClient, args[0], args[1]) if err != nil { return err } if commitInfo == nil { return fmt.Errorf("commit %s not found", args[1]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintCommitInfoHeader(writer) pretty.PrintCommitInfo(writer, commitInfo) return writer.Flush() }), } listCommit := &cobra.Command{ Use: "list-commit repo-name", Short: "Return all commits on a repo.", Long: "Return all commits on a repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } commitInfos, err := pfsutil.ListCommit(apiClient, args) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintCommitInfoHeader(writer) for _, commitInfo := range commitInfos { pretty.PrintCommitInfo(writer, commitInfo) } return writer.Flush() }), } deleteCommit := &cobra.Command{ Use: "delete-commit repo-name commit-id", Short: "Delete a commit.", Long: "Delete a commit.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.DeleteCommit(apiClient, args[0], args[1]) }), } mkdir := &cobra.Command{ Use: "mkdir repo-name commit-id path/to/dir", Short: "Make a directory.", Long: "Make a directory. Parent directories need not exist.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.MakeDirectory(apiClient, args[0], args[1], args[2]) }), } putFile := &cobra.Command{ Use: "put-file repo-name commit-id path/to/file", Short: "Put a file from stdin", Long: "Put a file from stdin. Directories must exist. commit-id must be a writeable commit.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } _, err = pfsutil.PutFile(apiClient, args[0], args[1], args[2], 0, os.Stdin) return err }), } getFile := &cobra.Command{ Use: "get-file repo-name commit-id path/to/file", Short: "Return the contents of a file.", Long: "Return the contents of a file.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.GetFile(apiClient, args[0], args[1], args[2], 0, math.MaxInt64, shard(), os.Stdout) }), } getFile.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from") getFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") inspectFile := &cobra.Command{ Use: "inspect-file repo-name commit-id path/to/file", Short: "Return info about a file.", Long: "Return info about a file.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } fileInfo, err := pfsutil.InspectFile(apiClient, args[0], args[1], args[2], shard()) if err != nil { return err } if fileInfo == nil { return fmt.Errorf("file %s not found", args[2]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintFileInfoHeader(writer) pretty.PrintFileInfo(writer, fileInfo) return writer.Flush() }), } inspectFile.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from") inspectFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") listFile := &cobra.Command{ Use: "list-file repo-name commit-id path/to/dir", Short: "Return the files in a directory.", Long: "Return the files in a directory.", Run: pkgcobra.RunBoundedArgs(pkgcobra.Bounds{Min: 2, Max: 3}, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } var path string if len(args) == 3 { path = args[2] } fileInfos, err := pfsutil.ListFile(apiClient, args[0], args[1], path, shard()) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintFileInfoHeader(writer) for _, fileInfo := range fileInfos { pretty.PrintFileInfo(writer, fileInfo) } return writer.Flush() }), } listFile.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from") listFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") deleteFile := &cobra.Command{ Use: "delete-file repo-name commit-id path/to/file", Short: "Delete a file.", Long: "Delete a file.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.DeleteFile(apiClient, args[0], args[1], args[2]) }), } listChange := &cobra.Command{ Use: "list-change repo-name commit-id path/to/dir", Short: "Return the changes in a directory.", Long: "Return the changes in a directory.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } changeInfos, err := pfsutil.ListChange(apiClient, args[0], args[1], args[2], shard()) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintChangeHeader(writer) for _, changeInfo := range changeInfos { pretty.PrintChange(writer, changeInfo) } return writer.Flush() }), } listChange.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from") listChange.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") inspectServer := &cobra.Command{ Use: "inspect-server server-id", Short: "Inspect a server.", Long: "Inspect a server.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { clusterAPIClient, err := getClusterAPIClient(address) if err != nil { return err } serverInfo, err := pfsutil.InspectServer(clusterAPIClient, args[0]) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintServerInfoHeader(writer) pretty.PrintServerInfo(writer, serverInfo) return writer.Flush() }), } listServer := &cobra.Command{ Use: "list-server", Short: "Return all servers in the cluster.", Long: "Return all servers in the cluster.", Run: pkgcobra.RunFixedArgs(0, func(args []string) error { clusterAPIClient, err := getClusterAPIClient(address) if err != nil { return err } serverInfos, err := pfsutil.ListServer(clusterAPIClient) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintServerInfoHeader(writer) for _, serverInfo := range serverInfos { pretty.PrintServerInfo(writer, serverInfo) } return writer.Flush() }), } var mountPoint string mount := &cobra.Command{ Use: "mount [repo/commit:alias...]", Short: "Mount pfs locally.", Long: "Mount pfs locally.", Run: pkgcobra.Run(func(args []string) error { protolog.SetLevel(protolog.Level_LEVEL_DEBUG) apiClient, err := getAPIClient(address) if err != nil { return err } mounter := fuse.NewMounter(address, apiClient) return mounter.Mount(mountPoint, shard(), parseCommitMounts(args), nil) }), } mount.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from") mount.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") mount.Flags().StringVarP(&mountPoint, "mount-point", "p", "/pfs", "root of mounted filesystem") var result []*cobra.Command result = append(result, createRepo) result = append(result, inspectRepo) result = append(result, listRepo) result = append(result, deleteRepo) result = append(result, startCommit) result = append(result, finishCommit) result = append(result, inspectCommit) result = append(result, listCommit) result = append(result, deleteCommit) result = append(result, mkdir) result = append(result, putFile) result = append(result, getFile) result = append(result, inspectFile) result = append(result, listFile) result = append(result, deleteFile) result = append(result, listChange) result = append(result, inspectServer) result = append(result, listServer) result = append(result, mount) return result, nil }
func testReplica(t *testing.T, apiClient pfs.ApiClient, internalAPIClient pfs.InternalApiClient) { masterName := TestRepositoryName() err := pfsutil.InitRepository(apiClient, masterName, false) require.NoError(t, err) replicaName := TestRepositoryName() err = pfsutil.InitRepository(apiClient, replicaName, true) require.NoError(t, err) for i := 0; i < testShardsPerServer*testNumServers; i++ { var buffer bytes.Buffer err := pfsutil.PullDiff(internalAPIClient, masterName, "scratch", uint64(i), &buffer) require.NoError(t, err) err = pfsutil.PushDiff(internalAPIClient, replicaName, "scratch", uint64(i), &buffer) require.NoError(t, err) } getCommitInfoResponse, err := pfsutil.GetCommitInfo(apiClient, replicaName, "scratch") require.NoError(t, err) require.NotNil(t, getCommitInfoResponse) require.NotNil(t, getCommitInfoResponse.CommitInfo) require.Equal(t, "scratch", getCommitInfoResponse.CommitInfo.Commit.Id) require.Equal(t, pfs.CommitType_COMMIT_TYPE_READ, getCommitInfoResponse.CommitInfo.CommitType) require.Nil(t, getCommitInfoResponse.CommitInfo.ParentCommit) branchResponse, err := pfsutil.Branch(apiClient, masterName, "scratch") require.NoError(t, err) require.NotNil(t, branchResponse) newCommitID := branchResponse.Commit.Id var wg sync.WaitGroup for i := 0; i < testSize; i++ { i := i wg.Add(1) go func() { defer wg.Done() _, iErr := pfsutil.PutFile(apiClient, masterName, newCommitID, fmt.Sprintf("file%d", i), 0, strings.NewReader(fmt.Sprintf("hello%d", i))) require.NoError(t, iErr) }() } wg.Wait() err = pfsutil.Commit(apiClient, masterName, newCommitID) require.NoError(t, err) for i := 0; i < testShardsPerServer*testNumServers; i++ { var buffer bytes.Buffer err := pfsutil.PullDiff(internalAPIClient, masterName, newCommitID, uint64(i), &buffer) require.NoError(t, err) err = pfsutil.PushDiff(internalAPIClient, replicaName, newCommitID, uint64(i), &buffer) require.NoError(t, err) } getCommitInfoResponse, err = pfsutil.GetCommitInfo(apiClient, replicaName, newCommitID) require.NoError(t, err) require.NotNil(t, getCommitInfoResponse) require.NotNil(t, getCommitInfoResponse.CommitInfo) require.Equal(t, newCommitID, getCommitInfoResponse.CommitInfo.Commit.Id) require.Equal(t, pfs.CommitType_COMMIT_TYPE_READ, getCommitInfoResponse.CommitInfo.CommitType) require.Equal(t, "scratch", getCommitInfoResponse.CommitInfo.ParentCommit.Id) }
func do(appEnvObj interface{}) error { appEnv := appEnvObj.(*appEnv) logrus.Register() address := appEnv.PachydermPfsd1Port if address == "" { address = appEnv.Address } else { address = strings.Replace(address, "tcp://", "", -1) } clientConn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { return err } apiClient := pfs.NewApiClient(clientConn) var shard int var modulus int createRepo := cobramainutil.Command{ Use: "create-repo repo-name", Short: "Create a new repo.", Long: "Create a new repo.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.CreateRepo(apiClient, args[0]) }, }.ToCobraCommand() inspectRepo := cobramainutil.Command{ Use: "inspect-repo repo-name", Short: "Return info about a repo.", Long: "Return info about a repo.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { repoInfo, err := pfsutil.InspectRepo(apiClient, args[0]) if err != nil { return err } if repoInfo == nil { return fmt.Errorf("repo %s not found", args[0]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintRepoHeader(writer) pretty.PrintRepoInfo(writer, repoInfo) return writer.Flush() }, }.ToCobraCommand() listRepo := cobramainutil.Command{ Use: "list-repo", Short: "Return all repos.", Long: "Reutrn all repos.", NumArgs: 0, Run: func(cmd *cobra.Command, args []string) error { repoInfos, err := pfsutil.ListRepo(apiClient) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintRepoHeader(writer) for _, repoInfo := range repoInfos { pretty.PrintRepoInfo(writer, repoInfo) } return writer.Flush() }, }.ToCobraCommand() deleteRepo := cobramainutil.Command{ Use: "delete-repo repo-name", Short: "Delete a repo.", Long: "Delete a repo.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.DeleteRepo(apiClient, args[0]) }, }.ToCobraCommand() startCommit := cobramainutil.Command{ Use: "start-commit repo-name parent-commit-id", Short: "Start a new commit.", Long: "Start a new commit with parent-commit-id as the parent.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { commit, err := pfsutil.StartCommit(apiClient, args[0], args[1]) if err != nil { return err } fmt.Println(commit.Id) return nil }, }.ToCobraCommand() finishCommit := cobramainutil.Command{ Use: "finish-commit repo-name commit-id", Short: "Finish a started commit.", Long: "Finish a started commit. Commit-id must be a writeable commit.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.FinishCommit(apiClient, args[0], args[1]) }, }.ToCobraCommand() inspectCommit := cobramainutil.Command{ Use: "inspect-commit repo-name commit-id", Short: "Return info about a commit.", Long: "Return info about a commit.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { commitInfo, err := pfsutil.InspectCommit(apiClient, args[0], args[1]) if err != nil { return err } if commitInfo == nil { return fmt.Errorf("commit %s not found", args[1]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintCommitInfoHeader(writer) pretty.PrintCommitInfo(writer, commitInfo) return writer.Flush() }, }.ToCobraCommand() listCommit := cobramainutil.Command{ Use: "list-commit repo-name", Short: "Return all commits on a repo.", Long: "Return all commits on a repo.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { commitInfos, err := pfsutil.ListCommit(apiClient, args[0]) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintCommitInfoHeader(writer) for _, commitInfo := range commitInfos { pretty.PrintCommitInfo(writer, commitInfo) } return writer.Flush() }, }.ToCobraCommand() deleteCommit := cobramainutil.Command{ Use: "delete-commit repo-name commit-id", Short: "Delete a commit.", Long: "Delete a commit.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.DeleteCommit(apiClient, args[0], args[1]) }, }.ToCobraCommand() putBlock := cobramainutil.Command{ Use: "put-block repo-name commit-id path/to/file", Short: "Put a block from stdin", Long: "Put a block from stdin. Directories must exist. commit-id must be a writeable commit.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { block, err := pfsutil.PutBlock(apiClient, args[0], args[1], args[2], os.Stdin) if err != nil { return err } fmt.Println(block.Hash) return nil }, }.ToCobraCommand() getBlock := cobramainutil.Command{ Use: "get-block hash", Short: "Return the contents of a block.", Long: "Return the contents of a block.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.GetBlock(apiClient, args[0], os.Stdout) }, }.ToCobraCommand() inspectBlock := cobramainutil.Command{ Use: "inspect-block hash", Short: "Return info about a block.", Long: "Return info about a block.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { blockInfo, err := pfsutil.InspectBlock(apiClient, args[0]) if err != nil { return err } if blockInfo == nil { return fmt.Errorf("block %s not found", args[2]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintBlockInfoHeader(writer) pretty.PrintBlockInfo(writer, blockInfo) return writer.Flush() }, }.ToCobraCommand() listBlock := cobramainutil.Command{ Use: "list-block", Short: "Return the blocks in a directory.", Long: "Return the blocks in a directory.", NumArgs: 0, Run: func(cmd *cobra.Command, args []string) error { blockInfos, err := pfsutil.ListBlock(apiClient, uint64(shard), uint64(modulus)) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintBlockInfoHeader(writer) for _, blockInfo := range blockInfos { pretty.PrintBlockInfo(writer, blockInfo) } return writer.Flush() }, }.ToCobraCommand() listBlock.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from") listBlock.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") mkdir := cobramainutil.Command{ Use: "mkdir repo-name commit-id path/to/dir", Short: "Make a directory.", Long: "Make a directory. Parent directories need not exist.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.MakeDirectory(apiClient, args[0], args[1], args[2]) }, }.ToCobraCommand() putFile := cobramainutil.Command{ Use: "put-file repo-name commit-id path/to/file", Short: "Put a file from stdin", Long: "Put a file from stdin. Directories must exist. commit-id must be a writeable commit.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { _, err := pfsutil.PutFile(apiClient, args[0], args[1], args[2], 0, os.Stdin) return err }, }.ToCobraCommand() getFile := cobramainutil.Command{ Use: "get-file repo-name commit-id path/to/file", Short: "Return the contents of a file.", Long: "Return the contents of a file.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.GetFile(apiClient, args[0], args[1], args[2], 0, math.MaxInt64, os.Stdout) }, }.ToCobraCommand() inspectFile := cobramainutil.Command{ Use: "inspect-file repo-name commit-id path/to/file", Short: "Return info about a file.", Long: "Return info about a file.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { fileInfo, err := pfsutil.InspectFile(apiClient, args[0], args[1], args[2]) if err != nil { return err } if fileInfo == nil { return fmt.Errorf("file %s not found", args[2]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintFileInfoHeader(writer) pretty.PrintFileInfo(writer, fileInfo) return writer.Flush() }, }.ToCobraCommand() listFile := cobramainutil.Command{ Use: "list-file repo-name commit-id path/to/dir", Short: "Return the files in a directory.", Long: "Return the files in a directory.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { fileInfos, err := pfsutil.ListFile(apiClient, args[0], args[1], args[2], uint64(shard), uint64(modulus)) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintFileInfoHeader(writer) for _, fileInfo := range fileInfos { pretty.PrintFileInfo(writer, fileInfo) } return writer.Flush() }, }.ToCobraCommand() listFile.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from") listFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") deleteFile := cobramainutil.Command{ Use: "delete-file repo-name commit-id path/to/file", Short: "Delete a file.", Long: "Delete a file.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.DeleteFile(apiClient, args[0], args[1], args[2]) }, }.ToCobraCommand() listChange := cobramainutil.Command{ Use: "list-change repo-name commit-id path/to/dir", Short: "Return the changes in a directory.", Long: "Return the changes in a directory.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { changeInfos, err := pfsutil.ListChange(apiClient, args[0], args[1], args[2], uint64(shard), uint64(modulus)) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintChangeHeader(writer) for _, changeInfo := range changeInfos { pretty.PrintChange(writer, changeInfo) } return writer.Flush() }, }.ToCobraCommand() listChange.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from") listChange.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") inspectServer := cobramainutil.Command{ Use: "inspect-server server-id", Short: "Inspect a server.", Long: "Inspect a server.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { serverInfo, err := pfsutil.InspectServer(apiClient, args[0]) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintServerInfoHeader(writer) pretty.PrintServerInfo(writer, serverInfo) return writer.Flush() }, }.ToCobraCommand() listServer := cobramainutil.Command{ Use: "list-server", Short: "Return all servers in the cluster.", Long: "Return all servers in the cluster.", NumArgs: 0, Run: func(cmd *cobra.Command, args []string) error { serverInfos, err := pfsutil.ListServer(apiClient) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintServerInfoHeader(writer) for _, serverInfo := range serverInfos { pretty.PrintServerInfo(writer, serverInfo) } return writer.Flush() }, }.ToCobraCommand() mount := cobramainutil.Command{ Use: "mount mountpoint repo-name [commit-id]", Short: "Mount a repo as a local file system.", Long: "Mount a repo as a local file system.", MinNumArgs: 2, MaxNumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { mountPoint := args[0] repo := args[1] commitID := "" if len(args) == 3 { commitID = args[2] } mounter := fuse.NewMounter(apiClient) if err := mounter.Mount(repo, commitID, mountPoint, uint64(shard), uint64(modulus)); err != nil { return err } return mounter.Wait(mountPoint) }, }.ToCobraCommand() mount.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from") mount.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") rootCmd := &cobra.Command{ Use: "pfs", Long: `Access the PFS API. Note that this CLI is experimental and does not even check for common errors. The environment variable PFS_ADDRESS controls what server the CLI connects to, the default is 0.0.0.0:650.`, } rootCmd.AddCommand(protoclient.NewVersionCommand(clientConn, pachyderm.Version, nil)) rootCmd.AddCommand(createRepo) rootCmd.AddCommand(inspectRepo) rootCmd.AddCommand(listRepo) rootCmd.AddCommand(deleteRepo) rootCmd.AddCommand(startCommit) rootCmd.AddCommand(finishCommit) rootCmd.AddCommand(inspectCommit) rootCmd.AddCommand(listCommit) rootCmd.AddCommand(deleteCommit) rootCmd.AddCommand(mkdir) rootCmd.AddCommand(putBlock) rootCmd.AddCommand(getBlock) rootCmd.AddCommand(inspectBlock) rootCmd.AddCommand(listBlock) rootCmd.AddCommand(putFile) rootCmd.AddCommand(getFile) rootCmd.AddCommand(inspectFile) rootCmd.AddCommand(listFile) rootCmd.AddCommand(deleteFile) rootCmd.AddCommand(listChange) rootCmd.AddCommand(inspectServer) rootCmd.AddCommand(listServer) rootCmd.AddCommand(mount) return rootCmd.Execute() }
func testMount(t *testing.T, apiClient pfs.ApiClient, internalAPIClient pfs.InternalApiClient) { repositoryName := TestRepositoryName() err := pfsutil.InitRepository(apiClient, repositoryName, false) require.NoError(t, err) directory := "/compile/testMount" mounter := fuse.NewMounter() go func() { err = mounter.Mount(apiClient, repositoryName, directory, 0, 1) require.NoError(t, err) }() mounter.Ready() _, err = os.Stat(filepath.Join(directory, "scratch")) require.NoError(t, err) branchResponse, err := pfsutil.Branch(apiClient, repositoryName, "scratch") require.NoError(t, err) require.NotNil(t, branchResponse) newCommitID := branchResponse.Commit.Id _, err = os.Stat(filepath.Join(directory, newCommitID)) require.NoError(t, err) err = ioutil.WriteFile(filepath.Join(directory, newCommitID, "foo"), []byte("foo"), 0666) require.NoError(t, err) _, err = pfsutil.PutFile(apiClient, repositoryName, newCommitID, "bar", 0, strings.NewReader("bar")) require.NoError(t, err) bigValue := make([]byte, 1024*1024) for i := 0; i < 1024*1024; i++ { bigValue[i] = 'a' } err = ioutil.WriteFile(filepath.Join(directory, newCommitID, "big1"), bigValue, 0666) require.NoError(t, err) _, err = pfsutil.PutFile(apiClient, repositoryName, newCommitID, "big2", 0, bytes.NewReader(bigValue)) require.NoError(t, err) err = pfsutil.Commit(apiClient, repositoryName, newCommitID) require.NoError(t, err) fInfo, err := os.Stat(filepath.Join(directory, newCommitID, "foo")) require.NoError(t, err) require.Equal(t, int64(3), fInfo.Size()) data, err := ioutil.ReadFile(filepath.Join(directory, newCommitID, "foo")) require.NoError(t, err) require.Equal(t, "foo", string(data)) data, err = ioutil.ReadFile(filepath.Join(directory, newCommitID, "bar")) require.NoError(t, err) require.Equal(t, "bar", string(data)) data, err = ioutil.ReadFile(filepath.Join(directory, newCommitID, "big1")) require.NoError(t, err) require.Equal(t, bigValue, data) data, err = ioutil.ReadFile(filepath.Join(directory, newCommitID, "big2")) require.NoError(t, err) require.Equal(t, bigValue, data) }
func do(appEnvObj interface{}) error { appEnv := appEnvObj.(*appEnv) clientConn, err := grpc.Dial(appEnv.Address) if err != nil { return err } apiClient := pfs.NewApiClient(clientConn) var shard int var modulus int initCmd := cobramainutil.Command{ Use: "init repository-name", Long: "Initalize a repository.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.InitRepository(apiClient, args[0], false) }, }.ToCobraCommand() mkdirCmd := cobramainutil.Command{ Use: "mkdir repository-name commit-id path/to/dir", Long: "Make a directory. Sub directories must already exist.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.MakeDirectory(apiClient, args[0], args[1], args[2]) }, }.ToCobraCommand() putCmd := cobramainutil.Command{ Use: "put repository-name branch-id path/to/file", Long: "Put a file from stdin. Directories must exist. branch-id must be a writeable commit.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { _, err := pfsutil.PutFile(apiClient, args[0], args[1], args[2], 0, os.Stdin) return err }, }.ToCobraCommand() getCmd := cobramainutil.Command{ Use: "get repository-name commit-id path/to/file", Long: "Get a file from stdout. commit-id must be a readable commit.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.GetFile(apiClient, args[0], args[1], args[2], 0, pfsutil.GetAll, os.Stdout) }, }.ToCobraCommand() lsCmd := cobramainutil.Command{ Use: "ls repository-name branch-id path/to/dir", Long: "List a directory. Directory must exist.", NumArgs: 3, Run: func(cmd *cobra.Command, args []string) error { listFilesResponse, err := pfsutil.ListFiles(apiClient, args[0], args[1], args[2], uint64(shard), uint64(modulus)) if err != nil { return err } for _, fileInfo := range listFilesResponse.FileInfo { fmt.Printf("%+v\n", fileInfo) } return nil }, }.ToCobraCommand() lsCmd.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from") lsCmd.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") branchCmd := cobramainutil.Command{ Use: "branch repository-name commit-id", Long: "Branch a commit. commit-id must be a readable commit.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { branchResponse, err := pfsutil.Branch(apiClient, args[0], args[1]) if err != nil { return err } fmt.Println(branchResponse.Commit.Id) return nil }, }.ToCobraCommand() commitCmd := cobramainutil.Command{ Use: "commit repository-name branch-id", Long: "Commit a branch. branch-id must be a writeable commit.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { return pfsutil.Commit(apiClient, args[0], args[1]) }, }.ToCobraCommand() commitInfoCmd := cobramainutil.Command{ Use: "commit-info repository-name commit-id", Long: "Get info for a commit.", NumArgs: 2, Run: func(cmd *cobra.Command, args []string) error { commitInfoResponse, err := pfsutil.GetCommitInfo(apiClient, args[0], args[1]) if err != nil { return err } fmt.Printf("%+v\n", commitInfoResponse.CommitInfo) return nil }, }.ToCobraCommand() listCommitsCmd := cobramainutil.Command{ Use: "list-commits repository-name", Long: "List commits on the repository.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { listCommitsResponse, err := pfsutil.ListCommits(apiClient, args[0]) if err != nil { return err } for _, commitInfo := range listCommitsResponse.CommitInfo { fmt.Printf("%+v\n", commitInfo) } return nil }, }.ToCobraCommand() mountCmd := cobramainutil.Command{ Use: "mount repository-name", Long: "Mount a repository as a local file system.", NumArgs: 1, Run: func(cmd *cobra.Command, args []string) error { return fuse.NewMounter().Mount(apiClient, args[0], args[0], uint64(shard), uint64(modulus)) }, }.ToCobraCommand() mountCmd.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from") mountCmd.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards") rootCmd := &cobra.Command{ Use: "pfs", Long: `Access the PFS API. Note that this CLI is experimental and does not even check for common errors. The environment variable PFS_ADDRESS controls what server the CLI connects to, the default is 0.0.0.0:650.`, } rootCmd.AddCommand(cobramainutil.NewVersionCommand(clientConn, pachyderm.Version)) rootCmd.AddCommand(initCmd) rootCmd.AddCommand(mkdirCmd) rootCmd.AddCommand(putCmd) rootCmd.AddCommand(getCmd) rootCmd.AddCommand(lsCmd) rootCmd.AddCommand(branchCmd) rootCmd.AddCommand(commitCmd) rootCmd.AddCommand(commitInfoCmd) rootCmd.AddCommand(listCommitsCmd) rootCmd.AddCommand(mountCmd) return rootCmd.Execute() }
func (w *worker) work(pfsClient pfs.APIClient, ppsClient pps.APIClient) error { opt := w.rand.Float64() switch { case opt < repo: repoName := w.randString(10) if err := pfsutil.CreateRepo(pfsClient, repoName); err != nil { return err } w.repos = append(w.repos, &pfs.Repo{Name: repoName}) commit, err := pfsutil.StartCommit(pfsClient, repoName, "") if err != nil { return err } w.started = append(w.started, commit) case opt < commit: if len(w.started) >= maxStartedCommits || len(w.finished) == 0 { if len(w.started) == 0 { return nil } i := w.rand.Intn(len(w.started)) commit := w.started[i] if err := pfsutil.FinishCommit(pfsClient, commit.Repo.Name, commit.Id); err != nil { return err } w.started = append(w.started[:i], w.started[i+1:]...) w.finished = append(w.finished, commit) } else { if len(w.finished) == 0 { return nil } commit := w.finished[w.rand.Intn(len(w.finished))] commit, err := pfsutil.StartCommit(pfsClient, commit.Repo.Name, commit.Id) if err != nil { return err } w.started = append(w.started, commit) } case opt < file: if len(w.started) == 0 { return nil } commit := w.started[w.rand.Intn(len(w.started))] if _, err := pfsutil.PutFile(pfsClient, commit.Repo.Name, commit.Id, w.randString(10), 0, w.reader()); err != nil { return err } case opt < job: if len(w.startedJobs) >= maxStartedJobs { job := w.startedJobs[0] w.startedJobs = w.startedJobs[1:] jobInfo, err := ppsClient.InspectJob( context.Background(), &pps.InspectJobRequest{ Job: job, BlockState: true, }, ) if err != nil { return err } if jobInfo.State != pps.JobState_JOB_STATE_SUCCESS { return fmt.Errorf("job %s failed", job.Id) } w.jobs = append(w.jobs, job) } else { if len(w.finished) == 0 { return nil } inputs := [5]string{} var jobInputs []*pps.JobInput repoSet := make(map[string]bool) for i := range inputs { commit := w.finished[w.rand.Intn(len(w.finished))] if _, ok := repoSet[commit.Repo.Name]; ok { continue } repoSet[commit.Repo.Name] = true inputs[i] = commit.Repo.Name jobInputs = append(jobInputs, &pps.JobInput{Commit: commit}) } var parentJobID string if len(w.jobs) > 0 { parentJobID = w.jobs[w.rand.Intn(len(w.jobs))].Id } outFilename := w.randString(10) job, err := ppsutil.CreateJob( ppsClient, "", []string{"bash"}, w.grepCmd(inputs, outFilename), 1, jobInputs, parentJobID, ) if err != nil { return err } w.startedJobs = append(w.startedJobs, job) } case opt < pipeline: if len(w.repos) == 0 { return nil } inputs := [5]string{} var pipelineInputs []*pps.PipelineInput repoSet := make(map[string]bool) for i := range inputs { repo := w.repos[w.rand.Intn(len(w.repos))] if _, ok := repoSet[repo.Name]; ok { continue } repoSet[repo.Name] = true inputs[i] = repo.Name pipelineInputs = append(pipelineInputs, &pps.PipelineInput{Repo: repo}) } pipelineName := w.randString(10) outFilename := w.randString(10) if err := ppsutil.CreatePipeline( ppsClient, pipelineName, "", []string{"bash"}, w.grepCmd(inputs, outFilename), 1, pipelineInputs, ); err != nil { return err } w.pipelines = append(w.pipelines, ppsutil.NewPipeline(pipelineName)) } return nil }
func TestPipeline(t *testing.T) { t.Parallel() pachClient := getPachClient(t) // create repos dataRepo := uniqueString("TestPipeline.data") require.NoError(t, pfsutil.CreateRepo(pachClient, dataRepo)) // create pipeline pipelineName := uniqueString("pipeline") outRepo := pps.PipelineRepo(ppsutil.NewPipeline(pipelineName)) require.NoError(t, ppsutil.CreatePipeline( pachClient, pipelineName, "", []string{"cp", path.Join("/pfs", dataRepo, "file"), "/pfs/out/file"}, nil, 1, []*pps.PipelineInput{{Repo: &pfs.Repo{Name: dataRepo}}}, )) // Do first commit to repo commit1, err := pfsutil.StartCommit(pachClient, dataRepo, "") require.NoError(t, err) _, err = pfsutil.PutFile(pachClient, dataRepo, commit1.Id, "file", 0, strings.NewReader("foo\n")) require.NoError(t, err) require.NoError(t, pfsutil.FinishCommit(pachClient, dataRepo, commit1.Id)) listCommitRequest := &pfs.ListCommitRequest{ Repo: []*pfs.Repo{outRepo}, CommitType: pfs.CommitType_COMMIT_TYPE_READ, Block: true, } listCommitResponse, err := pachClient.ListCommit( context.Background(), listCommitRequest, ) require.NoError(t, err) outCommits := listCommitResponse.CommitInfo require.Equal(t, 1, len(outCommits)) var buffer bytes.Buffer require.NoError(t, pfsutil.GetFile(pachClient, outRepo.Name, outCommits[0].Commit.Id, "file", 0, 0, "", nil, &buffer)) require.Equal(t, "foo\n", buffer.String()) // Do second commit to repo commit2, err := pfsutil.StartCommit(pachClient, dataRepo, commit1.Id) require.NoError(t, err) _, err = pfsutil.PutFile(pachClient, dataRepo, commit2.Id, "file", 0, strings.NewReader("bar\n")) require.NoError(t, err) require.NoError(t, pfsutil.FinishCommit(pachClient, dataRepo, commit2.Id)) listCommitRequest = &pfs.ListCommitRequest{ Repo: []*pfs.Repo{outRepo}, FromCommit: []*pfs.Commit{outCommits[0].Commit}, CommitType: pfs.CommitType_COMMIT_TYPE_READ, Block: true, } listCommitResponse, err = pachClient.ListCommit( context.Background(), listCommitRequest, ) require.NoError(t, err) require.NotNil(t, listCommitResponse.CommitInfo[0].ParentCommit) require.Equal(t, outCommits[0].Commit.Id, listCommitResponse.CommitInfo[0].ParentCommit.Id) outCommits = listCommitResponse.CommitInfo require.Equal(t, 1, len(outCommits)) buffer = bytes.Buffer{} require.NoError(t, pfsutil.GetFile(pachClient, outRepo.Name, outCommits[0].Commit.Id, "file", 0, 0, "", nil, &buffer)) require.Equal(t, "foo\nbar\n", buffer.String()) }
func Cmds(address string) []*cobra.Command { var fileNumber int var fileModulus int var blockNumber int var blockModulus int shard := func() *pfs.Shard { return &pfs.Shard{ FileNumber: uint64(fileNumber), FileModulus: uint64(fileModulus), BlockNumber: uint64(blockNumber), BlockModulus: uint64(blockModulus), } } addShardFlags := func(cmd *cobra.Command) { cmd.Flags().IntVarP(&fileNumber, "file-shard", "s", 0, "file shard to read") cmd.Flags().IntVarP(&fileModulus, "file-modulus", "m", 1, "modulus of file shard") cmd.Flags().IntVarP(&blockNumber, "block-shard", "b", 0, "block shard to read") cmd.Flags().IntVarP(&blockModulus, "block-modulus", "n", 1, "modulus of block shard") } repo := &cobra.Command{ Use: "repo", Short: "Docs for repos.", Long: `Repos, short for repository, are the top level data object in Pachyderm. Repos are created with create-repo.`, Run: pkgcobra.RunFixedArgs(0, func(args []string) error { return nil }), } createRepo := &cobra.Command{ Use: "create-repo repo-name", Short: "Create a new repo.", Long: "Create a new repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.CreateRepo(apiClient, args[0]) }), } inspectRepo := &cobra.Command{ Use: "inspect-repo repo-name", Short: "Return info about a repo.", Long: "Return info about a repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } repoInfo, err := pfsutil.InspectRepo(apiClient, args[0]) if err != nil { return err } if repoInfo == nil { return fmt.Errorf("repo %s not found", args[0]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintRepoHeader(writer) pretty.PrintRepoInfo(writer, repoInfo) return writer.Flush() }), } listRepo := &cobra.Command{ Use: "list-repo", Short: "Return all repos.", Long: "Reutrn all repos.", Run: pkgcobra.RunFixedArgs(0, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } repoInfos, err := pfsutil.ListRepo(apiClient) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintRepoHeader(writer) for _, repoInfo := range repoInfos { pretty.PrintRepoInfo(writer, repoInfo) } return writer.Flush() }), } deleteRepo := &cobra.Command{ Use: "delete-repo repo-name", Short: "Delete a repo.", Long: "Delete a repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.DeleteRepo(apiClient, args[0]) }), } commit := &cobra.Command{ Use: "commit", Short: "Docs for commits.", Long: `Commits are atomic transactions on the content of a repo. Creating a commit is a multistep process: - start a new commit with start-commit - write files to it through fuse or with put-file - finish the new commit with finish-commit Commits that have been started but not finished are NOT durable storage. Commits become reliable (and immutable) when they are finished. Commits can be created with another commit as a parent. This layers the data in the commit over the data in the parent.`, Run: pkgcobra.RunFixedArgs(0, func(args []string) error { return nil }), } startCommit := &cobra.Command{ Use: "start-commit repo-name [parent-commit-id]", Short: "Start a new commit.", Long: "Start a new commit with parent-commit-id as the parent.", Run: pkgcobra.RunBoundedArgs(pkgcobra.Bounds{Min: 1, Max: 2}, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } parentCommitID := "" if len(args) == 2 { parentCommitID = args[1] } commit, err := pfsutil.StartCommit(apiClient, args[0], parentCommitID) if err != nil { return err } fmt.Println(commit.Id) return nil }), } finishCommit := &cobra.Command{ Use: "finish-commit repo-name commit-id", Short: "Finish a started commit.", Long: "Finish a started commit. Commit-id must be a writeable commit.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.FinishCommit(apiClient, args[0], args[1]) }), } inspectCommit := &cobra.Command{ Use: "inspect-commit repo-name commit-id", Short: "Return info about a commit.", Long: "Return info about a commit.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } commitInfo, err := pfsutil.InspectCommit(apiClient, args[0], args[1]) if err != nil { return err } if commitInfo == nil { return fmt.Errorf("commit %s not found", args[1]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintCommitInfoHeader(writer) pretty.PrintCommitInfo(writer, commitInfo) return writer.Flush() }), } listCommit := &cobra.Command{ Use: "list-commit repo-name", Short: "Return all commits on a repo.", Long: "Return all commits on a repo.", Run: pkgcobra.RunFixedArgs(1, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } commitInfos, err := pfsutil.ListCommit(apiClient, args) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintCommitInfoHeader(writer) for _, commitInfo := range commitInfos { pretty.PrintCommitInfo(writer, commitInfo) } return writer.Flush() }), } deleteCommit := &cobra.Command{ Use: "delete-commit repo-name commit-id", Short: "Delete a commit.", Long: "Delete a commit.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.DeleteCommit(apiClient, args[0], args[1]) }), } file := &cobra.Command{ Use: "file", Short: "Docs for files.", Long: `Files are the lowest level data object in Pachyderm. Files can be written to started (but not finished) commits with put-file. Files can be read from finished commits with get-file.`, Run: pkgcobra.RunFixedArgs(0, func(args []string) error { return nil }), } putFile := &cobra.Command{ Use: "put-file repo-name commit-id path/to/file", Short: "Put a file from stdin", Long: "Put a file from stdin. Directories must exist. commit-id must be a writeable commit.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } _, err = pfsutil.PutFile(apiClient, args[0], args[1], args[2], 0, os.Stdin) return err }), } getFile := &cobra.Command{ Use: "get-file repo-name commit-id path/to/file", Short: "Return the contents of a file.", Long: "Return the contents of a file.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.GetFile(apiClient, args[0], args[1], args[2], 0, 0, "", shard(), os.Stdout) }), } addShardFlags(getFile) inspectFile := &cobra.Command{ Use: "inspect-file repo-name commit-id path/to/file", Short: "Return info about a file.", Long: "Return info about a file.", Run: pkgcobra.RunFixedArgs(3, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } fileInfo, err := pfsutil.InspectFile(apiClient, args[0], args[1], args[2], "", shard()) if err != nil { return err } if fileInfo == nil { return fmt.Errorf("file %s not found", args[2]) } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintFileInfoHeader(writer) pretty.PrintFileInfo(writer, fileInfo) return writer.Flush() }), } addShardFlags(inspectFile) listFile := &cobra.Command{ Use: "list-file repo-name commit-id path/to/dir", Short: "Return the files in a directory.", Long: "Return the files in a directory.", Run: pkgcobra.RunBoundedArgs(pkgcobra.Bounds{Min: 2, Max: 3}, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } var path string if len(args) == 3 { path = args[2] } fileInfos, err := pfsutil.ListFile(apiClient, args[0], args[1], path, "", shard()) if err != nil { return err } writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) pretty.PrintFileInfoHeader(writer) for _, fileInfo := range fileInfos { pretty.PrintFileInfo(writer, fileInfo) } return writer.Flush() }), } addShardFlags(listFile) deleteFile := &cobra.Command{ Use: "delete-file repo-name commit-id path/to/file", Short: "Delete a file.", Long: "Delete a file.", Run: pkgcobra.RunFixedArgs(2, func(args []string) error { apiClient, err := getAPIClient(address) if err != nil { return err } return pfsutil.DeleteFile(apiClient, args[0], args[1], args[2]) }), } var mountPoint string mount := &cobra.Command{ Use: "mount [repo/commit:alias...]", Short: "Mount pfs locally.", Long: "Mount pfs locally.", Run: pkgcobra.Run(func(args []string) error { //lion.SetLevel(lion.LevelDebug) apiClient, err := getAPIClient(address) if err != nil { return err } mounter := fuse.NewMounter(address, apiClient) return mounter.Mount(mountPoint, shard(), parseCommitMounts(args), nil) }), } mount.Flags().StringVarP(&mountPoint, "mount-point", "p", "/pfs", "root of mounted filesystem") addShardFlags(mount) var result []*cobra.Command result = append(result, repo) result = append(result, createRepo) result = append(result, inspectRepo) result = append(result, listRepo) result = append(result, deleteRepo) result = append(result, commit) result = append(result, startCommit) result = append(result, finishCommit) result = append(result, inspectCommit) result = append(result, listCommit) result = append(result, deleteCommit) result = append(result, file) result = append(result, putFile) result = append(result, getFile) result = append(result, inspectFile) result = append(result, listFile) result = append(result, deleteFile) result = append(result, mount) return result }
func (w *worker) work(pfsClient pfs.APIClient, ppsClient pps.APIClient) error { opt := w.rand.Float64() switch { case opt < repo: repoName := w.name() if err := pfsutil.CreateRepo(pfsClient, repoName); err != nil { return err } w.repos = append(w.repos, &pfs.Repo{Name: repoName}) commit, err := pfsutil.StartCommit(pfsClient, repoName, "") if err != nil { return err } w.started = append(w.started, commit) case opt < commit: if len(w.started) >= maxStartedCommits { i := w.rand.Intn(len(w.started)) commit := w.started[i] if err := pfsutil.FinishCommit(pfsClient, commit.Repo.Name, commit.Id); err != nil { return err } w.started = append(w.started[:i], w.started[i+1:]...) w.finished = append(w.finished, commit) } else { commit := w.finished[w.rand.Intn(len(w.finished))] commit, err := pfsutil.StartCommit(pfsClient, commit.Repo.Name, commit.Id) if err != nil { return err } w.started = append(w.started, commit) } case opt < file: commit := w.started[w.rand.Intn(len(w.started))] if _, err := pfsutil.PutFile(pfsClient, commit.Repo.Name, commit.Id, w.name(), 0, w.reader()); err != nil { return err } case opt < job: inputs := [5]string{} var inputCommits []*pfs.Commit for i := range inputs { randI := w.rand.Intn(len(w.finished)) inputs[i] = w.finished[randI].Repo.Name inputCommits = append(inputCommits, w.finished[randI]) } var parentJobID string if len(w.jobs) > 0 { parentJobID = w.jobs[w.rand.Intn(len(w.jobs))].Id } outFilename := w.name() job, err := ppsutil.CreateJob( ppsClient, "", []string{"sh"}, w.grepCmd(inputs, outFilename), 1, inputCommits, parentJobID, ) if err != nil { return err } w.jobs = append(w.jobs, job) case opt < pipeline: inputs := [5]string{} var inputRepos []*pfs.Repo for i := range inputs { randI := w.rand.Intn(len(w.repos)) inputs[i] = w.repos[randI].Name inputRepos = append(inputRepos, w.repos[randI]) } pipelineName := w.name() outFilename := w.name() if err := ppsutil.CreatePipeline( ppsClient, pipelineName, "", []string{"sh"}, w.grepCmd(inputs, outFilename), 1, inputRepos, ); err != nil { return err } w.pipelines = append(w.pipelines, ppsutil.NewPipeline(pipelineName)) } return nil }
func testSimple(t *testing.T, apiClient pfs.ApiClient) { repositoryName := testRepositoryName() err := pfsutil.InitRepository(apiClient, repositoryName) require.NoError(t, err) getCommitInfoResponse, err := pfsutil.GetCommitInfo(apiClient, repositoryName, "scratch") require.NoError(t, err) require.NotNil(t, getCommitInfoResponse) require.Equal(t, "scratch", getCommitInfoResponse.CommitInfo.Commit.Id) require.Equal(t, pfs.CommitType_COMMIT_TYPE_READ, getCommitInfoResponse.CommitInfo.CommitType) require.Nil(t, getCommitInfoResponse.CommitInfo.ParentCommit) branchResponse, err := pfsutil.Branch(apiClient, repositoryName, "scratch") require.NoError(t, err) require.NotNil(t, branchResponse) newCommitID := branchResponse.Commit.Id getCommitInfoResponse, err = pfsutil.GetCommitInfo(apiClient, repositoryName, newCommitID) require.NoError(t, err) require.NotNil(t, getCommitInfoResponse) require.Equal(t, newCommitID, getCommitInfoResponse.CommitInfo.Commit.Id) require.Equal(t, pfs.CommitType_COMMIT_TYPE_WRITE, getCommitInfoResponse.CommitInfo.CommitType) require.Equal(t, "scratch", getCommitInfoResponse.CommitInfo.ParentCommit.Id) err = pfsutil.MakeDirectory(apiClient, repositoryName, newCommitID, "a/b") require.NoError(t, err) err = pfsutil.MakeDirectory(apiClient, repositoryName, newCommitID, "a/c") require.NoError(t, err) var wg sync.WaitGroup for i := 0; i < testSize; i++ { i := i wg.Add(1) go func() { defer wg.Done() iErr := pfsutil.PutFile(apiClient, repositoryName, newCommitID, fmt.Sprintf("a/b/file%d", i), strings.NewReader(fmt.Sprintf("hello%d", i))) require.NoError(t, iErr) iErr = pfsutil.PutFile(apiClient, repositoryName, newCommitID, fmt.Sprintf("a/c/file%d", i), strings.NewReader(fmt.Sprintf("hello%d", i))) require.NoError(t, iErr) }() } wg.Wait() err = pfsutil.Commit(apiClient, repositoryName, newCommitID) require.NoError(t, err) getCommitInfoResponse, err = pfsutil.GetCommitInfo(apiClient, repositoryName, newCommitID) require.NoError(t, err) require.NotNil(t, getCommitInfoResponse) require.Equal(t, newCommitID, getCommitInfoResponse.CommitInfo.Commit.Id) require.Equal(t, pfs.CommitType_COMMIT_TYPE_READ, getCommitInfoResponse.CommitInfo.CommitType) require.Equal(t, "scratch", getCommitInfoResponse.CommitInfo.ParentCommit.Id) wg = sync.WaitGroup{} for i := 0; i < testSize; i++ { i := i wg.Add(1) go func() { defer wg.Done() reader, iErr := pfsutil.GetFile(apiClient, repositoryName, newCommitID, fmt.Sprintf("a/b/file%d", i)) require.NoError(t, iErr) buffer := bytes.NewBuffer(nil) _, iErr = buffer.ReadFrom(reader) require.NoError(t, iErr) require.Equal(t, fmt.Sprintf("hello%d", i), buffer.String()) reader, iErr = pfsutil.GetFile(apiClient, repositoryName, newCommitID, fmt.Sprintf("a/c/file%d", i)) require.NoError(t, iErr) buffer = bytes.NewBuffer(nil) _, iErr = buffer.ReadFrom(reader) require.NoError(t, iErr) require.Equal(t, fmt.Sprintf("hello%d", i), buffer.String()) }() } wg.Wait() listFilesResponse, err := pfsutil.ListFiles(apiClient, repositoryName, newCommitID, "a/b", 0, 1) require.NoError(t, err) require.Equal(t, testSize, len(listFilesResponse.FileInfo)) listFilesResponse, err = pfsutil.ListFiles(apiClient, repositoryName, newCommitID, "a/c", 0, 1) require.NoError(t, err) require.Equal(t, testSize, len(listFilesResponse.FileInfo)) var fileInfos [7][]*pfs.FileInfo wg = sync.WaitGroup{} for i := 0; i < 7; i++ { i := i wg.Add(1) go func() { defer wg.Done() listFilesResponse, iErr := pfsutil.ListFiles(apiClient, repositoryName, newCommitID, "a/b", i, 7) require.NoError(t, iErr) fileInfos[i] = listFilesResponse.FileInfo }() } wg.Wait() count := 0 for i := 0; i < 7; i++ { count += len(fileInfos[i]) } require.Equal(t, testSize, count) }