Random methods public void testRandomStringLength() { String randomString = randomAlphaOfLength(10); assertThat(randomString.length(), is(10)); boolean randomBoolean = randomBoolean(); assertThat(randomBoolean, is(anyOf(is(true), is(false)))); final Integer randomInt = randomFrom(1, 22, 11, 41, 58); assertThat(randomInt, is(allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(58)))); final int randomIntBetween = randomIntBetween(1, 10); assertThat(randomIntBetween, is(allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(10)))); final long nonNegativeLong = randomNonNegativeLong(); assertThat(nonNegativeLong, is(greaterThanOrEqualTo(0L))); final ZoneId zoneId = randomZone(); assertThat(ZoneId.getAvailableZoneIds(), hasItem(zoneId.toString())); final Locale locale = randomLocale(random()); assertThat(Arrays.asList(Locale.getAvailableLocales()), hasItem(locale)); }
Slide 19
Random methods public void testRandomStringLength() { String randomString = randomAlphaOfLength(10); assertThat(randomString.length(), is(10)); }
Slide 20
Random methods public void testRandomStringLength() { String randomString = randomAlphaOfLength(10); assertThat(randomString.length(), is(10)); } public void testRandomStringLength() { String randomString = randomAlphaOfLength(10); assertThat(randomString.length(), is(Integer.MAX_VALUE)); }
Slide 21
Randomization Example private int add (int a, int b) { assert a > 0; assert b > 0; return a + b; }
Slide 22
Randomization Example private int add (int a, int b) { assert a > 0; assert b > 0; return a + b; } public void testAdd() { assertThat(add(1, 1), is(2)); assertThat(add(2, 2), is(4)); }
Slide 23
Randomization Example private int add (int a, int b) { assert a > 0; assert b > 0; return a + b; } public void testAdd() { final int a = randomIntBetween(0, Integer.MAX_VALUE); final int b = randomIntBetween(0, Integer.MAX_VALUE); assertThat(add(a, b), allOf(greaterThanOrEqualTo(a), greaterThanOrEqualTo(b))); }
Slide 24
Randomization Example private int add (int a, int b) { assert a > 0; assert b > 0; return a + b; } @Repeat(iterations = 1000) public void testAdd() { final int a = randomIntBetween(0, Integer.MAX_VALUE); final int b = randomIntBetween(0, Integer.MAX_VALUE); assertThat(add(a, b), allOf(greaterThanOrEqualTo(a), greaterThanOrEqualTo(b))); }
Slide 25
Randomization Example private int add (int a, int b) { assert a > 0; assert b > 0; return a + b; } @Repeat(iterations = 1000) public void testAdd() { final int a = randomIntBetween(0, Integer.MAX_VALUE); final int b = randomIntBetween(0, Integer.MAX_VALUE); assertThat(add(a, b), allOf(greaterThanOrEqualTo(a), greaterThanOrEqualTo(b))); }
java.lang.AssertionError: Expected: (a value equal to or greater than <1667057423> and a value equal to or greater than <1800656534>) but: a value equal to or greater than <1667057423> <-827253339> was less than <1667057423>
Slide 26
Randomization Example private int add (int a, int b) { assert a > 0; assert b > 0; return a + b; } @Repeat(iterations = 1000) public void testAdd() { final int a = randomIntBetween(0, Integer.MAX_VALUE); final int b = randomIntBetween(0, Integer.MAX_VALUE); assertThat(add(a, b), allOf(greaterThanOrEqualTo(a), greaterThanOrEqualTo(b))); }
REPRODUCE WITH: ./gradlew ‘:server:test’ —tests “de.spinscale.MyTest.testAdd” -Dtests.seed=EC29A319F9128F9A -Dtests.locale=pl-PL -Dtests.timezone=America/St_Kitts
Slide 27
Randomization Example private int add (int a, int b) { assert a > 0; assert b > 0; return a + b; } @Seed(“EC29A319F9128F9A”) public void testAdd() { final int a = randomIntBetween(0, Integer.MAX_VALUE); final int b = randomIntBetween(0, Integer.MAX_VALUE); assertThat(add(a, b), allOf(greaterThanOrEqualTo(a), greaterThanOrEqualTo(b))); }
Slide 28
ESTestCase goodies Thread leak detection Change log level for single test/package Checks for excessive sysout/err writes Test method order is randomized Test class order is randomized Deprecation logging checks No inflight search contexts
Slide 29
Integration Testing YAML ftw!
Slide 30
HTTP Integration tests Run tests against Elasticsearch HTTP interface Tests are written in YAML API definition is written in JSON ESClientYamlSuiteTestCase to extend All official clients are using the same spec to guarantee feature parity
Slide 31
API definition {
}
“get”:{ “documentation”:{ “url”:”https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-get.html”, “description”:”Returns a document.” }, “stability”:”stable”, “url”:{ “paths”:[ { “path”:”/{index}/_doc/{id}”, “methods”:[ “GET” ], “parts”:{ “id”:{ “type”:”string”, “description”:”The document ID” }, “index”:{ “type”:”string”, “description”:”The name of the index” } } } ] }, “params”:{ “preference”:{ “type”:”string”, “description”:”Specify the node or shard the operation should be performed on (default: random)” } … } }
More integration testing Test against kerberos/samba/openldap/shibboleth-idp using docker and docker-compose S3 integration testing using minio (via dockercompose) Testing the docker image via docker-compose
Slide 34
Package Testing Containers
Slide 35
Elasticsearch: A lot of flavours tar.gz, zip, deb, rpm apt / yum repositories docker images osx brew tap Windows MSI helm chart, ECK (K8s operator) puppet, ansible, chef
Testing packages Test package behaviour (install/upgrade/delete) Moved from bats to Java package installation/start/stop/uninstall
https://github.com/elastic/elasticsearch/tree/master/qa/os
Slide 38
BWC Testing You get an upgrade, everyone gets an upgrade!
Slide 39
BWC Testing Upgrades must be supported and tested! Full cluster restart Rolling restarts between minor versions Rolling restarts from the latest old major version to the current major version, i.e. 6.8.8 to 7.6.2
Slide 40
Rolling upgrade tests
6.8.x
6.8.x
6.8.x
Slide 41
Rolling upgrade tests
6.8.x
6.8.x
6.8.x
Slide 42
Rolling upgrade tests upgrade 7.9.x
6.8.x
6.8.x
Slide 43
Rolling upgrade tests
7.9.x
6.8.x
6.8.x
Slide 44
Rolling upgrade tests
7.9.x
6.8.x
6.8.x
Slide 45
Rolling upgrade tests upgrade 7.9.x
7.9.x
6.8.x
Slide 46
Rolling upgrade tests
7.9.x
7.9.x
6.8.x
Slide 47
Rolling upgrade tests
7.9.x
7.9.x
6.8.x
Slide 48
Rolling upgrade tests upgrade 7.9.x
7.9.x
7.9.x
Slide 49
Rolling upgrade tests
7.9.x
7.9.x
7.9.x
Slide 50
Documentation Testing Y’all doing this, right?
Slide 51
Documentation Testing All documentation is written in asciidoc Fire up a test cluster Extract snippets from documentation Run snippets against cluster Optionally: check response contents
Embrace the difference Every product in the stack will test differently Java, JRuby, Ruby, Go, Javascript, TypeScript, Scala, .NET, perl, PHP, python, bash, Groovy, C++, Haskell, Clojure JSON, YAML, terraform, hcl
Slide 73
Everyone be ready! Releases are time based Every product’s branch should be ready Build of release candidate artifacts Testing of these artifacts Repeat until done across products: Fix all blockers Releasing of those artifacts
Slide 74
Release manager A person responsible for the release Triggers the build of all artifacts Performs follow up tasks for each team after a release
Slide 75
Trust the process! Staged artifacts are the final release artifacts, no rebuilds! Push artifacts to their final destinations Official links, OSS sonatype, rubygems, docker images, package repositories
Slide 76
Trust the process! +200 artifacts are promoted to release bucket Using Tekton Pipelines instead of single process started on release manager machine promoting artifacts: 4x faster 3rd party promotion: 6x faster > 40 pods are doing a single release
Slide 77
More Work begins after releasing website communication release blog posts ensuring everything has been published
Slide 78
Support it! Don’t forget to phase out…
Slide 79
Products have a lifecycle Stop supporting old products Be consistent with support guarantees Provide maintenance policy Distinguish between end of life & fixing bugs
Slide 80
Slide 81
Slide 82
Summary Automate all the things!
Slide 83
Summary Automate early, automate often Automate your tests, all of them Manual testing will still find bugs Automate your releases Ensure everyone can do a release Non-technical aspects are much harder to automate
Slide 84
Thanks for listening! Questions?
Alexander Reelsen @spinscale alex@elastic.co