Skip to content

Commit 4d2f56d

Browse files
committed
feat: separate framework
Signed-off-by: ashing <[email protected]>
1 parent 75ae919 commit 4d2f56d

File tree

12 files changed

+682
-772
lines changed

12 files changed

+682
-772
lines changed

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ toolchain go1.22.5
77
require (
88
github.com/Masterminds/sprig/v3 v3.2.3
99
github.com/api7/gopkg v0.2.1-0.20230601092738-0f3730f9b57a
10+
github.com/bytedance/sonic/loader v0.2.4
1011
github.com/gavv/httpexpect v2.0.0+incompatible
1112
github.com/gavv/httpexpect/v2 v2.16.0
1213
github.com/go-logr/logr v1.4.2
@@ -28,13 +29,15 @@ require (
2829
go.uber.org/zap v1.27.0
2930
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
3031
golang.org/x/net v0.28.0
32+
google.golang.org/appengine v1.6.7
3133
gopkg.in/yaml.v2 v2.4.0
3234
gorm.io/gorm v1.25.11
3335
helm.sh/helm/v3 v3.15.4
3436
k8s.io/api v0.31.1
3537
k8s.io/apiextensions-apiserver v0.31.1
3638
k8s.io/apimachinery v0.31.1
3739
k8s.io/client-go v0.31.1
40+
k8s.io/kubectl v0.30.3
3841
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
3942
sigs.k8s.io/controller-runtime v0.19.0
4043
sigs.k8s.io/gateway-api v1.2.0
@@ -192,6 +195,7 @@ require (
192195
go.opentelemetry.io/otel/trace v1.28.0 // indirect
193196
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
194197
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
198+
go.uber.org/goleak v1.3.0 // indirect
195199
golang.org/x/arch v0.6.0 // indirect
196200
golang.org/x/crypto v0.26.0 // indirect
197201
golang.org/x/mod v0.20.0 // indirect
@@ -217,7 +221,6 @@ require (
217221
k8s.io/component-base v0.31.1 // indirect
218222
k8s.io/klog/v2 v2.130.1 // indirect
219223
k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect
220-
k8s.io/kubectl v0.30.3 // indirect
221224
moul.io/http2curl/v2 v2.3.0 // indirect
222225
oras.land/oras-go v1.2.5 // indirect
223226
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect

go.sum

Lines changed: 209 additions & 0 deletions
Large diffs are not rendered by default.

test/e2e/framework/license.go renamed to test/e2e/apisix/e2e_test.go

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,26 @@
1010
// See the License for the specific language governing permissions and
1111
// limitations under the License.
1212

13-
package framework
13+
package apisix
1414

1515
import (
16-
_ "embed"
17-
"encoding/json"
16+
"fmt"
17+
"testing"
1818

19-
"github.com/stretchr/testify/assert"
20-
)
19+
. "github.com/onsi/ginkgo/v2"
20+
. "github.com/onsi/gomega"
2121

22-
func (f *Framework) UploadLicense() {
23-
payload := map[string]any{"data": API7EELicense}
24-
payloadBytes, err := json.Marshal(payload)
25-
assert.Nil(f.GinkgoT, err)
22+
"github.com/apache/apisix-ingress-controller/test/e2e/framework"
23+
)
2624

27-
respExpect := f.DashboardHTTPClient().PUT("/api/license").
28-
WithBasicAuth("admin", "admin").
29-
WithHeader("Content-Type", "application/json").
30-
WithBytes(payloadBytes).
31-
Expect()
25+
// TestAPISIXE2E runs e2e tests using the APISIX standalone mode
26+
func TestAPISIXE2E(t *testing.T) {
27+
RegisterFailHandler(Fail)
28+
// init framework
29+
_ = framework.NewFramework()
3230

33-
body := respExpect.Body().Raw()
34-
f.Logf("request /api/license, response body: %s", body)
31+
// TODO: init newDeployer function
3532

36-
respExpect.Status(200)
33+
_, _ = fmt.Fprintf(GinkgoWriter, "Starting APISIX standalone e2e suite\n")
34+
RunSpecs(t, "apisix standalone e2e suite")
3735
}

test/e2e/framework/consts.go renamed to test/e2e/framework/api7_consts.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ import (
1616
_ "embed"
1717
)
1818

19+
const (
20+
postgres = "postgres"
21+
oceanbase = "oceanbase"
22+
mysql = "mysql"
23+
postgresDSN = "postgres://api7ee:changeme@api7-postgresql:5432/api7ee"
24+
oceanbaseDSN = "mysql://root@tcp(oceanbase:2881)/api7ee"
25+
mysqlDSN = "mysql://root:changeme@tcp(mysql:3306)/api7ee"
26+
)
27+
1928
const (
2029
DashboardEndpoint = "http://api7ee3-dashboard.api7-ee-e2e:7080"
2130
DashboardTLSEndpoint = "https://api7ee3-dashboard.api7-ee-e2e:7443"

test/e2e/framework/dashboard.go renamed to test/e2e/framework/api7_dashboard.go

Lines changed: 108 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,32 @@
1313
package framework
1414

1515
import (
16-
"bytes"
1716
_ "embed"
1817
"encoding/json"
1918
"fmt"
19+
"github.com/gavv/httpexpect/v2"
20+
"net/http"
21+
"net/url"
2022
"os"
23+
"strings"
2124
"text/template"
22-
"time"
2325

24-
"github.com/api7/gopkg/pkg/log"
2526
"github.com/google/uuid"
2627
. "github.com/onsi/gomega"
27-
"golang.org/x/net/html"
28-
"helm.sh/helm/v3/pkg/action"
29-
"helm.sh/helm/v3/pkg/chart/loader"
30-
"helm.sh/helm/v3/pkg/cli"
31-
"helm.sh/helm/v3/pkg/kube"
32-
"k8s.io/apimachinery/pkg/util/yaml"
3328

3429
v1 "github.com/apache/apisix-ingress-controller/api/dashboard/v1"
3530
)
3631

3732
var (
38-
API7EELicense string
39-
4033
valuesTemplate *template.Template
41-
42-
dashboardVersion string
34+
_db string
4335
)
4436

4537
func init() {
46-
API7EELicense = os.Getenv("API7_EE_LICENSE")
47-
if API7EELicense == "" {
48-
panic("env {API7_EE_LICENSE} is required")
38+
_db = os.Getenv("DB")
39+
if _db == "" {
40+
_db = postgres
4941
}
50-
51-
dashboardVersion = os.Getenv("DASHBOARD_VERSION")
52-
if dashboardVersion == "" {
53-
dashboardVersion = "dev"
54-
}
55-
5642
tmpl, err := template.New("values.yaml").Parse(`
5743
dashboard:
5844
image:
@@ -258,116 +244,54 @@ api_usage:
258244
valuesTemplate = tmpl
259245
}
260246

261-
type responseCreateGateway struct {
262-
Value responseCreateGatewayValue `json:"value"`
263-
ErrorMsg string `json:"error_msg"`
264-
}
247+
// DatabaseConfig is the database related configuration entrypoint.
248+
type DatabaseConfig struct {
249+
DSN string `json:"dsn" yaml:"dsn" mapstructure:"dsn"`
265250

266-
type responseCreateGatewayValue struct {
267-
ID string `json:"id"`
268-
TokenPlainText string `json:"token_plain_text"`
269-
Key string `json:"key"`
251+
MaxOpenConns int `json:"max_open_conns" yaml:"max_open_conns" mapstructure:"max_open_conns"`
252+
MaxIdleConns int `json:"max_idle_conns" yaml:"max_idle_conns" mapstructure:"max_idle_conns"`
270253
}
271254

272-
func (f *Framework) deploy() {
273-
debug := func(format string, v ...any) {
274-
log.Infof(format, v...)
275-
}
276-
277-
kubeConfigPath := os.Getenv("KUBECONFIG")
278-
actionConfig := new(action.Configuration)
279-
280-
err := actionConfig.Init(
281-
kube.GetConfig(kubeConfigPath, "", f.kubectlOpts.Namespace),
282-
f.kubectlOpts.Namespace,
283-
"memory",
284-
debug,
285-
)
286-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "init helm action config")
287-
288-
install := action.NewInstall(actionConfig)
289-
install.Namespace = f.kubectlOpts.Namespace
290-
install.ReleaseName = "api7ee3"
291-
292-
chartPath, err := install.LocateChart("api7/api7ee3", cli.New())
293-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "locate helm chart")
294-
295-
chart, err := loader.Load(chartPath)
296-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "load helm chart")
297-
298-
buf := bytes.NewBuffer(nil)
299-
_ = valuesTemplate.Execute(buf, map[string]any{
300-
"DB": _db,
301-
"DSN": getDSN(),
302-
"Tag": dashboardVersion,
303-
})
304-
305-
var v map[string]any
306-
err = yaml.Unmarshal(buf.Bytes(), &v)
307-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "unmarshal values")
308-
_, err = install.Run(chart, v)
309-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "install dashboard")
310-
311-
err = f.ensureService("api7ee3-dashboard", _namespace, 1)
312-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "ensuring dashboard service")
313-
314-
err = f.ensureService("api7-postgresql", _namespace, 1)
315-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "ensuring postgres service")
316-
317-
err = f.ensureService("api7-prometheus-server", _namespace, 1)
318-
f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "ensuring prometheus-server service")
255+
type LogOptions struct {
256+
// Level is the minimum logging level that a logging message should have
257+
// to output itself.
258+
Level string `json:"level" yaml:"level"`
259+
// Output defines the destination file path to output logging messages.
260+
// Two keywords "stderr" and "stdout" can be specified so that message will
261+
// be written to stderr or stdout.
262+
Output string `json:"output" yaml:"output"`
319263
}
320264

321-
func (f *Framework) initDashboard() {
322-
f.deletePods("app.kubernetes.io/name=api7ee3")
323-
time.Sleep(5 * time.Second)
265+
func (conf *DatabaseConfig) GetType() string {
266+
parts := strings.SplitN(conf.DSN, "://", 2)
267+
if len(parts) > 1 {
268+
return parts[0]
269+
}
270+
return ""
324271
}
325272

326-
// ParseHTML will parse the doc from login page and generate a map contains id and action.
327-
func (f *Framework) ParseHTML(doc *html.Node) map[string]string {
328-
var fu func(*html.Node)
329-
htmlMap := make(map[string]string)
330-
fu = func(n *html.Node) {
331-
var (
332-
name string
333-
value string
334-
)
335-
for _, attr := range n.Attr {
336-
if attr.Key == "id" || attr.Key == "name" {
337-
name = attr.Val
338-
}
339-
if attr.Key == "action" || attr.Key == "value" {
340-
value = attr.Val
341-
}
342-
343-
htmlMap[name] = value
344-
}
345-
346-
for c := n.FirstChild; c != nil; c = c.NextSibling {
347-
fu(c)
348-
}
273+
//nolint:unused
274+
func getDSN() string {
275+
switch _db {
276+
case postgres:
277+
return postgresDSN
278+
case oceanbase:
279+
return oceanbaseDSN
280+
case mysql:
281+
return mysqlDSN
349282
}
350-
fu(doc)
351-
352-
return htmlMap
283+
panic("unknown database")
353284
}
354285

355-
func (f *Framework) GetTokenFromDashboard(gatewayGroupID string) (string, error) {
356-
respExp := f.DashboardHTTPClient().
357-
POST("/api/gateway_groups/"+gatewayGroupID+"/instance_token").
358-
WithHeader("Content-Type", "application/json").
359-
WithBasicAuth("admin", "admin").
360-
Expect()
286+
type responseCreateGateway struct {
287+
Value responseCreateGatewayValue `json:"value"`
288+
ErrorMsg string `json:"error_msg"`
289+
}
361290

362-
respExp.Status(200).Body().Contains("token_plain_text")
363-
body := respExp.Body().Raw()
364-
// unmarshal into responseCreateGateway
365-
var response responseCreateGateway
366-
err := json.Unmarshal([]byte(body), &response)
367-
if err != nil {
368-
return "", err
369-
}
370-
return response.Value.TokenPlainText, nil
291+
type responseCreateGatewayValue struct {
292+
ID string `json:"id"`
293+
TokenPlainText string `json:"token_plain_text"`
294+
Key string `json:"key"`
371295
}
372296

373297
func (f *Framework) GetDataplaneCertificates(gatewayGroupID string) *v1.DataplaneCertificate {
@@ -461,3 +385,66 @@ func (f *Framework) CreateNewGatewayGroupWithIngressE() (string, error) {
461385
}
462386
return response.Value.ID, nil
463387
}
388+
389+
func (f *Framework) setDpManagerEndpoints() {
390+
payload := []byte(fmt.Sprintf(`{"control_plane_address":["%s"]}`, DPManagerTLSEndpoint))
391+
392+
respExp := f.DashboardHTTPClient().
393+
PUT("/api/system_settings").
394+
WithBasicAuth("admin", "admin").
395+
WithHeader("Content-Type", "application/json").
396+
WithBytes(payload).
397+
Expect()
398+
399+
respExp.Raw()
400+
f.Logf("set dp manager endpoints response: %s", respExp.Body().Raw())
401+
402+
respExp.Status(200).
403+
Body().Contains("control_plane_address")
404+
}
405+
406+
func (f *Framework) GetDashboardEndpoint() string {
407+
return f.dashboardHTTPTunnel.Endpoint()
408+
}
409+
410+
func (f *Framework) GetDashboardEndpointHTTPS() string {
411+
return f.dashboardHTTPSTunnel.Endpoint()
412+
}
413+
414+
func (f *Framework) DashboardHTTPClient() *httpexpect.Expect {
415+
u := url.URL{
416+
Scheme: "http",
417+
Host: f.GetDashboardEndpoint(),
418+
}
419+
return httpexpect.WithConfig(httpexpect.Config{
420+
BaseURL: u.String(),
421+
Client: &http.Client{
422+
Transport: &http.Transport{},
423+
CheckRedirect: func(req *http.Request, via []*http.Request) error {
424+
return http.ErrUseLastResponse
425+
},
426+
},
427+
Reporter: httpexpect.NewAssertReporter(
428+
httpexpect.NewAssertReporter(f.GinkgoT),
429+
),
430+
})
431+
}
432+
433+
func (f *Framework) DashboardHTTPSClient() *httpexpect.Expect {
434+
u := url.URL{
435+
Scheme: "https",
436+
Host: f.GetDashboardEndpointHTTPS(),
437+
}
438+
return httpexpect.WithConfig(httpexpect.Config{
439+
BaseURL: u.String(),
440+
Client: &http.Client{
441+
Transport: &http.Transport{},
442+
CheckRedirect: func(req *http.Request, via []*http.Request) error {
443+
return http.ErrUseLastResponse
444+
},
445+
},
446+
Reporter: httpexpect.NewAssertReporter(
447+
httpexpect.NewAssertReporter(f.GinkgoT),
448+
),
449+
})
450+
}

0 commit comments

Comments
 (0)