refactor get tags API to return more info

This commit is contained in:
Wenkai Yin 2017-03-09 17:30:00 +08:00
parent c8802f05ad
commit 3cb53011eb
4 changed files with 130 additions and 34 deletions

View File

@ -682,11 +682,11 @@ paths:
- Products
responses:
200:
description: Searched for respositories successfully.
description: If detail is false, the response body is a string array which contains the names of repositories, or the response body contains an object array as described in schema.
schema:
type: array
items:
type: string
$ref: '#/definitions/Repository'
headers:
X-Total-Count:
description: The total count of repositories
@ -741,15 +741,20 @@ paths:
type: string
required: true
description: Relevant repository name.
- name: detail
in: query
type: boolean
required: false
description: If detail is true, the manifests is returned too.
tags:
- Products
responses:
200:
description: Retrieved tags from a relevant repository successfully.
description: If detail is false, the response body is a string array, or the response body contains the manifest informations as described in schema.
schema:
type: array
items:
type: string
$ref: '#/definitions/DetailedTag'
500:
description: Unexpected internal errors.
/repositories/manifests:
@ -779,7 +784,7 @@ paths:
200:
description: Retrieved manifests from a relevant repository successfully.
schema:
$ref: '#/definitions/Repository'
$ref: '#/definitions/Manifest'
404:
description: Retrieved manifests from a relevant repository not found.
500:
@ -1613,7 +1618,7 @@ definitions:
repo_count:
type: integer
description: The number of the repositories under this project.
Repository:
Manifest:
type: object
properties:
manifest:
@ -2058,3 +2063,45 @@ definitions:
hashes:
type: object
description: The JSON object of the hash of the image.
DetailedTag:
type: object
properties:
tag:
type: string
description: The tag of image.
manifest:
type: object
description: The detail of manifest.
Repository:
type: object
properties:
id:
type: string
description: The ID of repository.
name:
type: string
description: The name of repository.
owner_id:
type: integer
description: The owner ID of repository.
project_id:
type: integer
description: The project ID of repository.
description:
type: string
description: The description of repository.
pull_count:
type: integer
description: The pull count of repository.
star_count:
type: integer
description: The star count of repository.
tags_count:
type: integer
description: The tags count of repository.
creation_time:
type: string
description: The creation time of repository.
update_time:
type: string
description: The update time of repository.

View File

