github.com/Redstoneguy129/cli@v0.0.0-20230211220159-15dca4e91917/internal/stop/stop_test.go (about) 1 package stop 2 3 import ( 4 "context" 5 "errors" 6 "net/http" 7 "os" 8 "testing" 9 10 "github.com/docker/docker/api/types" 11 "github.com/spf13/afero" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 "github.com/Redstoneguy129/cli/internal/testing/apitest" 15 "github.com/Redstoneguy129/cli/internal/utils" 16 "gopkg.in/h2non/gock.v1" 17 ) 18 19 func TestStopCommand(t *testing.T) { 20 t.Run("stops containers with backup", func(t *testing.T) { 21 // Setup in-memory fs 22 fsys := afero.NewMemMapFs() 23 require.NoError(t, utils.WriteConfig(fsys, false)) 24 // Setup mock docker 25 require.NoError(t, apitest.MockDocker(utils.Docker)) 26 defer gock.OffAll() 27 gock.New(utils.Docker.DaemonHost()). 28 Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). 29 Reply(http.StatusOK). 30 JSON([]types.Container{}) 31 gock.New(utils.Docker.DaemonHost()). 32 Post("/v" + utils.Docker.ClientVersion() + "/containers/prune"). 33 Reply(http.StatusOK). 34 JSON(types.ContainersPruneReport{}) 35 gock.New(utils.Docker.DaemonHost()). 36 Post("/v" + utils.Docker.ClientVersion() + "/networks/prune"). 37 Reply(http.StatusOK). 38 JSON(types.NetworksPruneReport{}) 39 // Run test 40 err := Run(context.Background(), true, fsys) 41 // Check error 42 assert.NoError(t, err) 43 assert.Empty(t, apitest.ListUnmatchedRequests()) 44 }) 45 46 t.Run("throws error on invalid config", func(t *testing.T) { 47 // Setup in-memory fs 48 fsys := afero.NewMemMapFs() 49 // Run test 50 err := Run(context.Background(), false, fsys) 51 // Check error 52 assert.ErrorIs(t, err, os.ErrNotExist) 53 }) 54 55 t.Run("throws error on stop failure", func(t *testing.T) { 56 // Setup in-memory fs 57 fsys := afero.NewMemMapFs() 58 require.NoError(t, utils.WriteConfig(fsys, false)) 59 // Setup mock docker 60 require.NoError(t, apitest.MockDocker(utils.Docker)) 61 defer gock.OffAll() 62 gock.New(utils.Docker.DaemonHost()). 63 Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). 64 Reply(http.StatusServiceUnavailable) 65 // Run test 66 err := Run(context.Background(), false, afero.NewReadOnlyFs(fsys)) 67 // Check error 68 assert.ErrorContains(t, err, "request returned Service Unavailable for API route and version") 69 assert.Empty(t, apitest.ListUnmatchedRequests()) 70 }) 71 } 72 73 func TestStopServices(t *testing.T) { 74 t.Run("stops all services", func(t *testing.T) { 75 containers := []types.Container{{ID: "c1", State: "running"}, {ID: "c2"}} 76 // Setup mock docker 77 require.NoError(t, apitest.MockDocker(utils.Docker)) 78 defer gock.OffAll() 79 gock.New(utils.Docker.DaemonHost()). 80 Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). 81 Reply(http.StatusOK). 82 JSON(containers) 83 gock.New(utils.Docker.DaemonHost()). 84 Post("/v" + utils.Docker.ClientVersion() + "/containers/" + containers[0].ID + "/stop"). 85 Reply(http.StatusOK) 86 gock.New(utils.Docker.DaemonHost()). 87 Post("/v" + utils.Docker.ClientVersion() + "/containers/prune"). 88 Reply(http.StatusOK). 89 JSON(types.ContainersPruneReport{}) 90 gock.New(utils.Docker.DaemonHost()). 91 Post("/v" + utils.Docker.ClientVersion() + "/networks/prune"). 92 Reply(http.StatusOK). 93 JSON(types.NetworksPruneReport{}) 94 // Run test 95 err := stop(context.Background(), true) 96 // Check error 97 assert.NoError(t, err) 98 assert.Empty(t, apitest.ListUnmatchedRequests()) 99 }) 100 101 t.Run("removes data volumes", func(t *testing.T) { 102 utils.DbId = "test-db" 103 utils.StorageId = "test-storage" 104 // Setup mock docker 105 require.NoError(t, apitest.MockDocker(utils.Docker)) 106 defer gock.OffAll() 107 gock.New(utils.Docker.DaemonHost()). 108 Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). 109 Reply(http.StatusOK). 110 JSON([]types.Container{}) 111 gock.New(utils.Docker.DaemonHost()). 112 Post("/v" + utils.Docker.ClientVersion() + "/containers/prune"). 113 Reply(http.StatusOK). 114 JSON(types.ContainersPruneReport{}) 115 gock.New(utils.Docker.DaemonHost()). 116 Delete("/v" + utils.Docker.ClientVersion() + "/volumes/" + utils.DbId). 117 Reply(http.StatusOK) 118 gock.New(utils.Docker.DaemonHost()). 119 Delete("/v" + utils.Docker.ClientVersion() + "/volumes/" + utils.StorageId). 120 Reply(http.StatusNotFound) 121 gock.New(utils.Docker.DaemonHost()). 122 Post("/v" + utils.Docker.ClientVersion() + "/networks/prune"). 123 Reply(http.StatusOK). 124 JSON(types.NetworksPruneReport{}) 125 // Run test 126 err := stop(context.Background(), false) 127 // Check error 128 assert.NoError(t, err) 129 assert.Empty(t, apitest.ListUnmatchedRequests()) 130 }) 131 132 t.Run("throws error on prune failure", func(t *testing.T) { 133 // Setup mock docker 134 require.NoError(t, apitest.MockDocker(utils.Docker)) 135 defer gock.OffAll() 136 gock.New(utils.Docker.DaemonHost()). 137 Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). 138 Reply(http.StatusOK). 139 JSON([]types.Container{}) 140 gock.New(utils.Docker.DaemonHost()). 141 Post("/v" + utils.Docker.ClientVersion() + "/containers/prune"). 142 ReplyError(errors.New("network error")) 143 // Run test 144 err := stop(context.Background(), true) 145 // Check error 146 assert.ErrorContains(t, err, "network error") 147 assert.Empty(t, apitest.ListUnmatchedRequests()) 148 }) 149 }