gitee.com/mysnapcore/mysnapd@v0.1.0/dbusutil/netplantest/netplantest.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2021 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 // netplantest provides a fake implementation of the netplan dbus API for 21 // testing. Unlike the real netplan-dbus it uses the session bus but that 22 // is good enough for the testing. See configcore/netplan_test.go for 23 // example usage. 24 package netplantest 25 26 import ( 27 "fmt" 28 29 "github.com/godbus/dbus" 30 31 "gitee.com/mysnapcore/mysnapd/dbusutil" 32 ) 33 34 const ( 35 netplanBusName = "io.netplan.Netplan" 36 netplanObjectPath = "/io/netplan/Netplan" 37 netplanInterface = "io.netplan.Netplan" 38 39 netplanConfigInterface = "io.netplan.Netplan.Config" 40 ) 41 42 type NetplanServer struct { 43 conn *dbus.Conn 44 45 MockNetplanConfigYaml string 46 47 ConfigErr *dbus.Error 48 49 ConfigApiGetCalls int 50 ConfigApiGetErr *dbus.Error 51 52 ConfigApiSetCalls []string 53 ConfigApiSetRet bool 54 ConfigApiSetErr *dbus.Error 55 56 ConfigApiApplyCalls int 57 ConfigApiApplyRet bool 58 ConfigApiApplyErr *dbus.Error 59 60 ConfigApiTryCalls int 61 ConfigApiTryRet bool 62 ConfigApiTryErr *dbus.Error 63 64 ConfigApiCancelCalls int 65 ConfigApiCancelRet bool 66 ConfigApiCancelErr *dbus.Error 67 } 68 69 func NewNetplanServer(mockNetplanConfigYaml string) (*NetplanServer, error) { 70 // we use a private bus for testing 71 conn, err := dbusutil.SessionBusPrivate() 72 if err != nil { 73 return nil, err 74 } 75 76 server := &NetplanServer{ 77 conn: conn, 78 MockNetplanConfigYaml: mockNetplanConfigYaml, 79 } 80 81 reply, err := conn.RequestName(netplanBusName, dbus.NameFlagDoNotQueue) 82 if err != nil { 83 conn.Close() 84 return nil, err 85 } 86 87 if reply != dbus.RequestNameReplyPrimaryOwner { 88 conn.Close() 89 return nil, fmt.Errorf("cannot obtain bus name %q", netplanBusName) 90 } 91 return server, nil 92 } 93 94 func (server *NetplanServer) ExportApiV1() { 95 // netplanApiV1 implements the original netplan DBus API that is found 96 // in netplan 0.98. It can only do a global "Apply". 97 server.conn.Export(netplanApiV1{server}, netplanObjectPath, netplanInterface) 98 } 99 100 func (server *NetplanServer) ExportApiV2() { 101 // netplanApiV2 implements the "Config/Get/Set/Try" API that is found 102 // in netplan 0.101-0ubuntu3. 103 server.conn.Export(netplanApiV2{netplanApiV1{server}}, netplanObjectPath, netplanInterface) 104 } 105 106 func (server *NetplanServer) Stop() error { 107 if _, err := server.conn.ReleaseName(netplanBusName); err != nil { 108 return err 109 } 110 return server.conn.Close() 111 } 112 113 // netplanApiV1 implements the original netplan DBus API that is found 114 // in netplan 0.98. It can only do a global "Apply". 115 type netplanApiV1 struct { 116 server *NetplanServer 117 } 118 119 func (a netplanApiV1) Apply() (bool, *dbus.Error) { 120 return true, a.server.ConfigApiApplyErr 121 } 122 123 // netplanApiV2 implements the "Config/Get/Set/Try" API that is found 124 // in netplan 0.101-0ubuntu3. 125 type netplanApiV2 struct { 126 netplanApiV1 127 } 128 129 func (a netplanApiV2) Config() (dbus.ObjectPath, *dbus.Error) { 130 path := dbus.ObjectPath("/io/netplan/Netplan/config/WFIU80") 131 a.server.conn.Export(netplanConfigApi{a.server, path}, path, netplanConfigInterface) 132 133 return path, a.server.ConfigErr 134 } 135 136 type netplanConfigApi struct { 137 server *NetplanServer 138 139 path dbus.ObjectPath 140 } 141 142 func (c netplanConfigApi) Get() (string, *dbus.Error) { 143 c.server.ConfigApiGetCalls++ 144 return c.server.MockNetplanConfigYaml, c.server.ConfigApiGetErr 145 } 146 147 func (c netplanConfigApi) Set(value, originHint string) (bool, *dbus.Error) { 148 c.server.ConfigApiSetCalls = append(c.server.ConfigApiSetCalls, fmt.Sprintf("%s/%s", value, originHint)) 149 return c.server.ConfigApiSetRet, c.server.ConfigApiSetErr 150 } 151 152 func (c netplanConfigApi) Apply() (bool, *dbus.Error) { 153 c.server.ConfigApiApplyCalls++ 154 return c.server.ConfigApiApplyRet, c.server.ConfigApiApplyErr 155 } 156 157 func (c netplanConfigApi) Cancel() (bool, *dbus.Error) { 158 c.server.ConfigApiCancelCalls++ 159 return c.server.ConfigApiCancelRet, c.server.ConfigApiCancelErr 160 } 161 162 func (c netplanConfigApi) Try(timeout int) (bool, *dbus.Error) { 163 c.server.ConfigApiTryCalls++ 164 return c.server.ConfigApiTryRet, c.server.ConfigApiTryErr 165 }