Commit 98a800f8 authored by Andreas Bigger's avatar Andreas Bigger

channel builder test suite

parent e80cfdb2
...@@ -79,9 +79,9 @@ type channelBuilder struct { ...@@ -79,9 +79,9 @@ type channelBuilder struct {
frames []taggedData frames []taggedData
} }
// NewChannelBuilder creates a new channel builder or returns an error if the // newChannelBuilder creates a new channel builder or returns an error if the
// channel out could not be created. // channel out could not be created.
func NewChannelBuilder(cfg ChannelConfig) (*channelBuilder, error) { func newChannelBuilder(cfg ChannelConfig) (*channelBuilder, error) {
co, err := derive.NewChannelOut() co, err := derive.NewChannelOut()
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -5,31 +5,45 @@ import ( ...@@ -5,31 +5,45 @@ import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/suite"
) )
var defaultTestConfig = ChannelConfig{ // ChannelBuilderTestSuite encapsulates testing on the ChannelBuilder.
SeqWindowSize: 15, type ChannelBuilderTestSuite struct {
ChannelTimeout: 40, suite.Suite
MaxChannelDuration: 1, channelConfig ChannelConfig
SubSafetyMargin: 4, }
MaxFrameSize: 120000,
TargetFrameSize: 100000, // SetupTest sets up the test suite.
TargetNumFrames: 1, func (testSuite *ChannelBuilderTestSuite) SetupTest() {
ApproxComprRatio: 0.4, testSuite.channelConfig = ChannelConfig{
SeqWindowSize: 15,
ChannelTimeout: 40,
MaxChannelDuration: 1,
SubSafetyMargin: 4,
MaxFrameSize: 120000,
TargetFrameSize: 100000,
TargetNumFrames: 1,
ApproxComprRatio: 0.4,
}
}
// TestChannelBuilder runs the ChannelBuilderTestSuite.
func TestChannelBuilder(t *testing.T) {
suite.Run(t, new(ChannelBuilderTestSuite))
} }
// TestBuilderNextFrame tests calling NextFrame on a ChannelBuilder with only one frame // TestBuilderNextFrame tests calling NextFrame on a ChannelBuilder with only one frame
func TestBuilderNextFrame(t *testing.T) { func (testSuite *ChannelBuilderTestSuite) TestBuilderNextFrame() {
cb, err := NewChannelBuilder(defaultTestConfig) cb, err := newChannelBuilder(testSuite.channelConfig)
require.NoError(t, err) testSuite.NoError(err)
// Mock the internals of `channelBuilder.outputFrame` // Mock the internals of `channelBuilder.outputFrame`
// to construct a single frame // to construct a single frame
co := cb.co co := cb.co
var buf bytes.Buffer var buf bytes.Buffer
fn, err := co.OutputFrame(&buf, defaultTestConfig.MaxFrameSize) fn, err := co.OutputFrame(&buf, testSuite.channelConfig.MaxFrameSize)
require.NoError(t, err) testSuite.NoError(err)
// Push one frame into to the channel builder // Push one frame into to the channel builder
expectedTx := txID{chID: co.ID(), frameNumber: fn} expectedTx := txID{chID: co.ID(), frameNumber: fn}
...@@ -37,34 +51,34 @@ func TestBuilderNextFrame(t *testing.T) { ...@@ -37,34 +51,34 @@ func TestBuilderNextFrame(t *testing.T) {
cb.PushFrame(expectedTx, expectedBytes) cb.PushFrame(expectedTx, expectedBytes)
// There should only be 1 frame in the channel builder // There should only be 1 frame in the channel builder
require.Equal(t, 1, cb.NumFrames()) testSuite.Equal(1, cb.NumFrames())
// We should be able to increment to the next frame // We should be able to increment to the next frame
constructedTx, constructedBytes := cb.NextFrame() constructedTx, constructedBytes := cb.NextFrame()
require.Equal(t, expectedTx, constructedTx) testSuite.Equal(expectedTx, constructedTx)
require.Equal(t, expectedBytes, constructedBytes) testSuite.Equal(expectedBytes, constructedBytes)
require.Equal(t, 0, cb.NumFrames()) testSuite.Equal(0, cb.NumFrames())
// The next call should panic since the length of frames is 0 // The next call should panic since the length of frames is 0
defer func() { _ = recover() }() defer func() { _ = recover() }()
cb.NextFrame() cb.NextFrame()
// If we get here, `NextFrame` did not panic as expected // If we get here, `NextFrame` did not panic as expected
t.Errorf("did not panic") testSuite.T().Errorf("did not panic")
} }
// TestBuilderInvalidFrameId tests that a panic is thrown when a frame is pushed with an invalid frame id // TestBuilderInvalidFrameId tests that a panic is thrown when a frame is pushed with an invalid frame id
func TestBuilderWrongFramePanic(t *testing.T) { func (testSuite *ChannelBuilderTestSuite) TestBuilderWrongFramePanic() {
cb, err := NewChannelBuilder(defaultTestConfig) cb, err := newChannelBuilder(testSuite.channelConfig)
require.NoError(t, err) testSuite.NoError(err)
// Mock the internals of `channelBuilder.outputFrame` // Mock the internals of `channelBuilder.outputFrame`
// to construct a single frame // to construct a single frame
co, err := derive.NewChannelOut() co, err := derive.NewChannelOut()
require.NoError(t, err) testSuite.NoError(err)
var buf bytes.Buffer var buf bytes.Buffer
fn, err := co.OutputFrame(&buf, defaultTestConfig.MaxFrameSize) fn, err := co.OutputFrame(&buf, testSuite.channelConfig.MaxFrameSize)
require.NoError(t, err) testSuite.NoError(err)
// The frame push should panic since we constructed a new channel out // The frame push should panic since we constructed a new channel out
// so the channel out id won't match // so the channel out id won't match
...@@ -75,5 +89,5 @@ func TestBuilderWrongFramePanic(t *testing.T) { ...@@ -75,5 +89,5 @@ func TestBuilderWrongFramePanic(t *testing.T) {
cb.PushFrame(tx, buf.Bytes()) cb.PushFrame(tx, buf.Bytes())
// If we get here, `PushFrame` did not panic as expected // If we get here, `PushFrame` did not panic as expected
t.Errorf("did not panic") testSuite.T().Errorf("did not panic")
} }
package batcher_test
import (
"math"
"testing"
"github.com/ethereum-optimism/optimism/op-batcher/batcher"
"github.com/stretchr/testify/require"
)
// TestInputThreshold tests the [ChannelConfig.InputThreshold] function.
func TestInputThreshold(t *testing.T) {
// Construct an empty channel config
config := batcher.ChannelConfig{
SeqWindowSize: 15,
ChannelTimeout: 40,
MaxChannelDuration: 1,
SubSafetyMargin: 4,
MaxFrameSize: 120000,
TargetFrameSize: 100000,
TargetNumFrames: 1,
ApproxComprRatio: 0.4,
}
// The input threshold is calculated as: (targetNumFrames * targetFrameSize) / approxComprRatio
// Here we see that 100,000 / 0.4 = 100,000 * 2.5 = 250,000
inputThreshold := config.InputThreshold()
require.Equal(t, uint64(250_000), inputThreshold)
// Set the approximate compression ratio to 0
// Logically, this represents infinite compression,
// so there is no threshold on the size of the input.
// In practice, this should never be set to 0.
config.ApproxComprRatio = 0
// The input threshold will overflow to the max uint64 value
receivedThreshold := config.InputThreshold()
var maxUint64 uint64 = math.MaxUint64
require.Equal(t, maxUint64, receivedThreshold)
}
...@@ -229,7 +229,7 @@ func (s *channelManager) ensurePendingChannel(l1Head eth.BlockID) error { ...@@ -229,7 +229,7 @@ func (s *channelManager) ensurePendingChannel(l1Head eth.BlockID) error {
return nil return nil
} }
cb, err := NewChannelBuilder(s.cfg) cb, err := newChannelBuilder(s.cfg)
if err != nil { if err != nil {
return fmt.Errorf("creating new channel: %w", err) return fmt.Errorf("creating new channel: %w", err)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment