mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-14 16:37:56 -05:00
128 lines
3.6 KiB
Go
128 lines
3.6 KiB
Go
package dockercompose
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"fmt"
|
|
"math/big"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/cloudflare/cfssl/log"
|
|
"github.com/scroll-tech/go-ethereum/ethclient"
|
|
tc "github.com/testcontainers/testcontainers-go/modules/compose"
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
|
)
|
|
|
|
// PoSL1TestEnv represents the config needed to test in PoS Layer 1.
|
|
type PoSL1TestEnv struct {
|
|
dockerComposeFile string
|
|
compose tc.ComposeStack
|
|
gethHTTPPort int
|
|
hostPath string
|
|
}
|
|
|
|
// NewPoSL1TestEnv creates and initializes a new instance of PoSL1TestEnv with a random HTTP port.
|
|
func NewPoSL1TestEnv() (*PoSL1TestEnv, error) {
|
|
rootDir, err := findProjectRootDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to find project root directory: %v", err)
|
|
}
|
|
|
|
hostPath, found := os.LookupEnv("HOST_PATH")
|
|
if !found {
|
|
hostPath = ""
|
|
}
|
|
|
|
rnd, err := rand.Int(rand.Reader, big.NewInt(65536-1024))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate a random: %v", err)
|
|
}
|
|
gethHTTPPort := int(rnd.Int64()) + 1024
|
|
|
|
if err := os.Setenv("GETH_HTTP_PORT", fmt.Sprintf("%d", gethHTTPPort)); err != nil {
|
|
return nil, fmt.Errorf("failed to set GETH_HTTP_PORT: %v", err)
|
|
}
|
|
|
|
return &PoSL1TestEnv{
|
|
dockerComposeFile: filepath.Join(rootDir, "common", "docker-compose", "l1", "docker-compose.yml"),
|
|
gethHTTPPort: gethHTTPPort,
|
|
hostPath: hostPath,
|
|
}, nil
|
|
}
|
|
|
|
// Start starts the PoS L1 test environment by running the associated Docker Compose configuration.
|
|
func (e *PoSL1TestEnv) Start() error {
|
|
var err error
|
|
e.compose, err = tc.NewDockerCompose([]string{e.dockerComposeFile}...)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create docker compose: %w", err)
|
|
}
|
|
|
|
env := map[string]string{
|
|
"GETH_HTTP_PORT": fmt.Sprintf("%d", e.gethHTTPPort),
|
|
}
|
|
|
|
if e.hostPath != "" {
|
|
env["HOST_PATH"] = e.hostPath
|
|
}
|
|
|
|
if err = e.compose.WaitForService("geth", wait.NewHTTPStrategy("/").WithPort("8545/tcp").WithStartupTimeout(15*time.Second)).WithEnv(env).Up(context.Background()); err != nil {
|
|
if errStop := e.Stop(); errStop != nil {
|
|
log.Error("failed to stop PoS L1 test environment", "err", errStop)
|
|
}
|
|
return fmt.Errorf("failed to start PoS L1 test environment: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Stop stops the PoS L1 test environment by stopping and removing the associated Docker Compose services.
|
|
func (e *PoSL1TestEnv) Stop() error {
|
|
if e.compose != nil {
|
|
if err := e.compose.Down(context.Background(), tc.RemoveOrphans(true), tc.RemoveVolumes(true), tc.RemoveImagesLocal); err != nil {
|
|
return fmt.Errorf("failed to stop PoS L1 test environment: %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Endpoint returns the HTTP endpoint for the PoS L1 test environment.
|
|
func (e *PoSL1TestEnv) Endpoint() string {
|
|
return fmt.Sprintf("http://127.0.0.1:%d", e.gethHTTPPort)
|
|
}
|
|
|
|
// L1Client returns an ethclient by dialing the running PoS L1 test environment
|
|
func (e *PoSL1TestEnv) L1Client() (*ethclient.Client, error) {
|
|
if e == nil {
|
|
return nil, fmt.Errorf("PoS L1 test environment is not initialized")
|
|
}
|
|
|
|
client, err := ethclient.Dial(e.Endpoint())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to dial PoS L1 test environment: %w", err)
|
|
}
|
|
return client, nil
|
|
}
|
|
|
|
func findProjectRootDir() (string, error) {
|
|
currentDir, err := os.Getwd()
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get working directory: %w", err)
|
|
}
|
|
|
|
for {
|
|
_, err := os.Stat(filepath.Join(currentDir, "go.work"))
|
|
if err == nil {
|
|
return currentDir, nil
|
|
}
|
|
|
|
parentDir := filepath.Dir(currentDir)
|
|
if parentDir == currentDir {
|
|
return "", fmt.Errorf("go.work file not found in any parent directory")
|
|
}
|
|
|
|
currentDir = parentDir
|
|
}
|
|
}
|