未验证 提交 b8b4cd52 编写于 作者: LinuxSuRen's avatar LinuxSuRen 提交者: GitHub

Remove the unnecessary code lines (#178)

* Remove the unnecessary code lines

* Remove reduant empty line

* Complete the todo task

* Add more test cases

* Adjust the test data
上级 d052bf28
package cmd
import (
"net/http"
"github.com/jenkins-zh/jenkins-cli/client"
"github.com/spf13/cobra"
)
// PluginTreadOption is the option of plugin trend command
type PluginTreadOption struct {
RoundTripper http.RoundTripper
}
var pluginTreadOption PluginTreadOption
func init() {
pluginCmd.AddCommand(pluginTrendCmd)
}
......@@ -21,7 +30,11 @@ var pluginTrendCmd = &cobra.Command{
pluginName := args[0]
jclient := &client.PluginAPI{}
jclient.ShowTrend(pluginName)
jclient := &client.PluginAPI{
RoundTripper: pluginTreadOption.RoundTripper,
}
if tread, err := jclient.ShowTrend(pluginName); err == nil {
cmd.Print(tread)
}
},
}
package cmd
import (
"bytes"
"io/ioutil"
"os"
"github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/jenkins-zh/jenkins-cli/client"
"github.com/jenkins-zh/jenkins-cli/mock/mhttp"
)
var _ = Describe("plugin trend command", func() {
var (
ctrl *gomock.Controller
roundTripper *mhttp.MockRoundTripper
pluginName string
)
BeforeEach(func() {
ctrl = gomock.NewController(GinkgoT())
roundTripper = mhttp.NewMockRoundTripper(ctrl)
pluginTreadOption.RoundTripper = roundTripper
rootCmd.SetArgs([]string{})
rootOptions.Jenkins = ""
rootOptions.ConfigFile = "test.yaml"
pluginName = "fake"
})
AfterEach(func() {
rootCmd.SetArgs([]string{})
os.Remove(rootOptions.ConfigFile)
rootOptions.ConfigFile = ""
ctrl.Finish()
})
Context("basic cases", func() {
It("should success", func() {
data, err := generateSampleConfig()
Expect(err).To(BeNil())
err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664)
Expect(err).To(BeNil())
client.PrepareShowTrend(roundTripper, pluginName)
rootCmd.SetArgs([]string{"plugin", "trend", pluginName})
buf := new(bytes.Buffer)
rootCmd.SetOutput(buf)
_, err = rootCmd.ExecuteC()
Expect(err).To(BeNil())
Expect(buf.String()).NotTo(Equal(""))
})
})
})
......@@ -165,6 +165,26 @@ func (j *JenkinsCore) ErrorHandle(statusCode int, data []byte) (err error) {
return
}
// RequestWithResponse make a common request
func (j *JenkinsCore) RequestWithResponse(method, api string, headers map[string]string, payload io.Reader) (
response *http.Response, err error) {
var (
req *http.Request
)
if req, err = http.NewRequest(method, fmt.Sprintf("%s%s", j.URL, api), payload); err != nil {
return
}
j.AuthHandle(req)
for k, v := range headers {
req.Header.Add(k, v)
}
client := j.GetClient()
return client.Do(req)
}
// Request make a common request
func (j *JenkinsCore) Request(method, api string, headers map[string]string, payload io.Reader) (
statusCode int, data []byte, err error) {
......
......@@ -3,16 +3,19 @@ package client
import (
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"fmt"
"net/http"
"strings"
"github.com/jenkins-zh/jenkins-cli/util"
)
// PluginAPI represetns a plugin API
type PluginAPI struct {
dependencyMap map[string]string
RoundTripper http.RoundTripper
}
// PluginDependency represents a plugin dependency
......@@ -62,42 +65,23 @@ type PluginInstallationInfo struct {
}
// ShowTrend show the trend of plugins
func (d *PluginAPI) ShowTrend(name string) {
if plugin, err := d.getPlugin(name); err == nil {
data := []float64{}
installations := plugin.Stats.Installations
offset, count := 0, 10
if len(installations) > count {
offset = len(installations) - count
}
for _, installation := range installations[offset:] {
data = append(data, float64(installation.Total))
}
min, max := 0.0, 0.0
for _, item := range data {
if item < min {
min = item
} else if item > max {
max = item
}
}
func (d *PluginAPI) ShowTrend(name string) (trend string, err error) {
var plugin *PluginInfo
if plugin, err = d.getPlugin(name); err != nil {
return
}
unit := (max - min) / 100
for _, num := range data {
total := (int)(num / unit)
if total == 0 {
total = 1
}
arr := make([]int, total)
for range arr {
fmt.Print("*")
}
fmt.Println("", num)
}
} else {
log.Fatal(err)
data := []float64{}
installations := plugin.Stats.Installations
offset, count := 0, 10
if len(installations) > count {
offset = len(installations) - count
}
for _, installation := range installations[offset:] {
data = append(data, float64(installation.Total))
}
trend = util.PrintCollectTrend(data)
return
}
// DownloadPlugins will download those plugins from update center
......@@ -135,11 +119,16 @@ func (d *PluginAPI) download(url string, name string) {
func (d *PluginAPI) getPlugin(name string) (plugin *PluginInfo, err error) {
var cli = http.Client{}
cli.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
if d.RoundTripper == nil {
cli.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
} else {
cli.Transport = d.RoundTripper
}
resp, err := cli.Get("https://plugins.jenkins.io/api/plugin/" + name)
if err != nil {
return plugin, err
......
package client
import (
"github.com/golang/mock/gomock"
"github.com/jenkins-zh/jenkins-cli/mock/mhttp"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("plugin api test", func() {
var (
ctrl *gomock.Controller
roundTripper *mhttp.MockRoundTripper
pluginAPI PluginAPI
)
BeforeEach(func() {
ctrl = gomock.NewController(GinkgoT())
roundTripper = mhttp.NewMockRoundTripper(ctrl)
pluginAPI = PluginAPI{
RoundTripper: roundTripper,
}
})
AfterEach(func() {
ctrl.Finish()
})
Context("ShowTrend", func() {
It("basic case", func() {
keyword := "fake"
PrepareShowTrend(roundTripper, keyword)
trend, err := pluginAPI.ShowTrend(keyword)
Expect(err).To(BeNil())
Expect(trend).NotTo(Equal(""))
})
})
})
package client
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"github.com/jenkins-zh/jenkins-cli/mock/mhttp"
)
// PrepareShowTrend only for test
func PrepareShowTrend(roundTripper *mhttp.MockRoundTripper, keyword string) {
request, _ := http.NewRequest("GET", fmt.Sprintf("https://plugins.jenkins.io/api/plugin/%s", keyword), nil)
response := &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`
{"stats": {"installations":[{"total":1512},{"total":3472},{"total":4385},{"total":3981}]}}
`)),
}
roundTripper.EXPECT().
RoundTrip(request).Return(response, nil)
}
\ No newline at end of file
......@@ -140,6 +140,23 @@ var _ = Describe("PluginManager test", func() {
err := pluginMgr.InstallPlugin([]string{pluginName})
Expect(err).To(BeNil())
})
It("with 400", func() {
PrepareForInstallPluginWithCode(roundTripper, 400, pluginMgr.URL, pluginName, "", "")
err := pluginMgr.InstallPlugin([]string{pluginName})
Expect(err).NotTo(BeNil())
})
It("with 400, error message", func() {
response := PrepareForInstallPluginWithCode(roundTripper, 400, pluginMgr.URL, pluginName, "", "")
response.Header = map[string][]string{
"X-Error": []string{"X-Error"},
}
err := pluginMgr.InstallPlugin([]string{pluginName})
Expect(err).To(Equal(fmt.Errorf("X-Error")))
})
})
Context("UninstallPlugin", func() {
......
......@@ -118,18 +118,18 @@ func getPluginsInstallQuery(names []string) string {
// InstallPlugin install a plugin by name
func (p *PluginManager) InstallPlugin(names []string) (err error) {
api := fmt.Sprintf("/pluginManager/install?%s", getPluginsInstallQuery(names))
_, err = p.RequestWithoutData("POST", api, nil, nil, 200)
// TODO needs to consider the following cases
// code == 400 {
// if errMsg, ok := response.Header["X-Error"]; ok {
// for _, msg := range errMsg {
// fmt.Println(msg)
// }
// } else {
// fmt.Println("Cannot found plugins", names)
// }
// }
var response *http.Response
response, err = p.RequestWithResponse("POST", api, nil, nil)
if response.StatusCode == 400 {
if errMsg, ok := response.Header["X-Error"]; ok {
for _, msg := range errMsg {
err = fmt.Errorf(msg)
}
} else {
err = fmt.Errorf("Cannot found plugins %v", names)
}
}
return
}
......
......@@ -21,7 +21,6 @@ func PrepareForEmptyAvaiablePluginList(roundTripper *mhttp.MockRoundTripper, roo
request, _ = http.NewRequest("GET", fmt.Sprintf("%s/pluginManager/plugins", rootURL), nil)
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`{
"status": "ok",
......@@ -89,7 +88,6 @@ func PrepareForEmptyInstalledPluginList(roundTripper *mhttp.MockRoundTripper, ro
request, _ = http.NewRequest("GET", fmt.Sprintf("%s/pluginManager/api/json?depth=1", rootURL), nil)
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`{
"plugins": []
......@@ -179,7 +177,6 @@ func PrepareForUploadPlugin(roundTripper *mhttp.MockRoundTripper, rootURL string
request.Header.Set("Content-Type", writer.FormDataContentType())
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString("")),
}
......@@ -198,7 +195,6 @@ func PrepareForUninstallPlugin(roundTripper *mhttp.MockRoundTripper, rootURL, pl
request.Header.Add("CrumbRequestField", "Crumb")
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString("")),
}
......@@ -225,7 +221,6 @@ func PrepareCancelQueue(roundTripper *mhttp.MockRoundTripper, rootURL, user, pas
response := &http.Response{
StatusCode: 200,
Header: map[string][]string{},
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString("")),
}
......@@ -245,7 +240,6 @@ func PrepareGetQueue(roundTripper *mhttp.MockRoundTripper, rootURL, user, passwd
response := &http.Response{
StatusCode: 200,
Header: map[string][]string{},
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`
{
......@@ -285,7 +279,6 @@ func RequestCrumb(roundTripper *mhttp.MockRoundTripper, rootURL string) (
requestCrumb, _ = http.NewRequest("GET", fmt.Sprintf("%s%s", rootURL, "/crumbIssuer/api/json"), nil)
responseCrumb = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: requestCrumb,
Body: ioutil.NopCloser(bytes.NewBufferString(`
{"crumbRequestField":"CrumbRequestField","crumb":"Crumb"}
......@@ -302,7 +295,6 @@ func PrepareForRequestUpdateCenter(roundTripper *mhttp.MockRoundTripper, rootURL
requestCenter, _ = http.NewRequest("GET", fmt.Sprintf("%s/updateCenter/site/default/api/json?pretty=true&depth=2", rootURL), nil)
responseCenter = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: requestCenter,
Body: ioutil.NopCloser(bytes.NewBufferString(`
{
......@@ -381,7 +373,6 @@ func PrepareForNoAvailablePlugins(roundTripper *mhttp.MockRoundTripper, rootURL
requestCenter, _ = http.NewRequest("GET", fmt.Sprintf("%s/updateCenter/site/default/api/json?pretty=true&depth=2", rootURL), nil)
responseCenter = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: requestCenter,
Body: ioutil.NopCloser(bytes.NewBufferString(`
{
......@@ -412,10 +403,16 @@ func PrepareForRequest500UpdateCenter(roundTripper *mhttp.MockRoundTripper, root
// PrepareForInstallPlugin only for test
func PrepareForInstallPlugin(roundTripper *mhttp.MockRoundTripper, rootURL, pluginName, user, passwd string) {
PrepareForInstallPluginWithCode(roundTripper, 200, rootURL, pluginName, user, passwd)
}
// PrepareForInstallPluginWithCode only for test
func PrepareForInstallPluginWithCode(roundTripper *mhttp.MockRoundTripper,
statusCode int, rootURL, pluginName, user, passwd string) (response *http.Response) {
request, _ := http.NewRequest("POST", fmt.Sprintf("%s/pluginManager/install?plugin.%s=", rootURL, pluginName), nil)
request.Header.Add("CrumbRequestField", "Crumb")
response := &http.Response{
StatusCode: 200,
response = &http.Response{
StatusCode: statusCode,
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString("")),
}
......@@ -438,7 +435,6 @@ func PrepareForPipelineJob(roundTripper *mhttp.MockRoundTripper, rootURL, user,
request, _ = http.NewRequest("GET", fmt.Sprintf("%s/job/test/restFul", rootURL), nil)
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`{"type":null,"displayName":null,"script":"script","sandbox":true}`)),
}
......@@ -510,7 +506,6 @@ func PrepareCommonPost(request *http.Request, roundTripper *mhttp.MockRoundTripp
request.Header.Add("CrumbRequestField", "Crumb")
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString("")),
}
......
package util
import (
"fmt"
)
// MaxAndMin return the max and min number
func MaxAndMin(data []float64) (max, min float64) {
if len(data) > 0 {
max, min = data[0], data[0]
}
for _, item := range data {
if item < min {
min = item
} else if item > max {
max = item
}
}
return
}
// PrintCollectTrend print the trend of data
func PrintCollectTrend(data []float64) (buf string) {
max, min := MaxAndMin(data)
unit := (max - min) / 100
for _, num := range data {
total := (int)(num / unit)
if total == 0 {
total = 1
}
arr := make([]int, total)
for range arr {
buf = fmt.Sprintf("%s*", buf)
}
buf = fmt.Sprintf("%s %.0f\n", buf, num)
}
return
}
package util
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("collect test", func() {
Context("MaxAndMin", func() {
It("normal case, should success", func() {
data := []float64{0.2, 0.3, 0.1, 0.4}
max, min := MaxAndMin(data)
Expect(max).To(Equal(0.4))
Expect(min).To(Equal(0.1))
return
})
It("empty collect, should success", func() {
data := []float64{}
max, min := MaxAndMin(data)
Expect(max).To(Equal(0.0))
Expect(min).To(Equal(0.0))
return
})
It("only one item, should success", func() {
data := []float64{0.3}
max, min := MaxAndMin(data)
Expect(max).To(Equal(0.3))
Expect(min).To(Equal(0.3))
return
})
})
Context("PrintCollectTrend", func() {
It("should success", func() {
data := []float64{1512, 3472, 4385, 3981}
buf := PrintCollectTrend(data)
Expect(buf).NotTo(Equal(""))
return
})
})
})
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册