Remove the testing/apitests code from this repo (#14518)

Moved to the vmware/harbor-boshrelease repo already

Signed-off-by: stonezdj <stonezdj@gmail.com>
This commit is contained in:
stonezdj(Daojun Zhang) 2021-03-30 19:07:36 +08:00 committed by GitHub
parent ee9be8d742
commit 70165be3f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 0 additions and 1486 deletions

View File

@ -1,97 +0,0 @@
package client
import "os/exec"
import "strings"
import "errors"
import "bufio"
import "fmt"
// DockerClient : Run docker commands
type DockerClient struct{}
// Status : Check if docker daemon is there
func (dc *DockerClient) Status() error {
cmdName := "docker"
args := []string{"info"}
return dc.runCommand(cmdName, args)
}
// Pull : Pull image
func (dc *DockerClient) Pull(image string) error {
if len(strings.TrimSpace(image)) == 0 {
return errors.New("Empty image")
}
cmdName := "docker"
args := []string{"pull", image}
return dc.runCommandWithOutput(cmdName, args)
}
// Tag :Tag image
func (dc *DockerClient) Tag(source, target string) error {
if len(strings.TrimSpace(source)) == 0 ||
len(strings.TrimSpace(target)) == 0 {
return errors.New("Empty images")
}
cmdName := "docker"
args := []string{"tag", source, target}
return dc.runCommandWithOutput(cmdName, args)
}
// Push : push image
func (dc *DockerClient) Push(image string) error {
if len(strings.TrimSpace(image)) == 0 {
return errors.New("Empty image")
}
cmdName := "docker"
args := []string{"push", image}
return dc.runCommandWithOutput(cmdName, args)
}
// Login : Login docker
func (dc *DockerClient) Login(userName, password string, uri string) error {
if len(strings.TrimSpace(userName)) == 0 ||
len(strings.TrimSpace(password)) == 0 {
return errors.New("Invlaid credential")
}
cmdName := "docker"
args := []string{"login", "-u", userName, "-p", password, uri}
return dc.runCommandWithOutput(cmdName, args)
}
func (dc *DockerClient) runCommand(cmdName string, args []string) error {
return exec.Command(cmdName, args...).Run()
}
func (dc *DockerClient) runCommandWithOutput(cmdName string, args []string) error {
cmd := exec.Command(cmdName, args...)
cmdReader, err := cmd.StdoutPipe()
if err != nil {
return err
}
scanner := bufio.NewScanner(cmdReader)
go func() {
for scanner.Scan() {
fmt.Printf("%s out | %s\n", cmdName, scanner.Text())
}
}()
if err = cmd.Start(); err != nil {
return err
}
if err = cmd.Wait(); err != nil {
return err
}
return nil
}

View File

@ -1,210 +0,0 @@
package client
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
const (
httpHeaderJSON = "application/json"
httpHeaderContentType = "Content-Type"
httpHeaderAccept = "Accept"
)
// APIClientConfig : Keep config options for APIClient
type APIClientConfig struct {
Username string
Password string
CaFile string
CertFile string
KeyFile string
Proxy string
}
// APIClient provided the http client for trigger http requests
type APIClient struct {
// http client
client *http.Client
// Configuration
config APIClientConfig
}
// NewAPIClient is constructor of APIClient
func NewAPIClient(config APIClientConfig) (*APIClient, error) {
// Load client cert
cert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
if err != nil {
return nil, err
}
// Add ca
caCert, err := ioutil.ReadFile(config.CaFile)
if err != nil {
return nil, err
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
tlsConfig.BuildNameToCertificate()
transport := &http.Transport{
TLSClientConfig: tlsConfig,
}
// If proxy should be set
if len(strings.TrimSpace(config.Proxy)) > 0 {
if proxyURL, err := url.Parse(config.Proxy); err == nil {
transport.Proxy = http.ProxyURL(proxyURL)
}
}
client := &http.Client{
Transport: transport,
}
return &APIClient{
client: client,
config: config,
}, nil
}
// Get data
func (ac *APIClient) Get(url string) ([]byte, error) {
if strings.TrimSpace(url) == "" {
return nil, errors.New("empty url")
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Set(httpHeaderAccept, httpHeaderJSON)
req.SetBasicAuth(ac.config.Username, ac.config.Password)
resp, err := ac.client.Do(req)
if err != nil {
return nil, err
}
defer func() {
if resp.Body != nil {
resp.Body.Close()
}
}()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return data, nil
}
// Post data
func (ac *APIClient) Post(url string, data []byte) error {
if strings.TrimSpace(url) == "" {
return errors.New("Empty url")
}
req, err := http.NewRequest("POST", url, strings.NewReader(string(data)))
if err != nil {
return err
}
req.Header.Set(httpHeaderContentType, httpHeaderJSON)
req.SetBasicAuth(ac.config.Username, ac.config.Password)
resp, err := ac.client.Do(req)
if err != nil {
return err
}
if resp.StatusCode != http.StatusCreated &&
resp.StatusCode != http.StatusOK {
if err := getErrorMessage(resp); err != nil {
return fmt.Errorf("%s:%s", resp.Status, err.Error())
}
return errors.New(resp.Status)
}
return nil
}
// Delete data
func (ac *APIClient) Delete(url string) error {
if strings.TrimSpace(url) == "" {
return errors.New("Empty url")
}
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return err
}
req.Header.Set(httpHeaderAccept, httpHeaderJSON)
req.SetBasicAuth(ac.config.Username, ac.config.Password)
resp, err := ac.client.Do(req)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
if err := getErrorMessage(resp); err != nil {
return fmt.Errorf("%s:%s", resp.Status, err.Error())
}
return errors.New(resp.Status)
}
return nil
}
// SwitchAccount : Switch account
func (ac *APIClient) SwitchAccount(username, password string) {
if len(strings.TrimSpace(username)) == 0 ||
len(strings.TrimSpace(password)) == 0 {
return
}
ac.config.Username = username
ac.config.Password = password
}
// Read error message from response body
func getErrorMessage(resp *http.Response) error {
if resp == nil {
return errors.New("nil response")
}
if resp.Body == nil || resp.ContentLength == 0 {
// nothing to read
return nil
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
// abandon to read deatiled error message
return nil
}
return fmt.Errorf("%s", data)
}

View File

@ -1,17 +0,0 @@
package envs
// ConcourseCIEnv : Env for concourse pipeline
var ConcourseCIEnv = Environment{
Protocol: "https",
TestingProject: "concoursecitesting01",
ImageName: "busybox",
ImageTag: "latest",
CAFile: "../../../ca.crt",
KeyFile: "../../../key.crt",
CertFile: "../../../cert.crt",
Account: "cody",
Password: "Admin!23",
Admin: "admin",
AdminPass: "pksxgxmifc0cnwa5px9h",
Hostname: "10.112.122.1",
}

View File

@ -1,17 +0,0 @@
package envs
// ConcourseCILdapEnv : Ldap env for concourse pipeline
var ConcourseCILdapEnv = Environment{
Protocol: "https",
TestingProject: "concoursecitesting01",
ImageName: "busybox",
ImageTag: "latest",
CAFile: "../../../ca.crt",
KeyFile: "../../../key.crt",
CertFile: "../../../cert.crt",
Account: "mike",
Password: "zhu88jie",
Admin: "admin",
AdminPass: "pksxgxmifc0cnwa5px9h",
Hostname: "30.0.0.3",
}

View File

@ -1,141 +0,0 @@
package envs
import (
"fmt"
"os"
"strings"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/client"
)
// Environment keeps the testing env info
type Environment struct {
Protocol string // env var: HTTP_PROTOCOL
Hostname string // env var: TESTING_ENV_HOSTNAME
Account string // env var: TESTING_ENV_ACCOUNT
Password string // env var: TESTING_ENV_PASSWORD
Admin string // env var: TESTING_ENV_ADMIN
AdminPass string // env var: TESTING_ENV_ADMIN_PASS
TestingProject string // env var: TESTING_PROJECT_NAME
ImageName string // env var: TESTING_IMAGE_NAME
ImageTag string // env var: TESTING_IMAGE_TAG
CAFile string // env var: CA_FILE_PATH
CertFile string // env var: CERT_FILE_PATH
KeyFile string // env var: KEY_FILE_PATH
ProxyURL string // env var: http_proxy, https_proxy, HTTP_PROXY, HTTPS_PROXY
// API client
HTTPClient *client.APIClient
// Docker client
DockerClient *client.DockerClient
// Initialize status
loaded bool
}
// Load test env info
func (env *Environment) Load() error {
host := os.Getenv("TESTING_ENV_HOSTNAME")
if isNotEmpty(host) {
env.Hostname = host
}
account := os.Getenv("TESTING_ENV_ACCOUNT")
if isNotEmpty(account) {
env.Account = account
}
pwd := os.Getenv("TESTING_ENV_PASSWORD")
if isNotEmpty(pwd) {
env.Password = pwd
}
admin := os.Getenv("TESTING_ENV_ADMIN")
if isNotEmpty(admin) {
env.Admin = admin
}
adminPwd := os.Getenv("TESTING_ENV_ADMIN_PASS")
if isNotEmpty(adminPwd) {
env.AdminPass = adminPwd
}
pro := os.Getenv("TESTING_PROJECT_NAME")
if isNotEmpty(pro) {
env.TestingProject = pro
}
imgName := os.Getenv("TESTING_IMAGE_NAME")
if isNotEmpty(imgName) {
env.ImageName = imgName
}
imgTag := os.Getenv("TESTING_IMAGE_TAG")
if isNotEmpty(imgTag) {
env.ImageTag = imgTag
}
protocol := os.Getenv("HTTP_PROTOCOL")
if isNotEmpty(protocol) {
env.Protocol = protocol
}
caFile := os.Getenv("CA_FILE_PATH")
if isNotEmpty(caFile) {
env.CAFile = caFile
}
keyFile := os.Getenv("KEY_FILE_PATH")
if isNotEmpty(keyFile) {
env.KeyFile = keyFile
}
certFile := os.Getenv("CERT_FILE_PATH")
if isNotEmpty(certFile) {
env.CertFile = certFile
}
proxyEnvVar := "https_proxy"
if env.Protocol == "http" {
proxyEnvVar = "http_proxy"
}
proxyURL := os.Getenv(proxyEnvVar)
if !isNotEmpty(proxyURL) {
proxyURL = os.Getenv(strings.ToUpper(proxyEnvVar))
}
if isNotEmpty(proxyURL) {
env.ProxyURL = proxyURL
}
if !env.loaded {
cfg := client.APIClientConfig{
Username: env.Admin,
Password: env.AdminPass,
CaFile: env.CAFile,
CertFile: env.CertFile,
KeyFile: env.KeyFile,
Proxy: env.ProxyURL,
}
httpClient, err := client.NewAPIClient(cfg)
if err != nil {
return err
}
env.HTTPClient = httpClient
env.DockerClient = &client.DockerClient{}
env.loaded = true
}
return nil
}
// RootURI : The root URI like https://<hostname>
func (env *Environment) RootURI() string {
return fmt.Sprintf("%s://%s", env.Protocol, env.Hostname)
}
func isNotEmpty(str string) bool {
return len(strings.TrimSpace(str)) > 0
}

View File

@ -1,137 +0,0 @@
package lib
import (
"encoding/json"
"errors"
"fmt"
"strings"
"time"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/client"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/models"
)
// ImageUtil : For repository and tag functions
type ImageUtil struct {
rootURI string
testingClient *client.APIClient
}
// NewImageUtil : Constructor
func NewImageUtil(rootURI string, httpClient *client.APIClient) *ImageUtil {
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
return nil
}
return &ImageUtil{
rootURI: rootURI,
testingClient: httpClient,
}
}
// DeleteRepo : Delete repo
func (iu *ImageUtil) DeleteRepo(repoName string) error {
if len(strings.TrimSpace(repoName)) == 0 {
return errors.New("Empty repo name for deleting")
}
url := fmt.Sprintf("%s%s%s", iu.rootURI, "/api/repositories/", repoName)
if err := iu.testingClient.Delete(url); err != nil {
return err
}
return nil
}
// ScanTag :Scan a tag
func (iu *ImageUtil) ScanTag(repoName string, tagName string) error {
if len(strings.TrimSpace(repoName)) == 0 {
return errors.New("Empty repo name for scanning")
}
if len(strings.TrimSpace(tagName)) == 0 {
return errors.New("Empty tag name for scanning")
}
url := fmt.Sprintf("%s%s%s%s%s%s", iu.rootURI, "/api/repositories/", repoName, "/tags/", tagName, "/scan")
if err := iu.testingClient.Post(url, nil); err != nil {
return err
}
tk := time.NewTicker(1 * time.Second)
defer tk.Stop()
done := make(chan bool)
errchan := make(chan error)
url = fmt.Sprintf("%s%s%s%s%s", iu.rootURI, "/api/repositories/", repoName, "/tags/", tagName)
go func() {
for range tk.C {
data, err := iu.testingClient.Get(url)
if err != nil {
errchan <- err
return
}
var tag models.Tag
if err = json.Unmarshal(data, &tag); err != nil {
errchan <- err
return
}
if tag.ScanOverview != nil && tag.ScanOverview.Status == "finished" {
done <- true
}
}
}()
select {
case <-done:
return nil
case <-time.After(20 * time.Second):
return errors.New("Scan timeout after 30 seconds")
}
}
// GetRepos : Get repos in the project
func (iu *ImageUtil) GetRepos(projectName string) ([]models.Repository, error) {
if len(strings.TrimSpace(projectName)) == 0 {
return nil, errors.New("Empty project name for getting repos")
}
proUtil := NewProjectUtil(iu.rootURI, iu.testingClient)
pid := proUtil.GetProjectID(projectName)
if pid == -1 {
return nil, fmt.Errorf("Failed to get project ID with name %s", projectName)
}
url := fmt.Sprintf("%s%s%d", iu.rootURI, "/api/repositories?project_id=", pid)
data, err := iu.testingClient.Get(url)
if err != nil {
return nil, err
}
var repos []models.Repository
if err = json.Unmarshal(data, &repos); err != nil {
return nil, err
}
return repos, nil
}
// GetTags : Get tags
func (iu *ImageUtil) GetTags(repoName string) ([]models.Tag, error) {
if len(strings.TrimSpace(repoName)) == 0 {
return nil, errors.New("Empty repository name for getting tags")
}
url := fmt.Sprintf("%s%s%s%s", iu.rootURI, "/api/repositories/", repoName, "/tags")
tagData, err := iu.testingClient.Get(url)
if err != nil {
return nil, err
}
var tags []models.Tag
if err = json.Unmarshal(tagData, &tags); err != nil {
return nil, err
}
return tags, nil
}

