nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: pion/mediadevices
Pull request #72 (2020-02-18 17:09:29)

Call OnEnded even if errored before register
OnEnded handler was not called if something errored before
registering the handler. Store error and call handler immediately
on handler registration.




Patch:
diff --git a/track.go b/track.go
index 6fb49aa..4b23348 100644
--- a/track.go
+++ b/track.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"io"
 	"math/rand"
-	"sync/atomic"
+	"sync"
 
 	"github.com/pion/mediadevices/pkg/codec"
 	"github.com/pion/mediadevices/pkg/driver"
@@ -19,6 +19,9 @@ type Tracker interface {
 	Track() *webrtc.Track
 	LocalTrack() LocalTrack
 	Stop()
+	// OnEnded registers a handler to receive an error from the media stream track.
+	// If the error is already occured before registering, the handler will be
+	// immediately called.
 	OnEnded(func(error))
 }
 
@@ -33,7 +36,10 @@ type track struct {
 	t LocalTrack
 	s *sampler
 
-	onErrorHandler atomic.Value // func(error)
+	onErrorHandler func(error)
+	err            error
+	mu             sync.Mutex
+	endOnce        sync.Once
 }
 
 func newTrack(codecs []*webrtc.RTPCodec, trackGenerator TrackGenerator, d driver.Driver, codecName string) (*track, error) {
@@ -66,13 +72,29 @@ func newTrack(codecs []*webrtc.RTPCodec, trackGenerator TrackGenerator, d driver
 }
 
 func (t *track) OnEnded(handler func(error)) {
-	t.onErrorHandler.Store(handler)
+	t.mu.Lock()
+	t.onErrorHandler = handler
+	err := t.err
+	t.mu.Unlock()
+
+	if err != nil && handler != nil {
+		// Already errored.
+		t.endOnce.Do(func() {
+			handler(err)
+		})
+	}
 }
 
 func (t *track) onError(err error) {
-	handler := t.onErrorHandler.Load()
+	t.mu.Lock()
+	t.err = err
+	handler := t.onErrorHandler
+	t.mu.Unlock()
+
 	if handler != nil {
-		handler.(func(error))(err)
+		t.endOnce.Do(func() {
+			handler(err)
+		})
 	}
 }
 


Test patch:
diff --git a/track_test.go b/track_test.go
new file mode 100644
index 0000000..baf67c5
--- /dev/null
+++ b/track_test.go
@@ -0,0 +1,55 @@
+package mediadevices
+
+import (
+	"errors"
+	"testing"
+	"time"
+)
+
+func TestOnEnded(t *testing.T) {
+	errExpected := errors.New("an error")
+
+	t.Run("ErrorAfterRegister", func(t *testing.T) {
+		tr := &track{}
+
+		called := make(chan error, 1)
+		tr.OnEnded(func(error) {
+			called <- errExpected
+		})
+		select {
+		case <-called:
+			t.Error("OnEnded handler is unexpectedly called")
+		case <-time.After(10 * time.Millisecond):
+		}
+
+		tr.onError(errExpected)
+
+		select {
+		case err := <-called:
+			if err != errExpected {
+				t.Errorf("Expected to receive error: %v, got: %v", errExpected, err)
+			}
+		case <-time.After(10 * time.Millisecond):
+			t.Error("Timeout")
+		}
+	})
+
+	t.Run("ErrorBeforeRegister", func(t *testing.T) {
+		tr := &track{}
+
+		tr.onError(errExpected)
+
+		called := make(chan error, 1)
+		tr.OnEnded(func(err error) {
+			called <- errExpected
+		})
+		select {
+		case err := <-called:
+			if err != errExpected {
+				t.Errorf("Expected to receive error: %v, got: %v", errExpected, err)
+			}
+		case <-time.After(10 * time.Millisecond):
+			t.Error("Timeout")
+		}
+	})
+}
Repository: pion/mediadevices
Pull request #165 (2020-05-15 04:36:25)

Fix wrong required size


Patch:
diff --git a/pkg/io/io.go b/pkg/io/io.go
index d235335..26f3216 100644
--- a/pkg/io/io.go
+++ b/pkg/io/io.go
@@ -4,7 +4,7 @@ package io
 // InsufficientBufferError.
 func Copy(dst, src []byte) (n int, err error) {
 	if len(dst) < len(src) {
-		return 0, &InsufficientBufferError{len(dst)}
+		return 0, &InsufficientBufferError{len(src)}
 	}
 
 	return copy(dst, src), nil


Test patch:
diff --git a/pkg/io/io_test.go b/pkg/io/io_test.go
new file mode 100644
index 0000000..047e3a1
--- /dev/null
+++ b/pkg/io/io_test.go
@@ -0,0 +1,45 @@
+package io
+
+import (
+	"log"
+	"testing"
+)
+
+func TestCopy(t *testing.T) {
+	var dst []byte
+	src := make([]byte, 4)
+
+	n, err := Copy(dst, src)
+	if err == nil {
+		t.Fatal("expected err to be non-nill")
+	}
+
+	if n != 0 {
+		t.Fatalf("expected n to be 0, but got %d", n)
+	}
+
+	e, ok := err.(*InsufficientBufferError)
+	if !ok {
+		t.Fatalf("expected error to be InsufficientBufferError")
+	}
+
+	if e.RequiredSize != len(src) {
+		t.Fatalf("expected required size to be %d, but got %d", len(src), e.RequiredSize)
+	}
+
+	dst = make([]byte, 2*e.RequiredSize)
+	n, err = Copy(dst, src)
+	if err != nil {
+		t.Fatalf("expected to not get an error after expanding the buffer")
+	}
+
+	if n != len(src) {
+		t.Fatalf("expected n to be %d, but got %d", len(src), n)
+	}
+
+	for i := 0; i < len(src); i++ {
+		if src[i] != dst[i] {
+			log.Fatalf("expected value at %d to be %d, but got %d", i, src[i], dst[i])
+		}
+	}
+}