Skip to content

Commit 0d6a2ae

Browse files
cache: add a synthetic delay to the cache server
Signed-off-by: Steve Kuznetsov <[email protected]>
1 parent f18044f commit 0d6a2ae

File tree

6 files changed

+23
-5
lines changed

6 files changed

+23
-5
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ test-e2e-sharded: require-kind build-all build-kind-images
317317
kind get kubeconfig > "$(WORK_DIR)/.kcp/kind.kubeconfig"
318318
rm -f "$(WORK_DIR)/.kcp/ready-to-test"
319319
UNSAFE_E2E_HACK_DISABLE_ETCD_FSYNC=true NO_GORUN=1 \
320-
./bin/sharded-test-server --quiet --v=2 --log-dir-path="$(LOG_DIR)" --work-dir-path="$(WORK_DIR)" --shard-run-virtual-workspaces=false $(TEST_SERVER_ARGS) --number-of-shards=$(SHARDS) 2>&1 & PID=$$!; echo "PID $$PID" && \
320+
./bin/sharded-test-server --quiet --v=2 --log-dir-path="$(LOG_DIR)" --work-dir-path="$(WORK_DIR)" --shard-run-virtual-workspaces=false $(TEST_SERVER_ARGS) --number-of-shards=$(SHARDS) --cache-synthetic-delay=500ms 2>&1 & PID=$$!; echo "PID $$PID" && \
321321
trap 'kill -TERM $$PID' TERM INT EXIT && \
322322
while [ ! -f "$(WORK_DIR)/.kcp/ready-to-test" ]; do sleep 1; done && \
323323
NO_GORUN=1 GOOS=$(OS) GOARCH=$(ARCH) \

cmd/sharded-test-server/cache.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import (
3939
"github.com/kcp-dev/kcp/test/e2e/framework"
4040
)
4141