View File

@ -1,193 +0,0 @@
package lib
import (
"encoding/json"
"errors"
"fmt"
"strings"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/client"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/models"
)
// ProjectUtil : Util methods for project related
type ProjectUtil struct {
rootURI string
testingClient *client.APIClient
}
// NewProjectUtil : Constructor
func NewProjectUtil(rootURI string, httpClient *client.APIClient) *ProjectUtil {
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
return nil
}
return &ProjectUtil{
rootURI: rootURI,
testingClient: httpClient,
}
}
// GetProjects : Get projects
// If name specified, then only get the specified project
func (pu *ProjectUtil) GetProjects(name string) ([]models.ExistingProject, error) {
url := pu.rootURI + "/api/projects"
if len(strings.TrimSpace(name)) > 0 {
url = url + "?name=" + name
}
data, err := pu.testingClient.Get(url)
if err != nil {
return nil, err
}
var pros []models.ExistingProject
if err = json.Unmarshal(data, &pros); err != nil {
return nil, err
}
return pros, nil
}
// GetProjectID : Get the project ID
// If no project existing with the name, then return -1
func (pu *ProjectUtil) GetProjectID(projectName string) int {
pros, err := pu.GetProjects(projectName)
if err != nil {
return -1
}
if len(pros) == 0 {
return -1
}
for _, pro := range pros {
if pro.Name == projectName {
return pro.ID
}
}
return -1
}
// CreateProject :Create project
func (pu *ProjectUtil) CreateProject(projectName string, accessLevel bool) error {
if len(strings.TrimSpace(projectName)) == 0 {
return errors.New("Empty project name for creating")
}
p := models.Project{
Name: projectName,
Metadata: &models.Metadata{
AccessLevel: fmt.Sprintf("%v", accessLevel),
},
}
body, err := json.Marshal(&p)
if err != nil {
return err
}
url := pu.rootURI + "/api/projects"
return pu.testingClient.Post(url, body)
}
// DeleteProject : Delete project
func (pu *ProjectUtil) DeleteProject(projectName string) error {
if len(strings.TrimSpace(projectName)) == 0 {
return errors.New("Empty project name for deleting")
}
pid := pu.GetProjectID(projectName)
if pid == -1 {
return errors.New("Failed to get project ID")
}
url := fmt.Sprintf("%s%s%d", pu.rootURI, "/api/projects/", pid)
return pu.testingClient.Delete(url)
}
// AssignRole : Assign role to user
func (pu *ProjectUtil) AssignRole(projectName, username string) error {
if len(strings.TrimSpace(projectName)) == 0 ||
len(strings.TrimSpace(username)) == 0 {
return errors.New("Project name and username are required for assigning role")
}
pid := pu.GetProjectID(projectName)
if pid == -1 {
return fmt.Errorf("Failed to get project ID with name %s", projectName)
}
m := models.Member{
RoleID: 2,
Member: &models.MemberUser{
Username: username,
},
}
body, err := json.Marshal(&m)
if err != nil {
return err
}
url := fmt.Sprintf("%s%s%d%s", pu.rootURI, "/api/projects/", pid, "/members")
return pu.testingClient.Post(url, body)
}
// RevokeRole : RevokeRole role from user
func (pu *ProjectUtil) RevokeRole(projectName string, username string) error {
if len(strings.TrimSpace(projectName)) == 0 {
return errors.New("Project name is required for revoking role")
}
if len(strings.TrimSpace(username)) == 0 {
return errors.New("User ID is required for revoking role")
}
pid := pu.GetProjectID(projectName)
if pid == -1 {
return fmt.Errorf("Failed to get project ID with name %s", projectName)
}
m, err := pu.GetProjectMember(pid, username)
if err != nil {
return err
}
url := fmt.Sprintf("%s%s%d%s%d", pu.rootURI, "/api/projects/", pid, "/members/", m.MID)
return pu.testingClient.Delete(url)
}
// GetProjectMember : Get the project member by name
func (pu *ProjectUtil) GetProjectMember(pid int, member string) (*models.ExistingMember, error) {
if pid == 0 {
return nil, errors.New("invalid project ID")
}
if len(strings.TrimSpace(member)) == 0 {
return nil, errors.New("empty member name")
}
url := fmt.Sprintf("%s/api/projects/%d/members", pu.rootURI, pid)
data, err := pu.testingClient.Get(url)
if err != nil {
return nil, err
}
members := []*models.ExistingMember{}
if err := json.Unmarshal(data, &members); err != nil {
return nil, err
}
for _, m := range members {
if m.Name == member {
return m, nil
}
}
return nil, fmt.Errorf("no member found by the name '%s'", member)
}

