...

Source file src/github.com/godbus/dbus/v5/proto_test.go

Documentation: github.com/godbus/dbus/v5

     1  package dbus
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"io/ioutil"
     7  	"math"
     8  	"reflect"
     9  	"testing"
    10  )
    11  
    12  var protoTests = []struct {
    13  	vs           []interface{}
    14  	bigEndian    []byte
    15  	littleEndian []byte
    16  }{
    17  	{
    18  		[]interface{}{int32(0)},
    19  		[]byte{0, 0, 0, 0},
    20  		[]byte{0, 0, 0, 0},
    21  	},
    22  	{
    23  		[]interface{}{true, false},
    24  		[]byte{0, 0, 0, 1, 0, 0, 0, 0},
    25  		[]byte{1, 0, 0, 0, 0, 0, 0, 0},
    26  	},
    27  	{
    28  		[]interface{}{byte(0), uint16(12), int16(32), uint32(43)},
    29  		[]byte{0, 0, 0, 12, 0, 32, 0, 0, 0, 0, 0, 43},
    30  		[]byte{0, 0, 12, 0, 32, 0, 0, 0, 43, 0, 0, 0},
    31  	},
    32  	{
    33  		[]interface{}{int64(-1), uint64(1<<64 - 1)},
    34  		bytes.Repeat([]byte{255}, 16),
    35  		bytes.Repeat([]byte{255}, 16),
    36  	},
    37  	{
    38  		[]interface{}{math.Inf(+1)},
    39  		[]byte{0x7f, 0xf0, 0, 0, 0, 0, 0, 0},
    40  		[]byte{0, 0, 0, 0, 0, 0, 0xf0, 0x7f},
    41  	},
    42  	{
    43  		[]interface{}{"foo"},
    44  		[]byte{0, 0, 0, 3, 'f', 'o', 'o', 0},
    45  		[]byte{3, 0, 0, 0, 'f', 'o', 'o', 0},
    46  	},
    47  	{
    48  		[]interface{}{Signature{"ai"}},
    49  		[]byte{2, 'a', 'i', 0},
    50  		[]byte{2, 'a', 'i', 0},
    51  	},
    52  	{
    53  		[]interface{}{[]int16{42, 256}},
    54  		[]byte{0, 0, 0, 4, 0, 42, 1, 0},
    55  		[]byte{4, 0, 0, 0, 42, 0, 0, 1},
    56  	},
    57  	{
    58  		[]interface{}{MakeVariant("foo")},
    59  		[]byte{1, 's', 0, 0, 0, 0, 0, 3, 'f', 'o', 'o', 0},
    60  		[]byte{1, 's', 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0},
    61  	},
    62  	{
    63  		[]interface{}{MakeVariant(MakeVariant(Signature{"v"}))},
    64  		[]byte{1, 'v', 0, 1, 'g', 0, 1, 'v', 0},
    65  		[]byte{1, 'v', 0, 1, 'g', 0, 1, 'v', 0},
    66  	},
    67  	{
    68  		[]interface{}{map[int32]bool{42: true}},
    69  		[]byte{0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 1},
    70  		[]byte{8, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 1, 0, 0, 0},
    71  	},
    72  	{
    73  		[]interface{}{map[string]Variant{}, byte(42)},
    74  		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
    75  		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
    76  	},
    77  	{
    78  		[]interface{}{[]uint64{}, byte(42)},
    79  		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
    80  		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
    81  	},
    82  }
    83  
    84  func TestProto(t *testing.T) {
    85  	for i, v := range protoTests {
    86  		buf := new(bytes.Buffer)
    87  		fds := make([]int, 0)
    88  		bigEnc := newEncoder(buf, binary.BigEndian, fds)
    89  		bigEnc.Encode(v.vs...)
    90  		marshalled := buf.Bytes()
    91  		if !bytes.Equal(marshalled, v.bigEndian) {
    92  			t.Errorf("test %d (marshal be): got '%v', but expected '%v'\n", i+1, marshalled,
    93  				v.bigEndian)
    94  		}
    95  		buf.Reset()
    96  		fds = make([]int, 0)
    97  		litEnc := newEncoder(buf, binary.LittleEndian, fds)
    98  		litEnc.Encode(v.vs...)
    99  		marshalled = buf.Bytes()
   100  		if !bytes.Equal(marshalled, v.littleEndian) {
   101  			t.Errorf("test %d (marshal le): got '%v', but expected '%v'\n", i+1, marshalled,
   102  				v.littleEndian)
   103  		}
   104  		unmarshalled := reflect.MakeSlice(reflect.TypeOf(v.vs),
   105  			0, 0)
   106  		for i := range v.vs {
   107  			unmarshalled = reflect.Append(unmarshalled,
   108  				reflect.New(reflect.TypeOf(v.vs[i])))
   109  		}
   110  		bigDec := newDecoder(bytes.NewReader(v.bigEndian), binary.BigEndian, make([]int, 0))
   111  		vs, err := bigDec.Decode(SignatureOf(v.vs...))
   112  		if err != nil {
   113  			t.Errorf("test %d (unmarshal be): %s\n", i+1, err)
   114  			continue
   115  		}
   116  		if !reflect.DeepEqual(vs, v.vs) {
   117  			t.Errorf("test %d (unmarshal be): got %#v, but expected %#v\n", i+1, vs, v.vs)
   118  		}
   119  		litDec := newDecoder(bytes.NewReader(v.littleEndian), binary.LittleEndian, make([]int, 0))
   120  		vs, err = litDec.Decode(SignatureOf(v.vs...))
   121  		if err != nil {
   122  			t.Errorf("test %d (unmarshal le): %s\n", i+1, err)
   123  			continue
   124  		}
   125  		if !reflect.DeepEqual(vs, v.vs) {
   126  			t.Errorf("test %d (unmarshal le): got %#v, but expected %#v\n", i+1, vs, v.vs)
   127  		}
   128  
   129  	}
   130  }
   131  
   132  func TestProtoMap(t *testing.T) {
   133  	m := map[string]uint8{
   134  		"foo": 23,
   135  		"bar": 2,
   136  	}
   137  	var n map[string]uint8
   138  	buf := new(bytes.Buffer)
   139  	fds := make([]int, 0)
   140  	enc := newEncoder(buf, binary.LittleEndian, fds)
   141  	enc.Encode(m)
   142  	dec := newDecoder(buf, binary.LittleEndian, enc.fds)
   143  	vs, err := dec.Decode(Signature{"a{sy}"})
   144  	if err != nil {
   145  		t.Fatal(err)
   146  	}
   147  	if err = Store(vs, &n); err != nil {
   148  		t.Fatal(err)
   149  	}
   150  	if len(n) != 2 || n["foo"] != 23 || n["bar"] != 2 {
   151  		t.Error("got", n)
   152  	}
   153  }
   154  
   155  func TestProtoVariantStruct(t *testing.T) {
   156  	var variant Variant
   157  	v := MakeVariant(struct {
   158  		A int32
   159  		B int16
   160  	}{1, 2})
   161  	buf := new(bytes.Buffer)
   162  	fds := make([]int, 0)
   163  	enc := newEncoder(buf, binary.LittleEndian, fds)
   164  	enc.Encode(v)
   165  	dec := newDecoder(buf, binary.LittleEndian, enc.fds)
   166  	vs, err := dec.Decode(Signature{"v"})
   167  	if err != nil {
   168  		t.Fatal(err)
   169  	}
   170  	if err = Store(vs, &variant); err != nil {
   171  		t.Fatal(err)
   172  	}
   173  	sl := variant.Value().([]interface{})
   174  	v1, v2 := sl[0].(int32), sl[1].(int16)
   175  	if v1 != int32(1) {
   176  		t.Error("got", v1, "as first int")
   177  	}
   178  	if v2 != int16(2) {
   179  		t.Error("got", v2, "as second int")
   180  	}
   181  }
   182  
   183  func TestProtoStructTag(t *testing.T) {
   184  	type Bar struct {
   185  		A int32
   186  		B chan interface{} `dbus:"-"`
   187  		C int32
   188  	}
   189  	var bar1, bar2 Bar
   190  	bar1.A = 234
   191  	bar2.C = 345
   192  	buf := new(bytes.Buffer)
   193  	fds := make([]int, 0)
   194  	enc := newEncoder(buf, binary.LittleEndian, fds)
   195  	enc.Encode(bar1)
   196  	dec := newDecoder(buf, binary.LittleEndian, enc.fds)
   197  	vs, err := dec.Decode(Signature{"(ii)"})
   198  	if err != nil {
   199  		t.Fatal(err)
   200  	}
   201  	if err = Store(vs, &bar2); err != nil {
   202  		t.Fatal(err)
   203  	}
   204  	if bar1 != bar2 {
   205  		t.Error("struct tag test: got", bar2)
   206  	}
   207  }
   208  
   209  func TestProtoStoreStruct(t *testing.T) {
   210  	var foo struct {
   211  		A int32
   212  		B string
   213  		c chan interface{}
   214  		D interface{} `dbus:"-"`
   215  	}
   216  	src := []interface{}{[]interface{}{int32(42), "foo"}}
   217  	err := Store(src, &foo)
   218  	if err != nil {
   219  		t.Fatal(err)
   220  	}
   221  }
   222  
   223  func TestProtoStoreNestedStruct(t *testing.T) {
   224  	var foo struct {
   225  		A int32
   226  		B struct {
   227  			C string
   228  			D float64
   229  		}
   230  	}
   231  	src := []interface{}{
   232  		[]interface{}{
   233  			int32(42),
   234  			[]interface{}{
   235  				"foo",
   236  				3.14,
   237  			},
   238  		},
   239  	}
   240  	err := Store(src, &foo)
   241  	if err != nil {
   242  		t.Fatal(err)
   243  	}
   244  }
   245  
   246  func TestMessage(t *testing.T) {
   247  	buf := new(bytes.Buffer)
   248  	message := new(Message)
   249  	message.Type = TypeMethodCall
   250  	message.serial = 32
   251  	message.Headers = map[HeaderField]Variant{
   252  		FieldPath:   MakeVariant(ObjectPath("/org/foo/bar")),
   253  		FieldMember: MakeVariant("baz"),
   254  	}
   255  	message.Body = make([]interface{}, 0)
   256  	err := message.EncodeTo(buf, binary.LittleEndian)
   257  	if err != nil {
   258  		t.Error(err)
   259  	}
   260  	_, err = DecodeMessage(buf)
   261  	if err != nil {
   262  		t.Error(err)
   263  	}
   264  }
   265  
   266  func TestProtoStructInterfaces(t *testing.T) {
   267  	b := []byte{42}
   268  	vs, err := newDecoder(bytes.NewReader(b), binary.LittleEndian, make([]int, 0)).Decode(Signature{"(y)"})
   269  	if err != nil {
   270  		t.Fatal(err)
   271  	}
   272  	if vs[0].([]interface{})[0].(byte) != 42 {
   273  		t.Errorf("wrongs results (got %v)", vs)
   274  	}
   275  }
   276  
   277  // ordinary org.freedesktop.DBus.Hello call
   278  var smallMessage = &Message{
   279  	Type:   TypeMethodCall,
   280  	serial: 1,
   281  	Headers: map[HeaderField]Variant{
   282  		FieldDestination: MakeVariant("org.freedesktop.DBus"),
   283  		FieldPath:        MakeVariant(ObjectPath("/org/freedesktop/DBus")),
   284  		FieldInterface:   MakeVariant("org.freedesktop.DBus"),
   285  		FieldMember:      MakeVariant("Hello"),
   286  	},
   287  }
   288  
   289  // org.freedesktop.Notifications.Notify
   290  var bigMessage = &Message{
   291  	Type:   TypeMethodCall,
   292  	serial: 2,
   293  	Headers: map[HeaderField]Variant{
   294  		FieldDestination: MakeVariant("org.freedesktop.Notifications"),
   295  		FieldPath:        MakeVariant(ObjectPath("/org/freedesktop/Notifications")),
   296  		FieldInterface:   MakeVariant("org.freedesktop.Notifications"),
   297  		FieldMember:      MakeVariant("Notify"),
   298  		FieldSignature:   MakeVariant(Signature{"susssasa{sv}i"}),
   299  	},
   300  	Body: []interface{}{
   301  		"app_name",
   302  		uint32(0),
   303  		"dialog-information",
   304  		"Notification",
   305  		"This is the body of a notification",
   306  		[]string{"ok", "Ok"},
   307  		map[string]Variant{
   308  			"sound-name": MakeVariant("dialog-information"),
   309  		},
   310  		int32(-1),
   311  	},
   312  }
   313  
   314  func BenchmarkDecodeMessageSmall(b *testing.B) {
   315  	var err error
   316  	var rd *bytes.Reader
   317  
   318  	b.StopTimer()
   319  	buf := new(bytes.Buffer)
   320  	err = smallMessage.EncodeTo(buf, binary.LittleEndian)
   321  	if err != nil {
   322  		b.Fatal(err)
   323  	}
   324  	decoded := buf.Bytes()
   325  	b.StartTimer()
   326  	for i := 0; i < b.N; i++ {
   327  		rd = bytes.NewReader(decoded)
   328  		_, err = DecodeMessage(rd)
   329  		if err != nil {
   330  			b.Fatal(err)
   331  		}
   332  	}
   333  }
   334  
   335  func BenchmarkDecodeMessageBig(b *testing.B) {
   336  	var err error
   337  	var rd *bytes.Reader
   338  
   339  	b.StopTimer()
   340  	buf := new(bytes.Buffer)
   341  	err = bigMessage.EncodeTo(buf, binary.LittleEndian)
   342  	if err != nil {
   343  		b.Fatal(err)
   344  	}
   345  	decoded := buf.Bytes()
   346  	b.StartTimer()
   347  	for i := 0; i < b.N; i++ {
   348  		rd = bytes.NewReader(decoded)
   349  		_, err = DecodeMessage(rd)
   350  		if err != nil {
   351  			b.Fatal(err)
   352  		}
   353  	}
   354  }
   355  
   356  func BenchmarkEncodeMessageSmall(b *testing.B) {
   357  	var err error
   358  	for i := 0; i < b.N; i++ {
   359  		err = smallMessage.EncodeTo(ioutil.Discard, binary.LittleEndian)
   360  		if err != nil {
   361  			b.Fatal(err)
   362  		}
   363  	}
   364  }
   365  
   366  func BenchmarkEncodeMessageBig(b *testing.B) {
   367  	var err error
   368  	for i := 0; i < b.N; i++ {
   369  		err = bigMessage.EncodeTo(ioutil.Discard, binary.LittleEndian)
   370  		if err != nil {
   371  			b.Fatal(err)
   372  		}
   373  	}
   374  }
   375  

View as plain text