Message filtering tests

This commit is contained in:
Philipp Heckel 2021-12-22 09:44:16 +01:00
parent 09bf13bd70
commit b6120cf6d7
5 changed files with 211 additions and 89 deletions

View file

@ -322,7 +322,7 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, _ *visito
func (s *Server) parseParams(r *http.Request, m *message) (cache bool, firebase bool, err error) {
cache = readParam(r, "x-cache", "cache") != "no"
firebase = readParam(r, "x-firebase", "firebase") != "no"
m.Title = readParam(r, "x-title", "title", "ti", "t")
m.Title = readParam(r, "x-title", "title", "t")
messageStr := readParam(r, "x-message", "message", "m")
if messageStr != "" {
m.Message = messageStr
@ -331,7 +331,7 @@ func (s *Server) parseParams(r *http.Request, m *message) (cache bool, firebase
if err != nil {
return false, false, errHTTPBadRequest
}
tagsStr := readParam(r, "x-tags", "tag", "tags", "ta")
tagsStr := readParam(r, "x-tags", "tags", "tag", "ta")
if tagsStr != "" {
m.Tags = make([]string, 0)
for _, s := range util.SplitNoEmpty(tagsStr, ",") {
@ -418,17 +418,17 @@ func (s *Server) handleSubscribe(w http.ResponseWriter, r *http.Request, v *visi
if err != nil {
return err
}
since, err := parseSince(r)
poll := readParam(r, "x-poll", "poll", "po") == "1"
scheduled := readParam(r, "x-scheduled", "scheduled", "sched") == "1"
since, err := parseSince(r, poll)
if err != nil {
return err
}
var wlock sync.Mutex
poll := r.URL.Query().Has("poll")
scheduled := r.URL.Query().Has("scheduled") || r.URL.Query().Has("sched")
messageFilter, titleFilter, priorityFilter, tagsFilter, err := parseQueryFilters(r)
if err != nil {
return err
}
var wlock sync.Mutex
sub := func(msg *message) error {
if !passesQueryFilter(msg, messageFilter, titleFilter, priorityFilter, tagsFilter) {
return nil
@ -481,11 +481,11 @@ func (s *Server) handleSubscribe(w http.ResponseWriter, r *http.Request, v *visi
}
func parseQueryFilters(r *http.Request) (messageFilter string, titleFilter string, priorityFilter int, tagsFilter []string, err error) {
messageFilter = r.URL.Query().Get("message")
titleFilter = r.URL.Query().Get("title")
tagsFilter = util.SplitNoEmpty(r.URL.Query().Get("tags"), ",")
priorityFilter, err = util.ParsePriority(r.URL.Query().Get("priority"))
return
messageFilter = readParam(r, "x-message", "message", "m")
titleFilter = readParam(r, "x-title", "title", "t")
tagsFilter = util.SplitNoEmpty(readParam(r, "x-tags", "tags", "tag", "ta"), ",")
priorityFilter, err = util.ParsePriority(readParam(r, "x-priority", "priority", "prio", "p"))
return // may be err!
}
func passesQueryFilter(msg *message, messageFilter string, titleFilter string, priorityFilter int, tagsFilter []string) bool {
@ -498,7 +498,11 @@ func passesQueryFilter(msg *message, messageFilter string, titleFilter string, p
if titleFilter != "" && msg.Title != titleFilter {
return false
}
if priorityFilter > 0 && (msg.Priority != priorityFilter || (msg.Priority == 0 && priorityFilter != 3)) {
messagePriority := msg.Priority
if messagePriority == 0 {
messagePriority = 3 // For query filters, default priority (3) is the same as "not set" (0)
}
if priorityFilter > 0 && messagePriority != priorityFilter {
return false
}
if len(tagsFilter) > 0 && !util.InStringListAll(msg.Tags, tagsFilter) {
@ -529,18 +533,19 @@ func (s *Server) sendOldMessages(topics []*topic, since sinceTime, scheduled boo
//
// Values in the "since=..." parameter can be either a unix timestamp or a duration (e.g. 12h), or
// "all" for all messages.
func parseSince(r *http.Request) (sinceTime, error) {
if !r.URL.Query().Has("since") {
if r.URL.Query().Has("poll") {
func parseSince(r *http.Request, poll bool) (sinceTime, error) {
since := readParam(r, "x-since", "since", "si")
if since == "" {
if poll {
return sinceAllMessages, nil
}
return sinceNoMessages, nil
}
if r.URL.Query().Get("since") == "all" {
if since == "all" {
return sinceAllMessages, nil
} else if s, err := strconv.ParseInt(r.URL.Query().Get("since"), 10, 64); err == nil {
} else if s, err := strconv.ParseInt(since, 10, 64); err == nil {
return sinceTime(time.Unix(s, 0)), nil
} else if d, err := time.ParseDuration(r.URL.Query().Get("since")); err == nil {
} else if d, err := time.ParseDuration(since); err == nil {
return sinceTime(time.Now().Add(-1 * d)), nil
}
return sinceNoMessages, errHTTPBadRequest

View file

@ -392,6 +392,98 @@ func TestServer_PublishFirebase(t *testing.T) {
time.Sleep(500 * time.Millisecond) // Time for sends
}
func TestServer_PollWithQueryFilters(t *testing.T) {
s := newTestServer(t, newTestConfig(t))
response := request(t, s, "PUT", "/mytopic?priority=1&tags=tag1,tag2", "my first message", nil)
msg := toMessage(t, response.Body.String())
require.NotEmpty(t, msg.ID)
response = request(t, s, "PUT", "/mytopic?title=a+title", "my second message", map[string]string{
"Tags": "tag2,tag3",
})
msg = toMessage(t, response.Body.String())
require.NotEmpty(t, msg.ID)
queriesThatShouldReturnMessageOne := []string{
"/mytopic/json?poll=1&priority=1",
"/mytopic/json?poll=1&priority=min",
"/mytopic/json?poll=1&tags=tag1",
"/mytopic/json?poll=1&tags=tag1,tag2",
"/mytopic/json?poll=1&message=my+first+message",
}
for _, query := range queriesThatShouldReturnMessageOne {
response = request(t, s, "GET", query, "", nil)
messages := toMessages(t, response.Body.String())
require.Equal(t, 1, len(messages), "Query failed: "+query)
require.Equal(t, "my first message", messages[0].Message, "Query failed: "+query)
}
queriesThatShouldReturnMessageTwo := []string{
"/mytopic/json?poll=1&x-priority=3", // !
"/mytopic/json?poll=1&priority=3",
"/mytopic/json?poll=1&priority=default",
"/mytopic/json?poll=1&p=3",
"/mytopic/json?poll=1&x-tags=tag2,tag3",
"/mytopic/json?poll=1&tags=tag2,tag3",
"/mytopic/json?poll=1&tag=tag2,tag3",
"/mytopic/json?poll=1&ta=tag2,tag3",
"/mytopic/json?poll=1&x-title=a+title",
"/mytopic/json?poll=1&title=a+title",
"/mytopic/json?poll=1&t=a+title",
"/mytopic/json?poll=1&x-message=my+second+message",
"/mytopic/json?poll=1&message=my+second+message",
"/mytopic/json?poll=1&m=my+second+message",
"/mytopic/json?x-poll=1&m=my+second+message",
"/mytopic/json?po=1&m=my+second+message",
}
for _, query := range queriesThatShouldReturnMessageTwo {
response = request(t, s, "GET", query, "", nil)
messages := toMessages(t, response.Body.String())
require.Equal(t, 1, len(messages), "Query failed: "+query)
require.Equal(t, "my second message", messages[0].Message, "Query failed: "+query)
}
queriesThatShouldReturnNoMessages := []string{
"/mytopic/json?poll=1&priority=4",
"/mytopic/json?poll=1&tags=tag1,tag2,tag3",
"/mytopic/json?poll=1&title=another+title",
"/mytopic/json?poll=1&message=my+third+message",
"/mytopic/json?poll=1&message=my+third+message",
}
for _, query := range queriesThatShouldReturnNoMessages {
response = request(t, s, "GET", query, "", nil)
messages := toMessages(t, response.Body.String())
require.Equal(t, 0, len(messages), "Query failed: "+query)
}
}
func TestServer_SubscribeWithQueryFilters(t *testing.T) {
c := newTestConfig(t)
c.KeepaliveInterval = 800 * time.Millisecond
s := newTestServer(t, c)
subscribeResponse := httptest.NewRecorder()
subscribeCancel := subscribe(t, s, "/mytopic/json?tags=zfs-issue", subscribeResponse)
response := request(t, s, "PUT", "/mytopic", "my first message", nil)
require.Equal(t, 200, response.Code)
response = request(t, s, "PUT", "/mytopic", "ZFS scrub failed", map[string]string{
"Tags": "zfs-issue,zfs-scrub",
})
require.Equal(t, 200, response.Code)
time.Sleep(850 * time.Millisecond)
subscribeCancel()
messages := toMessages(t, subscribeResponse.Body.String())
require.Equal(t, 3, len(messages))
require.Equal(t, openEvent, messages[0].Event)
require.Equal(t, messageEvent, messages[1].Event)
require.Equal(t, "ZFS scrub failed", messages[1].Message)
require.Equal(t, keepaliveEvent, messages[2].Event)
}
func newTestConfig(t *testing.T) *Config {
conf := NewConfig(":80")
conf.CacheFile = filepath.Join(t.TempDir(), "cache.db")