View File

@ -1,47 +0,0 @@
package lib
import (
"fmt"
)
type Report struct {
passed []string
failed []string
}
// Passed case
func (r *Report) Passed(caseName string) {
r.passed = append(r.passed, fmt.Sprintf("%s: [%s]", caseName, "PASSED"))
}
// Failed case
func (r *Report) Failed(caseName string, err error) {
errMsg := ""
if err != nil {
errMsg = err.Error()
}
r.failed = append(r.failed, fmt.Sprintf("%s: [%s] %s", caseName, "FAILED", errMsg))
}
// Print report
func (r *Report) Print() {
passed := len(r.passed)
failed := len(r.failed)
total := passed + failed
fmt.Println("=====================================")
fmt.Printf("Overall: %d/%d passed , %d/%d failed\n", passed, total, failed, total)
fmt.Println("=====================================")
for _, res := range r.passed {
fmt.Println(res)
}
for _, res := range r.failed {
fmt.Println(res)
}
}
// IsFail : Overall result
func (r *Report) IsFail() bool {
return len(r.failed) > 0
}

View File

@ -1,50 +0,0 @@
package lib
import (
"encoding/json"
"fmt"
"strings"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/client"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/models"
)
// SystemUtil : For getting system info
type SystemUtil struct {
rootURI string
hostname string
testingClient *client.APIClient
}
// NewSystemUtil : Constructor
func NewSystemUtil(rootURI, hostname string, httpClient *client.APIClient) *SystemUtil {
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
return nil
}
return &SystemUtil{
rootURI: rootURI,
hostname: hostname,
testingClient: httpClient,
}
}
// GetSystemInfo : Get systeminfo
func (nsu *SystemUtil) GetSystemInfo() error {
url := nsu.rootURI + "/api/systeminfo"
data, err := nsu.testingClient.Get(url)
if err != nil {
return err
}
var info models.SystemInfo
if err := json.Unmarshal(data, &info); err != nil {
return err
}
if info.RegistryURL != nsu.hostname {
return fmt.Errorf("Invalid registry url in system info: expect %s got %s ", nsu.hostname, info.RegistryURL)
}
return nil
}

