github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/overlord/servicestate/servicestate_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2015-2020 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  package servicestate_test
    21  
    22  import (
    23  	"bytes"
    24  	"fmt"
    25  	"os"
    26  	"path/filepath"
    27  	"strings"
    28  
    29  	. "gopkg.in/check.v1"
    30  
    31  	"github.com/snapcore/snapd/client"
    32  	"github.com/snapcore/snapd/dirs"
    33  	"github.com/snapcore/snapd/overlord/servicestate"
    34  	"github.com/snapcore/snapd/snap"
    35  	"github.com/snapcore/snapd/systemd"
    36  )
    37  
    38  type statusDecoratorSuite struct{}
    39  
    40  var _ = Suite(&statusDecoratorSuite{})
    41  
    42  func (s *statusDecoratorSuite) TestDecorateWithStatus(c *C) {
    43  	dirs.SetRootDir(c.MkDir())
    44  	defer dirs.SetRootDir("")
    45  	snp := &snap.Info{
    46  		SideInfo: snap.SideInfo{
    47  			RealName: "foo",
    48  			Revision: snap.R(1),
    49  		},
    50  	}
    51  	err := os.MkdirAll(snp.MountDir(), 0755)
    52  	c.Assert(err, IsNil)
    53  	err = os.Symlink(snp.Revision.String(), filepath.Join(filepath.Dir(snp.MountDir()), "current"))
    54  	c.Assert(err, IsNil)
    55  
    56  	disabled := false
    57  	r := systemd.MockSystemctl(func(args ...string) (buf []byte, err error) {
    58  		switch args[0] {
    59  		case "show":
    60  			c.Assert(args[0], Equals, "show")
    61  			unit := args[2]
    62  			activeState, unitState := "active", "enabled"
    63  			if disabled {
    64  				activeState = "inactive"
    65  				unitState = "disabled"
    66  			}
    67  			if strings.HasSuffix(unit, ".timer") || strings.HasSuffix(unit, ".socket") {
    68  				return []byte(fmt.Sprintf(`Id=%s
    69  ActiveState=%s
    70  UnitFileState=%s
    71  `, args[2], activeState, unitState)), nil
    72  			} else {
    73  				return []byte(fmt.Sprintf(`Id=%s
    74  Type=simple
    75  ActiveState=%s
    76  UnitFileState=%s
    77  `, args[2], activeState, unitState)), nil
    78  			}
    79  		case "--user":
    80  			c.Assert(args[1], Equals, "--global")
    81  			c.Assert(args[2], Equals, "is-enabled")
    82  			unitState := "enabled\n"
    83  			if disabled {
    84  				unitState = "disabled\n"
    85  			}
    86  			return bytes.Repeat([]byte(unitState), len(args)-3), nil
    87  		default:
    88  			c.Errorf("unexpected systemctl command: %v", args)
    89  			return nil, fmt.Errorf("should not be reached")
    90  		}
    91  	})
    92  	defer r()
    93  
    94  	sd := servicestate.NewStatusDecorator(nil)
    95  
    96  	// not a service
    97  	app := &client.AppInfo{
    98  		Snap: "foo",
    99  		Name: "app",
   100  	}
   101  	snapApp := &snap.AppInfo{Snap: snp, Name: "app"}
   102  
   103  	err = sd.DecorateWithStatus(app, snapApp)
   104  	c.Assert(err, IsNil)
   105  
   106  	for _, enabled := range []bool{true, false} {
   107  		disabled = !enabled
   108  
   109  		// service only
   110  		app = &client.AppInfo{
   111  			Snap:   snp.InstanceName(),
   112  			Name:   "svc",
   113  			Daemon: "simple",
   114  		}
   115  		snapApp = &snap.AppInfo{
   116  			Snap:        snp,
   117  			Name:        "svc",
   118  			Daemon:      "simple",
   119  			DaemonScope: snap.SystemDaemon,
   120  		}
   121  
   122  		err = sd.DecorateWithStatus(app, snapApp)
   123  		c.Assert(err, IsNil)
   124  		c.Check(app.Active, Equals, enabled)
   125  		c.Check(app.Enabled, Equals, enabled)
   126  
   127  		// service  + timer
   128  		app = &client.AppInfo{
   129  			Snap:   snp.InstanceName(),
   130  			Name:   "svc",
   131  			Daemon: "simple",
   132  		}
   133  		snapApp = &snap.AppInfo{
   134  			Snap:        snp,
   135  			Name:        "svc",
   136  			Daemon:      "simple",
   137  			DaemonScope: snap.SystemDaemon,
   138  		}
   139  		snapApp.Timer = &snap.TimerInfo{
   140  			App:   snapApp,
   141  			Timer: "10:00",
   142  		}
   143  
   144  		err = sd.DecorateWithStatus(app, snapApp)
   145  		c.Assert(err, IsNil)
   146  		c.Check(app.Active, Equals, enabled)
   147  		c.Check(app.Enabled, Equals, enabled)
   148  		c.Check(app.Activators, DeepEquals, []client.AppActivator{
   149  			{Name: "svc", Type: "timer", Active: enabled, Enabled: enabled},
   150  		})
   151  
   152  		// service with socket
   153  		app = &client.AppInfo{
   154  			Snap:   snp.InstanceName(),
   155  			Name:   "svc",
   156  			Daemon: "simple",
   157  		}
   158  		snapApp = &snap.AppInfo{
   159  			Snap:        snp,
   160  			Name:        "svc",
   161  			Daemon:      "simple",
   162  			DaemonScope: snap.SystemDaemon,
   163  		}
   164  		snapApp.Sockets = map[string]*snap.SocketInfo{
   165  			"socket1": {
   166  				App:          snapApp,
   167  				Name:         "socket1",
   168  				ListenStream: "a.socket",
   169  			},
   170  		}
   171  
   172  		err = sd.DecorateWithStatus(app, snapApp)
   173  		c.Assert(err, IsNil)
   174  		c.Check(app.Active, Equals, enabled)
   175  		c.Check(app.Enabled, Equals, enabled)
   176  		c.Check(app.Activators, DeepEquals, []client.AppActivator{
   177  			{Name: "socket1", Type: "socket", Active: enabled, Enabled: enabled},
   178  		})
   179  
   180  		// service with D-Bus activation
   181  		app = &client.AppInfo{
   182  			Snap:   snp.InstanceName(),
   183  			Name:   "svc",
   184  			Daemon: "simple",
   185  		}
   186  		snapApp = &snap.AppInfo{
   187  			Snap:        snp,
   188  			Name:        "svc",
   189  			Daemon:      "simple",
   190  			DaemonScope: snap.SystemDaemon,
   191  		}
   192  		snapApp.ActivatesOn = []*snap.SlotInfo{
   193  			{
   194  				Snap:      snp,
   195  				Name:      "dbus-slot",
   196  				Interface: "dbus",
   197  				Attrs: map[string]interface{}{
   198  					"bus":  "system",
   199  					"name": "org.example.Svc",
   200  				},
   201  			},
   202  		}
   203  
   204  		err = sd.DecorateWithStatus(app, snapApp)
   205  		c.Assert(err, IsNil)
   206  		c.Check(app.Active, Equals, enabled)
   207  		c.Check(app.Enabled, Equals, enabled)
   208  		c.Check(app.Activators, DeepEquals, []client.AppActivator{
   209  			{Name: "org.example.Svc", Type: "dbus", Active: true, Enabled: true},
   210  		})
   211  
   212  		// No state is currently extracted for user daemons
   213  		app = &client.AppInfo{
   214  			Snap:   snp.InstanceName(),
   215  			Name:   "svc",
   216  			Daemon: "simple",
   217  		}
   218  		snapApp = &snap.AppInfo{
   219  			Snap:        snp,
   220  			Name:        "svc",
   221  			Daemon:      "simple",
   222  			DaemonScope: snap.UserDaemon,
   223  		}
   224  		snapApp.Sockets = map[string]*snap.SocketInfo{
   225  			"socket1": {
   226  				App:          snapApp,
   227  				Name:         "socket1",
   228  				ListenStream: "a.socket",
   229  			},
   230  		}
   231  		snapApp.Timer = &snap.TimerInfo{
   232  			App:   snapApp,
   233  			Timer: "10:00",
   234  		}
   235  		snapApp.ActivatesOn = []*snap.SlotInfo{
   236  			{
   237  				Snap:      snp,
   238  				Name:      "dbus-slot",
   239  				Interface: "dbus",
   240  				Attrs: map[string]interface{}{
   241  					"bus":  "session",
   242  					"name": "org.example.Svc",
   243  				},
   244  			},
   245  		}
   246  
   247  		err = sd.DecorateWithStatus(app, snapApp)
   248  		c.Assert(err, IsNil)
   249  		c.Check(app.Active, Equals, false)
   250  		c.Check(app.Enabled, Equals, enabled)
   251  		c.Check(app.Activators, DeepEquals, []client.AppActivator{
   252  			{Name: "socket1", Type: "socket", Active: false, Enabled: enabled},
   253  			{Name: "svc", Type: "timer", Active: false, Enabled: enabled},
   254  			{Name: "org.example.Svc", Type: "dbus", Active: true, Enabled: true},
   255  		})
   256  	}
   257  }