Files
go-gst/gst/gst_promise_test.go
2025-09-16 22:36:07 +02:00

122 lines
2.0 KiB
Go

package gst
import (
"context"
"errors"
"runtime"
"testing"
"time"
)
//go:noinline
//
// Deprecated: This is handwritten and will be removed in a future version. Please use the autogenerated bindings instead.
func awaitGC() {
type tmp struct{ v string }
setup := make(chan struct{})
done := make(chan struct{})
go func() {
v := &tmp{"foo"}
runtime.SetFinalizer(v, func(v *tmp) {
close(done)
})
close(setup)
}()
<-setup
runtime.GC()
<-done
runtime.GC()
time.Sleep(1 * time.Second)
}
//
// Deprecated: This is handwritten and will be removed in a future version. Please use the autogenerated bindings instead.
func TestPromise(t *testing.T) {
Init(nil)
prom := NewPromise()
cprom := prom.Instance()
reply := NewStructure("foo/bar")
errchan := make(chan error)
go func() {
res, err := prom.Await(context.Background())
if err != nil {
errchan <- err
}
// even though we don't use the promise, the result structure should be still accessible.
// the returned structure is owned by the promise, so the promise must not get GC'ed until
// we don't use the structure anymore
awaitGC()
if res.Name() != reply.Name() {
errchan <- errors.New("name mismatch")
}
runtime.GC()
runtime.GC()
runtime.GC()
close(errchan)
}()
prom.Reply(reply)
err := <-errchan
if err != nil {
t.FailNow()
}
awaitGC()
if cprom.parent.refcount != 1 {
panic("refcount too high")
}
runtime.KeepAlive(prom)
awaitGC()
}
//
// Deprecated: This is handwritten and will be removed in a future version. Please use the autogenerated bindings instead.
func TestPromiseMarshal(t *testing.T) {
Init(nil)
prom := NewPromise()
gv, err := prom.ToGValue()
if err != nil {
t.Fatal(err)
}
receivedPromI, err := gv.GoValue()
if err != nil {
t.Fatal(err)
}
receivedProm, ok := receivedPromI.(*Promise)
if !ok {
t.Fatal("could not cast")
}
// Awaiting received promise should error immediately
_, err = receivedProm.Await(context.Background())
if err == nil {
t.FailNow()
}
}