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  }