// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ip_test

import (
	"math/rand"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"gvisor.dev/gvisor/pkg/sync"
	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/faketime"
	"gvisor.dev/gvisor/pkg/tcpip/network/internal/ip"
)

const maxUnsolicitedReportDelay = time.Second

var _ ip.MulticastGroupProtocol = (*mockMulticastGroupProtocol)(nil)

type mockMulticastGroupProtocolProtectedFields struct {
	sync.RWMutex

	genericMulticastGroup    ip.GenericMulticastProtocolState
	sendReportGroupAddrCount map[tcpip.Address]int
	sendLeaveGroupAddrCount  map[tcpip.Address]int
	makeQueuePackets         bool
	disabled                 bool
}

type mockMulticastGroupProtocol struct {
	t *testing.T

	mu mockMulticastGroupProtocolProtectedFields
}

func (m *mockMulticastGroupProtocol) init(opts ip.GenericMulticastProtocolOptions) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.initLocked()
	opts.Protocol = m
	m.mu.genericMulticastGroup.Init(&m.mu.RWMutex, opts)
}

func (m *mockMulticastGroupProtocol) initLocked() {
	m.mu.sendReportGroupAddrCount = make(map[tcpip.Address]int)
	m.mu.sendLeaveGroupAddrCount = make(map[tcpip.Address]int)
}

func (m *mockMulticastGroupProtocol) setEnabled(v bool) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.disabled = !v
}

func (m *mockMulticastGroupProtocol) setQueuePackets(v bool) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.makeQueuePackets = v
}

func (m *mockMulticastGroupProtocol) joinGroup(addr tcpip.Address) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.genericMulticastGroup.JoinGroupLocked(addr)
}

func (m *mockMulticastGroupProtocol) leaveGroup(addr tcpip.Address) bool {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.mu.genericMulticastGroup.LeaveGroupLocked(addr)
}

func (m *mockMulticastGroupProtocol) handleReport(addr tcpip.Address) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.genericMulticastGroup.HandleReportLocked(addr)
}

func (m *mockMulticastGroupProtocol) handleQuery(addr tcpip.Address, maxRespTime time.Duration) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.genericMulticastGroup.HandleQueryLocked(addr, maxRespTime)
}

func (m *mockMulticastGroupProtocol) isLocallyJoined(addr tcpip.Address) bool {
	m.mu.RLock()
	defer m.mu.RUnlock()
	return m.mu.genericMulticastGroup.IsLocallyJoinedRLocked(addr)
}

func (m *mockMulticastGroupProtocol) makeAllNonMember() {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.genericMulticastGroup.MakeAllNonMemberLocked()
}

func (m *mockMulticastGroupProtocol) initializeGroups() {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.genericMulticastGroup.InitializeGroupsLocked()
}

func (m *mockMulticastGroupProtocol) sendQueuedReports() {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.mu.genericMulticastGroup.SendQueuedReportsLocked()
}

// Enabled implements ip.MulticastGroupProtocol.
//
// Precondition: m.mu must be read locked.
func (m *mockMulticastGroupProtocol) Enabled() bool {
	if m.mu.TryLock() {
		m.mu.Unlock()
		m.t.Fatal("got write lock, expected to not take the lock; generic multicast protocol must take the read or write lock before calling Enabled")
	}

	return !m.mu.disabled
}

// SendReport implements ip.MulticastGroupProtocol.
//
// Precondition: m.mu must be locked.
func (m *mockMulticastGroupProtocol) SendReport(groupAddress tcpip.Address) (bool, tcpip.Error) {
	if m.mu.TryLock() {
		m.mu.Unlock()
		m.t.Fatalf("got write lock, expected to not take the lock; generic multicast protocol must take the write lock before sending report for %s", groupAddress)
	}
	if m.mu.TryRLock() {
		m.mu.RUnlock()
		m.t.Fatalf("got read lock, expected to not take the lock; generic multicast protocol must take the write lock before sending report for %s", groupAddress)
	}

	m.mu.sendReportGroupAddrCount[groupAddress]++
	return !m.mu.makeQueuePackets, nil
}

