From a10910f3981908424493c043d26dfcb4e5f8dc25 Mon Sep 17 00:00:00 2001 From: Steven Angles Date: Mon, 16 Aug 2021 17:04:47 -0400 Subject: admin: Sync server variables (fix #4260) (#4274) * Synchronize server assignment/references to avoid data race * only hold lock during var reassignment --- admin_test.go | 54 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'admin_test.go') diff --git a/admin_test.go b/admin_test.go index cfb4ab7..608a32c 100644 --- a/admin_test.go +++ b/admin_test.go @@ -17,9 +17,28 @@ package caddy import ( "encoding/json" "reflect" + "sync" "testing" ) +var testCfg = []byte(`{ + "apps": { + "http": { + "servers": { + "myserver": { + "listen": ["tcp/localhost:8080-8084"], + "read_timeout": "30s" + }, + "yourserver": { + "listen": ["127.0.0.1:5000"], + "read_header_timeout": "15s" + } + } + } + } + } + `) + func TestUnsyncedConfigAccess(t *testing.T) { // each test is performed in sequence, so // each change builds on the previous ones; @@ -108,25 +127,24 @@ func TestUnsyncedConfigAccess(t *testing.T) { } } +// TestLoadConcurrent exercises Load under concurrent conditions +// and is most useful under test with `-race` enabled. +func TestLoadConcurrent(t *testing.T) { + var wg sync.WaitGroup + + for i := 0; i < 100; i++ { + wg.Add(1) + go func() { + _ = Load(testCfg, true) + wg.Done() + }() + } + + wg.Wait() +} + func BenchmarkLoad(b *testing.B) { for i := 0; i < b.N; i++ { - cfg := []byte(`{ - "apps": { - "http": { - "servers": { - "myserver": { - "listen": ["tcp/localhost:8080-8084"], - "read_timeout": "30s" - }, - "yourserver": { - "listen": ["127.0.0.1:5000"], - "read_header_timeout": "15s" - } - } - } - } - } - `) - Load(cfg, true) + Load(testCfg, true) } } -- cgit v1.2.3