process.Conn.Keeps, stdio.Keeps and the TypeScript keeps publish the announcement on the module's own subject; afterwards a state the code did not announce is refused at the call, so announcement and code cannot drift. The package goes to 0.1.15 for keeps.
102 lines
3.7 KiB
Go
102 lines
3.7 KiB
Go
//go:build integration
|
|
|
|
package process
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/nats-io/nats-server/v2/server"
|
|
"github.com/nats-io/nats.go"
|
|
"github.com/nats-io/nats.go/jetstream"
|
|
)
|
|
|
|
// sendUser and sendPassword are mesh-mail's process "send" on novox, as mesh-controller would mint it
|
|
// (mesh-controller internal/broker/process_grants_test.go mailSenderProcess, Principal.Username).
|
|
const (
|
|
sendUser = "novox.mesh-mail.send"
|
|
sendPassword = "the-pw"
|
|
adminUser = "admin"
|
|
adminPass = "admin-pw"
|
|
)
|
|
|
|
// sendGrants is the process principal mailSenderProcess's whole publish set, copied from
|
|
// mesh-controller internal/broker/process_grants_test.go (TestAProcessIsGrantedExactlyItsBusDeclaration,
|
|
// "dumped from a passing run... 16 subjects, correct today"), since this package may not import the
|
|
// controller: the exact grant the controller composes for novox.mesh-mail.send.
|
|
var sendGrants = []string{
|
|
"$JS.ACK.MAIL_SENDS.novox_mesh-mail_send.>",
|
|
"$JS.API.CONSUMER.CREATE.KV_mesh-mail_sends.>",
|
|
"$JS.API.CONSUMER.DELETE.KV_mesh-mail_sends.>",
|
|
"$JS.API.CONSUMER.INFO.MAIL_SENDS.novox_mesh-mail_send",
|
|
"$JS.API.CONSUMER.MSG.NEXT.MAIL_SENDS.novox_mesh-mail_send",
|
|
"$JS.API.DIRECT.GET.KV_mesh-mail_sends.>",
|
|
"$JS.API.DIRECT.GET.KV_messenger_asks.$KV.messenger_asks.mesh-mail.>",
|
|
"$JS.API.STREAM.INFO.KV_mesh-mail_sends",
|
|
"$JS.FC.KV_mesh-mail_sends.>",
|
|
"$KV.mesh-mail_sends.>",
|
|
"mesh.mod.mesh-mail.event.mail.send.failed",
|
|
"mesh.mod.mesh-mail.event.mail.send.sent",
|
|
"mesh.mod.mesh-mail.event.states",
|
|
"mesh.seat.operator-channel.call.tell.*.novox~mesh-mail~send",
|
|
"mesh.seat.operator-channel.call.tell.novox~mesh-mail~send",
|
|
"mesh.seat.operator-channel.tool.tell",
|
|
"mesh.seat.operator-channel.tool.tell.*",
|
|
}
|
|
|
|
// grantedSendProcess is a test bus with JetStream, with two users: novox.mesh-mail.send, permissioned to
|
|
// exactly sendGrants and its own inbox (nats-server server.Options Users with Permissions, as
|
|
// mesh-controller's cmd/mesh-controller/process_live_test.go composes accounts for a real bus — copied as
|
|
// literal grants here since this package may not import the controller); and an unrestricted admin for the
|
|
// test's own setup (creating streams and buckets, standing in for the holder and the runtime).
|
|
func grantedSendProcess(t *testing.T) (url string, account Account) {
|
|
t.Helper()
|
|
opts := &server.Options{Host: "127.0.0.1", Port: server.RANDOM_PORT, JetStream: true, StoreDir: t.TempDir(),
|
|
NoLog: true, NoSigs: true,
|
|
Users: []*server.User{
|
|
{Username: adminUser, Password: adminPass},
|
|
{Username: sendUser, Password: sendPassword, Permissions: &server.Permissions{
|
|
Publish: &server.SubjectPermission{Allow: sendGrants},
|
|
Subscribe: &server.SubjectPermission{Allow: []string{"_INBOX." + sendUser + ".>"}},
|
|
}},
|
|
},
|
|
}
|
|
s, err := server.NewServer(opts)
|
|
if err != nil {
|
|
t.Fatalf("a granted test bus could not be made: %v", err)
|
|
}
|
|
go s.Start()
|
|
if !s.ReadyForConnections(10 * time.Second) {
|
|
s.Shutdown()
|
|
t.Fatal("a granted test bus did not come up within 10s")
|
|
}
|
|
t.Cleanup(func() {
|
|
s.Shutdown()
|
|
s.WaitForShutdown()
|
|
})
|
|
url = s.ClientURL()
|
|
return url, Account{URL: url, Node: "novox", Module: "mesh-mail", User: sendUser, Password: sendPassword}
|
|
}
|
|
|
|
// adminJS is the test's own unrestricted connection to url, for setting up fixtures.
|
|
func adminJS(t *testing.T, url string) (*nats.Conn, jetstream.JetStream) {
|
|
t.Helper()
|
|
nc, err := nats.Connect(url, nats.UserInfo(adminUser, adminPass), nats.CustomInboxPrefix("_INBOX."+adminUser))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(nc.Close)
|
|
js, err := jetstream.New(nc)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return nc, js
|
|
}
|
|
|
|
func ctxFor(t *testing.T) context.Context {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
t.Cleanup(cancel)
|
|
return ctx
|
|
}
|