View File

@ -1,118 +0,0 @@
package lib
import (
"encoding/json"
"errors"
"fmt"
"strings"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/client"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/models"
)
// UserUtil : For user related
type UserUtil struct {
rootURI string
testingClient *client.APIClient
}
// NewUserUtil : Constructor
func NewUserUtil(rootURI string, httpClient *client.APIClient) *UserUtil {
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
return nil
}
return &UserUtil{
rootURI: rootURI,
testingClient: httpClient,
}
}
// CreateUser : Create user
func (uu *UserUtil) CreateUser(username, password string) error {
if len(strings.TrimSpace(username)) == 0 ||
len(strings.TrimSpace(password)) == 0 {
return errors.New("Username and password required for creating user")
}
u := models.User{
Username: username,
Password: password,
Email: username + "@vmware.com",
RealName: username + "pks",
Comment: "testing",
}
body, err := json.Marshal(&u)
if err != nil {
return err
}
url := fmt.Sprintf("%s%s", uu.rootURI, "/api/users")
if err := uu.testingClient.Post(url, body); err != nil {
return err
}
return nil
}
// DeleteUser : Delete testing account
func (uu *UserUtil) DeleteUser(username string) error {
uid := uu.GetUserID(username)
if uid == -1 {
return fmt.Errorf("Failed to get user with name %s", username)
}
url := fmt.Sprintf("%s%s%d", uu.rootURI, "/api/users/", uid)
if err := uu.testingClient.Delete(url); err != nil {
return err
}
return nil
}
// GetUsers : Get users
// If name specified, then return that one
func (uu *UserUtil) GetUsers(name string) ([]models.ExistingUser, error) {
url := fmt.Sprintf("%s%s", uu.rootURI, "/api/users")
if len(strings.TrimSpace(name)) > 0 {
url = url + "?username=" + name
}
data, err := uu.testingClient.Get(url)
if err != nil {
return nil, err
}
var users []models.ExistingUser
if err = json.Unmarshal(data, &users); err != nil {
return nil, err
}
return users, nil
}
// GetUserID : Get user ID
// If user with the username is not existing, then return -1
func (uu *UserUtil) GetUserID(username string) int {
if len(strings.TrimSpace(username)) == 0 {
return -1
}
users, err := uu.GetUsers(username)
if err != nil {
return -1
}
if len(users) == 0 {
return -1
}
for _, u := range users {
if u.Username == username {
return u.ID
}
}
return -1
}

