Skip to content

Commit

Permalink
Improve test orginazation (#1219)
Browse files Browse the repository at this point in the history
Signed-off-by: Cody Littley <[email protected]>
  • Loading branch information
cody-littley authored Feb 5, 2025
1 parent d0f49e9 commit c809091
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 52 deletions.
5 changes: 5 additions & 0 deletions test/v2/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
test:
cd correctness && go test

load:
cd load && go test
20 changes: 14 additions & 6 deletions test/v2/test_client.go → test/v2/client/test_client.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package v2
package client

import (
"context"
"fmt"
"github.com/prometheus/client_golang/prometheus"
"os"
"path"
"strings"
Expand Down Expand Up @@ -36,12 +37,12 @@ const (
SRSPathG2 = SRSPath + "/g2.point"
SRSPathG2PowerOf2 = SRSPath + "/g2.point.powerOf2"
SRSPathSRSTables = SRSPath + "/SRSTables"
KeyPath = "private-key.txt"
)

// TestClientConfig is the configuration for the test client.
type TestClientConfig struct {
TestDataPath string
KeyPath string
DisperserHostname string
DisperserPort int
EthRPCURLs []string
Expand All @@ -67,15 +68,21 @@ type TestClient struct {
RetrievalClient clients.RetrievalClient
CertVerifier *verification.CertVerifier
PrivateKey string
MetricsRegistry *prometheus.Registry
metrics *testClientMetrics
}

// path returns the full path to a file in the test data directory.
func (c *TestClientConfig) path(t *testing.T, elements ...string) string {
// resolveTildeInPath resolves the tilde (~) in the given path to the user's home directory.
func resolveTildeInPath(t *testing.T, path string) string {
homeDir, err := os.UserHomeDir()
require.NoError(t, err)

root := strings.Replace(c.TestDataPath, "~", homeDir, 1)
return strings.Replace(path, "~", homeDir, 1)
}

// path returns the full path to a file in the test data directory.
func (c *TestClientConfig) path(t *testing.T, elements ...string) string {
root := resolveTildeInPath(t, c.TestDataPath)

combinedElements := make([]string, 0, len(elements)+1)
combinedElements = append(combinedElements, root)
Expand Down Expand Up @@ -108,7 +115,7 @@ func NewTestClient(t *testing.T, config *TestClientConfig) *TestClient {

// Construct the disperser client

privateKeyFile := config.path(t, KeyPath)
privateKeyFile := resolveTildeInPath(t, config.KeyPath)
privateKey, err := os.ReadFile(privateKeyFile)
require.NoError(t, err)

Expand Down Expand Up @@ -229,6 +236,7 @@ func NewTestClient(t *testing.T, config *TestClientConfig) *TestClient {
RetrievalClient: retrievalClient,
CertVerifier: certVerifier,
PrivateKey: privateKeyString,
MetricsRegistry: metrics.registry,
metrics: metrics,
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v2
package client

import (
"errors"
Expand Down
65 changes: 37 additions & 28 deletions test/v2/test_setup.go → test/v2/client/test_setup.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package v2
package client

import (
"encoding/json"
"fmt"
"github.com/docker/go-units"
"github.com/stretchr/testify/require"
"os"
"os/exec"
Expand All @@ -11,41 +11,50 @@ import (
)

var (
preprodConfig = &TestClientConfig{
TestDataPath: "~/.test-v2",
DisperserHostname: "disperser-preprod-holesky.eigenda.xyz",
DisperserPort: 443,
EthRPCURLs: []string{"https://ethereum-holesky-rpc.publicnode.com"},
BLSOperatorStateRetrieverAddr: "0x93545e3b9013CcaBc31E80898fef7569a4024C0C",
EigenDAServiceManagerAddr: "0x54A03db2784E3D0aCC08344D05385d0b62d4F432",
EigenDACertVerifierAddress: "0xe2C7AfB3c47B800b439b0a3d8EA40ca79759B245",
SubgraphURL: "https://subgraph.satsuma-prod.com/51caed8fa9cb/eigenlabs/eigenda-operator-state-preprod-holesky/version/v0.7.0/api",
SRSOrder: 268435456,
MaxBlobSize: 16 * units.MiB,
MinimumSigningPercent: 55,
MetricsPort: 9101,
targetConfigFile = "../config/environment/preprod.json"
configLock sync.Mutex
config *TestClientConfig
clientLock sync.Mutex
client *TestClient
)

// GetConfig returns a TestClientConfig instance, creating one if it does not exist.
func GetConfig(t *testing.T) *TestClientConfig {
configLock.Lock()
defer configLock.Unlock()

skipInCI(t)
if config != nil {
return config
}

lock sync.Mutex
client *TestClient
configFile := resolveTildeInPath(t, targetConfigFile)
configFileBytes, err := os.ReadFile(configFile)
require.NoError(t, err)

targetConfig = preprodConfig
)
config = &TestClientConfig{}
err = json.Unmarshal(configFileBytes, config)
require.NoError(t, err)

return config
}

// getClient returns a TestClient instance, creating one if it does not exist.
// GetClient returns a TestClient instance, creating one if it does not exist.
// This uses a global static client... this is icky, but it takes ~1 minute
// to read the SRS points, so it's the lesser of two evils to keep it around.
func getClient(t *testing.T) *TestClient {
lock.Lock()
defer lock.Unlock()
func GetClient(t *testing.T) *TestClient {
clientLock.Lock()
defer clientLock.Unlock()

skipInCI(t)
setupFilesystem(t, targetConfig)

if client == nil {
client = NewTestClient(t, targetConfig)
if client != nil {
return client
}

testConfig := GetConfig(t)
client = NewTestClient(t, testConfig)
setupFilesystem(t, testConfig)

return client
}

Expand Down Expand Up @@ -122,7 +131,7 @@ func setupFilesystem(t *testing.T, config *TestClientConfig) {
}

// Check to see if the private key file exists. If not, stop the test.
filePath = config.path(t, KeyPath)
filePath = resolveTildeInPath(t, config.KeyPath)
_, err = os.Stat(filePath)
require.NoError(t, err,
"private key file %s does not exist. This file should "+
Expand Down
17 changes: 17 additions & 0 deletions test/v2/config/environment/preprod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"TestDataPath": "~/.test-v2",
"KeyPath": "~/.test-v2/preprod-private-key.txt",
"DisperserHostname": "disperser-preprod-holesky.eigenda.xyz",
"DisperserPort": 443,
"EthRPCURLs": [
"https://ethereum-holesky-rpc.publicnode.com"
],
"BLSOperatorStateRetrieverAddr": "0x93545e3b9013CcaBc31E80898fef7569a4024C0C",
"EigenDAServiceManagerAddr": "0x54A03db2784E3D0aCC08344D05385d0b62d4F432",
"EigenDACertVerifierAddress": "0xe2C7AfB3c47B800b439b0a3d8EA40ca79759B245",
"SubgraphURL": "https://subgraph.satsuma-prod.com/51caed8fa9cb/eigenlabs/eigenda-operator-state-preprod-holesky/version/v0.7.0/api",
"SRSOrder": 268435456,
"MaxBlobSize": 16777216,
"MinimumSigningPercent": 55,
"MetricsPort": 9101
}
13 changes: 13 additions & 0 deletions test/v2/config/load/100kb_s-1mb-3x.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"BytesPerSecond": 10240,
"AverageBlobSize": 1048576,
"BlobSizeStdDev": 262144,
"RelayReadAmplification": 3,
"ValidatorReadAmplification": 3,
"MaxParallelism": 10,
"DispersalTimeout": 300,
"Quorums": [
0,
1
]
}
19 changes: 10 additions & 9 deletions test/v2/v2_test.go → test/v2/correctness/correctness_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package v2
package correctness

import (
"context"
"fmt"
"github.com/Layr-Labs/eigenda/api/clients/v2"
auth "github.com/Layr-Labs/eigenda/core/auth/v2"
"github.com/Layr-Labs/eigenda/test/v2/client"
"github.com/docker/go-units"
gethcommon "github.com/ethereum/go-ethereum/common"
"strings"
Expand All @@ -28,12 +29,12 @@ func testBasicDispersal(
payload []byte,
quorums []core.QuorumID) error {

client := getClient(t)
c := client.GetClient(t)

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()

err := client.DisperseAndVerify(ctx, payload, quorums, rand.Uint32())
err := c.DisperseAndVerify(ctx, payload, quorums, rand.Uint32())
if err != nil {
return fmt.Errorf("failed to disperse and verify: %v", err)
}
Expand Down Expand Up @@ -100,7 +101,7 @@ func TestMediumBlobDispersal(t *testing.T) {
// Disperse a medium payload (between 1MB and 2MB).
func TestLargeBlobDispersal(t *testing.T) {
rand := random.NewTestRandom(t)
dataLength := int(rand.Uint64n(targetConfig.MaxBlobSize/2) + targetConfig.MaxBlobSize/4)
dataLength := int(rand.Uint64n(client.GetConfig(t).MaxBlobSize/2) + client.GetConfig(t).MaxBlobSize/4)
payload := rand.Bytes(dataLength)
paddedPayload := codec.ConvertByPaddingEmptyByte(payload)
err := testBasicDispersal(t, rand, paddedPayload, []core.QuorumID{0, 1})
Expand All @@ -119,7 +120,7 @@ func TestSmallBlobDispersalSingleQuorum(t *testing.T) {
// Disperse a blob that is exactly at the maximum size after padding (16MB)
func TestMaximumSizedBlobDispersal(t *testing.T) {
rand := random.NewTestRandom(t)
dataLength := int(targetConfig.MaxBlobSize)
dataLength := int(client.GetConfig(t).MaxBlobSize)
payload := rand.Bytes(dataLength)
paddedPayload := codec.ConvertByPaddingEmptyByte(payload)[:dataLength]

Expand All @@ -130,7 +131,7 @@ func TestMaximumSizedBlobDispersal(t *testing.T) {
// Disperse a blob that is too large (>16MB after padding)
func TestTooLargeBlobDispersal(t *testing.T) {
rand := random.NewTestRandom(t)
dataLength := int(targetConfig.MaxBlobSize) + 1
dataLength := int(client.GetConfig(t).MaxBlobSize) + 1
payload := rand.Bytes(dataLength)
paddedPayload := codec.ConvertByPaddingEmptyByte(payload)[:dataLength+1]

Expand All @@ -141,7 +142,7 @@ func TestTooLargeBlobDispersal(t *testing.T) {

func TestDoubleDispersal(t *testing.T) {
rand := random.NewTestRandom(t)
c := getClient(t)
c := client.GetClient(t)

payload := rand.VariableBytes(units.KiB, 2*units.KiB)
paddedPayload := codec.ConvertByPaddingEmptyByte(payload)
Expand All @@ -161,7 +162,7 @@ func TestDoubleDispersal(t *testing.T) {

func TestUnauthorizedGetChunks(t *testing.T) {
rand := random.NewTestRandom(t)
c := getClient(t)
c := client.GetClient(t)

payload := rand.VariableBytes(units.KiB, 2*units.KiB)
paddedPayload := codec.ConvertByPaddingEmptyByte(payload)
Expand Down Expand Up @@ -191,7 +192,7 @@ func TestUnauthorizedGetChunks(t *testing.T) {
func TestDispersalWithInvalidSignature(t *testing.T) {
rand := random.NewTestRandom(t)

c := getClient(t)
c := client.GetClient(t)

// Create a dispersal client with a random key
signer, err := auth.NewLocalBlobRequestSigner(fmt.Sprintf("%x", rand.Bytes(32)))
Expand Down
11 changes: 6 additions & 5 deletions test/v2/load_generator.go → test/v2/load/load_generator.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package v2
package load

import (
"context"
"fmt"
"github.com/Layr-Labs/eigenda/common/testutils/random"
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/encoding/utils/codec"
"github.com/Layr-Labs/eigenda/test/v2/client"
"github.com/docker/go-units"
"math/rand"
"sync/atomic"
Expand Down Expand Up @@ -55,8 +56,8 @@ type LoadGenerator struct {

// The configuration for the load generator.
config *LoadGeneratorConfig
// The test client to use for the load test.
client *TestClient
// The test client to use for the load test.
client *client.TestClient
// The random number generator to use for the load test.
rand *random.TestRandom
// The time between starting each blob submission.
Expand All @@ -74,7 +75,7 @@ type LoadGenerator struct {
// NewLoadGenerator creates a new LoadGenerator.
func NewLoadGenerator(
config *LoadGeneratorConfig,
client *TestClient,
client *client.TestClient,
rand *random.TestRandom) *LoadGenerator {

submissionFrequency := config.BytesPerSecond / config.AverageBlobSize
Expand All @@ -85,7 +86,7 @@ func NewLoadGenerator(
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)

metrics := newLoadGeneratorMetrics(client.metrics.registry)
metrics := newLoadGeneratorMetrics(client.MetricsRegistry)

return &LoadGenerator{
ctx: ctx,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package v2
package load

import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

const namespace = "eigenda_test_client"

// loadGeneratorMetrics encapsulates the metrics for the load generator.
type loadGeneratorMetrics struct {
operationsInFlight *prometheus.GaugeVec
Expand Down
5 changes: 3 additions & 2 deletions test/v2/load_test.go → test/v2/load/load_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package v2
package load

import (
"github.com/Layr-Labs/eigenda/common/testutils/random"
"github.com/Layr-Labs/eigenda/test/v2/client"
"github.com/docker/go-units"
"os"
"testing"
)

func TestLightLoad(t *testing.T) {
rand := random.NewTestRandom(t)
c := getClient(t)
c := client.GetClient(t)

config := DefaultLoadGeneratorConfig()
config.AverageBlobSize = 100 * units.KiB
Expand Down

0 comments on commit c809091

Please sign in to comment.