github.com/Redstoneguy129/cli@v0.0.0-20230211220159-15dca4e91917/internal/db/test/test.go (about) 1 package test 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "context" 7 _ "embed" 8 "fmt" 9 "io" 10 "os" 11 "path/filepath" 12 13 "github.com/Redstoneguy129/cli/internal/utils" 14 "github.com/docker/docker/api/types" 15 "github.com/spf13/afero" 16 ) 17 18 var ( 19 //go:embed templates/test.sh 20 testScript string 21 ) 22 23 func Run(ctx context.Context, fsys afero.Fs) error { 24 // Sanity checks. 25 { 26 if err := utils.LoadConfigFS(fsys); err != nil { 27 return err 28 } 29 30 if err := utils.AssertSupabaseDbIsRunning(); err != nil { 31 return err 32 } 33 } 34 35 return pgProve(ctx, "/tmp", fsys) 36 } 37 38 func pgProve(ctx context.Context, dstPath string, fsys afero.Fs) error { 39 // Copy tests into database container 40 var buf bytes.Buffer 41 if err := compress(utils.DbTestsDir, &buf, fsys); err != nil { 42 return err 43 } 44 if err := utils.Docker.CopyToContainer(ctx, utils.DbId, dstPath, &buf, types.CopyToContainerOptions{}); err != nil { 45 return err 46 } 47 48 // Passing in script string means command line args must be set manually, ie. "$@" 49 args := "set -- " + dstPath + "/" + utils.DbTestsDir + ";" 50 // Requires unix path inside container 51 cmd := []string{"/bin/bash", "-c", args + testScript} 52 out, err := utils.DockerExecOnce(ctx, utils.DbId, nil, cmd) 53 fmt.Print(out) 54 return err 55 } 56 57 // Ref 1: https://medium.com/@skdomino/taring-untaring-files-in-go-6b07cf56bc07 58 // Ref 2: https://gist.github.com/mimoo/25fc9716e0f1353791f5908f94d6e726 59 func compress(src string, buf io.Writer, fsys afero.Fs) error { 60 tw := tar.NewWriter(buf) 61 62 // walk through every file in the folder 63 if err := afero.Walk(fsys, src, func(file string, fi os.FileInfo, err error) error { 64 // return on any error 65 if err != nil { 66 return err 67 } 68 69 // return on non-regular files 70 if !fi.Mode().IsRegular() { 71 return nil 72 } 73 74 // create a new dir/file header 75 header, err := tar.FileInfoHeader(fi, fi.Name()) 76 if err != nil { 77 return err 78 } 79 80 // must provide real name 81 header.Name = filepath.ToSlash(file) 82 83 // write the header 84 if err := tw.WriteHeader(header); err != nil { 85 return err 86 } 87 88 // open files for taring 89 f, err := fsys.Open(file) 90 if err != nil { 91 return err 92 } 93 94 // copy file data into tar writer 95 if _, err := io.Copy(tw, f); err != nil { 96 return err 97 } 98 99 // manually close here after each file operation; defering would cause each file close 100 // to wait until all operations have completed. 101 if err := f.Close(); err != nil { 102 return err 103 } 104 105 return nil 106 }); err != nil { 107 return err 108 } 109 110 // produce tar 111 if err := tw.Close(); err != nil { 112 return err 113 } 114 return nil 115 }