View File

@ -1,10 +0,0 @@
package models
// Endpoint : For /api/targets
type Endpoint struct {
Endpoint string `json:"endpoint"`
Name string `json:"name"`
Username string `json:"username"`
Password string `json:"password"`
Type int `json:"type"`
}

View File

@ -1,20 +0,0 @@
package models
// Repository : For /api/repositories
type Repository struct {
ID int `json:"id"`
Name string `json:"name"`
}
// Tag : For /api/repositories/:repo/tags
type Tag struct {
Digest string `json:"digest"`
Name string `json:"name"`
Signature map[string]interface{} `json:"signature, omitempty"`
ScanOverview *ScanOverview `json:"scan_overview, omitempty"`
}
// ScanOverview : For scanning
type ScanOverview struct {
Status string `json:"scan_status"`
}

View File

@ -1,19 +0,0 @@
package models
// Member : For /api/projects/:pid/members
type Member struct {
RoleID int `json:"role_id"`
Member *MemberUser `json:"member_user"`
}
// MemberUser ...
type MemberUser struct {
Username string `json:"username"`
}
// ExistingMember : For GET /api/projects/20/members
type ExistingMember struct {
MID int `json:"id"`
Name string `json:"entity_name"`
RoleID int `json:"role_id"`
}

View File

