From 9ef9bc0bca95b66c3566085f8241ef658d419e1a Mon Sep 17 00:00:00 2001 From: wy Date: Mon, 19 Feb 2024 12:53:33 +0800 Subject: [PATCH 1/8] add unit-test --- common/chan_utils_test.go | 200 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 common/chan_utils_test.go diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go new file mode 100644 index 00000000..9463c785 --- /dev/null +++ b/common/chan_utils_test.go @@ -0,0 +1,200 @@ +/* + * Copyright 2024 Function Stream Org. + * + * 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 common + +import ( + "context" + "fmt" + "sync" + "testing" + "time" +) + +func TestSendToChannel(t *testing.T) { + + //send data + //The first t.Run is a buffered chan, and the second t.Run is an unbuffered chan + t.Run("send success,Buffered chan", func(t *testing.T) { + c := make(chan string, 1) + ctx := context.Background() + if !SendToChannel(ctx, c, "data") { + t.Fatal("SendToChannel should return true when sending succeeds") + } + value := <-c + // Verify if the received data is correct + if value != "data" { + t.Errorf("expected to receive \"data\" from channel, but received %s", value) + } + }) + + t.Run("send success,Unbuffered chan", func(t *testing.T) { + c := make(chan string) + ctx := context.Background() + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + SendToChannel(ctx, c, "data") + }() + go func() { + defer wg.Done() + value := <-c + // Verify if the received data is correct + if value != "data" { + t.Errorf("expected to receive \"data\" from channel, but received %s", value) + } + }() + wg.Wait() + }) + + //context timeout + //The first t.Run is a test with a timeout setting, but it was successfully sent without timeout + //The second t.Run passes through time.Sleep setting timeout, simulating context timeout + t.Run("context not timeout", func(t *testing.T) { + c := make(chan string, 1) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + if SendToChannel(ctx, c, "hello") { + t.Log("Data sent successfully") + } else { + fmt.Println(SendToChannel(ctx, c, "hello")) + t.Fatal("Failed to send data due to context timeout") + } + select { + case <-c: + t.Log("Successfully received data") + case <-ctx.Done(): + t.Fatal("Channel closed after context timeout") + } + }) + + t.Run("context timeout", func(t *testing.T) { + c := make(chan string, 1) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + if SendToChannel(ctx, c, "data") { + t.Log("Data sent successfully") + } else { + t.Fatal("Failed to send data due to context timeout") + } + + go func() { + time.Sleep(time.Second) // Set timeout + select { + case <-c: + t.Error("Timed out but able to retrieve data") + return + case <-ctx.Done(): + t.Log("No data received due to context timeout") + } + }() + }) + + //incorrect type + //It is not necessary to distinguish between buffered and unbuffered, as it is necessary to test the incorrect type + t.Run("incorrect type", func(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Log("test-ok") + } else { + t.Log("test-fail") + } + }() + c := make(chan int) + ctx := context.Background() + SendToChannel(ctx, c, "incorrect type") + }) +} + +func TestZeroValue(t *testing.T) { + tests := []struct { + Type string + want interface{} + }{ + {Type: "int", want: 0}, + {Type: "string", want: ""}, + {Type: "bool", want: false}, + } + for _, tt := range tests { + t.Run(tt.Type, func(t *testing.T) { + zero := zeroValue[interface{}]() + switch v := zero.(type) { + case int: + if v != 0 { + t.Errorf("zeroValue = %v, want 0", v) + } + case string: + if v != "" { + t.Errorf("zeroValue = %v, want \"\"", v) + } + case bool: + if v != false { + t.Errorf("zeroValue = %v, want false", v) + } + default: + t.Log("ok") + } + }) + } +} + +func TestReceiveFromChannel(t *testing.T) { + + //Since SendToChannel has already been tested, only buffered chan will be considered here + //Successfully received chan data + t.Run("Success", func(t *testing.T) { + ctx := context.Background() + ch := make(chan string, 1) + SendToChannel(ctx, ch, "test-data") + value, _ := ReceiveFromChannel(ctx, ch) + if value != "test-data" { + t.Errorf("Receive failed,Expected value to be \"test-data\", but %s", value) + } + }) + + //context timeout + t.Run("Timeout", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + time.Sleep(10 * time.Millisecond) + ch := make(chan string, 1) + //No need to send data to SendToChannel as the context has been set to expire + value, ok := ReceiveFromChannel(ctx, ch) + if ok { + t.Fatal("Due to timeout setting, it is expected that no value will be received from the channel") + } + if value != "" { + t.Errorf("Expected zero value for int, but %s", value) + } + }) + + //context canceled + t.Run("Canceled", func(t *testing.T) { + + ctx, cancel := context.WithCancel(context.Background()) + //Cancel context + cancel() + ch := make(chan string, 1) + value, ok := ReceiveFromChannel(ctx, ch) + if ok { + t.Fatal("Expected no value to be received from channel due to context cancellation") + } + if value != "" { + t.Errorf("Expected zero value for int, but %s", value) + } + }) +} From 9dfdb61e58c14a41bbd8524375ec48f012dfcf83 Mon Sep 17 00:00:00 2001 From: wy Date: Mon, 19 Feb 2024 12:57:04 +0800 Subject: [PATCH 2/8] add unit-test --- common/chan_utils_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go index 9463c785..73a1ed70 100644 --- a/common/chan_utils_test.go +++ b/common/chan_utils_test.go @@ -178,7 +178,7 @@ func TestReceiveFromChannel(t *testing.T) { t.Fatal("Due to timeout setting, it is expected that no value will be received from the channel") } if value != "" { - t.Errorf("Expected zero value for int, but %s", value) + t.Errorf("Expected zero value for string, but %s", value) } }) @@ -194,7 +194,7 @@ func TestReceiveFromChannel(t *testing.T) { t.Fatal("Expected no value to be received from channel due to context cancellation") } if value != "" { - t.Errorf("Expected zero value for int, but %s", value) + t.Errorf("Expected zero value for string, but %s", value) } }) } From 1f38134adbfdd1b3c8345629b663029e870a6cc2 Mon Sep 17 00:00:00 2001 From: Zike Yang Date: Mon, 19 Feb 2024 23:18:14 +0800 Subject: [PATCH 3/8] Update common/chan_utils_test.go --- common/chan_utils_test.go | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go index 73a1ed70..bc769ba0 100644 --- a/common/chan_utils_test.go +++ b/common/chan_utils_test.go @@ -121,35 +121,18 @@ func TestSendToChannel(t *testing.T) { } func TestZeroValue(t *testing.T) { - tests := []struct { - Type string - want interface{} - }{ - {Type: "int", want: 0}, - {Type: "string", want: ""}, - {Type: "bool", want: false}, - } - for _, tt := range tests { - t.Run(tt.Type, func(t *testing.T) { - zero := zeroValue[interface{}]() - switch v := zero.(type) { - case int: - if v != 0 { - t.Errorf("zeroValue = %v, want 0", v) - } - case string: - if v != "" { - t.Errorf("zeroValue = %v, want \"\"", v) - } - case bool: - if v != false { - t.Errorf("zeroValue = %v, want false", v) - } - default: - t.Log("ok") + testZeroValue := func(name string, got, want interface{}) { + t.Run(name, func(t *testing.T) { + if !reflect.DeepEqual(got, want) { + t.Errorf("zeroValue() = %v, want %v", got, want) } }) } + + testZeroValue("int", zeroValue[int](), 0) + testZeroValue("float64", zeroValue[float64](), float64(0)) + testZeroValue("string", zeroValue[string](), "") + testZeroValue("bool", zeroValue[bool](), false) } func TestReceiveFromChannel(t *testing.T) { From cfb9e56fb145e22e748d30f0ed49b95f0fccc46f Mon Sep 17 00:00:00 2001 From: wy Date: Mon, 19 Feb 2024 23:32:01 +0800 Subject: [PATCH 4/8] add unit-test, correct issues --- common/chan_utils_test.go | 100 +++++++++++++++----------------------- 1 file changed, 40 insertions(+), 60 deletions(-) diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go index 73a1ed70..661bbefd 100644 --- a/common/chan_utils_test.go +++ b/common/chan_utils_test.go @@ -18,17 +18,16 @@ package common import ( "context" - "fmt" - "sync" + "reflect" "testing" "time" ) func TestSendToChannel(t *testing.T) { - //send data - //The first t.Run is a buffered chan, and the second t.Run is an unbuffered chan - t.Run("send success,Buffered chan", func(t *testing.T) { + // send data + t.Run("send_buffered_chan_success", func(t *testing.T) { + // buffered chan c := make(chan string, 1) ctx := context.Background() if !SendToChannel(ctx, c, "data") { @@ -41,48 +40,43 @@ func TestSendToChannel(t *testing.T) { } }) - t.Run("send success,Unbuffered chan", func(t *testing.T) { + t.Run("send_unbuffered_chan_success", func(t *testing.T) { + // unbuffered chan c := make(chan string) ctx := context.Background() - var wg sync.WaitGroup - wg.Add(2) + go func() { - defer wg.Done() SendToChannel(ctx, c, "data") }() - go func() { - defer wg.Done() - value := <-c - // Verify if the received data is correct - if value != "data" { - t.Errorf("expected to receive \"data\" from channel, but received %s", value) - } - }() - wg.Wait() + + value := <-c + // Verify if the received data is correct + if value != "data" { + t.Errorf("expected to receive \"data\" from channel, but received %s", value) + } }) - //context timeout - //The first t.Run is a test with a timeout setting, but it was successfully sent without timeout - //The second t.Run passes through time.Sleep setting timeout, simulating context timeout - t.Run("context not timeout", func(t *testing.T) { + // context timeout + t.Run("context_not_timeout", func(t *testing.T) { + // test with a timeout setting, but test was successfully sent without timeout c := make(chan string, 1) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() if SendToChannel(ctx, c, "hello") { t.Log("Data sent successfully") } else { - fmt.Println(SendToChannel(ctx, c, "hello")) t.Fatal("Failed to send data due to context timeout") } select { case <-c: t.Log("Successfully received data") case <-ctx.Done(): - t.Fatal("Channel closed after context timeout") + t.Fatal("Fail to receive data due to the context timeout") } }) - t.Run("context timeout", func(t *testing.T) { + t.Run("context_timeout", func(t *testing.T) { + // time.Sleep setting timeout, simulating context timeout c := make(chan string, 1) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() @@ -104,9 +98,9 @@ func TestSendToChannel(t *testing.T) { }() }) - //incorrect type - //It is not necessary to distinguish between buffered and unbuffered, as it is necessary to test the incorrect type - t.Run("incorrect type", func(t *testing.T) { + // incorrect type + t.Run("incorrect_type", func(t *testing.T) { + // It is not necessary to distinguish between buffered and unbuffered, as it is necessary to test the incorrect type defer func() { if r := recover(); r != nil { t.Log("test-ok") @@ -121,41 +115,27 @@ func TestSendToChannel(t *testing.T) { } func TestZeroValue(t *testing.T) { - tests := []struct { - Type string - want interface{} - }{ - {Type: "int", want: 0}, - {Type: "string", want: ""}, - {Type: "bool", want: false}, - } - for _, tt := range tests { - t.Run(tt.Type, func(t *testing.T) { - zero := zeroValue[interface{}]() - switch v := zero.(type) { - case int: - if v != 0 { - t.Errorf("zeroValue = %v, want 0", v) - } - case string: - if v != "" { - t.Errorf("zeroValue = %v, want \"\"", v) - } - case bool: - if v != false { - t.Errorf("zeroValue = %v, want false", v) - } - default: - t.Log("ok") + + testZeroValue := func(name string, got, want interface{}) { + t.Run(name, func(t *testing.T) { + if !reflect.DeepEqual(got, want) { + t.Errorf("zeroValue() = %v, want %v", got, want) } }) } + + testZeroValue("int", zeroValue[int](), 0) + testZeroValue("float64", zeroValue[float64](), float64(0)) + testZeroValue("string", zeroValue[string](), "") + testZeroValue("bool", zeroValue[bool](), false) + } func TestReceiveFromChannel(t *testing.T) { - //Since SendToChannel has already been tested, only buffered chan will be considered here - //Successfully received chan data + // Since SendToChannel has already been tested, only buffered chan will be considered here + // Successfully received chan data + t.Run("Success", func(t *testing.T) { ctx := context.Background() ch := make(chan string, 1) @@ -166,13 +146,13 @@ func TestReceiveFromChannel(t *testing.T) { } }) - //context timeout + // context timeout t.Run("Timeout", func(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() time.Sleep(10 * time.Millisecond) ch := make(chan string, 1) - //No need to send data to SendToChannel as the context has been set to expire + // No need to send data to SendToChannel as the context has been set to expire value, ok := ReceiveFromChannel(ctx, ch) if ok { t.Fatal("Due to timeout setting, it is expected that no value will be received from the channel") @@ -182,11 +162,11 @@ func TestReceiveFromChannel(t *testing.T) { } }) - //context canceled + // context canceled t.Run("Canceled", func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) - //Cancel context + // Cancel context cancel() ch := make(chan string, 1) value, ok := ReceiveFromChannel(ctx, ch) From 7fab48fd79e2d222ec5b787dc985a9d160c205ea Mon Sep 17 00:00:00 2001 From: wy Date: Tue, 20 Feb 2024 00:27:59 +0800 Subject: [PATCH 5/8] add unit-test, correct issues --- common/chan_utils_test.go | 44 ++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go index 661bbefd..a2813d7a 100644 --- a/common/chan_utils_test.go +++ b/common/chan_utils_test.go @@ -28,6 +28,7 @@ func TestSendToChannel(t *testing.T) { // send data t.Run("send_buffered_chan_success", func(t *testing.T) { // buffered chan + c := make(chan string, 1) ctx := context.Background() if !SendToChannel(ctx, c, "data") { @@ -38,10 +39,12 @@ func TestSendToChannel(t *testing.T) { if value != "data" { t.Errorf("expected to receive \"data\" from channel, but received %s", value) } + }) t.Run("send_unbuffered_chan_success", func(t *testing.T) { // unbuffered chan + c := make(chan string) ctx := context.Background() @@ -54,13 +57,15 @@ func TestSendToChannel(t *testing.T) { if value != "data" { t.Errorf("expected to receive \"data\" from channel, but received %s", value) } + }) // context timeout t.Run("context_not_timeout", func(t *testing.T) { // test with a timeout setting, but test was successfully sent without timeout + c := make(chan string, 1) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() if SendToChannel(ctx, c, "hello") { t.Log("Data sent successfully") @@ -73,34 +78,34 @@ func TestSendToChannel(t *testing.T) { case <-ctx.Done(): t.Fatal("Fail to receive data due to the context timeout") } + }) t.Run("context_timeout", func(t *testing.T) { // time.Sleep setting timeout, simulating context timeout + c := make(chan string, 1) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() - if SendToChannel(ctx, c, "data") { + if SendToChannel(ctx, c, "hello") { t.Log("Data sent successfully") } else { t.Fatal("Failed to send data due to context timeout") } + time.Sleep(100 * time.Millisecond) // Set timeout + select { + case <-c: + t.Log("Successfully received data") + case <-ctx.Done(): + t.Fatal("Fail to receive data due to the context timeout") + } - go func() { - time.Sleep(time.Second) // Set timeout - select { - case <-c: - t.Error("Timed out but able to retrieve data") - return - case <-ctx.Done(): - t.Log("No data received due to context timeout") - } - }() }) // incorrect type t.Run("incorrect_type", func(t *testing.T) { // It is not necessary to distinguish between buffered and unbuffered, as it is necessary to test the incorrect type + defer func() { if r := recover(); r != nil { t.Log("test-ok") @@ -111,6 +116,7 @@ func TestSendToChannel(t *testing.T) { c := make(chan int) ctx := context.Background() SendToChannel(ctx, c, "incorrect type") + }) } @@ -144,14 +150,17 @@ func TestReceiveFromChannel(t *testing.T) { if value != "test-data" { t.Errorf("Receive failed,Expected value to be \"test-data\", but %s", value) } + }) // context timeout t.Run("Timeout", func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() - time.Sleep(10 * time.Millisecond) + time.Sleep(100 * time.Millisecond) ch := make(chan string, 1) + // No need to send data to SendToChannel as the context has been set to expire value, ok := ReceiveFromChannel(ctx, ch) if ok { @@ -160,14 +169,14 @@ func TestReceiveFromChannel(t *testing.T) { if value != "" { t.Errorf("Expected zero value for string, but %s", value) } + }) // context canceled t.Run("Canceled", func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) - // Cancel context - cancel() + cancel() // Cancel context ch := make(chan string, 1) value, ok := ReceiveFromChannel(ctx, ch) if ok { @@ -176,5 +185,6 @@ func TestReceiveFromChannel(t *testing.T) { if value != "" { t.Errorf("Expected zero value for string, but %s", value) } + }) } From fc86e3e787ac1d54f6cfbed28d77108cc00f135e Mon Sep 17 00:00:00 2001 From: wy Date: Wed, 21 Feb 2024 11:45:03 +0800 Subject: [PATCH 6/8] add unit-test, Modify SendToChannel and ReceiveFromChannel logic --- common/chan_utils.go | 14 +++++++---- common/chan_utils_test.go | 52 ++++++++++++++------------------------- 2 files changed, 28 insertions(+), 38 deletions(-) diff --git a/common/chan_utils.go b/common/chan_utils.go index 642ebe42..183c357c 100644 --- a/common/chan_utils.go +++ b/common/chan_utils.go @@ -16,15 +16,18 @@ package common -import "context" +import ( + "context" +) func SendToChannel[T any](ctx context.Context, c chan<- T, e interface{}) bool { select { - case c <- e.(T): // It will panic if `e` is not of type `T` or a type that can be converted to `T`. - return true case <-ctx.Done(): close(c) return false + default: + c <- e.(T) + return true } } @@ -35,9 +38,10 @@ func zeroValue[T any]() T { func ReceiveFromChannel[T any](ctx context.Context, c <-chan T) (T, bool) { select { - case e := <-c: - return e, true case <-ctx.Done(): return zeroValue[T](), false + default: + e := <-c + return e, true } } diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go index a2813d7a..d9af43d6 100644 --- a/common/chan_utils_test.go +++ b/common/chan_utils_test.go @@ -18,6 +18,7 @@ package common import ( "context" + "fmt" "reflect" "testing" "time" @@ -25,9 +26,7 @@ import ( func TestSendToChannel(t *testing.T) { - // send data t.Run("send_buffered_chan_success", func(t *testing.T) { - // buffered chan c := make(chan string, 1) ctx := context.Background() @@ -35,7 +34,6 @@ func TestSendToChannel(t *testing.T) { t.Fatal("SendToChannel should return true when sending succeeds") } value := <-c - // Verify if the received data is correct if value != "data" { t.Errorf("expected to receive \"data\" from channel, but received %s", value) } @@ -43,8 +41,6 @@ func TestSendToChannel(t *testing.T) { }) t.Run("send_unbuffered_chan_success", func(t *testing.T) { - // unbuffered chan - c := make(chan string) ctx := context.Background() @@ -53,14 +49,12 @@ func TestSendToChannel(t *testing.T) { }() value := <-c - // Verify if the received data is correct if value != "data" { t.Errorf("expected to receive \"data\" from channel, but received %s", value) } }) - // context timeout t.Run("context_not_timeout", func(t *testing.T) { // test with a timeout setting, but test was successfully sent without timeout @@ -68,13 +62,13 @@ func TestSendToChannel(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() if SendToChannel(ctx, c, "hello") { - t.Log("Data sent successfully") + t.Log("data sent successfully") } else { t.Fatal("Failed to send data due to context timeout") } select { case <-c: - t.Log("Successfully received data") + t.Log("successfully received data") case <-ctx.Done(): t.Fatal("Fail to receive data due to the context timeout") } @@ -85,24 +79,18 @@ func TestSendToChannel(t *testing.T) { // time.Sleep setting timeout, simulating context timeout c := make(chan string, 1) - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() - if SendToChannel(ctx, c, "hello") { - t.Log("Data sent successfully") + time.Sleep(1 * time.Second) // Set timeout + if k := SendToChannel(ctx, c, "hello"); k { + fmt.Println(k) + t.Fatal("context timeout but data sent successfully") } else { - t.Fatal("Failed to send data due to context timeout") - } - time.Sleep(100 * time.Millisecond) // Set timeout - select { - case <-c: - t.Log("Successfully received data") - case <-ctx.Done(): - t.Fatal("Fail to receive data due to the context timeout") + t.Log("failed to send data due to context timeout") } }) - // incorrect type t.Run("incorrect_type", func(t *testing.T) { // It is not necessary to distinguish between buffered and unbuffered, as it is necessary to test the incorrect type @@ -138,41 +126,39 @@ func TestZeroValue(t *testing.T) { } func TestReceiveFromChannel(t *testing.T) { - // Since SendToChannel has already been tested, only buffered chan will be considered here - // Successfully received chan data t.Run("Success", func(t *testing.T) { ctx := context.Background() ch := make(chan string, 1) SendToChannel(ctx, ch, "test-data") - value, _ := ReceiveFromChannel(ctx, ch) + value, ok := ReceiveFromChannel(ctx, ch) + if ok { + t.Log("successfully received data") + } if value != "test-data" { - t.Errorf("Receive failed,Expected value to be \"test-data\", but %s", value) + t.Errorf("receive failed,expected value to be \"test-data\", but it's %s", value) } }) - // context timeout t.Run("Timeout", func(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() - time.Sleep(100 * time.Millisecond) ch := make(chan string, 1) - + time.Sleep(1 * time.Second) // No need to send data to SendToChannel as the context has been set to expire value, ok := ReceiveFromChannel(ctx, ch) if ok { - t.Fatal("Due to timeout setting, it is expected that no value will be received from the channel") + t.Fatal("due to timeout setting, it is expected that no value will be received from the channel") } if value != "" { - t.Errorf("Expected zero value for string, but %s", value) + t.Errorf("expected zero value for string, but it's %s", value) } }) - // context canceled t.Run("Canceled", func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -180,10 +166,10 @@ func TestReceiveFromChannel(t *testing.T) { ch := make(chan string, 1) value, ok := ReceiveFromChannel(ctx, ch) if ok { - t.Fatal("Expected no value to be received from channel due to context cancellation") + t.Fatal("expected no value to be received from channel due to context cancellation") } if value != "" { - t.Errorf("Expected zero value for string, but %s", value) + t.Errorf("expected zero value for string, but it's %s", value) } }) From fe27a9f74617d7cc41f8acc6da331ff54dcd4277 Mon Sep 17 00:00:00 2001 From: wy Date: Wed, 21 Feb 2024 23:07:51 +0800 Subject: [PATCH 7/8] chan_utils unit-test --- common/chan_utils.go | 10 ++++------ common/chan_utils_test.go | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/common/chan_utils.go b/common/chan_utils.go index 183c357c..af20a4b5 100644 --- a/common/chan_utils.go +++ b/common/chan_utils.go @@ -22,12 +22,11 @@ import ( func SendToChannel[T any](ctx context.Context, c chan<- T, e interface{}) bool { select { + case c <- e.(T): // It will panic if `e` is not of type `T` or a type that can be converted to `T`. + return true case <-ctx.Done(): close(c) return false - default: - c <- e.(T) - return true } } @@ -38,10 +37,9 @@ func zeroValue[T any]() T { func ReceiveFromChannel[T any](ctx context.Context, c <-chan T) (T, bool) { select { + case e := <-c: + return e, true case <-ctx.Done(): return zeroValue[T](), false - default: - e := <-c - return e, true } } diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go index d9af43d6..d6efbe2e 100644 --- a/common/chan_utils_test.go +++ b/common/chan_utils_test.go @@ -78,7 +78,7 @@ func TestSendToChannel(t *testing.T) { t.Run("context_timeout", func(t *testing.T) { // time.Sleep setting timeout, simulating context timeout - c := make(chan string, 1) + c := make(chan string) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() time.Sleep(1 * time.Second) // Set timeout From b606d3f2a2962171fd5c78f692db687cb4f59517 Mon Sep 17 00:00:00 2001 From: wy Date: Sat, 24 Feb 2024 00:23:33 +0800 Subject: [PATCH 8/8] chan_utils fix:unit-test --- common/chan_utils_test.go | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/common/chan_utils_test.go b/common/chan_utils_test.go index d6efbe2e..d631a203 100644 --- a/common/chan_utils_test.go +++ b/common/chan_utils_test.go @@ -18,7 +18,6 @@ package common import ( "context" - "fmt" "reflect" "testing" "time" @@ -55,35 +54,14 @@ func TestSendToChannel(t *testing.T) { }) - t.Run("context_not_timeout", func(t *testing.T) { - // test with a timeout setting, but test was successfully sent without timeout - - c := make(chan string, 1) - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) - defer cancel() - if SendToChannel(ctx, c, "hello") { - t.Log("data sent successfully") - } else { - t.Fatal("Failed to send data due to context timeout") - } - select { - case <-c: - t.Log("successfully received data") - case <-ctx.Done(): - t.Fatal("Fail to receive data due to the context timeout") - } - - }) - t.Run("context_timeout", func(t *testing.T) { - // time.Sleep setting timeout, simulating context timeout + // Using time.Sleep to simulating context timeout c := make(chan string) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() time.Sleep(1 * time.Second) // Set timeout if k := SendToChannel(ctx, c, "hello"); k { - fmt.Println(k) t.Fatal("context timeout but data sent successfully") } else { t.Log("failed to send data due to context timeout") @@ -92,7 +70,6 @@ func TestSendToChannel(t *testing.T) { }) t.Run("incorrect_type", func(t *testing.T) { - // It is not necessary to distinguish between buffered and unbuffered, as it is necessary to test the incorrect type defer func() { if r := recover(); r != nil {