Repository: pion/mediadevices
Pull request #57 (2020-02-15 21:52:39)

Fix Video/Adapter wrapper state guards
* Fix unguarded VideoRecord and AudioRecord
* Properties returns nil when driver is closed
* Add Video/Audio adapter wrapper state tests


Patch:
diff --git a/pkg/driver/wrapper.go b/pkg/driver/wrapper.go
index e4c45dc..a751415 100644
--- a/pkg/driver/wrapper.go
+++ b/pkg/driver/wrapper.go
@@ -66,8 +66,16 @@ func (w *adapterWrapper) Close() error {
 	return w.state.Update(StateClosed, w.Adapter.Close)
 }
 
+func (w *adapterWrapper) Properties() []prop.Media {
+	if w.state == StateClosed {
+		return nil
+	}
+
+	return w.Adapter.Properties()
+}
+
 func (w *adapterWrapper) VideoRecord(p prop.Media) (r video.Reader, err error) {
-	w.state.Update(StateRunning, func() error {
+	err = w.state.Update(StateRunning, func() error {
 		r, err = w.VideoRecorder.VideoRecord(p)
 		return err
 	})
@@ -75,7 +83,7 @@ func (w *adapterWrapper) VideoRecord(p prop.Media) (r video.Reader, err error) {
 }
 
 func (w *adapterWrapper) AudioRecord(p prop.Media) (r audio.Reader, err error) {
-	w.state.Update(StateRunning, func() error {
+	err = w.state.Update(StateRunning, func() error {
 		r, err = w.AudioRecorder.AudioRecord(p)
 		return err
 	})


Test patch:
diff --git a/pkg/driver/wrapper_test.go b/pkg/driver/wrapper_test.go
new file mode 100644
index 0000000..619fa4c
--- /dev/null
+++ b/pkg/driver/wrapper_test.go
@@ -0,0 +1,73 @@
+package driver
+
+import (
+	"testing"
+
+	"github.com/pion/mediadevices/pkg/io/audio"
+	"github.com/pion/mediadevices/pkg/io/video"
+	"github.com/pion/mediadevices/pkg/prop"
+)
+
+type adapterMock struct{}
+
+func (a *adapterMock) Open() error              { return nil }
+func (a *adapterMock) Close() error             { return nil }
+func (a *adapterMock) Properties() []prop.Media { return []prop.Media{prop.Media{}} }
+
+type videoAdapterMock struct{ adapterMock }
+
+func (a *videoAdapterMock) VideoRecord(p prop.Media) (r video.Reader, err error) { return nil, nil }
+
+type audioAdapterMock struct{ adapterMock }
+
+func (a *audioAdapterMock) AudioRecord(p prop.Media) (r audio.Reader, err error) { return nil, nil }
+
+func TestVideoWrapperState(t *testing.T) {
+	var a videoAdapterMock
+	d := wrapAdapter(&a, Info{})
+
+	if d.Properties() != nil {
+		t.Errorf("expected nil, but got %v", d.Properties())
+	}
+
+	vr := d.(VideoRecorder)
+	_, err := vr.VideoRecord(prop.Media{})
+	if err == nil {
+		t.Errorf("expected to get an invalid state")
+	}
+
+	err = d.Open()
+	if err != nil {
+		t.Errorf("expected to successfully open, but got %v", err)
+	}
+
+	_, err = vr.VideoRecord(prop.Media{})
+	if err != nil {
+		t.Errorf("expected to successfully start recording, but got %v", err)
+	}
+}
+
+func TestAudioWrapperState(t *testing.T) {
+	var a audioAdapterMock
+	d := wrapAdapter(&a, Info{})
+
+	if d.Properties() != nil {
+		t.Errorf("expected nil, but got %v", d.Properties())
+	}
+
+	ar := d.(AudioRecorder)
+	_, err := ar.AudioRecord(prop.Media{})
+	if err == nil {
+		t.Errorf("expected to get an invalid state")
+	}
+
+	err = d.Open()
+	if err != nil {
+		t.Errorf("expected to successfully open, but got %v", err)
+	}
+
+	_, err = ar.AudioRecord(prop.Media{})
+	if err != nil {
+		t.Errorf("expected to successfully start recording, but got %v", err)
+	}
+}