@ -1,18 +0,0 @@
package models
// Project : For /api/projects
type Project struct {
Name string `json:"project_name"`
Metadata *Metadata `json:"metadata,omitempty"`
}
// Metadata : Metadata for project
type Metadata struct {
AccessLevel string `json:"public"`
}
// ExistingProject : For /api/projects?name=***
type ExistingProject struct {
Name string `json:"name"`
ID int `json:"project_id"`
}

View File

@ -1,9 +0,0 @@
package models
// ReplicationPolicy : For /api/replications
type ReplicationPolicy struct {
ProjectID int `json:"project_id"`
}
type ExistingReplicationPolicy struct {
}

View File

@ -1,7 +0,0 @@
package models
// SystemInfo : For GET /api/systeminfo
type SystemInfo struct {
AuthMode string `json:"auth_mode"`
RegistryURL string `json:"registry_url"`
}

View File

@ -1,16 +0,0 @@
package models
// User : For /api/users
type User struct {
Username string `json:"username"`
RealName string `json:"realname"`
Password string `json:"password"`
Email string `json:"email"`
Comment string `json:"comment"`
}
// ExistingUser : For GET /api/users
type ExistingUser struct {
User
ID int `json:"user_id"`
}

View File

@ -1,74 +0,0 @@
package base
import (
"fmt"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/envs"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/lib"
)
// ConcourseCiSuite : Provides some base cases
type ConcourseCiSuite struct{}
// Run cases
// Not implemented
func (ccs *ConcourseCiSuite) Run(onEnvironment *envs.Environment) *lib.Report {
return &lib.Report{}
}
// PushImage : Push image to the registry
func (ccs *ConcourseCiSuite) PushImage(onEnvironment *envs.Environment) error {
docker := onEnvironment.DockerClient
if err := docker.Status(); err != nil {
return err
}
imagePulling := fmt.Sprintf("%s:%s", onEnvironment.ImageName, onEnvironment.ImageTag)
if err := docker.Pull(imagePulling); err != nil {
return err
}
if err := docker.Login(onEnvironment.Account, onEnvironment.Password, onEnvironment.Hostname); err != nil {
return err
}
imagePushing := fmt.Sprintf("%s/%s/%s:%s",
onEnvironment.Hostname,
onEnvironment.TestingProject,
onEnvironment.ImageName,
onEnvironment.ImageTag)
if err := docker.Tag(imagePulling, imagePushing); err != nil {
return err
}
if err := docker.Push(imagePushing); err != nil {
return err
}
return nil
}
// PullImage : Pull image from registry
func (ccs *ConcourseCiSuite) PullImage(onEnvironment *envs.Environment) error {
docker := onEnvironment.DockerClient
if err := docker.Status(); err != nil {
return err
}
if err := docker.Login(onEnvironment.Account, onEnvironment.Password, onEnvironment.Hostname); err != nil {
return err
}
imagePulling := fmt.Sprintf("%s/%s/%s:%s",
onEnvironment.Hostname,
onEnvironment.TestingProject,
onEnvironment.ImageName,
onEnvironment.ImageTag)
if err := docker.Pull(imagePulling); err != nil {
return err
}
return nil
}

