add list under an interface for easy testing

pull/8423/head
ys.achinta 5 years ago
parent f73d39ecc7
commit 3f1325faf8

@ -13,19 +13,22 @@ import (
) )
func main() { func main() {
app := servercontext.NewApp() servercontext.NewApp()
startServer(app) startServer()
} }
func startServer(appconfig *servercontext.Application) { func startServer() {
router := http.NewServeMux() router := http.NewServeMux()
//TODO: use gorilla mux and add middleware to write content type and other headers //TODO: use gorilla mux and add middleware to write content type and other headers
app := servercontext.App() app := servercontext.App()
logger.Setup("debug") logger.Setup("debug")
actionInstall := action.NewInstall(app.ActionConfig)
service := api.NewService(app.Config, new(action.ChartPathOptions), api.NewInstaller(actionInstall)) service := api.NewService(app.Config,
new(action.ChartPathOptions),
api.NewInstall(action.NewInstall(app.ActionConfig)),
api.NewList(action.NewList(app.ActionConfig)))
router.Handle("/ping", ping.Handler()) router.Handle("/ping", ping.Handler())
router.Handle("/list", list.Handler()) router.Handle("/list", list.Handler())
router.Handle("/install", api.Install(service)) router.Handle("/install", api.Install(service))

@ -0,0 +1,18 @@
package api
import (
"github.com/stretchr/testify/mock"
"helm.sh/helm/v3/pkg/cli"
)
type chartloader interface {
LocateChart(name string, settings *cli.EnvSettings) (string, error)
}
type MockChartLoader struct{ mock.Mock }
func (m *MockChartLoader) LocateChart(name string, settings *cli.EnvSettings) (string, error) {
args := m.Called(name, settings)
return args.String(0), args.Error(1)
}

@ -14,7 +14,6 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"helm.sh/helm/v3/pkg/api" "helm.sh/helm/v3/pkg/api"
"helm.sh/helm/v3/pkg/api/logger" "helm.sh/helm/v3/pkg/api/logger"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/release"
) )
@ -23,8 +22,9 @@ type InstallerTestSuite struct {
suite.Suite suite.Suite
recorder *httptest.ResponseRecorder recorder *httptest.ResponseRecorder
server *httptest.Server server *httptest.Server
mockInstaller *mockInstaller mockInstall *api.MockInstall
mockChartLoader *mockChartLoader mockChartLoader *api.MockChartLoader
mockList *api.MockList
appConfig *cli.EnvSettings appConfig *cli.EnvSettings
} }
@ -34,13 +34,14 @@ func (s *InstallerTestSuite) SetupSuite() {
func (s *InstallerTestSuite) SetupTest() { func (s *InstallerTestSuite) SetupTest() {
s.recorder = httptest.NewRecorder() s.recorder = httptest.NewRecorder()
s.mockInstaller = new(mockInstaller) s.mockInstall = new(api.MockInstall)
s.mockChartLoader = new(mockChartLoader) s.mockChartLoader = new(api.MockChartLoader)
s.mockList = new(api.MockList)
s.appConfig = &cli.EnvSettings{ s.appConfig = &cli.EnvSettings{
RepositoryConfig: "./testdata/helm", RepositoryConfig: "./testdata/helm",
PluginsDirectory: "./testdata/helm/plugin", PluginsDirectory: "./testdata/helm/plugin",
} }
service := api.NewService(s.appConfig, s.mockChartLoader, s.mockInstaller) service := api.NewService(s.appConfig, s.mockChartLoader, s.mockInstall, s.mockList)
handler := api.Install(service) handler := api.Install(service)
s.server = httptest.NewServer(handler) s.server = httptest.NewServer(handler)
} }
@ -54,11 +55,11 @@ func (s *InstallerTestSuite) TestShouldReturnDeployedStatusOnSuccessfulInstall()
req, _ := http.NewRequest("POST", fmt.Sprintf("%s/install", s.server.URL), strings.NewReader(body)) req, _ := http.NewRequest("POST", fmt.Sprintf("%s/install", s.server.URL), strings.NewReader(body))
s.mockChartLoader.On("LocateChart", chartName, s.appConfig).Return("./testdata/albatross", nil) s.mockChartLoader.On("LocateChart", chartName, s.appConfig).Return("./testdata/albatross", nil)
icfg := api.InstallConfig{ChartName: chartName, Name: "redis-v5", Namespace: "something"} icfg := api.InstallConfig{ChartName: chartName, Name: "redis-v5", Namespace: "something"}
s.mockInstaller.On("SetConfig", icfg) s.mockInstall.On("SetConfig", icfg)
release := &release.Release{Info: &release.Info{Status: release.StatusDeployed}} release := &release.Release{Info: &release.Info{Status: release.StatusDeployed}}
var vals map[string]interface{} var vals map[string]interface{}
//TODO: pass chart object and verify values present testdata chart yml //TODO: pass chart object and verify values present testdata chart yml
s.mockInstaller.On("Run", mock.AnythingOfType("*chart.Chart"), vals).Return(release, nil) s.mockInstall.On("Run", mock.AnythingOfType("*chart.Chart"), vals).Return(release, nil)
resp, err := http.DefaultClient.Do(req) resp, err := http.DefaultClient.Do(req)
@ -67,7 +68,7 @@ func (s *InstallerTestSuite) TestShouldReturnDeployedStatusOnSuccessfulInstall()
respBody, _ := ioutil.ReadAll(resp.Body) respBody, _ := ioutil.ReadAll(resp.Body)
assert.Equal(s.T(), expectedResponse, string(respBody)) assert.Equal(s.T(), expectedResponse, string(respBody))
require.NoError(s.T(), err) require.NoError(s.T(), err)
s.mockInstaller.AssertExpectations(s.T()) s.mockInstall.AssertExpectations(s.T())
s.mockChartLoader.AssertExpectations(s.T()) s.mockChartLoader.AssertExpectations(s.T())
} }
@ -78,21 +79,3 @@ func (s *InstallerTestSuite) TearDownTest() {
func TestInstallAPI(t *testing.T) { func TestInstallAPI(t *testing.T) {
suite.Run(t, new(InstallerTestSuite)) suite.Run(t, new(InstallerTestSuite))
} }
type mockInstaller struct{ mock.Mock }
func (m *mockInstaller) SetConfig(cfg api.InstallConfig) {
m.Called(cfg)
}
func (m *mockInstaller) Run(c *chart.Chart, vals map[string]interface{}) (*release.Release, error) {
args := m.Called(c, vals)
return args.Get(0).(*release.Release), args.Error(1)
}
type mockChartLoader struct{ mock.Mock }
func (m *mockChartLoader) LocateChart(name string, settings *cli.EnvSettings) (string, error) {
args := m.Called(name, settings)
return args.String(0), args.Error(1)
}

@ -1,24 +1,37 @@
package api package api
import ( import (
"github.com/stretchr/testify/mock"
"helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/release"
) )
type Installer struct { type install struct {
*action.Install *action.Install
} }
type runner interface { type Installer interface {
Run(*chart.Chart, map[string]interface{}) (*release.Release, error) Run(*chart.Chart, map[string]interface{}) (*release.Release, error)
SetConfig(InstallConfig)
} }
func (i *Installer) SetConfig(cfg InstallConfig) { func (i *install) SetConfig(cfg InstallConfig) {
i.ReleaseName = cfg.Name i.ReleaseName = cfg.Name
i.Namespace = cfg.Namespace i.Namespace = cfg.Namespace
} }
func NewInstaller(ai *action.Install) *Installer { func NewInstall(ai *action.Install) *install {
return &Installer{ai} return &install{ai}
}
type MockInstall struct{ mock.Mock }
func (m *MockInstall) SetConfig(cfg InstallConfig) {
m.Called(cfg)
}
func (m *MockInstall) Run(c *chart.Chart, vals map[string]interface{}) (*release.Release, error) {
args := m.Called(c, vals)
return args.Get(0).(*release.Release), args.Error(1)
} }

@ -0,0 +1,68 @@
package api
import (
"encoding/json"
"helm.sh/helm/v3/pkg/api/logger"
"net/http"
)
type ListRequest struct {
RequestID string
}
type ListResponse struct {
Error string `json:"error,omitempty"`
Data []HelmRelease
}
type HelmRelease struct {
Release string `json:"release"`
Namespace string `json:"namespace"`
}
func Handler(svc Service) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var response ListResponse
var request ListRequest
decoder := json.NewDecoder(r.Body)
decoder.UseNumber()
if err := decoder.Decode(&request); err != nil {
response.Error = err.Error()
logger.Errorf("[List] error decoding request: %v", err)
w.WriteHeader(http.StatusBadRequest)
return
}
defer r.Body.Close()
request.RequestID = r.Header.Get("Request-Id")
svc.lister.SetStateMask()
res, err := svc.lister.Run()
if err != nil {
response.Error = err.Error()
logger.Errorf("[List] error while installing chart: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
var helmReleases []HelmRelease
for _, eachRes := range res {
r := HelmRelease{Release: eachRes.Name, Namespace: eachRes.Namespace}
helmReleases = append(helmReleases, r)
}
response = ListResponse{"", helmReleases}
payload, err := json.Marshal(response)
if err != nil {
response.Error = err.Error()
logger.Errorf("[List] error writing response %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
w.Write(payload)
})
}

@ -0,0 +1,28 @@
package api
import (
"github.com/stretchr/testify/mock"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/release"
)
type list struct {
*action.List
}
type lister interface {
Run() ([]*release.Release, error)
SetStateMask()
}
func NewList(action *action.List) *list{
return &list{action}
}
type MockList struct{ mock.Mock }
func (m *MockList) Run() ([]*release.Release, error) {
args := m.Called()
return args.Get(0).([]*release.Release), args.Error(1)
}

@ -8,22 +8,13 @@ import (
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/release"
_ "k8s.io/client-go/plugin/pkg/client/auth" _ "k8s.io/client-go/plugin/pkg/client/auth"
) )
type installer interface {
SetConfig(InstallConfig)
Run(*chart.Chart, map[string]interface{}) (*release.Release, error)
}
type chartloader interface {
LocateChart(name string, settings *cli.EnvSettings) (string, error)
}
type Service struct { type Service struct {
settings *cli.EnvSettings settings *cli.EnvSettings
installer Installer
lister
chartloader chartloader
} }
@ -73,8 +64,8 @@ func (s Service) loadChart(chartName string) (*chart.Chart, error) {
} }
func (s Service) installChart(icfg InstallConfig, ch *chart.Chart, vals chartValues) (*installResult, error) { func (s Service) installChart(icfg InstallConfig, ch *chart.Chart, vals chartValues) (*installResult, error) {
s.installer.SetConfig(icfg) s.Installer.SetConfig(icfg)
release, err := s.installer.Run(ch, vals) release, err := s.Installer.Run(ch, vals)
if err != nil { if err != nil {
return nil, fmt.Errorf("error in installing chart: %v", err) return nil, fmt.Errorf("error in installing chart: %v", err)
} }
@ -85,10 +76,11 @@ func (s Service) installChart(icfg InstallConfig, ch *chart.Chart, vals chartVal
return result, nil return result, nil
} }
func NewService(settings *cli.EnvSettings, cl chartloader, i installer) Service { func NewService(settings *cli.EnvSettings, cl chartloader, i Installer, l lister) Service {
return Service{ return Service{
settings: settings, settings,
chartloader: cl, i,
installer: i, l,
cl,
} }
} }

Loading…
Cancel
Save