fake_dbus.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package dbus
  14. import (
  15. "fmt"
  16. "sync"
  17. godbus "github.com/godbus/dbus"
  18. )
  19. // Fake is a simple fake Interface type.
  20. type Fake struct {
  21. systemBus *FakeConnection
  22. sessionBus *FakeConnection
  23. }
  24. // FakeConnection represents a fake D-Bus connection
  25. type FakeConnection struct {
  26. lock sync.Mutex
  27. busObject *fakeObject
  28. objects map[string]*fakeObject
  29. signalHandlers []chan<- *godbus.Signal
  30. }
  31. // FakeHandler is used to handle fake D-Bus method calls
  32. type FakeHandler func(method string, args ...interface{}) ([]interface{}, error)
  33. type fakeObject struct {
  34. handler FakeHandler
  35. }
  36. type fakeCall struct {
  37. ret []interface{}
  38. err error
  39. }
  40. // NewFake returns a new Interface which will fake talking to D-Bus
  41. func NewFake(systemBus *FakeConnection, sessionBus *FakeConnection) *Fake {
  42. return &Fake{systemBus, sessionBus}
  43. }
  44. // NewFakeConnection returns a FakeConnection Interface
  45. func NewFakeConnection() *FakeConnection {
  46. return &FakeConnection{
  47. objects: make(map[string]*fakeObject),
  48. }
  49. }
  50. // SystemBus is part of Interface
  51. func (db *Fake) SystemBus() (Connection, error) {
  52. if db.systemBus != nil {
  53. return db.systemBus, nil
  54. }
  55. return nil, fmt.Errorf("DBus is not running")
  56. }
  57. // SessionBus is part of Interface
  58. func (db *Fake) SessionBus() (Connection, error) {
  59. if db.sessionBus != nil {
  60. return db.sessionBus, nil
  61. }
  62. return nil, fmt.Errorf("DBus is not running")
  63. }
  64. // BusObject is part of the Connection interface
  65. func (conn *FakeConnection) BusObject() Object {
  66. return conn.busObject
  67. }
  68. // Object is part of the Connection interface
  69. func (conn *FakeConnection) Object(name, path string) Object {
  70. return conn.objects[name+path]
  71. }
  72. // Signal is part of the Connection interface
  73. func (conn *FakeConnection) Signal(ch chan<- *godbus.Signal) {
  74. conn.lock.Lock()
  75. defer conn.lock.Unlock()
  76. for i := range conn.signalHandlers {
  77. if conn.signalHandlers[i] == ch {
  78. conn.signalHandlers = append(conn.signalHandlers[:i], conn.signalHandlers[i+1:]...)
  79. return
  80. }
  81. }
  82. conn.signalHandlers = append(conn.signalHandlers, ch)
  83. }
  84. // SetBusObject sets the handler for the BusObject of conn
  85. func (conn *FakeConnection) SetBusObject(handler FakeHandler) {
  86. conn.busObject = &fakeObject{handler}
  87. }
  88. // AddObject adds a handler for the Object at name and path
  89. func (conn *FakeConnection) AddObject(name, path string, handler FakeHandler) {
  90. conn.objects[name+path] = &fakeObject{handler}
  91. }
  92. // EmitSignal emits a signal on conn
  93. func (conn *FakeConnection) EmitSignal(name, path, iface, signal string, args ...interface{}) {
  94. conn.lock.Lock()
  95. defer conn.lock.Unlock()
  96. sig := &godbus.Signal{
  97. Sender: name,
  98. Path: godbus.ObjectPath(path),
  99. Name: iface + "." + signal,
  100. Body: args,
  101. }
  102. for _, ch := range conn.signalHandlers {
  103. ch <- sig
  104. }
  105. }
  106. // Call is part of the Object interface
  107. func (obj *fakeObject) Call(method string, flags godbus.Flags, args ...interface{}) Call {
  108. ret, err := obj.handler(method, args...)
  109. return &fakeCall{ret, err}
  110. }
  111. // Store is part of the Call interface
  112. func (call *fakeCall) Store(retvalues ...interface{}) error {
  113. if call.err != nil {
  114. return call.err
  115. }
  116. return godbus.Store(call.ret, retvalues...)
  117. }