View File

@ -1,11 +0,0 @@
package suites
import (
"github.com/goharbor/harbor/src/testing/apitests/api-testing/envs"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/lib"
)
// Suite : Run a group of test cases
type Suite interface {
Run(onEnvironment envs.Environment) *lib.Report
}

View File

@ -1,22 +0,0 @@
package suite01
import (
"testing"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/envs"
)
// TestRun : Start to run the case
func TestRun(t *testing.T) {
// Initialize env
if err := envs.ConcourseCIEnv.Load(); err != nil {
t.Fatal(err.Error())
}
suite := ConcourseCiSuite01{}
report := suite.Run(&envs.ConcourseCIEnv)
report.Print()
if report.IsFail() {
t.Fail()
}
}

View File

@ -1,124 +0,0 @@
package suite01
import (
"fmt"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/envs"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/lib"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/tests/suites/base"
)
// Steps of suite01:
// s0: Get systeminfo
// s1: create project
// s2: create user "cody"
// s3: assign cody as developer
// s4: push a busybox image to project
// s5: scan image
// s6: pull image from project
// s7: remove "cody" from project member list
// s8: pull image from project [FAIL]
// s9: remove repository busybox
// s10: delete project
// s11: delete user
// ConcourseCiSuite01 : For harbor journey in concourse pipeline
type ConcourseCiSuite01 struct {
base.ConcourseCiSuite
}
// Run : Run a group of cases
func (ccs *ConcourseCiSuite01) Run(onEnvironment *envs.Environment) *lib.Report {
report := &lib.Report{}
// s0
sys := lib.NewSystemUtil(onEnvironment.RootURI(), onEnvironment.Hostname, onEnvironment.HTTPClient)
if err := sys.GetSystemInfo(); err != nil {
report.Failed("GetSystemInfo", err)
} else {
report.Passed("GetSystemInfo")
}
// s1
pro := lib.NewProjectUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
if err := pro.CreateProject(onEnvironment.TestingProject, false); err != nil {
report.Failed("CreateProject", err)
} else {
report.Passed("CreateProject")
}
// s2
usr := lib.NewUserUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
if err := usr.CreateUser(onEnvironment.Account, onEnvironment.Password); err != nil {
report.Failed("CreateUser", err)
} else {
report.Passed("CreateUser")
}
// s3
if err := pro.AssignRole(onEnvironment.TestingProject, onEnvironment.Account); err != nil {
report.Failed("AssignRole", err)
} else {
report.Passed("AssignRole")
}
// s4
if err := ccs.PushImage(onEnvironment); err != nil {
report.Failed("pushImage", err)
} else {
report.Passed("pushImage")
}
// s5
img := lib.NewImageUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
repoName := fmt.Sprintf("%s/%s", onEnvironment.TestingProject, onEnvironment.ImageName)
if err := img.ScanTag(repoName, onEnvironment.ImageTag); err != nil {
report.Failed("ScanTag", err)
} else {
report.Passed("ScanTag")
}
// s6
if err := ccs.PullImage(onEnvironment); err != nil {
report.Failed("pullImage[1]", err)
} else {
report.Passed("pullImage[1]")
}
// s7
if err := pro.RevokeRole(onEnvironment.TestingProject, onEnvironment.Account); err != nil {
report.Failed("RevokeRole", err)
} else {
report.Passed("RevokeRole")
}
// s8
if err := ccs.PullImage(onEnvironment); err == nil {
report.Failed("pullImage[2]", err)
} else {
report.Passed("pullImage[2]")
}
// s9
if err := img.DeleteRepo(repoName); err != nil {
report.Failed("DeleteRepo", err)
} else {
report.Passed("DeleteRepo")
}
// s10
if err := pro.DeleteProject(onEnvironment.TestingProject); err != nil {
report.Failed("DeleteProject", err)
} else {
report.Passed("DeleteProject")
}
// s11
if err := usr.DeleteUser(onEnvironment.Account); err != nil {
report.Failed("DeleteUser", err)
} else {
report.Passed("DeleteUser")
}
return report
}

