github.com/supabase/cli@v1.168.1/internal/testing/apitest/helper.go (about) 1 package apitest 2 3 import ( 4 "bytes" 5 "fmt" 6 "net/http" 7 8 "github.com/docker/docker/api" 9 "github.com/docker/docker/api/types" 10 "github.com/docker/docker/api/types/container" 11 "github.com/docker/docker/api/types/volume" 12 "github.com/docker/docker/client" 13 "github.com/docker/docker/pkg/stdcopy" 14 "gopkg.in/h2non/gock.v1" 15 ) 16 17 const mockHost = "http://127.0.0.1" 18 19 func MockDocker(docker *client.Client) error { 20 // Skip setup if docker is already mocked 21 if docker.DaemonHost() == mockHost { 22 return nil 23 } 24 if err := client.WithVersion(api.DefaultVersion)(docker); err != nil { 25 return err 26 } 27 // Safe to ignore errors as transport will be replaced by gock 28 _ = client.WithHost(mockHost)(docker) 29 return client.WithHTTPClient(http.DefaultClient)(docker) 30 } 31 32 // Ref: internal/utils/docker.go::DockerStart 33 func MockDockerStart(docker *client.Client, image, containerID string) { 34 gock.New(docker.DaemonHost()). 35 Get("/v" + docker.ClientVersion() + "/images/" + image + "/json"). 36 Reply(http.StatusOK). 37 JSON(types.ImageInspect{}) 38 gock.New(docker.DaemonHost()). 39 Post("/v" + docker.ClientVersion() + "/networks/create"). 40 Reply(http.StatusCreated). 41 JSON(types.NetworkCreateResponse{}) 42 gock.New(docker.DaemonHost()). 43 Post("/v" + docker.ClientVersion() + "/volumes/create"). 44 Persist(). 45 Reply(http.StatusCreated). 46 JSON(volume.Volume{}) 47 gock.New(docker.DaemonHost()). 48 Post("/v" + docker.ClientVersion() + "/containers/create"). 49 Reply(http.StatusOK). 50 JSON(container.CreateResponse{ID: containerID}) 51 gock.New(docker.DaemonHost()). 52 Post("/v" + docker.ClientVersion() + "/containers/" + containerID + "/start"). 53 Reply(http.StatusAccepted) 54 } 55 56 // Ref: internal/utils/docker.go::DockerRemoveAll 57 func MockDockerStop(docker *client.Client) { 58 gock.New(docker.DaemonHost()). 59 Get("/v" + docker.ClientVersion() + "/containers/json"). 60 Reply(http.StatusOK). 61 JSON([]types.Container{}) 62 gock.New(docker.DaemonHost()). 63 Post("/v" + docker.ClientVersion() + "/containers/prune"). 64 Reply(http.StatusOK). 65 JSON(types.ContainersPruneReport{}) 66 gock.New(docker.DaemonHost()). 67 Post("/v" + docker.ClientVersion() + "/volumes/prune"). 68 Reply(http.StatusOK). 69 JSON(types.VolumesPruneReport{}) 70 gock.New(docker.DaemonHost()). 71 Post("/v" + docker.ClientVersion() + "/networks/prune"). 72 Reply(http.StatusOK). 73 JSON(types.NetworksPruneReport{}) 74 } 75 76 // Ref: internal/utils/docker.go::DockerRunOnce 77 func setupDockerLogs(docker *client.Client, containerID, stdout string, exitCode int) error { 78 var body bytes.Buffer 79 writer := stdcopy.NewStdWriter(&body, stdcopy.Stdout) 80 _, err := writer.Write([]byte(stdout)) 81 gock.New(docker.DaemonHost()). 82 Get("/v"+docker.ClientVersion()+"/containers/"+containerID+"/logs"). 83 Reply(http.StatusOK). 84 SetHeader("Content-Type", "application/vnd.docker.raw-stream"). 85 Body(&body) 86 gock.New(docker.DaemonHost()). 87 Get("/v" + docker.ClientVersion() + "/containers/" + containerID + "/json"). 88 Reply(http.StatusOK). 89 JSON(types.ContainerJSONBase{State: &types.ContainerState{ 90 ExitCode: exitCode, 91 }}) 92 gock.New(docker.DaemonHost()). 93 Delete("/v" + docker.ClientVersion() + "/containers/" + containerID). 94 Reply(http.StatusOK) 95 return err 96 } 97 98 func MockDockerLogs(docker *client.Client, containerID, stdout string) error { 99 return setupDockerLogs(docker, containerID, stdout, 0) 100 } 101 102 func MockDockerLogsExitCode(docker *client.Client, containerID string, exitCode int) error { 103 return setupDockerLogs(docker, containerID, "", exitCode) 104 } 105 106 func ListUnmatchedRequests() []string { 107 result := make([]string, len(gock.GetUnmatchedRequests())) 108 for i, r := range gock.GetUnmatchedRequests() { 109 result[i] = fmt.Sprintln(r.Method, r.URL.Path) 110 } 111 return result 112 }