package broker import ( "strings" "testing" ) // Which bus the mesh is on is one fact, and being told about both is refused. // // **Not a warning.** A mesh half on each bus is one where a declaration goes out on one and the // report comes back on the other, and every component reports success while it happens — which is // the exact failure ADR 0074 exists to catch, arriving through configuration instead of through code. func TestBeingToldAboutBothBusesIsRefused(t *testing.T) { err := MustBeOneBus("amqps://broker:5671/", "nats://bus:4222") if err == nil { t.Fatal("a control plane told about both buses was allowed to start") } // The remedy is in the words, because whoever reads this has to choose one and the wrong choice // is a rollout half done. for _, want := range []string{AMQPVarName, NATSVar, "unset"} { if !strings.Contains(err.Error(), want) { t.Errorf("the refusal does not mention %s: %v", want, err) } } } // One bus, or none, is ordinary. None is a control plane that publishes nothing and holds records, // which several of its own commands are. func TestOneBusOrNeitherIsAllowed(t *testing.T) { for _, c := range []struct{ what, amqp, nats string }{ {"the bus the mesh runs on today", "amqps://broker:5671/", ""}, {"the bus being built", "", "nats://bus:4222"}, {"neither", "", ""}, {"neither, with whitespace for an address", " ", "\t"}, } { if err := MustBeOneBus(c.amqp, c.nats); err != nil { t.Errorf("%s was refused: %v", c.what, err) } } } // The controller's own credential arrives in its address, and has to be readable out of it — its user // is created by the installer at a bootstrap password, before the controller exists to mint one. func TestACredentialIsReadOutOfABusAddress(t *testing.T) { for _, c := range []struct{ in, user, password, bare string }{ {"nats://controller:secret@127.0.0.1:4222", "controller", "secret", "nats://127.0.0.1:4222"}, {"controller:secret@127.0.0.1:4222", "controller", "secret", "127.0.0.1:4222"}, {"nats://127.0.0.1:4222", "", "", "nats://127.0.0.1:4222"}, {"127.0.0.1:4222", "", "", "127.0.0.1:4222"}, // A password containing an at-sign: split on the last one, or the address becomes part of the // credential and the connection goes somewhere nobody named. {"nats://controller:a@b@127.0.0.1:4222", "controller", "a@b", "nats://127.0.0.1:4222"}, } { user, password, bare := CredentialIn(c.in) if user != c.user || password != c.password || bare != c.bare { t.Errorf("%q read as %q/%q at %q; wanted %q/%q at %q", c.in, user, password, bare, c.user, c.password, c.bare) } } }