1package dbus
2
3import "testing"
4
5func TestSessionBus(t *testing.T) {
6	_, err := SessionBus()
7	if err != nil {
8		t.Error(err)
9	}
10}
11
12func TestSystemBus(t *testing.T) {
13	_, err := SystemBus()
14	if err != nil {
15		t.Error(err)
16	}
17}
18
19func TestSend(t *testing.T) {
20	bus, err := SessionBus()
21	if err != nil {
22		t.Fatal(err)
23	}
24	ch := make(chan *Call, 1)
25	msg := &Message{
26		Type:  TypeMethodCall,
27		Flags: 0,
28		Headers: map[HeaderField]Variant{
29			FieldDestination: MakeVariant(bus.Names()[0]),
30			FieldPath:        MakeVariant(ObjectPath("/org/freedesktop/DBus")),
31			FieldInterface:   MakeVariant("org.freedesktop.DBus.Peer"),
32			FieldMember:      MakeVariant("Ping"),
33		},
34	}
35	call := bus.Send(msg, ch)
36	<-ch
37	if call.Err != nil {
38		t.Error(call.Err)
39	}
40}
41
42func TestRemoveSignal(t *testing.T) {
43	bus, err := NewConn(nil)
44	if err != nil {
45		t.Error(err)
46	}
47	ch := make(chan *Signal)
48	ch2 := make(chan *Signal)
49	for _, ch := range []chan *Signal{ch, ch2, ch, ch2, ch2, ch} {
50		bus.Signal(ch)
51	}
52	if len(bus.signals) != 6 {
53		t.Errorf("remove signal: signals length not equal: got '%d', want '6'", len(bus.signals))
54	}
55	bus.RemoveSignal(ch)
56	if len(bus.signals) != 3 {
57		t.Errorf("remove signal: signals length not equal: got '%d', want '3'", len(bus.signals))
58	}
59	for _, bch := range bus.signals {
60		if bch != ch2 {
61			t.Errorf("remove signal: removed signal present: got '%v', want '%v'", bch, ch2)
62		}
63	}
64}
65
66type server struct{}
67
68func (server) Double(i int64) (int64, *Error) {
69	return 2 * i, nil
70}
71
72func BenchmarkCall(b *testing.B) {
73	b.StopTimer()
74	var s string
75	bus, err := SessionBus()
76	if err != nil {
77		b.Fatal(err)
78	}
79	name := bus.Names()[0]
80	obj := bus.BusObject()
81	b.StartTimer()
82	for i := 0; i < b.N; i++ {
83		err := obj.Call("org.freedesktop.DBus.GetNameOwner", 0, name).Store(&s)
84		if err != nil {
85			b.Fatal(err)
86		}
87		if s != name {
88			b.Errorf("got %s, wanted %s", s, name)
89		}
90	}
91}
92
93func BenchmarkCallAsync(b *testing.B) {
94	b.StopTimer()
95	bus, err := SessionBus()
96	if err != nil {
97		b.Fatal(err)
98	}
99	name := bus.Names()[0]
100	obj := bus.BusObject()
101	c := make(chan *Call, 50)
102	done := make(chan struct{})
103	go func() {
104		for i := 0; i < b.N; i++ {
105			v := <-c
106			if v.Err != nil {
107				b.Error(v.Err)
108			}
109			s := v.Body[0].(string)
110			if s != name {
111				b.Errorf("got %s, wanted %s", s, name)
112			}
113		}
114		close(done)
115	}()
116	b.StartTimer()
117	for i := 0; i < b.N; i++ {
118		obj.Go("org.freedesktop.DBus.GetNameOwner", 0, c, name)
119	}
120	<-done
121}
122
123func BenchmarkServe(b *testing.B) {
124	b.StopTimer()
125	srv, err := SessionBus()
126	if err != nil {
127		b.Fatal(err)
128	}
129	cli, err := SessionBusPrivate()
130	if err != nil {
131		b.Fatal(err)
132	}
133	if err = cli.Auth(nil); err != nil {
134		b.Fatal(err)
135	}
136	if err = cli.Hello(); err != nil {
137		b.Fatal(err)
138	}
139	benchmarkServe(b, srv, cli)
140}
141
142func BenchmarkServeAsync(b *testing.B) {
143	b.StopTimer()
144	srv, err := SessionBus()
145	if err != nil {
146		b.Fatal(err)
147	}
148	cli, err := SessionBusPrivate()
149	if err != nil {
150		b.Fatal(err)
151	}
152	if err = cli.Auth(nil); err != nil {
153		b.Fatal(err)
154	}
155	if err = cli.Hello(); err != nil {
156		b.Fatal(err)
157	}
158	benchmarkServeAsync(b, srv, cli)
159}
160
161func BenchmarkServeSameConn(b *testing.B) {
162	b.StopTimer()
163	bus, err := SessionBus()
164	if err != nil {
165		b.Fatal(err)
166	}
167
168	benchmarkServe(b, bus, bus)
169}
170
171func BenchmarkServeSameConnAsync(b *testing.B) {
172	b.StopTimer()
173	bus, err := SessionBus()
174	if err != nil {
175		b.Fatal(err)
176	}
177
178	benchmarkServeAsync(b, bus, bus)
179}
180
181func benchmarkServe(b *testing.B, srv, cli *Conn) {
182	var r int64
183	var err error
184	dest := srv.Names()[0]
185	srv.Export(server{}, "/org/guelfey/DBus/Test", "org.guelfey.DBus.Test")
186	obj := cli.Object(dest, "/org/guelfey/DBus/Test")
187	b.StartTimer()
188	for i := 0; i < b.N; i++ {
189		err = obj.Call("org.guelfey.DBus.Test.Double", 0, int64(i)).Store(&r)
190		if err != nil {
191			b.Fatal(err)
192		}
193		if r != 2*int64(i) {
194			b.Errorf("got %d, wanted %d", r, 2*int64(i))
195		}
196	}
197}
198
199func benchmarkServeAsync(b *testing.B, srv, cli *Conn) {
200	dest := srv.Names()[0]
201	srv.Export(server{}, "/org/guelfey/DBus/Test", "org.guelfey.DBus.Test")
202	obj := cli.Object(dest, "/org/guelfey/DBus/Test")
203	c := make(chan *Call, 50)
204	done := make(chan struct{})
205	go func() {
206		for i := 0; i < b.N; i++ {
207			v := <-c
208			if v.Err != nil {
209				b.Fatal(v.Err)
210			}
211			i, r := v.Args[0].(int64), v.Body[0].(int64)
212			if 2*i != r {
213				b.Errorf("got %d, wanted %d", r, 2*i)
214			}
215		}
216		close(done)
217	}()
218	b.StartTimer()
219	for i := 0; i < b.N; i++ {
220		obj.Go("org.guelfey.DBus.Test.Double", 0, c, int64(i))
221	}
222	<-done
223}
224