Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support to run test suite via http #478

Merged
merged 6 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cmd/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"io"
"path/filepath"
"runtime"
"time"

"github.com/linuxsuren/api-testing/pkg/downloader"
"github.com/spf13/cobra"
Expand All @@ -33,6 +34,7 @@ type extensionOption struct {
tag string
os string
arch string
timeout time.Duration
}

func createExtensionCommand(ociDownloader downloader.PlatformAwareOCIDownloader) (c *cobra.Command) {
Expand All @@ -52,12 +54,16 @@ func createExtensionCommand(ociDownloader downloader.PlatformAwareOCIDownloader)
flags.StringVarP(&opt.registry, "registry", "", "", "The target extension image registry, supported: docker.io, ghcr.io")
flags.StringVarP(&opt.os, "os", "", runtime.GOOS, "The OS")
flags.StringVarP(&opt.arch, "arch", "", runtime.GOARCH, "The architecture")
flags.DurationVarP(&opt.timeout, "timeout", "", time.Minute, "The timeout of downloading")
return
}

func (o *extensionOption) runE(cmd *cobra.Command, args []string) (err error) {
o.ociDownloader.WithOS(o.os)
o.ociDownloader.WithArch(o.arch)
o.ociDownloader.WithRegistry(o.registry)
o.ociDownloader.WithTimeout(o.timeout)
o.ociDownloader.WithContext(cmd.Context())

for _, arg := range args {
var reader io.Reader
Expand Down
7 changes: 4 additions & 3 deletions cmd/extension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ func TestExtensionCmd(t *testing.T) {
server.Stop()
}()

d.WithRegistry(fmt.Sprintf("127.0.0.1:%s", server.GetPort()))
registry := fmt.Sprintf("127.0.0.1:%s", server.GetPort())
d.WithRegistry(registry)
d.WithInsecure(true)
d.WithBasicAuth("", "")
d.WithOS("linux")
Expand All @@ -56,12 +57,12 @@ func TestExtensionCmd(t *testing.T) {
assert.NoError(t, err)

command := createExtensionCommand(d)
command.SetArgs([]string{"git", "--output", tmpDownloadDir})
command.SetArgs([]string{"git", "--output", tmpDownloadDir, "--registry", registry})
err = command.Execute()
assert.NoError(t, err)

// not found
command.SetArgs([]string{"orm", "--output", tmpDownloadDir})
command.SetArgs([]string{"orm", "--output", tmpDownloadDir, "--registry", registry})
err = command.Execute()
assert.Error(t, err)
})
Expand Down
22 changes: 13 additions & 9 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func createServerCmd(execer fakeruntime.Execer, httpServer server.HTTPServer) (c
flags.BoolVarP(&opt.dryRun, "dry-run", "", false, "Do not really start a gRPC server")
flags.StringArrayVarP(&opt.mockConfig, "mock-config", "", nil, "The mock config files")
flags.StringVarP(&opt.mockPrefix, "mock-prefix", "", "/mock", "The mock server API prefix")
flags.StringVarP(&opt.extensionRegistry, "extension-registry", "", "docker.io", "The extension registry URL")

// gc related flags
flags.IntVarP(&opt.gcPercent, "gc-percent", "", 100, "The GC percent of Go")
Expand All @@ -114,14 +115,15 @@ type serverOption struct {
httpServer server.HTTPServer
execer fakeruntime.Execer

port int
httpPort int
printProto bool
localStorage []string
consolePath string
secretServer string
configDir string
skyWalking string
port int
httpPort int
printProto bool
localStorage []string
consolePath string
secretServer string
configDir string
skyWalking string
extensionRegistry string

auth string
oauthProvider string
Expand Down Expand Up @@ -241,8 +243,10 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
template.SetSecretGetter(remote.NewGRPCSecretGetter(secretServer))
}

extDownloader := downloader.NewStoreDownloader()
extDownloader.WithRegistry(o.extensionRegistry)
storeExtMgr := server.NewStoreExtManager(o.execer)
storeExtMgr.WithDownloader(downloader.NewStoreDownloader())
storeExtMgr.WithDownloader(extDownloader)
remoteServer := server.NewRemoteServer(loader, remote.NewGRPCloaderFromStore(), secretServer, storeExtMgr, o.configDir, o.grpcMaxRecvMsgSize)
kinds, storeKindsErr := remoteServer.GetStoreKinds(ctx, nil)
if storeKindsErr != nil {
Expand Down
4 changes: 2 additions & 2 deletions e2e/compose-k8s.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ services:
- k8s:/output
# This is just so that we get the kubeconfig file out
# - .:/output
ports:
- 30000:30000
# ports:
# - 30000:30000
# - 6443:6443 # Kubernetes API Server
# - 80:80 # Ingress controller port 80
# - 443:443 # Ingress controller port 443
Expand Down
26 changes: 16 additions & 10 deletions e2e/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,35 @@ set -e
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
mkdir -p /root/.config/atest
mkdir -p /var/data
cd "/var/data"

# Generate private key
openssl genrsa -out server.key 2048
# Generate self-signed certificate
openssl req -new -x509 -key server.key -out server.crt -days 36500 \
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"
# Generate Certificate Signing Request (CSR)
openssl req -new -key server.key -out server.csr \
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"
# Generate a new private key
openssl genpkey -algorithm RSA -out test.key
# Generate a new CSR
openssl req -new -nodes -key test.key -out test.csr -days 3650 \
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" \
-config "$SCRIPT_DIR/openssl.cnf" -extensions v3_req
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" \
-config "openssl.cnf" -extensions v3_req
# Sign the new CSR with the self-signed certificate
openssl x509 -req -days 365 -in test.csr \
-out test.pem -CA server.crt -CAkey server.key \
-CAcreateserial -extfile "$SCRIPT_DIR/openssl.cnf" -extensions v3_req
-out test.pem -CA server.crt -CAkey server.key \
-CAcreateserial -extfile "openssl.cnf" -extensions v3_req

echo "start to download extenions"
atest extension --output /usr/local/bin --registry ghcr.io git
atest extension --output /usr/local/bin --registry ghcr.io orm
atest extension --output /usr/local/bin --registry ghcr.io etcd
atest extension --output /usr/local/bin --registry ghcr.io mongodb

nohup atest server --tls-grpc --cert-file /var/data/test.pem --key-file /var/data/test.key&
cmd="atest run -p test-suite-common.yaml --report github --report-github-identity e2e-testing --report-file /var/data/report.json --report-github-repo linuxsuren/api-testing --report-github-pr ${PULL_REQUEST:-0}"
echo "start to run server"
nohup atest server --tls-grpc --cert-file test.pem --key-file test.key&
cmd="atest run -p test-suite-common.yaml"

echo "start to run testing: $cmd"
kind=orm target=mysql:3306 driver=mysql $cmd
Expand All @@ -47,4 +54,3 @@ kind=orm target=postgres:5432 driver=postgres $cmd
# kind=s3 target=minio:9000 atest run -p test-suite-common.yaml

cat /root/.config/atest/stores.yaml
exit 0
14 changes: 11 additions & 3 deletions e2e/k8s.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ set -e

sleep 6
echo "Running k8s.sh"

ls -hal
cd api-testing
echo "build helm dependency"
helm dependency build

echo "install helm chart"
helm install --kube-apiserver https://server:6443 --kube-token abcd --kube-insecure-skip-tls-verify \
api-testing ./api-testing \
api-testing . \
--set service.type=NodePort \
--set service.nodePort=30000 \
--set persistence.enabled=false \
--set image.registry=linuxsuren.docker.scarf.sh \
--set image.registry=ghcr.io \
--set image.repository=linuxsuren/api-testing \
--set image.tag=master
--set image.tag=master \
--set extension.registry=ghcr.io

SERVER=http://server:30000 atest run -p git.yaml
24 changes: 2 additions & 22 deletions e2e/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,5 @@ then
fi

docker-compose version
docker-compose -f "$file" up --build -d

while true
do
docker-compose -f "$file" ps | grep testing
if [ $? -eq 1 ]
then
code=-1
docker-compose -f "$file" logs | grep testing
docker-compose -f "$file" logs | grep testing | grep Usage
if [ $? -eq 1 ]
then
code=0
echo "successed"
fi

docker-compose -f "$file" down
set -e
exit $code
fi
sleep 1
done
docker-compose -f "$file" down
docker-compose -f "$file" up --build testing --exit-code-from testing --remove-orphans
10 changes: 10 additions & 0 deletions e2e/test-suite-common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,16 @@ items:
"suite": "{{.param.gRPCSuiteName}}",
"testcase": "{{.param.gRPCCaseName}}"
}
- name: runTestSuite
request:
api: /RunTestSuite
method: POST
header:
X-Store-Name: "{{.param.store}}"
body: |
{
"name": "{{.param.gRPCSuiteName}}"
}
- name: version
request:
api: /GetVersion
Expand Down
1 change: 1 addition & 0 deletions helm/api-testing/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ spec:
command:
- atest
- server
- --extension-registry={{ .Values.extension.registry }}
- --local-storage=/root/.atest/data/*.yaml
{{- if .Values.skywalking.endpoint.http }}
- --skywalking={{ .Values.skywalking.endpoint.http }}
Expand Down
3 changes: 3 additions & 0 deletions helm/api-testing/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ persistence:
size: 500Mi
volumeMode: Filesystem

extension:
registry: docker.io

skywalking:
endpoint:
http: "" # http://skywalking-skywalking-helm-oap.skywalking.svc:12800
Expand Down
32 changes: 28 additions & 4 deletions pkg/downloader/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package downloader

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"

"github.com/blang/semver/v4"
)
Expand All @@ -32,6 +34,8 @@ type OCIDownloader interface {
WithRegistry(string)
WithRoundTripper(http.RoundTripper)
WithInsecure(bool)
WithTimeout(time.Duration)
WithContext(context.Context)
Download(image, tag, file string) (reader io.Reader, err error)
}

Expand All @@ -43,6 +47,8 @@ type PlatformAwareOCIDownloader interface {
}

type defaultOCIDownloader struct {
ctx context.Context
timeout time.Duration
serviceURL string
registry string
rawImage string
Expand All @@ -53,6 +59,8 @@ type defaultOCIDownloader struct {
func NewDefaultOCIDownloader() OCIDownloader {
return &defaultOCIDownloader{
protocol: "https",
timeout: time.Minute,
ctx: context.Background(),
}
}

Expand Down Expand Up @@ -82,15 +90,15 @@ func (d *defaultOCIDownloader) Download(image, tag, file string) (reader io.Read

var req *http.Request
api := fmt.Sprintf("%s://%s/v2/%s/manifests/%s", d.protocol, d.registry, d.rawImage, latestTag)
if req, err = http.NewRequest(http.MethodGet, api, nil); err != nil {
if req, err = http.NewRequestWithContext(d.ctx, http.MethodGet, api, nil); err != nil {
return
}

req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", authStr))
req.Header.Set("Accept", "application/vnd.oci.image.manifest.v1+json")

var resp *http.Response
if resp, err = http.DefaultClient.Do(req); err != nil {
if resp, err = d.getHTTPClient().Do(req); err != nil {
err = fmt.Errorf("failed to get manifest from %q, error: %v", api, err)
return
} else if resp.StatusCode != http.StatusOK {
Expand Down Expand Up @@ -132,6 +140,14 @@ func (d *defaultOCIDownloader) WithInsecure(insecure bool) {
}
}

func (d *defaultOCIDownloader) WithTimeout(timeout time.Duration) {
d.timeout = timeout
}

func (d *defaultOCIDownloader) WithContext(ctx context.Context) {
d.ctx = ctx
}

func (d *defaultOCIDownloader) WithRoundTripper(rt http.RoundTripper) {
d.roundTripper = rt
}
Expand All @@ -146,7 +162,7 @@ func (d *defaultOCIDownloader) getLatestTag(image, authToken string) (tag string

req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", authToken))
var resp *http.Response
if resp, err = http.DefaultClient.Do(req); err != nil {
if resp, err = d.getHTTPClient().Do(req); err != nil {
err = fmt.Errorf("failed to get image tags from %q, error: %v", req.URL, err)
} else if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("failed to get image tags from %q, status code: %d", req.URL, resp.StatusCode)
Expand Down Expand Up @@ -178,6 +194,14 @@ func (d *defaultOCIDownloader) getLatestTag(image, authToken string) (tag string
return
}

func (d *defaultOCIDownloader) getHTTPClient() (client *http.Client) {
client = &http.Client{
Timeout: d.timeout,
Transport: d.roundTripper,
}
return
}

type ImageTagList struct {
Name string `json:"name"`
Tags []string `json:"tags"`
Expand All @@ -191,7 +215,7 @@ func (d *defaultOCIDownloader) downloadLayer(image, digest, authToken string) (r

req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", authToken))
var resp *http.Response
if resp, err = http.DefaultClient.Do(req); err != nil {
if resp, err = d.getHTTPClient().Do(req); err != nil {
err = fmt.Errorf("failed to get layer from %q, error: %v", req.URL.String(), err)
} else {
var data []byte
Expand Down
Loading
Loading