Files
Toshi KikuchiandgVisor bot cde8d6050b iptables test: Implement testCase interface on pointers
Implementing interfaces on value types causes the interface to be
implemented by both the value type and the pointer type of the
implementer. This complicates type assertion as it requires the
assertion to check for both the pointer type and the value type.

PiperOrigin-RevId: 357061063
2021-02-11 14:39:41 -08:00

116 lines
3.5 KiB
Go

// Copyright 2019 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 iptables contains a set of iptables tests implemented as TestCases
package iptables
import (
"context"
"fmt"
"net"
"time"
)
// IPExchangePort is the port the container listens on to receive the IP
// address of the local process.
const IPExchangePort = 2349
// TerminalStatement is the last statement in the test runner.
const TerminalStatement = "Finished!"
// TestTimeout is the timeout used for all tests.
const TestTimeout = 10 * time.Second
// NegativeTimeout is the time tests should wait to establish the negative
// case, i.e. that connections are not made.
const NegativeTimeout = 2 * time.Second
// A TestCase contains one action to run in the container and one to run
// locally. The actions run concurrently and each must succeed for the test
// pass.
type TestCase interface {
// Name returns the name of the test.
Name() string
// ContainerAction runs inside the container. It receives the IP of the
// local process.
ContainerAction(ctx context.Context, ip net.IP, ipv6 bool) error
// LocalAction runs locally. It receives the IP of the container.
LocalAction(ctx context.Context, ip net.IP, ipv6 bool) error
// ContainerSufficient indicates whether ContainerAction's return value
// alone indicates whether the test succeeded.
ContainerSufficient() bool
// LocalSufficient indicates whether LocalAction's return value alone
// indicates whether the test succeeded.
LocalSufficient() bool
}
// baseCase provides defaults for ContainerSufficient and LocalSufficient when
// both actions are required to finish.
type baseCase struct{}
// ContainerSufficient implements TestCase.ContainerSufficient.
func (*baseCase) ContainerSufficient() bool {
return false
}
// LocalSufficient implements TestCase.LocalSufficient.
func (*baseCase) LocalSufficient() bool {
return false
}
// localCase provides defaults for ContainerSufficient and LocalSufficient when
// only the local action is required to finish.
type localCase struct{}
// ContainerSufficient implements TestCase.ContainerSufficient.
func (*localCase) ContainerSufficient() bool {
return false
}
// LocalSufficient implements TestCase.LocalSufficient.
func (*localCase) LocalSufficient() bool {
return true
}
// containerCase provides defaults for ContainerSufficient and LocalSufficient
// when only the container action is required to finish.
type containerCase struct{}
// ContainerSufficient implements TestCase.ContainerSufficient.
func (*containerCase) ContainerSufficient() bool {
return true
}
// LocalSufficient implements TestCase.LocalSufficient.
func (*containerCase) LocalSufficient() bool {
return false
}
// Tests maps test names to TestCase.
//
// New TestCases are added by calling RegisterTestCase in an init function.
var Tests = map[string]TestCase{}
// RegisterTestCase registers tc so it can be run.
func RegisterTestCase(tc TestCase) {
if _, ok := Tests[tc.Name()]; ok {
panic(fmt.Sprintf("TestCase %s already registered.", tc.Name()))
}
Tests[tc.Name()] = tc
}