Files
kopia/cli/command_server_notifications_test.go
2025-04-26 13:01:20 -07:00

105 lines
2.9 KiB
Go

package cli_test
import (
"bytes"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/kopia/kopia/internal/testutil"
"github.com/kopia/kopia/notification/sender"
"github.com/kopia/kopia/tests/testenv"
)
func TestServerNotifications(t *testing.T) {
mux := http.NewServeMux()
notificationsReceived := make(chan string, 100)
mux.HandleFunc("/notification-webhook", func(w http.ResponseWriter, r *http.Request) {
var b bytes.Buffer
io.Copy(&b, r.Body)
notificationsReceived <- b.String()
})
server := httptest.NewServer(mux)
defer server.Close()
env := testenv.NewCLITest(t, testenv.RepoFormatNotImportant, testenv.NewInProcRunner(t))
dir0 := testutil.TempDirectory(t)
dir1 := testutil.TempDirectory(t)
dir2 := testutil.TempDirectory(t)
env.RunAndExpectSuccess(t, "repo", "create", "filesystem", "--path", env.RepoDir, "--override-username=another-user", "--override-hostname=another-host")
env.RunAndExpectSuccess(t, "snap", "create", dir0)
env.RunAndExpectSuccess(t, "repo", "connect", "filesystem", "--path", env.RepoDir, "--override-username=test-user", "--override-hostname=test-host")
env.RunAndExpectSuccess(t, "snap", "create", dir1)
env.RunAndExpectSuccess(t, "snap", "create", dir2)
// setup webhook notification
env.RunAndExpectSuccess(t, "notification", "profile", "configure", "webhook", "--profile-name=mywebhook", "--endpoint="+server.URL+"/notification-webhook", "--method=POST", "--format=html")
var sp testutil.ServerParameters
jsonNotificationsReceived := make(chan string, 100)
wait, kill := env.RunAndProcessStderrAsync(t, sp.ProcessOutput, func(line string) {
const prefix = "NOTIFICATION: "
if strings.HasPrefix(line, prefix) {
t.Logf("JSON notification received: %v", line)
jsonNotificationsReceived <- line[len(prefix):]
}
}, "server", "start",
"--address=localhost:0",
"--insecure",
"--random-server-control-password",
"--kopiaui-notifications",
"--shutdown-grace-period", "100ms",
)
defer func() {
kill()
wait()
}()
// trigger server snapshot
env.RunAndExpectSuccess(t, "server", "snapshot", "--address", sp.BaseURL, "--server-control-password", sp.ServerControlPassword, dir1)
select {
case not := <-notificationsReceived:
t.Logf("notification received: %v", not)
assert.Contains(t, not, "snapshotstatus-success")
case <-time.After(5 * time.Second):
t.Error("notification not received in time")
}
select {
case not := <-jsonNotificationsReceived:
// make sure we received a valid sender.Message JSON
dec := json.NewDecoder(strings.NewReader(not))
dec.DisallowUnknownFields()
var msg sender.Message
require.NoError(t, dec.Decode(&msg))
require.Contains(t, msg.Subject, "Successfully created a snapshot of")
case <-time.After(5 * time.Second):
t.Error("notification not received in time")
}
}