@ -7,6 +7,7 @@ import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"path/filepath"
"runtime"
@ -474,7 +475,8 @@ func (a testapi) GetRepos(authInfo usrInfo, projectID, detail string) (int, erro
}
//Get tags of a relevant repository
func (a testapi) GetReposTags(authInfo usrInfo, repoName string) (int, error) {
func (a testapi) GetReposTags(authInfo usrInfo, repoName,
detail string) (int, interface{}, error) {
_sling := sling.New().Get(a.basePath)
path := "/api/repositories/tags"
@ -483,11 +485,35 @@ func (a testapi) GetReposTags(authInfo usrInfo, repoName string) (int, error) {
type QueryParams struct {
RepoName string `url:"repo_name"`
Detail string `url:"detail"`
}
_sling = _sling.QueryStruct(&QueryParams{RepoName: repoName})
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
_sling = _sling.QueryStruct(&QueryParams{
RepoName: repoName,
Detail: detail,
})
httpStatusCode, body, err := request(_sling, jsonAcceptHeader, authInfo)
if err != nil {
return 0, nil, err
}
if httpStatusCode != http.StatusOK {
return httpStatusCode, body, nil
}
if detail == "true" || detail == "1" {
result := []detailedTagResp{}
if err := json.Unmarshal(body, &result); err != nil {
return 0, nil, err
}
return http.StatusOK, result, nil
}
result := []string{}
if err := json.Unmarshal(body, &result); err != nil {
return 0, nil, err
}
return http.StatusOK, result, nil
}
//Get manifests of a relevant repository

View File

@ -63,6 +63,11 @@ type detailedTagResp struct {
Manifest interface{} `json:"manifest"`
}
type manifestResp struct {
Manifest interface{} `json:"manifest"`
Config interface{} `json:"config,omitempty" `
}
// Get ...
func (ra *RepositoryAPI) Get() {
projectID, err := ra.GetInt64("project_id")
@ -321,7 +326,7 @@ func (ra *RepositoryAPI) GetTags() {
result = append(result, detailedTagResp{
Tag: tag,
Manifest: manifest,
Manifest: manifest.Manifest,
})
}
@ -411,11 +416,8 @@ func (ra *RepositoryAPI) GetManifests() {
}
func getManifest(client *registry.Repository,
tag, version string) (interface{}, error) {
result := struct {
Manifest interface{} `json:"manifest"`
Config interface{} `json:"config,omitempty" `
}{}
tag, version string) (*manifestResp, error) {
result := &manifestResp{}
mediaTypes := []string{}
switch version {

View File

@ -52,43 +52,64 @@ func TestGetRepos(t *testing.T) {
}
func TestGetReposTags(t *testing.T) {
var httpStatusCode int
var err error
var repoName string
assert := assert.New(t)
apiTest := newHarborAPI()
repository := ""
detail := "false"
fmt.Println("Testing ReposTags Get API")
//-------------------case 1 : response code = 400------------------------//
fmt.Println("case 1 : response code = 400,repo_name is nil")
repoName = ""
httpStatusCode, err = apiTest.GetReposTags(*admin, repoName)
code, _, err := apiTest.GetReposTags(*admin, repository, detail)
if err != nil {
t.Error("Error whihle get reposTags by repoName", err.Error())
t.Log(err)
t.Errorf("failed to get tags of repository %s: %v", repository, err)
} else {
assert.Equal(int(400), httpStatusCode, "httpStatusCode should be 400")
assert.Equal(int(400), code, "httpStatusCode should be 400")
}
//-------------------case 2 : response code = 404------------------------//
fmt.Println("case 2 : response code = 404,repo not found")
repoName = "errorRepos"
httpStatusCode, err = apiTest.GetReposTags(*admin, repoName)
repository = "errorRepos"
code, _, err = apiTest.GetReposTags(*admin, repository, detail)
if err != nil {
t.Error("Error whihle get reposTags by repoName", err.Error())
t.Log(err)
t.Errorf("failed to get tags of repository %s: %v", repository, err)
} else {
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
assert.Equal(int(404), code, "httpStatusCode should be 404")
}
//-------------------case 3 : response code = 200------------------------//
fmt.Println("case 3 : response code = 200")
repoName = "library/hello-world"
httpStatusCode, err = apiTest.GetReposTags(*admin, repoName)
repository = "library/hello-world"
code, tags, err := apiTest.GetReposTags(*admin, repository, detail)
if err != nil {
t.Error("Error whihle get reposTags by repoName", err.Error())
t.Log(err)
t.Errorf("failed to get tags of repository %s: %v", repository, err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
assert.Equal(int(200), code, "httpStatusCode should be 200")
if tg, ok := tags.([]string); ok {
assert.Equal(1, len(tg), fmt.Sprintf("there should be only one tag, but now %v", tg))
assert.Equal(tg[0], "latest", "the tag should be latest")
} else {
t.Error("the tags should be in simple style as the detail is false")
}
}
//-------------------case 4 : response code = 200------------------------//
fmt.Println("case 4 : response code = 200")
repository = "library/hello-world"
detail = "true"
code, tags, err = apiTest.GetReposTags(*admin, repository, detail)
if err != nil {
t.Errorf("failed to get tags of repository %s: %v", repository, err)
} else {
assert.Equal(int(200), code, "httpStatusCode should be 200")
if tg, ok := tags.([]detailedTagResp); ok {
assert.Equal(1, len(tg), fmt.Sprintf("there should be only one tag, but now %v", tg))
assert.Equal(tg[0].Tag, "latest", "the tag should be latest")
} else {
t.Error("the tags should be in detail style as the detail is true")
}
}
fmt.Printf("\n")