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

channel builder test suite

parent e80cfdb2
......@@ -79,9 +79,9 @@ type channelBuilder struct {
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.
func NewChannelBuilder(cfg ChannelConfig) (*channelBuilder, error) {
func newChannelBuilder(cfg ChannelConfig) (*channelBuilder, error) {
co, err := derive.NewChannelOut()
if err != nil {
return nil, err
......
......@@ -5,31 +5,45 @@ import (
"testing"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
var defaultTestConfig = ChannelConfig{
SeqWindowSize: 15,
ChannelTimeout: 40,
MaxChannelDuration: 1,
SubSafetyMargin: 4,
MaxFrameSize: 120000,
TargetFrameSize: 100000,
TargetNumFrames: 1,
ApproxComprRatio: 0.4,
// ChannelBuilderTestSuite encapsulates testing on the ChannelBuilder.
type ChannelBuilderTestSuite struct {
suite.Suite
channelConfig ChannelConfig
}
// SetupTest sets up the test suite.
func (testSuite *ChannelBuilderTestSuite) SetupTest() {
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
func TestBuilderNextFrame(t *testing.T) {
cb, err := NewChannelBuilder(defaultTestConfig)
require.NoError(t, err)
func (testSuite *ChannelBuilderTestSuite) TestBuilderNextFrame() {
cb, err := newChannelBuilder(testSuite.channelConfig)
testSuite.NoError(err)
// Mock the internals of `channelBuilder.outputFrame`
// to construct a single frame
co := cb.co
var buf bytes.Buffer
fn, err := co.OutputFrame(&buf, defaultTestConfig.MaxFrameSize)
require.NoError(t, err)
fn, err := co.OutputFrame(&buf, testSuite.channelConfig.MaxFrameSize)
testSuite.NoError(err)
// Push one frame into to the channel builder
expectedTx := txID{chID: co.ID(), frameNumber: fn}
......@@ -37,34 +51,34 @@ func TestBuilderNextFrame(t *testing.T) {
cb.PushFrame(expectedTx, expectedBytes)
// 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
constructedTx, constructedBytes := cb.NextFrame()
require.Equal(t, expectedTx, constructedTx)
require.Equal(t, expectedBytes, constructedBytes)
require.Equal(t, 0, cb.NumFrames())
testSuite.Equal(expectedTx, constructedTx)
testSuite.Equal(expectedBytes, constructedBytes)
testSuite.Equal(0, cb.NumFrames())
// The next call should panic since the length of frames is 0
defer func() { _ = recover() }()
cb.NextFrame()
// 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
func TestBuilderWrongFramePanic(t *testing.T) {
cb, err := NewChannelBuilder(defaultTestConfig)
require.NoError(t, err)
func (testSuite *ChannelBuilderTestSuite) TestBuilderWrongFramePanic() {
cb, err := newChannelBuilder(testSuite.channelConfig)
testSuite.NoError(err)
// Mock the internals of `channelBuilder.outputFrame`
// to construct a single frame
co, err := derive.NewChannelOut()
require.NoError(t, err)
testSuite.NoError(err)
var buf bytes.Buffer
fn, err := co.OutputFrame(&buf, defaultTestConfig.MaxFrameSize)
require.NoError(t, err)
fn, err := co.OutputFrame(&buf, testSuite.channelConfig.MaxFrameSize)
testSuite.NoError(err)
// The frame push should panic since we constructed a new channel out
// so the channel out id won't match
......@@ -75,5 +89,5 @@ func TestBuilderWrongFramePanic(t *testing.T) {
cb.PushFrame(tx, buf.Bytes())
// 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 {
return nil
}
cb, err := NewChannelBuilder(s.cfg)
cb, err := newChannelBuilder(s.cfg)
if err != nil {
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