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 }