View File

@ -1,22 +0,0 @@
package suite02
import (
"testing"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/envs"
)
// TestRun : Start to run the case
func TestRun(t *testing.T) {
// Initialize env
if err := envs.ConcourseCILdapEnv.Load(); err != nil {
t.Fatal(err.Error())
}
suite := ConcourseCiSuite02{}
report := suite.Run(&envs.ConcourseCILdapEnv)
report.Print()
if report.IsFail() {
t.Fail()
}
}

View File

@ -1,107 +0,0 @@
package suite02
import (
"fmt"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/envs"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/lib"
"github.com/goharbor/harbor/src/testing/apitests/api-testing/tests/suites/base"
)
// Steps of suite01:
// s0: Get systeminfo
// s1: create project
// s2: assign ldap user "mike" as developer
// s3: push a busybox image to project
// s4: scan image
// s5: pull image from project
// s6: remove "mike" from project member list
// s7: pull image from project [FAIL]
// s8: remove repository busybox
// s9: delete project
// ConcourseCiSuite02 : For harbor ldap journey in concourse pipeline
type ConcourseCiSuite02 struct {
base.ConcourseCiSuite
}
// Run : Run a group of cases
func (ccs *ConcourseCiSuite02) Run(onEnvironment *envs.Environment) *lib.Report {
report := &lib.Report{}
// s0
sys := lib.NewSystemUtil(onEnvironment.RootURI(), onEnvironment.Hostname, onEnvironment.HTTPClient)
if err := sys.GetSystemInfo(); err != nil {
report.Failed("GetSystemInfo", err)
} else {
report.Passed("GetSystemInfo")
}
// s1
pro := lib.NewProjectUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
if err := pro.CreateProject(onEnvironment.TestingProject, false); err != nil {
report.Failed("CreateProject", err)
} else {
report.Passed("CreateProject")
}
// s2
if err := pro.AssignRole(onEnvironment.TestingProject, onEnvironment.Account); err != nil {
report.Failed("AssignRole", err)
} else {
report.Passed("AssignRole")
}
// s3
if err := ccs.PushImage(onEnvironment); err != nil {
report.Failed("pushImage", err)
} else {
report.Passed("pushImage")
}
// s4
img := lib.NewImageUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
repoName := fmt.Sprintf("%s/%s", onEnvironment.TestingProject, onEnvironment.ImageName)
if err := img.ScanTag(repoName, onEnvironment.ImageTag); err != nil {
report.Failed("ScanTag", err)
} else {
report.Passed("ScanTag")
}
// s5
if err := ccs.PullImage(onEnvironment); err != nil {
report.Failed("pullImage[1]", err)
} else {
report.Passed("pullImage[1]")
}
// s6
if err := pro.RevokeRole(onEnvironment.TestingProject, onEnvironment.Account); err != nil {
report.Failed("RevokeRole", err)
} else {
report.Passed("RevokeRole")
}
// s7
if err := ccs.PullImage(onEnvironment); err == nil {
report.Failed("pullImage[2]", err)
} else {
report.Passed("pullImage[2]")
}
// s8
if err := img.DeleteRepo(repoName); err != nil {
report.Failed("DeleteRepo", err)
} else {
report.Passed("DeleteRepo")
}
// s9
if err := pro.DeleteProject(onEnvironment.TestingProject); err != nil {
report.Failed("DeleteProject", err)
} else {
report.Passed("DeleteProject")
}
return report
}