package framework import ( "flag" "io" "math/rand" "os" "testing" "time" "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/reporters" "github.com/onsi/gomega" ) var DefaultStartTimeout = float64(60 * 60) type Framework struct { Config *Config ClusterConfig *ClusterConfig configFile string // 配置文件的路径 initTimeout float64 // 启动时候,包括安装集群和依赖及本程序的超时时间 } func NewFramework() *Framework { return &Framework{} } // Flags 解析命令行参数: --config --timeout func (f *Framework) Flags() *Framework { flag.StringVar(&f.configFile, "config", "config", "config file to used") flag.Float64Var(&f.initTimeout, "startup-timeout", DefaultStartTimeout, "startup timeout") flag.Parse() // 让配置生效,就是将参数赋值到变量中 return f } // LoadConfig 加载配置文件到 fmw func (f *Framework) LoadConfig(writer io.Writer) *Framework { // 1. 创建 config 对象 config := NewConfig() // 2. 加载配置文件内容到 config 对象中 if err := config.Load(f.configFile); err != nil { panic(err) } // 3. 将传入的 writer 应用到 config中 // 4. 将 config 加入到 fmw 中 return f.WithConfig(config.WithWriter(writer)) } func (f *Framework) SynchronizedBeforeSuite(initFunc func()) *Framework { if initFunc == nil { initFunc = func() { // 1. 安装环境 ginkgo.By("Deploying test environment") if err := f.DeployTestEnvironment(); err != nil { panic(err) } // 2. 初始化环境访问的授权,也就是创建kubectl 访问需要的config ginkgo.By("kubectl switch context") kubectlConfig := NewKubectlConfig(f.Config) if err := kubectlConfig.SetContext(f.ClusterConfig); err != nil { panic(err) } // 推出前清理context defer func() { ginkgo.By("kubectl reverting context") if !f.Config.Sub("cluster").Sub("kind").GetBool("retain") { _ = kubectlConfig.DeleteContext(f.ClusterConfig) } }() // 3. 安装依赖和我们的程序 ginkgo.By("Preparing install steps") installer := NewInstaller(f.Config) ginkgo.By("Executing install steps") if err := installer.Install(); err != nil { panic(err) } } } ginkgo.SynchronizedBeforeSuite(func() []byte { initFunc() return nil }, func(_ []byte) {}, f.initTimeout) return f } func (f *Framework) SynchronizedAfterSuite(destroyFunc func()) *Framework { if destroyFunc == nil { destroyFunc = func() { // 回收测试环境 if err := f.DestroyTestEnvironment(); err != nil { panic(err) } } } ginkgo.SynchronizedAfterSuite(func() {}, destroyFunc, f.initTimeout) return f } func (f *Framework) MRun(m *testing.M) { rand.Seed(time.Now().UnixNano()) // 优化随机数 os.Exit(m.Run()) // 执行真正的 TestMain } func (f *Framework) Run(t *testing.T) { gomega.RegisterFailHandler(ginkgo.Fail) var r []ginkgo.Reporter r = append(r, reporters.NewJUnitReporter("e2e.xml")) ginkgo.RunSpecsWithDefaultAndCustomReporters(t, "e2e", r) } func (f *Framework) WithConfig(config *Config) *Framework { f.Config = config return f } // TODO // 创建环境之后,填充f.ClusterConfig func (f *Framework) DeployTestEnvironment() error { return nil } // TODO func (f *Framework) DestroyTestEnvironment() error { return nil }