github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/commands/debughooks_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package commands
     5  
     6  import (
     7  	"regexp"
     8  	"runtime"
     9  
    10  	"github.com/juju/cmd/cmdtesting"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	jujussh "github.com/juju/juju/network/ssh"
    15  )
    16  
    17  var _ = gc.Suite(&DebugHooksSuite{})
    18  
    19  type DebugHooksSuite struct {
    20  	SSHCommonSuite
    21  }
    22  
    23  var debugHooksTests = []struct {
    24  	info        string
    25  	args        []string
    26  	hostChecker jujussh.ReachableChecker
    27  	forceAPIv1  bool
    28  	error       string
    29  	expected    *argsSpec
    30  }{{
    31  	info:        "literal script (api v1: unit name w/o hook or proxy)",
    32  	args:        []string{"mysql/0"},
    33  	hostChecker: validAddresses("0.private", "0.public"),
    34  	forceAPIv1:  true,
    35  	expected: &argsSpec{
    36  		hostKeyChecking: "yes",
    37  		knownHosts:      "0",
    38  		args:            "ubuntu@0.public sudo /bin/bash -c 'F=$(mktemp); echo IyEvYmluL2Jhc2gKKApjbGVhbnVwX29uX2V4aXQoKSAKeyAKCWVjaG8gIkNsZWFuaW5nIHVwIHRoZSBkZWJ1ZyBzZXNzaW9uIgoJdG11eCBraWxsLXNlc3Npb24gLXQgbXlzcWwvMDsgCn0KdHJhcCBjbGVhbnVwX29uX2V4aXQgRVhJVAoKIyBMb2NrIHRoZSBqdWp1LTx1bml0Pi1kZWJ1ZyBsb2NrZmlsZS4KZmxvY2sgLW4gOCB8fCAoCgllY2hvICJGb3VuZCBleGlzdGluZyBkZWJ1ZyBzZXNzaW9ucywgYXR0ZW1wdGluZyB0byByZWNvbm5lY3QiIDI+JjEKCWV4ZWMgdG11eCBhdHRhY2gtc2Vzc2lvbiAtdCBteXNxbC8wCglleGl0ICQ/CgkpCigKIyBDbG9zZSB0aGUgaW5oZXJpdGVkIGxvY2sgRkQsIG9yIHRtdXggd2lsbCBrZWVwIGl0IG9wZW4uCmV4ZWMgOD4mLQoKIyBXcml0ZSBvdXQgdGhlIGRlYnVnLWhvb2tzIGFyZ3MuCmVjaG8gImUzMEsiIHwgYmFzZTY0IC1kID4gL3RtcC9qdWp1LXVuaXQtbXlzcWwtMC1kZWJ1Zy1ob29rcwoKIyBMb2NrIHRoZSBqdWp1LTx1bml0Pi1kZWJ1Zy1leGl0IGxvY2tmaWxlLgpmbG9jayAtbiA5IHx8IGV4aXQgMQoKIyBXYWl0IGZvciB0bXV4IHRvIGJlIGluc3RhbGxlZC4Kd2hpbGUgWyAhIC1mIC91c3IvYmluL3RtdXggXTsgZG8KICAgIHNsZWVwIDEKZG9uZQoKaWYgWyAhIC1mIH4vLnRtdXguY29uZiBdOyB0aGVuCiAgICAgICAgaWYgWyAtZiAvdXNyL3NoYXJlL2J5b2J1L3Byb2ZpbGVzL3RtdXggXTsgdGhlbgogICAgICAgICAgICAgICAgIyBVc2UgYnlvYnUvdG11eCBwcm9maWxlIGZvciBmYW1pbGlhciBrZXliaW5kaW5ncyBhbmQgYnJhbmRpbmcKICAgICAgICAgICAgICAgIGVjaG8gInNvdXJjZS1maWxlIC91c3Ivc2hhcmUvYnlvYnUvcHJvZmlsZXMvdG11eCIgPiB+Ly50bXV4LmNvbmYKICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAjIE90aGVyd2lzZSwgdXNlIHRoZSBsZWdhY3kganVqdS90bXV4IGNvbmZpZ3VyYXRpb24KICAgICAgICAgICAgICAgIGNhdCA+IH4vLnRtdXguY29uZiA8PEVORAogICAgICAgICAgICAgICAgCiMgU3RhdHVzIGJhcgpzZXQtb3B0aW9uIC1nIHN0YXR1cy1iZyBibGFjawpzZXQtb3B0aW9uIC1nIHN0YXR1cy1mZyB3aGl0ZQoKc2V0LXdpbmRvdy1vcHRpb24gLWcgd2luZG93LXN0YXR1cy1jdXJyZW50LWJnIHJlZApzZXQtd2luZG93LW9wdGlvbiAtZyB3aW5kb3ctc3RhdHVzLWN1cnJlbnQtYXR0ciBicmlnaHQKCnNldC1vcHRpb24gLWcgc3RhdHVzLXJpZ2h0ICcnCgojIFBhbmVzCnNldC1vcHRpb24gLWcgcGFuZS1ib3JkZXItZmcgd2hpdGUKc2V0LW9wdGlvbiAtZyBwYW5lLWFjdGl2ZS1ib3JkZXItZmcgd2hpdGUKCiMgTW9uaXRvciBhY3Rpdml0eSBvbiB3aW5kb3dzCnNldC13aW5kb3ctb3B0aW9uIC1nIG1vbml0b3ItYWN0aXZpdHkgb24KCiMgU2NyZWVuIGJpbmRpbmdzLCBzaW5jZSBwZW9wbGUgYXJlIG1vcmUgZmFtaWxpYXIgd2l0aCB0aGF0LgpzZXQtb3B0aW9uIC1nIHByZWZpeCBDLWEKYmluZCBDLWEgbGFzdC13aW5kb3cKYmluZCBhIHNlbmQta2V5IEMtYQoKYmluZCB8IHNwbGl0LXdpbmRvdyAtaApiaW5kIC0gc3BsaXQtd2luZG93IC12CgojIEZpeCBDVFJMLVBHVVAvUEdET1dOIGZvciB2aW0Kc2V0LXdpbmRvdy1vcHRpb24gLWcgeHRlcm0ta2V5cyBvbgoKIyBQcmV2ZW50IEVTQyBrZXkgZnJvbSBhZGRpbmcgZGVsYXkgYW5kIGJyZWFraW5nIFZpbSdzIEVTQyA+IGFycm93IGtleQpzZXQtb3B0aW9uIC1zIGVzY2FwZS10aW1lIDAKCkVORAogICAgICAgIGZpCmZpCgooCiAgICAjIENsb3NlIHRoZSBpbmhlcml0ZWQgbG9jayBGRCwgb3IgdG11eCB3aWxsIGtlZXAgaXQgb3Blbi4KICAgIGV4ZWMgOT4mLQogICAgaWYgISB0bXV4IGhhcy1zZXNzaW9uIC10IG15c3FsLzA7IHRoZW4KCQl0bXV4IG5ldy1zZXNzaW9uIC1kIC1zIG15c3FsLzAKCWZpCgljbGllbnRfY291bnQ9JCh0bXV4IGxpc3QtY2xpZW50cyB8IHdjIC1sKQoJaWYgWyAkY2xpZW50X2NvdW50IC1nZSAxIF07IHRoZW4KCQlzZXNzaW9uX25hbWU9bXlzcWwvMCItIiRjbGllbnRfY250CgkJZXhlYyB0bXV4IG5ldy1zZXNzaW9uIC1kIC10IG15c3FsLzAgLXMgJHNlc3Npb25fbmFtZQoJCWV4ZWMgdG11eCBhdHRhY2gtc2Vzc2lvbiAtdCAkc2Vzc2lvbl9uYW1lIFw7IHNldC1vcHRpb24gZGVzdHJveS11bmF0dGFjaGVkCgllbHNlCgkgICAgZXhlYyB0bXV4IGF0dGFjaC1zZXNzaW9uIC10IG15c3FsLzAKCWZpCikKKSA5Pi90bXAvanVqdS11bml0LW15c3FsLTAtZGVidWctaG9va3MtZXhpdAopIDg+L3RtcC9qdWp1LXVuaXQtbXlzcWwtMC1kZWJ1Zy1ob29rcwpleGl0ICQ/Cg== | base64 -d > $F; . $F'",
    39  	},
    40  }, {
    41  	info:        "unit name without hook (api v1)",
    42  	args:        []string{"mysql/0"},
    43  	hostChecker: validAddresses("0.private", "0.public"),
    44  	forceAPIv1:  true,
    45  	expected: &argsSpec{
    46  		hostKeyChecking: "yes",
    47  		knownHosts:      "0",
    48  		argsMatch:       `ubuntu@0\.public sudo /bin/bash .+`,
    49  	},
    50  }, {
    51  	info:        "unit name without hook (api v2)",
    52  	args:        []string{"mysql/0"},
    53  	hostChecker: validAddresses("0.private", "0.public", "0.1.2.3"), // set by setAddresses() and setLinkLayerDevicesAddresses()
    54  	forceAPIv1:  false,
    55  	expected: &argsSpec{
    56  		hostKeyChecking: "yes",
    57  		knownHosts:      "0",
    58  		argsMatch:       `ubuntu@0\.(private|public|1\.2\.3) sudo .+`, // can be any of the 3
    59  	},
    60  }, {
    61  	info:        "proxy (api v1)",
    62  	args:        []string{"--proxy=true", "mysql/0"},
    63  	hostChecker: validAddresses("0.private", "0.public"),
    64  	forceAPIv1:  true,
    65  	expected: &argsSpec{
    66  		hostKeyChecking: "yes",
    67  		knownHosts:      "0",
    68  		withProxy:       true,
    69  		argsMatch:       `ubuntu@0\.private sudo /bin/bash .+`,
    70  	},
    71  }, {
    72  	info:        "proxy (api v2)",
    73  	args:        []string{"--proxy=true", "mysql/0"},
    74  	hostChecker: validAddresses("0.private", "0.public", "0.1.2.3"), // set by setAddresses() and setLinkLayerDevicesAddresses()
    75  	forceAPIv1:  false,
    76  	expected: &argsSpec{
    77  		hostKeyChecking: "yes",
    78  		knownHosts:      "0",
    79  		withProxy:       true,
    80  		argsMatch:       `ubuntu@0\.(private|public|1\.2\.3) sudo .+`, // can be any of the 3
    81  	},
    82  }, {
    83  	info:        "pty enabled",
    84  	args:        []string{"--pty=true", "mysql/0"},
    85  	hostChecker: validAddresses("0.private", "0.public", "0.1.2.3"), // set by setAddresses() and setLinkLayerDevicesAddresses()
    86  	forceAPIv1:  false,
    87  	expected: &argsSpec{
    88  		hostKeyChecking: "yes",
    89  		knownHosts:      "0",
    90  		enablePty:       true,
    91  		argsMatch:       `ubuntu@0\.(private|public|1\.2\.3) sudo .+`, // can be any of the 3
    92  	},
    93  }, {
    94  	info:        `"*" is a valid hook name: it means hook everything`,
    95  	args:        []string{"mysql/0", "*"},
    96  	hostChecker: validAddresses("0.public"),
    97  	expected:    nil,
    98  }, {
    99  	info:        `"*" mixed with named hooks is equivalent to "*"`,
   100  	args:        []string{"mysql/0", "*", "relation-get"},
   101  	hostChecker: validAddresses("0.public"),
   102  	expected:    nil,
   103  }, {
   104  	info:        `multiple named hooks may be specified`,
   105  	args:        []string{"mysql/0", "start", "stop"},
   106  	hostChecker: validAddresses("0.public"),
   107  	expected:    nil,
   108  }, {
   109  	info:        `relation hooks have the relation name prefixed`,
   110  	args:        []string{"mysql/0", "juju-info-relation-joined"},
   111  	hostChecker: validAddresses("0.public"),
   112  	expected:    nil,
   113  }, {
   114  	info:  `invalid unit syntax`,
   115  	args:  []string{"mysql"},
   116  	error: `"mysql" is not a valid unit name`,
   117  }, {
   118  	info:  `invalid unit`,
   119  	args:  []string{"nonexistent/123"},
   120  	error: `unit "nonexistent/123" not found`,
   121  }, {
   122  	info:  `invalid hook`,
   123  	args:  []string{"mysql/0", "invalid-hook"},
   124  	error: `unit "mysql/0" contains neither hook nor action "invalid-hook", valid actions are [fakeaction] and valid hooks are [collect-metrics config-changed install juju-info-relation-broken juju-info-relation-changed juju-info-relation-departed juju-info-relation-joined leader-deposed leader-elected leader-settings-changed meter-status-changed metrics-client-relation-broken metrics-client-relation-changed metrics-client-relation-departed metrics-client-relation-joined post-series-upgrade pre-series-upgrade server-admin-relation-broken server-admin-relation-changed server-admin-relation-departed server-admin-relation-joined server-relation-broken server-relation-changed server-relation-departed server-relation-joined start stop update-status upgrade-charm]`,
   125  }, {
   126  	info:  `no args at all`,
   127  	args:  nil,
   128  	error: `no unit name specified`,
   129  }}
   130  
   131  func (s *DebugHooksSuite) TestDebugHooksCommand(c *gc.C) {
   132  	//TODO(bogdanteleaga): Fix once debughooks are supported on windows
   133  	if runtime.GOOS == "windows" {
   134  		c.Skip("bug 1403084: Skipping on windows for now")
   135  	}
   136  
   137  	s.setupModel(c)
   138  
   139  	for i, t := range debugHooksTests {
   140  		c.Logf("test %d: %s\n\t%s\n", i, t.info, t.args)
   141  
   142  		s.setHostChecker(t.hostChecker)
   143  		s.setForceAPIv1(t.forceAPIv1)
   144  
   145  		ctx, err := cmdtesting.RunCommand(c, newDebugHooksCommand(s.hostChecker), t.args...)
   146  		if t.error != "" {
   147  			c.Check(err, gc.ErrorMatches, regexp.QuoteMeta(t.error))
   148  		} else {
   149  			c.Check(err, jc.ErrorIsNil)
   150  			if t.expected != nil {
   151  				t.expected.check(c, cmdtesting.Stdout(ctx))
   152  			}
   153  		}
   154  	}
   155  }