42-
func startCacheServer(ctx context.Context, logDirPath, workingDir string) (<-chan error, string, error) {
42+
func startCacheServer(ctx context.Context, logDirPath, workingDir string, syntheticDelay time.Duration) (<-chan error, string, error) {
4343
cyan := color.New(color.BgHiCyan, color.FgHiWhite).SprintFunc()
4444
inverse := color.New(color.BgHiWhite, color.FgHiCyan).SprintFunc()
4545
out := lineprefix.New(
@@ -59,6 +59,7 @@ func startCacheServer(ctx context.Context, logDirPath, workingDir string) (<-cha
5959
"--embedded-etcd-client-port=8010",
6060
"--embedded-etcd-peer-port=8011",
6161
fmt.Sprintf("--secure-port=%d", cachePort),
62+
fmt.Sprintf("--synthetic-delay=%s", syntheticDelay.String()),
6263
)
6364
fmt.Fprintf(out, "running: %v\n", strings.Join(commandLine, " "))
6465
cmd := exec.CommandContext(ctx, commandLine[0], commandLine[1:]...) //nolint:gosec

cmd/sharded-test-server/main.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"os"
2525
"path/filepath"
2626
"strings"
27+
"time"
2728

2829
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2930
"k8s.io/apimachinery/pkg/types"
@@ -46,6 +47,7 @@ func main() {
4647
logDirPath := flag.String("log-dir-path", "", "Path to the log files. If empty, log files are stored in the dot directories.")
4748
workDirPath := flag.String("work-dir-path", "", "Path to the working directory where the .kcp* dot directories are created. If empty, the working directory is the current directory.")
4849
numberOfShards := flag.Int("number-of-shards", 1, "The number of shards to create. The first created is assumed root.")
50+
cacheSyntheticDelay := flag.Duration("cache-synthetic-delay", 0, "The duration of time the cache server will inject a delay for to all inbound requests.")
4951
quiet := flag.Bool("quiet", false, "Suppress output of the subprocesses")
5052

5153
// split flags into --proxy-*, --shard-* and everything else (generic). The former are
@@ -62,13 +64,13 @@ func main() {
6264
}
6365
flag.CommandLine.Parse(genericFlags) //nolint:errcheck
6466

65-
if err := start(proxyFlags, shardFlags, *logDirPath, *workDirPath, *numberOfShards, *quiet); err != nil {
67+
if err := start(proxyFlags, shardFlags, *logDirPath, *workDirPath, *numberOfShards, *quiet, *cacheSyntheticDelay); err != nil {
6668
fmt.Println(err.Error())
6769
os.Exit(1)
6870
}
6971
}
7072

71-
func start(proxyFlags, shardFlags []string, logDirPath, workDirPath string, numberOfShards int, quiet bool) error {
73+
func start(proxyFlags, shardFlags []string, logDirPath, workDirPath string, numberOfShards int, quiet bool, cacheSyntheticDelay time.Duration) error {
7274
// We use a shutdown context to know that it's time to gather metrics, before stopping the shards, proxy, etc.
7375
shutdownCtx, shutdownCancel := context.WithCancel(genericapiserver.SetupSignalContext())
7476
defer shutdownCancel()
@@ -186,7 +188,7 @@ func start(proxyFlags, shardFlags []string, logDirPath, workDirPath string, numb
186188

187189
cacheServerErrCh := make(chan indexErrTuple)
188190
cacheServerConfigPath := ""
189-
cacheServerCh, configPath, err := startCacheServer(ctx, logDirPath, workDirPath)
191+
cacheServerCh, configPath, err := startCacheServer(ctx, logDirPath, workDirPath, cacheSyntheticDelay)
190192
if err != nil {
191193
return fmt.Errorf("error starting the cache server: %w", err)
192194
}

pkg/cache/server/config.go

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ func NewConfig(opts *cacheserveroptions.CompletedOptions, optionalLocalShardRest
141141
apiHandler = filters.WithClusterScope(apiHandler)
142142
apiHandler = WithShardScope(apiHandler)
143143
apiHandler = WithServiceScope(apiHandler)
144+
apiHandler = WithSyntheticDelay(apiHandler, opts.SyntheticDelay)
144145
return apiHandler
145146
}
146147

pkg/cache/server/handler.go

+9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"net/url"
2323
"regexp"
2424
"strings"
25+
"time"
2526

2627
apierrors "k8s.io/apimachinery/pkg/api/errors"
2728
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -141,3 +142,11 @@ func WithServiceScope(handler http.Handler) http.Handler {
141142
handler.ServeHTTP(w, req)
142143
})
143144
}
145+
146+
// WithSyntheticDelay injects a synthetic delay to calls, to exacerbate timing issues and expose inconsistent client behavior.
147+
func WithSyntheticDelay(handler http.Handler, delay time.Duration) http.Handler {
148+
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
149+
time.Sleep(delay)
150+
handler.ServeHTTP(w, req)
151+
})
152+
}

pkg/cache/server/options/options.go

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package options
1818

1919
import (
20+
"time"
21+
2022
"github.com/spf13/pflag"
2123

2224
genericoptions "k8s.io/apiserver/pkg/server/options"
@@ -34,6 +36,7 @@ type Options struct {
3436
Authorization *genericoptions.DelegatingAuthorizationOptions
3537
APIEnablement *genericoptions.APIEnablementOptions
3638
EmbeddedEtcd etcdoptions.Options
39+
SyntheticDelay time.Duration
3740
}
3841

3942
type completedOptions struct {
@@ -44,6 +47,7 @@ type completedOptions struct {
4447
Authorization *genericoptions.DelegatingAuthorizationOptions
4548
APIEnablement *genericoptions.APIEnablementOptions
4649
EmbeddedEtcd etcdoptions.CompletedOptions
50+
SyntheticDelay time.Duration
4751
}
4852

4953
type CompletedOptions struct {
@@ -113,4 +117,5 @@ func (o *Options) Complete() (*CompletedOptions, error) {
113117
func (o *Options) AddFlags(fs *pflag.FlagSet) {
114118
o.EmbeddedEtcd.AddFlags(fs)
115119
o.SecureServing.AddFlags(fs)
120+
fs.DurationVar(&o.SyntheticDelay, "synthetic-delay", 0, "The duration of time the cache server will inject a delay for to all inbound requests. Useful for testing.")
116121
}

0 commit comments

Comments
 (0)