// SendLeave implements ip.MulticastGroupProtocol.
//
// Precondition: m.mu must be locked.
func (m *mockMulticastGroupProtocol) SendLeave(groupAddress tcpip.Address) tcpip.Error {
	if m.mu.TryLock() {
		m.mu.Unlock()
		m.t.Fatalf("got write lock, expected to not take the lock; generic multicast protocol must take the write lock before sending leave for %s", groupAddress)
	}
	if m.mu.TryRLock() {
		m.mu.RUnlock()
		m.t.Fatalf("got read lock, expected to not take the lock; generic multicast protocol must take the write lock before sending leave for %s", groupAddress)
	}

	m.mu.sendLeaveGroupAddrCount[groupAddress]++
	return nil
}

func (m *mockMulticastGroupProtocol) check(sendReportGroupAddresses []tcpip.Address, sendLeaveGroupAddresses []tcpip.Address) string {
	m.mu.Lock()
	defer m.mu.Unlock()

	sendReportGroupAddrCount := make(map[tcpip.Address]int)
	for _, a := range sendReportGroupAddresses {
		sendReportGroupAddrCount[a] = 1
	}

	sendLeaveGroupAddrCount := make(map[tcpip.Address]int)
	for _, a := range sendLeaveGroupAddresses {
		sendLeaveGroupAddrCount[a] = 1
	}

	diff := cmp.Diff(
		&mockMulticastGroupProtocol{
			mu: mockMulticastGroupProtocolProtectedFields{
				sendReportGroupAddrCount: sendReportGroupAddrCount,
				sendLeaveGroupAddrCount:  sendLeaveGroupAddrCount,
			},
		},
		m,
		cmp.AllowUnexported(mockMulticastGroupProtocol{}),
		cmp.AllowUnexported(mockMulticastGroupProtocolProtectedFields{}),
		// ignore mockMulticastGroupProtocol.mu and mockMulticastGroupProtocol.t
		cmp.FilterPath(
			func(p cmp.Path) bool {
				switch p.Last().String() {
				case ".RWMutex", ".t", ".makeQueuePackets", ".disabled", ".genericMulticastGroup":
					return true
				}
				return false
			},
			cmp.Ignore(),
		),
	)
	m.initLocked()
	return diff
}

