<commit_before>package congestion_test

import (
	"time"

	"github.com/lucas-clemente/quic-go/congestion"
	"github.com/lucas-clemente/quic-go/protocol"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const kBeta float32 = 0.7 // Default Cubic backoff factor.
const kNumConnections uint32 = 2
const kNConnectionBeta float32 = (float32(kNumConnections) - 1 + kBeta) / float32(kNumConnections)
const kNConnectionAlpha float32 = 3 * float32(kNumConnections) * float32(kNumConnections) * (1 - kNConnectionBeta) / (1 + kNConnectionBeta)

var _ = Describe("Cubic", func() {
	var (
		clock mockClock
		cubic *congestion.Cubic
	)

	BeforeEach(func() {
		clock = mockClock{}
		cubic = congestion.NewCubic(&clock)
	})

	It("works above origin", func() {
		// Convex growth.
		rtt_min := 100 * time.Millisecond
		current_cwnd := protocol.PacketNumber(10)
		expected_cwnd := current_cwnd + 1
		// Initialize the state.
		clock.Advance(time.Millisecond)
		Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(expected_cwnd))
		current_cwnd = expected_cwnd
		// Normal TCP phase.
		for i := 0; i < 48; i++ {
			for n := uint64(1); n < uint64(float32(current_cwnd)/kNConnectionAlpha); n++ {
				// Call once per ACK.
				Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(BeNumerically("~", current_cwnd, 1))
			}
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
			Expect(current_cwnd).To(BeNumerically("~", expected_cwnd, 1))
			expected_cwnd++
		}
		// Cubic phase.
		for i := 0; i < 52; i++ {
			for n := protocol.PacketNumber(1); n < current_cwnd; n++ {
				// Call once per ACK.
				Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(current_cwnd))
			}
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
		}
		// Total time elapsed so far; add min_rtt (0.1s) here as well.
		elapsed_time_s := 10.0 + 0.1
		// |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
		expected_cwnd = protocol.PacketNumber(11 + (elapsed_time_s*elapsed_time_s*elapsed_time_s*410)/1024)
		Expect(current_cwnd).To(Equal(expected_cwnd))
	})

	// TODO: Test copied from Chromium has no assertions
	It("has increasing cwnd stats during convex region", func() {
		rtt_min := 100 * time.Millisecond
		current_cwnd := protocol.PacketNumber(10)
		expected_cwnd := current_cwnd + 1
		// Initialize the state.
		clock.Advance(time.Millisecond)
		expected_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
		current_cwnd = expected_cwnd
		// Testing Reno mode increase.
		for i := 0; i < 48; i++ {
			for n := uint64(1); n < uint64(float32(current_cwnd)/kNConnectionAlpha); n++ {
				// Call once per ACK, causing cwnd growth in Reno mode.
				cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
			}
			// Advance current time so that cwnd update is allowed to happen by Cubic.
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
			expected_cwnd++
		}

		// Testing Cubic mode increase.
		for i := 0; i < 52; i++ {
			for n := protocol.PacketNumber(1); n < current_cwnd; n++ {
				// Call once per ACK.
				cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
			}
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
		}
	})

	It("manages loss events", func() {
		rtt_min := 100 * time.Millisecond
		current_cwnd := protocol.PacketNumber(422)
		expected_cwnd := current_cwnd + 1
		// Initialize the state.
		clock.Advance(time.Millisecond)
		Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(expected_cwnd))
		expected_cwnd = protocol.PacketNumber(float32(current_cwnd) * kNConnectionBeta)
		Expect(cubic.CongestionWindowAfterPacketLoss(current_cwnd)).To(Equal(expected_cwnd))
		expected_cwnd = protocol.PacketNumber(float32(current_cwnd) * kNConnectionBeta)
		Expect(cubic.CongestionWindowAfterPacketLoss(current_cwnd)).To(Equal(expected_cwnd))
	})

	It("works below origin", func() {
		// Concave growth.
		rtt_min := 100 * time.Millisecond
		current_cwnd := protocol.PacketNumber(422)
		expected_cwnd := current_cwnd + 1
		// Initialize the state.
		clock.Advance(time.Millisecond)
		Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(expected_cwnd))
		expected_cwnd = protocol.PacketNumber(float32(current_cwnd) * kNConnectionBeta)
		Expect(cubic.CongestionWindowAfterPacketLoss(current_cwnd)).To(Equal(expected_cwnd))
		current_cwnd = expected_cwnd
		// First update after loss to initialize the epoch.
		current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
		// Cubic phase.
		for i := 0; i < 40; i++ {
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)<commit_msg>remove unnecessary cubic test<commit_after>package congestion_test

import (
	"time"

	"github.com/lucas-clemente/quic-go/congestion"
	"github.com/lucas-clemente/quic-go/protocol"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const kBeta float32 = 0.7 // Default Cubic backoff factor.
const kNumConnections uint32 = 2
const kNConnectionBeta float32 = (float32(kNumConnections) - 1 + kBeta) / float32(kNumConnections)
const kNConnectionAlpha float32 = 3 * float32(kNumConnections) * float32(kNumConnections) * (1 - kNConnectionBeta) / (1 + kNConnectionBeta)

var _ = Describe("Cubic", func() {
	var (
		clock mockClock
		cubic *congestion.Cubic
	)

	BeforeEach(func() {
		clock = mockClock{}
		cubic = congestion.NewCubic(&clock)
	})

	It("works above origin", func() {
		// Convex growth.
		rtt_min := 100 * time.Millisecond
		current_cwnd := protocol.PacketNumber(10)
		expected_cwnd := current_cwnd + 1
		// Initialize the state.
		clock.Advance(time.Millisecond)
		Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(expected_cwnd))
		current_cwnd = expected_cwnd
		// Normal TCP phase.
		for i := 0; i < 48; i++ {
			for n := uint64(1); n < uint64(float32(current_cwnd)/kNConnectionAlpha); n++ {
				// Call once per ACK.
				Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(BeNumerically("~", current_cwnd, 1))
			}
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
			Expect(current_cwnd).To(BeNumerically("~", expected_cwnd, 1))
			expected_cwnd++
		}
		// Cubic phase.
		for i := 0; i < 52; i++ {
			for n := protocol.PacketNumber(1); n < current_cwnd; n++ {
				// Call once per ACK.
				Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(current_cwnd))
			}
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
		}
		// Total time elapsed so far; add min_rtt (0.1s) here as well.
		elapsed_time_s := 10.0 + 0.1
		// |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
		expected_cwnd = protocol.PacketNumber(11 + (elapsed_time_s*elapsed_time_s*elapsed_time_s*410)/1024)
		Expect(current_cwnd).To(Equal(expected_cwnd))
	})

	It("manages loss events", func() {
		rtt_min := 100 * time.Millisecond
		current_cwnd := protocol.PacketNumber(422)
		expected_cwnd := current_cwnd + 1
		// Initialize the state.
		clock.Advance(time.Millisecond)
		Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(expected_cwnd))
		expected_cwnd = protocol.PacketNumber(float32(current_cwnd) * kNConnectionBeta)
		Expect(cubic.CongestionWindowAfterPacketLoss(current_cwnd)).To(Equal(expected_cwnd))
		expected_cwnd = protocol.PacketNumber(float32(current_cwnd) * kNConnectionBeta)
		Expect(cubic.CongestionWindowAfterPacketLoss(current_cwnd)).To(Equal(expected_cwnd))
	})

	It("works below origin", func() {
		// Concave growth.
		rtt_min := 100 * time.Millisecond
		current_cwnd := protocol.PacketNumber(422)
		expected_cwnd := current_cwnd + 1
		// Initialize the state.
		clock.Advance(time.Millisecond)
		Expect(cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)).To(Equal(expected_cwnd))
		expected_cwnd = protocol.PacketNumber(float32(current_cwnd) * kNConnectionBeta)
		Expect(cubic.CongestionWindowAfterPacketLoss(current_cwnd)).To(Equal(expected_cwnd))
		current_cwnd = expected_cwnd
		// First update after loss to initialize the epoch.
		current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
		// Cubic phase.
		for i := 0; i < 40; i++ {
			clock.Advance(100 * time.Millisecond)
			current_cwnd = cubic.CongestionWindowAfterAck(current_cwnd, rtt_min)
{'fraction_non_alphanumeric': 0.12110968644364145, 'fraction_numerical': 0.0254108870497727, 'mean_word_length': 4.708582834331337, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7285763', 'n_tokens_mistral': 3695, 'n_tokens_neox': 3225, 'n_words': 577}