# How can Watchers be tested?

**URL:** https://discuss.elastic.co/t/how-can-watchers-be-tested/65384
**Category:** Elasticsearch
**Tags:** elastic-stack-alerting
**Created:** [November 8, 2016, 5:38pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384 "2016-11-08T17:38:17Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Ryan\_Grannell](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ryan_grannell/32/41712_2.png) [@Ryan\_Grannell](https://discuss.elastic.co/u/Ryan_Grannell)
#### Post date: [November 8, 2016, 5:38pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/1 "2016-11-08T17:38:17Z")

</div>

Hi,

We use a large number of watchers to monitor the health of our VMs and services (RAM usage, failed services, etc.). Unfortunately, it's extremely prone to false-negatives; we often have problems that are ongoing but aren't detected by email-alerts, which from our perspective looks like there's no problem.

I want to test our email-alerting with data that will definitively trigger an email-alert to make our watchers more reliable.

For example, the following watcher is triggered if less than 90 heartbeat-messages are seen in `heartbeat-*` within the last ten minutes. I'd like to test this watcher over REST with a manually-provided search\_match result (an empty array), and then check that the watcher was triggered from the response body.

If I can do this, I can build a test-suite for our watchers easily.

I think the Execute API supports this, but I don't really understand exactly what the parameter documentation for `trigger-data` or `alternative_input` meant, or how these parameters differ.

- Can `trigger-data` or `alternative_input` be used to provide fake input data to a watcher? What would this data be in the case of providing empty search results?
- How do the `trigger_data` and `alternative_input` parameters differ?
- Is there a 'canonical' way of testing watchers that I missed?

Any help would be appreciated

## Example Watcher

```
{
  "trigger": {
    "schedule": {
      "interval": "15m"
    }
  },
  "input": {
    "search": {
      "request": {
        "search_type": "query_then_fetch",
        "indices": [
          "heartbeat-*"
        ],
        "types": [],
        "body": {
          "query": {
            "bool": {
              "must": [
                {
                  "match": {
                    "host": "vm_0"
                  }
                },
                {
                  "match": {
                    "tags": "heartbeat"
                  }
                },
                {
                  "range": {
                    "@timestamp": {
                      "gte": "now-10m"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  },
  "condition": {
    "compare": {
      "ctx.payload.hits.total": {
        "lt": 90
      }
    }
  },
  "actions": {
    "email_administrator": {
      "throttle_period": "15m",
      "email": {
        "profile": "standard",
        "attachments": {
          "attached_data": {
            "data": {
              "format": "json"
            }
          }
        },
        "priority": "low",
        "to": [
          "foo@example.com"
        ],
        "subject": "Watcher - too heartbeat messages",
        "body": {}
      }
    }
  }
}
```

---

<div class="post-metadata">

### Author: ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)
#### Post date: [November 9, 2016, 9:54am UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/2 "2016-11-09T09:54:07Z")

</div>

Hey Ryan,

you are right, that the execute watch API is what you are searching for. Let me try to explain what those parameters do (if it worked) and of course, how we can improve the documentation.

First, `alternative_input` is the parameter you searching for to provide custom input. Let me demo this with a simple watch (using 5.0 here, but the principle is the same).

```auto
PUT _xpack/watcher/watch/test
{
  "trigger" : { "schedule" : { "interval" : "1h" }},
  "input" : {
    "simple" : { "foo" : "bar" }
  },
  "actions" : {
    "log_error" : {
      "logging" : {
        "text" : "Got payload {{ctx.payload}}"
      }
    }
  }
}

PUT _xpack/watcher/watch/test/_execute

```

If you execute the above watch, you will see a log message like

```auto
[2016-11-09T10:50:11,628][INFO][o.e.x.w.a.l.ExecutableLoggingAction] [EXYBbWD] Got payload {foo=bar}

```

However, if you use the `alternative_input` variable

```auto
PUT _xpack/watcher/watch/test/_execute
{
  "alternative_input" : {
    "spam" : "eggs"
  }
}

```

The log statement changes to

```auto
[2016-11-09T10:50:34,808][INFO][o.e.x.w.a.l.ExecutableLoggingAction] [EXYBbWD] Got payload {spam=eggs}

```

Now, on to `trigger_data`

```auto
PUT _xpack/watcher/watch/test/_execute
{
  "alternative_input" : {
    "spam" : "eggs"
  },
  "trigger_data" : {
    "scheduled_time" : "2001-11-09T09:50:34.807Z",
    "triggered_time": "2010-11-09T09:50:34.807Z"
    
  }
}

```

This changes the scheduled and execution time of your trigger (as you can see in the output of that call). If you have a search query that uses a time filter to only return the last five minutes, this allows you to reconstruct a past query.

Hope that as helpful! Otherwise feel free to ask further questions!

--Alex

---

<div class="post-metadata">

### Author: ![Ryan\_Grannell](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ryan_grannell/32/41712_2.png) [@Ryan\_Grannell](https://discuss.elastic.co/u/Ryan_Grannell)
#### Post date: [November 11, 2016, 3:58pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/3 "2016-11-11T15:58:53Z")

</div>

Hi Alexander,

Thanks for explaining both parameters so clearly; your example shows that `alternative_input` essentially sets `ctx.payload`, which is useful to know. I imagine something like

```
{
	"alternative_input" : {
		"hits": {
			"total": 0
		}
	}
}

```

Will trigger the example I gave above.

This isn't ideal for testing though; I'm really trying to test whether the query / aggregation section of my Watcher is returning the correct result.

Is there anything like the `alternative_input` section that lets my provide a fake document-set to the watcher, rather than just setting `ctx.payload` directly?

---

<div class="post-metadata">

### Author: ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)
#### Post date: [November 11, 2016, 4:29pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/4 "2016-11-11T16:29:22Z")

</div>

Hey,

I think what you may want to try instead then is the execute watch API, but with simulated action modes like this

```auto
POST _watcher/watch/my-watch/_execute
{
  "action_modes" : {
    "_all" : "simulate"
  }
}

```

Which executes your configured search, but will not execute the actions.. yet return useful info in the JSON response.

--Alex

---

<div class="post-metadata">

### Author: ![Ryan\_Grannell](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ryan_grannell/32/41712_2.png) [@Ryan\_Grannell](https://discuss.elastic.co/u/Ryan_Grannell)
#### Post date: [November 17, 2016, 5:11pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/5 "2016-11-17T17:11:00Z")

</div>

Hi,

Yes, that makes more sense. I'm still looking for a way to provide a "pre-queried" set of logs to the watcher though (or a manually-uploaded list of documents), rather than pointing it at an active index.

It seems that Watcher doesn't directly support this, so the only way I can think of getting this to work is:

- Manually query a test-set of logs using the query / aggs block of the watcher
- Provide this result-set to the watcher using `alternative_input`, with simulate mode enabled
- Check the expected action was triggered

This will work, it's just a little awkward.

Thanks for your help

---

<div class="post-metadata">

### Author: ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)
#### Post date: [November 18, 2016, 1:25pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/6 "2016-11-18T13:25:34Z")

</div>

Hey,

a workaround for this issue could be, that you use an alias in your watch to query, and that points to your test data or your live data, but using the `alternative_input` with some scripting on the client side might be easier, to be honest.

--Alex

---

<div class="post-metadata">

### Author: ![Ryan\_Grannell](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ryan_grannell/32/41712_2.png) [@Ryan\_Grannell](https://discuss.elastic.co/u/Ryan_Grannell)
#### Post date: [November 18, 2016, 4:21pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/7 "2016-11-18T16:21:26Z")

</div>

Thanks a lot Alex, I appreciate your help. I'll try the second approach, which shouldn't really be too difficult to implement anyway.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [December 16, 2016, 4:21pm UTC](https://discuss.elastic.co/t/how-can-watchers-be-tested/65384/8 "2016-12-16T16:21:52Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