func TestJoinGroup(t *testing.T) {
	tests := []struct {
		name              string
		addr              tcpip.Address
		shouldSendReports bool
	}{
		{
			name:              "Normal group",
			addr:              addr1,
			shouldSendReports: true,
		},
		{
			name:              "All-nodes group",
			addr:              addr2,
			shouldSendReports: false,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			mgp := mockMulticastGroupProtocol{t: t}
			clock := faketime.NewManualClock()

			mgp.init(ip.GenericMulticastProtocolOptions{
				Rand:                      rand.New(rand.NewSource(0)),
				Clock:                     clock,
				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
				AllNodesAddress:           addr2,
			})

			// Joining a group should send a report immediately and another after
			// a random interval between 0 and the maximum unsolicited report delay.
			mgp.joinGroup(test.addr)
			if test.shouldSendReports {
				if diff := mgp.check([]tcpip.Address{test.addr} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
				}

				// Generic multicast protocol timers are expected to take the job mutex.
				clock.Advance(maxUnsolicitedReportDelay)
				if diff := mgp.check([]tcpip.Address{test.addr} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
				}
			}

			// Should have no more messages to send.
			clock.Advance(time.Hour)
			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestLeaveGroup(t *testing.T) {
	tests := []struct {
		name               string
		addr               tcpip.Address
		shouldSendMessages bool
	}{
		{
			name:               "Normal group",
			addr:               addr1,
			shouldSendMessages: true,
		},
		{
			name:               "All-nodes group",
			addr:               addr2,
			shouldSendMessages: false,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			mgp := mockMulticastGroupProtocol{t: t}
			clock := faketime.NewManualClock()

			mgp.init(ip.GenericMulticastProtocolOptions{
				Rand:                      rand.New(rand.NewSource(1)),
				Clock:                     clock,
				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
				AllNodesAddress:           addr2,
			})

			mgp.joinGroup(test.addr)
			if test.shouldSendMessages {
				if diff := mgp.check([]tcpip.Address{test.addr} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
					t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
				}
			}

			// Leaving a group should send a leave report immediately and cancel any
			// delayed reports.
			{

				if !mgp.leaveGroup(test.addr) {
					t.Fatalf("got mgp.leaveGroup(%s) = false, want = true", test.addr)
				}
			}
			if test.shouldSendMessages {
				if diff := mgp.check(nil /* sendReportGroupAddresses */, []tcpip.Address{test.addr} /* sendLeaveGroupAddresses */); diff != "" {
					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
				}
			}

			// Should have no more messages to send.
			//
			// Generic multicast protocol timers are expected to take the job mutex.
			clock.Advance(time.Hour)
			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestHandleReport(t *testing.T) {
	tests := []struct {
		name             string
		reportAddr       tcpip.Address
		expectReportsFor []tcpip.Address
	}{
		{
			name:             "Unpecified empty",
			reportAddr:       "",
			expectReportsFor: []tcpip.Address{addr1, addr2},
		},
		{
			name:             "Unpecified any",
			reportAddr:       "\x00",
			expectReportsFor: []tcpip.Address{addr1, addr2},
		},
		{
			name:             "Specified",
			reportAddr:       addr1,
			expectReportsFor: []tcpip.Address{addr2},
		},
		{
			name:             "Specified all-nodes",
			reportAddr:       addr3,
			expectReportsFor: []tcpip.Address{addr1, addr2},
		},
		{
			name:             "Specified other",
			reportAddr:       addr4,
			expectReportsFor: []tcpip.Address{addr1, addr2},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			mgp := mockMulticastGroupProtocol{t: t}
			clock := faketime.NewManualClock()

			mgp.init(ip.GenericMulticastProtocolOptions{
				Rand:                      rand.New(rand.NewSource(2)),
				Clock:                     clock,
				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
				AllNodesAddress:           addr3,
			})

			mgp.joinGroup(addr1)
			if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
			mgp.joinGroup(addr2)
			if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
			mgp.joinGroup(addr3)
			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}

			// Receiving a report for a group we have a timer scheduled for should
			// cancel our delayed report timer for the group.
			mgp.handleReport(test.reportAddr)
			if len(test.expectReportsFor) != 0 {
				// Generic multicast protocol timers are expected to take the job mutex.
				clock.Advance(maxUnsolicitedReportDelay)
				if diff := mgp.check(test.expectReportsFor /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
					t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
				}
			}

			// Should have no more messages to send.
			clock.Advance(time.Hour)
			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestHandleQuery(t *testing.T) {
	tests := []struct {
		name                    string
		queryAddr               tcpip.Address
		maxDelay                time.Duration
		expectQueriedReportsFor []tcpip.Address
		expectDelayedReportsFor []tcpip.Address
	}{
		{
			name:                    "Unpecified empty",
			queryAddr:               "",
			maxDelay:                0,
			expectQueriedReportsFor: []tcpip.Address{addr1, addr2},
			expectDelayedReportsFor: nil,
		},
		{
			name:                    "Unpecified any",
			queryAddr:               "\x00",
			maxDelay:                1,
			expectQueriedReportsFor: []tcpip.Address{addr1, addr2},
			expectDelayedReportsFor: nil,
		},
		{
			name:                    "Specified",
			queryAddr:               addr1,
			maxDelay:                2,
			expectQueriedReportsFor: []tcpip.Address{addr1},
			expectDelayedReportsFor: []tcpip.Address{addr2},
		},
		{
			name:                    "Specified all-nodes",
			queryAddr:               addr3,
			maxDelay:                3,
			expectQueriedReportsFor: nil,
			expectDelayedReportsFor: []tcpip.Address{addr1, addr2},
		},
		{
			name:                    "Specified other",
			queryAddr:               addr4,
			maxDelay:                4,
			expectQueriedReportsFor: nil,
			expectDelayedReportsFor: []tcpip.Address{addr1, addr2},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			mgp := mockMulticastGroupProtocol{t: t}
			clock := faketime.NewManualClock()

			mgp.init(ip.GenericMulticastProtocolOptions{
				Rand:                      rand.New(rand.NewSource(3)),
				Clock:                     clock,
				MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
				AllNodesAddress:           addr3,
			})

			mgp.joinGroup(addr1)
			if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
			mgp.joinGroup(addr2)
			if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
			mgp.joinGroup(addr3)
			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}

			// Receiving a query should make us reschedule our delayed report timer
			// to some time within the new max response delay.
			mgp.handleQuery(test.queryAddr, test.maxDelay)
			clock.Advance(test.maxDelay)
			if diff := mgp.check(test.expectQueriedReportsFor /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}

			// The groups that were not affected by the query should still send a
			// report after the max unsolicited report delay.
			clock.Advance(maxUnsolicitedReportDelay)
			if diff := mgp.check(test.expectDelayedReportsFor /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}

			// Should have no more messages to send.
			clock.Advance(time.Hour)
			if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
				t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestJoinCount(t *testing.T) {
	mgp := mockMulticastGroupProtocol{t: t}
	clock := faketime.NewManualClock()

	mgp.init(ip.GenericMulticastProtocolOptions{
		Rand:                      rand.New(rand.NewSource(4)),
		Clock:                     clock,
		MaxUnsolicitedReportDelay: time.Second,
	})

	// Set the join count to 2 for a group.
	mgp.joinGroup(addr1)
	if !mgp.isLocallyJoined(addr1) {
		t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
	}
	// Only the first join should trigger a report to be sent.
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	mgp.joinGroup(addr1)
	if !mgp.isLocallyJoined(addr1) {
		t.Errorf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
	}
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	if t.Failed() {
		t.FailNow()
	}

	// Group should still be considered joined after leaving once.
	if !mgp.leaveGroup(addr1) {
		t.Errorf("got mgp.leaveGroup(%s) = false, want = true", addr1)
	}
	if !mgp.isLocallyJoined(addr1) {
		t.Errorf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
	}
	// A leave report should only be sent once the join count reaches 0.
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	if t.Failed() {
		t.FailNow()
	}

	// Leaving once more should actually remove us from the group.
	if !mgp.leaveGroup(addr1) {
		t.Errorf("got mgp.leaveGroup(%s) = false, want = true", addr1)
	}
	if mgp.isLocallyJoined(addr1) {
		t.Errorf("got mgp.isLocallyJoined(%s) = true, want = false", addr1)
	}
	if diff := mgp.check(nil /* sendReportGroupAddresses */, []tcpip.Address{addr1} /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	if t.Failed() {
		t.FailNow()
	}

	// Group should no longer be joined so we should not have anything to
	// leave.
	if mgp.leaveGroup(addr1) {
		t.Errorf("got mgp.leaveGroup(%s) = true, want = false", addr1)
	}
	if mgp.isLocallyJoined(addr1) {
		t.Errorf("got mgp.isLocallyJoined(%s) = true, want = false", addr1)
	}
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Should have no more messages to send.
	//
	// Generic multicast protocol timers are expected to take the job mutex.
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
}

func TestMakeAllNonMemberAndInitialize(t *testing.T) {
	mgp := mockMulticastGroupProtocol{t: t}
	clock := faketime.NewManualClock()

	mgp.init(ip.GenericMulticastProtocolOptions{
		Rand:                      rand.New(rand.NewSource(3)),
		Clock:                     clock,
		MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
		AllNodesAddress:           addr3,
	})

	mgp.joinGroup(addr1)
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	mgp.joinGroup(addr2)
	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	mgp.joinGroup(addr3)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Should send the leave reports for each but still consider them locally
	// joined.
	mgp.makeAllNonMember()
	if diff := mgp.check(nil /* sendReportGroupAddresses */, []tcpip.Address{addr1, addr2} /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	// Generic multicast protocol timers are expected to take the job mutex.
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	for _, group := range []tcpip.Address{addr1, addr2, addr3} {
		if !mgp.isLocallyJoined(group) {
			t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", group)
		}
	}

	// Should send the initial set of unsolcited reports.
	mgp.initializeGroups()
	if diff := mgp.check([]tcpip.Address{addr1, addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	clock.Advance(maxUnsolicitedReportDelay)
	if diff := mgp.check([]tcpip.Address{addr1, addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Should have no more messages to send.
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
}

// TestGroupStateNonMember tests that groups do not send packets when in the
// non-member state, but are still considered locally joined.
func TestGroupStateNonMember(t *testing.T) {
	mgp := mockMulticastGroupProtocol{t: t}
	clock := faketime.NewManualClock()

	mgp.init(ip.GenericMulticastProtocolOptions{
		Rand:                      rand.New(rand.NewSource(3)),
		Clock:                     clock,
		MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
	})
	mgp.setEnabled(false)

	// Joining groups should not send any reports.
	mgp.joinGroup(addr1)
	if !mgp.isLocallyJoined(addr1) {
		t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", addr1)
	}
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	mgp.joinGroup(addr2)
	if !mgp.isLocallyJoined(addr1) {
		t.Fatalf("got mgp.isLocallyJoined(%s) = false, want = true", addr2)
	}
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Receiving a query should not send any reports.
	mgp.handleQuery(addr1, time.Nanosecond)
	// Generic multicast protocol timers are expected to take the job mutex.
	clock.Advance(time.Nanosecond)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Leaving groups should not send any leave messages.
	if !mgp.leaveGroup(addr1) {
		t.Errorf("got mgp.leaveGroup(%s) = false, want = true", addr2)
	}
	if mgp.isLocallyJoined(addr1) {
		t.Errorf("got mgp.isLocallyJoined(%s) = true, want = false", addr2)
	}
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
}

func TestQueuedPackets(t *testing.T) {
	clock := faketime.NewManualClock()
	mgp := mockMulticastGroupProtocol{t: t}
	mgp.init(ip.GenericMulticastProtocolOptions{
		Rand:                      rand.New(rand.NewSource(4)),
		Clock:                     clock,
		MaxUnsolicitedReportDelay: maxUnsolicitedReportDelay,
	})

	// Joining should trigger a SendReport, but mgp should report that we did not
	// send the packet.
	mgp.setQueuePackets(true)
	mgp.joinGroup(addr1)
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// The delayed report timer should have been cancelled since we did not send
	// the initial report earlier.
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Mock being able to successfully send the report.
	mgp.setQueuePackets(false)
	mgp.sendQueuedReports()
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// The delayed report (sent after the initial report) should now be sent.
	clock.Advance(maxUnsolicitedReportDelay)
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Should not have anything else to send (we should be idle).
	mgp.sendQueuedReports()
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Receive a query but mock being unable to send reports again.
	mgp.setQueuePackets(true)
	mgp.handleQuery(addr1, time.Nanosecond)
	clock.Advance(time.Nanosecond)
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Mock being able to send reports again - we should have a packet queued to
	// send.
	mgp.setQueuePackets(false)
	mgp.sendQueuedReports()
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Should not have anything else to send.
	mgp.sendQueuedReports()
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Receive a query again, but mock being unable to send reports.
	mgp.setQueuePackets(true)
	mgp.handleQuery(addr1, time.Nanosecond)
	clock.Advance(time.Nanosecond)
	if diff := mgp.check([]tcpip.Address{addr1} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Receiving a report should should transition us into the idle member state,
	// even if we had a packet queued. We should no longer have any packets to
	// send.
	mgp.handleReport(addr1)
	mgp.sendQueuedReports()
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// When we fail to send the initial set of reports, incoming reports should
	// not affect a newly joined group's reports from being sent.
	mgp.setQueuePackets(true)
	mgp.joinGroup(addr2)
	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	mgp.handleReport(addr2)
	// Attempting to send queued reports while still unable to send reports should
	// not change the host state.
	mgp.sendQueuedReports()
	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	// Mock being able to successfully send the report.
	mgp.setQueuePackets(false)
	mgp.sendQueuedReports()
	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
	// The delayed report (sent after the initial report) should now be sent.
	clock.Advance(maxUnsolicitedReportDelay)
	if diff := mgp.check([]tcpip.Address{addr2} /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Errorf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}

	// Should not have anything else to send.
	mgp.sendQueuedReports()
	clock.Advance(time.Hour)
	if diff := mgp.check(nil /* sendReportGroupAddresses */, nil /* sendLeaveGroupAddresses */); diff != "" {
		t.Fatalf("mockMulticastGroupProtocol mismatch (-want +got):\n%s", diff)
	}
}
