From 17edc441e6ab397a2e1cda6aba72ce2292d02aa1 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Mon, 24 Feb 2020 22:21:16 +0100 Subject: [PATCH] Fix yaml tests not deleting newly defined hidden indices (#4447) * Fix yaml tests not deleting newly defined hidden indices Before we were not deleting system indices only `.ml-*` However this started to become an issue because it left closed indices around. This might be related to .ml indices now being hidden. Warrants more investigation as the new solution deleting all indices all the time is definitely a bit slower * update refresh and delete to include hidden indices --- tests/Tests.YamlRunner/Commands.fs | 1 - tests/Tests.YamlRunner/TestSuiteBootstrap.fs | 158 +++++++++++++++++ .../Tests.YamlRunner/Tests.YamlRunner.fsproj | 1 + tests/Tests.YamlRunner/TestsReader.fs | 159 +----------------- 4 files changed, 160 insertions(+), 159 deletions(-) create mode 100644 tests/Tests.YamlRunner/TestSuiteBootstrap.fs diff --git a/tests/Tests.YamlRunner/Commands.fs b/tests/Tests.YamlRunner/Commands.fs index 3586a921bfa..775583edd7e 100644 --- a/tests/Tests.YamlRunner/Commands.fs +++ b/tests/Tests.YamlRunner/Commands.fs @@ -5,7 +5,6 @@ open ShellProgressBar open Tests.YamlRunner.AsyncExtensions open Tests.YamlRunner.TestsLocator open Tests.YamlRunner.TestsReader -open Elasticsearch.Net open Tests.YamlRunner let private barOptions = diff --git a/tests/Tests.YamlRunner/TestSuiteBootstrap.fs b/tests/Tests.YamlRunner/TestSuiteBootstrap.fs new file mode 100644 index 00000000000..4136e8dac11 --- /dev/null +++ b/tests/Tests.YamlRunner/TestSuiteBootstrap.fs @@ -0,0 +1,158 @@ +module Tests.YamlRunner.TestSuiteBootstrap + +open System +open System.Linq + +open Elasticsearch.Net +open Elasticsearch.Net.Specification.CatApi +open Elasticsearch.Net.Specification.ClusterApi +open Elasticsearch.Net.Specification.IndicesApi +open Tests.YamlRunner.Models + +let DefaultSetup : Operation list = [Actions("Setup", fun (client, suite) -> + let firstFailure (responses:DynamicResponse seq) = + responses + |> Seq.filter (fun r -> not r.Success && r.HttpStatusCode <> Nullable.op_Implicit 404) + |> Seq.tryHead + + match suite with + | Oss -> + let deleteAll = client.Indices.Delete("*") + let templates = + client.Cat.Templates("*", CatTemplatesRequestParameters(Headers=["name"].ToArray())) + .Body.Split("\n") + |> Seq.filter(fun f -> not(String.IsNullOrWhiteSpace(f)) && not(f.StartsWith(".")) && f <> "security-audit-log") + //TODO template does not accept comma separated list but is documented as such + |> Seq.map(fun template -> client.Indices.DeleteTemplateForAll(template)) + |> Seq.toList + firstFailure <| [deleteAll] @ templates + + | XPack -> + firstFailure <| seq { + //delete all templates + let templates = + client.Cat.Templates("*", CatTemplatesRequestParameters(Headers=["name"].ToArray())) + .Body.Split("\n") + |> Seq.filter(fun f -> not(String.IsNullOrWhiteSpace(f)) && not(f.StartsWith(".")) && f <> "security-audit-log") + //TODO template does not accept comma separated list but is documented as such + |> Seq.map(fun template -> client.Indices.DeleteTemplateForAll(template)) + + yield! templates + + yield client.Watcher.Delete("my_watch") + + let deleteNonReserved (setup:_ -> DynamicResponse) (delete:(_ -> DynamicResponse)) = + setup().Dictionary.GetKeyValues() + |> Seq.map (fun kv -> + match kv.Value.Get "metadata._reserved" with + | false -> Some <| delete(kv.Key) + | _ -> None + ) + |> Seq.choose id + |> Seq.toList + + yield! //roles + deleteNonReserved + (fun _ -> client.Security.GetRole()) + (fun role -> client.Security.DeleteRole role) + + yield! //users + deleteNonReserved + (fun _ -> client.Security.GetUser()) + (fun user -> client.Security.DeleteUser user) + + yield! //privileges + deleteNonReserved + (fun _ -> client.Security.GetPrivileges()) + (fun priv -> client.Security.DeletePrivileges(priv, "_all")) + + // deleting feeds before jobs is important + let mlDataFeeds = + let stopFeeds = client.MachineLearning.StopDatafeed("_all") + let getFeeds = client.MachineLearning.GetDatafeeds () + let deleteFeeds = + getFeeds.Get "datafeeds.datafeed_id" + |> Seq.map (fun jobId -> client.MachineLearning.DeleteDatafeed(jobId)) + |> Seq.toList + [stopFeeds; getFeeds] @ deleteFeeds + yield! mlDataFeeds + + yield client.IndexLifecycleManagement.RemovePolicy("_all") + + let mlJobs = + let closeJobs = client.MachineLearning.CloseJob("_all", PostData.Empty) + let getJobs = client.MachineLearning.GetJobs "_all" + let deleteJobs = + getJobs.Get "jobs.job_id" + |> Seq.map (fun jobId -> client.MachineLearning.DeleteJob(jobId)) + |> Seq.toList + [closeJobs; getJobs] @ deleteJobs + yield! mlJobs + + let rollupJobs = + let getJobs = client.Rollup.GetJob "_all" + let deleteJobs = + getJobs.Get "jobs.config.id" + |> Seq.collect (fun jobId -> [ + client.Rollup.StopJob(jobId) + client.Rollup.DeleteJob(jobId) + ]) + |> Seq.toList + [getJobs] @ deleteJobs + yield! rollupJobs + + let tasks = + let getJobs = client.Tasks.List () + let cancelJobs = + let dict = getJobs.Get "nodes" + dict.GetKeyValues() + |> Seq.collect(fun kv -> + let dict = kv.Value.Get "tasks" + dict.GetKeyValues() + ) + |> Seq.map (fun kv -> + match kv.Value.Get "cancellable" with + | true -> Some <| client.Tasks.Cancel(kv.Key) + | _ -> None + ) + |> Seq.choose id + |> Seq.toList + + [getJobs] @ cancelJobs + yield! tasks + + let transforms = + let transforms = client.Transform.Get "_all" + let stopTransforms = + transforms.Get "transforms.id" + |> Seq.collect (fun id -> [ + client.Transform.Stop id + client.Transform.Delete id + ]) + |> Seq.toList + [transforms] @ stopTransforms + yield! transforms + + let yellowStatus = Nullable.op_Implicit WaitForStatus.Yellow + yield client.Cluster.Health(ClusterHealthRequestParameters(WaitForStatus=yellowStatus)) + + let indices = + let dp = DeleteIndexRequestParameters() + dp.SetQueryString("expand_wildcards", "open,closed,hidden") + client.Indices.Delete("*", dp) + yield indices + + let data = PostData.String @"{""password"":""x-pack-test-password"", ""roles"":[""superuser""]}" + yield client.Security.PutUser("x_pack_rest_user", data) + + let refreshAll = + let rp = RefreshRequestParameters() + rp.SetQueryString("expand_wildcards", "open,closed,hidden") + client.Indices.Refresh( "_all", rp) + + yield refreshAll + + yield client.Cluster.Health(ClusterHealthRequestParameters(WaitForStatus=yellowStatus)) + } +)] + diff --git a/tests/Tests.YamlRunner/Tests.YamlRunner.fsproj b/tests/Tests.YamlRunner/Tests.YamlRunner.fsproj index 6a7b4a2c836..ac6a48fed58 100644 --- a/tests/Tests.YamlRunner/Tests.YamlRunner.fsproj +++ b/tests/Tests.YamlRunner/Tests.YamlRunner.fsproj @@ -21,6 +21,7 @@ + diff --git a/tests/Tests.YamlRunner/TestsReader.fs b/tests/Tests.YamlRunner/TestsReader.fs index 4b10b8cb9b7..baa3b7c77b3 100644 --- a/tests/Tests.YamlRunner/TestsReader.fs +++ b/tests/Tests.YamlRunner/TestsReader.fs @@ -6,18 +6,10 @@ open System.Text.RegularExpressions open System.Linq open System.Collections.Specialized -open Elasticsearch.Net -open Elasticsearch.Net -open Elasticsearch.Net.Specification.CatApi -open Elasticsearch.Net.Specification.ClusterApi -open Elasticsearch.Net.Specification.MachineLearningApi open System.IO -open Tests.YamlRunner -open Tests.YamlRunner.Models open Tests.YamlRunner.Models open Tests.YamlRunner.TestsLocator - let private tryPick<'a> (map:YamlMap) key = let found, value = map.TryGetValue key if (found) then @@ -211,160 +203,11 @@ type YamlTestDocument = { Tests: YamlTest list } -let private DefaultSetup : Operation list = [Actions("Setup", fun (client, suite) -> - let firstFailure (responses:DynamicResponse seq) = - responses - |> Seq.filter (fun r -> not r.Success && r.HttpStatusCode <> Nullable.op_Implicit 404) - |> Seq.tryHead - - match suite with - | Oss -> - let deleteAll = client.Indices.Delete("*") - let templates = - client.Cat.Templates("*", CatTemplatesRequestParameters(Headers=["name"].ToArray())) - .Body.Split("\n") - |> Seq.filter(fun f -> not(String.IsNullOrWhiteSpace(f)) && not(f.StartsWith(".")) && f <> "security-audit-log") - //TODO template does not accept comma separated list but is documented as such - |> Seq.map(fun template -> client.Indices.DeleteTemplateForAll(template)) - |> Seq.toList - firstFailure <| [deleteAll] @ templates - - | XPack -> - firstFailure <| seq { - //delete all templates - let templates = - client.Cat.Templates("*", CatTemplatesRequestParameters(Headers=["name"].ToArray())) - .Body.Split("\n") - |> Seq.filter(fun f -> not(String.IsNullOrWhiteSpace(f)) && not(f.StartsWith(".")) && f <> "security-audit-log") - //TODO template does not accept comma separated list but is documented as such - |> Seq.map(fun template -> client.Indices.DeleteTemplateForAll(template)) - - yield! templates - - yield client.Watcher.Delete("my_watch") - - let deleteNonReserved (setup:_ -> DynamicResponse) (delete:(_ -> DynamicResponse)) = - setup().Dictionary.GetKeyValues() - |> Seq.map (fun kv -> - match kv.Value.Get "metadata._reserved" with - | false -> Some <| delete(kv.Key) - | _ -> None - ) - |> Seq.choose id - |> Seq.toList - - yield! //roles - deleteNonReserved - (fun _ -> client.Security.GetRole()) - (fun role -> client.Security.DeleteRole role) - - yield! //users - deleteNonReserved - (fun _ -> client.Security.GetUser()) - (fun user -> client.Security.DeleteUser user) - - yield! //privileges - deleteNonReserved - (fun _ -> client.Security.GetPrivileges()) - (fun priv -> client.Security.DeletePrivileges(priv, "_all")) - - // deleting feeds before jobs is important - let mlDataFeeds = - let stopFeeds = client.MachineLearning.StopDatafeed("_all") - let getFeeds = client.MachineLearning.GetDatafeeds () - let deleteFeeds = - getFeeds.Get "datafeeds.datafeed_id" - |> Seq.map (fun jobId -> client.MachineLearning.DeleteDatafeed(jobId)) - |> Seq.toList - [stopFeeds; getFeeds] @ deleteFeeds - yield! mlDataFeeds - - yield client.IndexLifecycleManagement.RemovePolicy("_all") - - let mlJobs = - let closeJobs = client.MachineLearning.CloseJob("_all", PostData.Empty) - let getJobs = client.MachineLearning.GetJobs "_all" - let deleteJobs = - getJobs.Get "jobs.job_id" - |> Seq.map (fun jobId -> client.MachineLearning.DeleteJob(jobId)) - |> Seq.toList - [closeJobs; getJobs] @ deleteJobs - yield! mlJobs - - let rollupJobs = - let getJobs = client.Rollup.GetJob "_all" - let deleteJobs = - getJobs.Get "jobs.config.id" - |> Seq.collect (fun jobId -> [ - client.Rollup.StopJob(jobId) - client.Rollup.DeleteJob(jobId) - ]) - |> Seq.toList - [getJobs] @ deleteJobs - yield! rollupJobs - - let tasks = - let getJobs = client.Tasks.List () - let cancelJobs = - let dict = getJobs.Get "nodes" - dict.GetKeyValues() - |> Seq.collect(fun kv -> - let dict = kv.Value.Get "tasks" - dict.GetKeyValues() - ) - |> Seq.map (fun kv -> - match kv.Value.Get "cancellable" with - | true -> Some <| client.Tasks.Cancel(kv.Key) - | _ -> None - ) - |> Seq.choose id - |> Seq.toList - - [getJobs] @ cancelJobs - yield! tasks - - let transforms = - let transforms = client.Transform.Get "_all" - let stopTransforms = - transforms.Get "transforms.id" - |> Seq.collect (fun id -> [ - client.Transform.Stop id - client.Transform.Delete id - ]) - |> Seq.toList - [transforms] @ stopTransforms - yield! transforms - - let yellowStatus = Nullable.op_Implicit WaitForStatus.Yellow - yield client.Cluster.Health(ClusterHealthRequestParameters(WaitForStatus=yellowStatus)) - - //make sure we don't delete system indices - let indices = - client.Cat.Indices("*", CatIndicesRequestParameters(Headers=["index"].ToArray())) - .Body.Split("\n") - |> Seq.filter(fun f -> not(String.IsNullOrWhiteSpace(f))) - |> Seq.filter(fun f -> not(f.StartsWith(".")) || f.StartsWith(".ml-")) - |> String.concat "," - |> function - | s when String.IsNullOrEmpty(s) -> None - | s -> Some <| client.Indices.Delete(s) - - match indices with Some r -> yield r | None -> ignore() - - let data = PostData.String @"{""password"":""x-pack-test-password"", ""roles"":[""superuser""]}" - yield client.Security.PutUser("x_pack_rest_user", data) - - yield client.Indices.Refresh "_all" - - yield client.Cluster.Health(ClusterHealthRequestParameters(WaitForStatus=yellowStatus)) - } -)] - let private toDocument (yamlInfo:YamlFileInfo) (sections:YamlTestSection list) = let setups = (sections |> List.tryPick (fun s -> match s with | Setup s -> Some s | _ -> None)) { FileInfo = FileInfo yamlInfo.File - Setup = Some <| (DefaultSetup @ (setups |> Option.defaultValue [])) + Setup = Some <| (TestSuiteBootstrap.DefaultSetup @ (setups |> Option.defaultValue [])) Teardown = sections |> List.tryPick (fun s -> match s with | Teardown s -> Some s | _ -> None) Tests = sections |> List.map (fun s -> match s with | YamlTest s -> Some s | _ -> None) |> List.choose id }