From eeec80885dfe058af199139e98e0543c2f107a9a Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 21 May 2017 12:50:36 -0400 Subject: [PATCH 001/276] First Commit : SolrNightlyBenchmarks --- .../CreateCollectionBenchmarkCloud.html | 324 ++++++++++ .../CreateCollectionBenchmarkStandalone.html | 324 ++++++++++ .../WebAppSource/IndexingBenchmarkCloud.html | 324 ++++++++++ .../IndexingBenchmarkCloudConcurrent.html | 324 ++++++++++ .../IndexingBenchmarkStandalone.html | 324 ++++++++++ .../IndexingThroughputBenchmarkCloud.html | 324 ++++++++++ ...ingThroughputBenchmarkCloudConcurrent.html | 324 ++++++++++ ...IndexingThroughputBenchmarkStandalone.html | 324 ++++++++++ .../WebAppSource/images/loading.gif | Bin 0 -> 130310 bytes .../WebAppSource/images/running.gif | Bin 0 -> 73090 bytes .../WebAppSource/images/solr.png | Bin 0 -> 47661 bytes .../WebAppSource/images/solr_logo_rgb.png | Bin 0 -> 173732 bytes .../SolrNightlyBenchmarks/config.properties | 8 + .../BenchmarkAppConnector.java | 95 +++ .../nightlybenchmarks/MetricEstimation.java | 142 +++++ .../ProcessStreamReader.java | 32 + .../tests/nightlybenchmarks/SolrClient.java | 255 ++++++++ .../tests/nightlybenchmarks/SolrCloud.java | 104 +++ .../SolrNightlyBenchmarks.java | 74 +++ .../tests/nightlybenchmarks/SolrNode.java | 283 +++++++++ .../tests/nightlybenchmarks/TestType.java | 7 + .../solr/tests/nightlybenchmarks/Util.java | 590 ++++++++++++++++++ .../tests/nightlybenchmarks/Zookeeper.java | 248 ++++++++ 23 files changed, 4430 insertions(+) create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/loading.gif create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/running.gif create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr.png create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/config.properties create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java create mode 100644 solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html new file mode 100644 index 000000000000..ce4a7390356d --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Create Collection Performance - Cloud
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Day/Time | Y-Axis: Seconds
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html new file mode 100644 index 000000000000..c4345a3e32ad --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Create Collection Performance
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Day/Time | Y-Axis: Seconds
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html new file mode 100644 index 000000000000..51e3874ed61a --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Indexing Performance - Cloud
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Day/Time | Y-Axis: Seconds
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html new file mode 100644 index 000000000000..21f1a414f825 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Indexing Performance - Cloud Concurrent
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Day/Time | Y-Axis: Seconds
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html new file mode 100644 index 000000000000..a102a9e8be06 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Indexing Performance
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Day/Time | Y-Axis: Seconds
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html new file mode 100644 index 000000000000..b591198c7640 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Indexing Throughput (doc/sec)
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Date/Time | Y-Axis: Documents/Sec
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html new file mode 100644 index 000000000000..6cc895ddad15 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Indexing Throughput (doc/sec)
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Date/Time | Y-Axis: Documents/Sec
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html new file mode 100644 index 000000000000..77fcb636967f --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -0,0 +1,324 @@ + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
Indexing Throughput (doc/sec)
+
+
+
+ +
+ +
+ +
+
Test Runtime Information
+
+
+
+ +
+
Graph Information
+
+ X-Axis: Date/Time | Y-Axis: Documents/Sec
+

+
Please hover on the graph to get more information!
+
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/loading.gif b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..b04dd11bc8b9fe8aaaf37fdd80deb95db788c66b GIT binary patch literal 130310 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 B9wGn$ literal 0 HcmV?d00001 diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/running.gif b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/running.gif new file mode 100644 index 0000000000000000000000000000000000000000..2415fd2fe97b63c9c8745397597e17f71f1d9a31 GIT binary patch literal 73090 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 literal 0 HcmV?d00001 diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png b/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png new file mode 100644 index 0000000000000000000000000000000000000000..5c3f962279f35694e852e2d5f8f7d5062b67e50c GIT binary patch literal 173732 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 literal 0 HcmV?d00001 diff --git a/solr/dev-tools/SolrNightlyBenchmarks/config.properties b/solr/dev-tools/SolrNightlyBenchmarks/config.properties new file mode 100644 index 000000000000..ce6c0f48389a --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/config.properties @@ -0,0 +1,8 @@ +SolrNightlyBenchmarks.benchmarkAppDirectory=/var/www/html/ +SolrNightlyBenchmarks.solrCommitHistoryData=/root/GSoC17/SolrNightlyBenchmarks/solrcommit.log +SolrNightlyBenchmarks.amazonFoodDataLocation=/root/GSoC17/data/Reviews.csv +SolrNightlyBenchmarks.metricsURL=http://localhost:PORT/solr/admin/metrics?wt=json&group=jvm +SolrNightlyBenchmarks.zookeeperDownloadURL=http://www.us.apache.org/dist/zookeeper/ +SolrNightlyBenchmarks.zookeeperDownloadVersion=3.4.6 +SolrNightlyBenchmarks.zookeeperHostIp=127.0.0.1 +SolrNightlyBenchmarks.zookeeperHostPort=2181 diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java new file mode 100644 index 000000000000..2e0ac6eabdee --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -0,0 +1,95 @@ +package org.apache.solr.tests.nightlybenchmarks; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class BenchmarkAppConnector { + + public static String benchmarkAppDirectory; + + public BenchmarkAppConnector() { + super(); + } + + public enum FileType { + + MEMORY_HEAP_USED, + PROCESS_CPU_LOAD, + TEST_ENV_FILE, + STANDALONE_INDEXING_MAIN, + STANDALONE_CREATE_COLLECTION_MAIN, + STANDALONE_INDEXING_THROUGHPUT, + CLOUD_CREATE_COLLECTION_MAIN, + CLOUD_SERIAL_INDEXING_THROUGHPUT, + CLOUD_CONCURRENT_INDEXING_THROUGHPUT + + } + + public static void writeToWebAppDataFile(String fileName, String data, boolean createNewFile, FileType type) { + + + BufferedWriter bw = null; + FileWriter fw = null; + File file = null; + + try { + data += "\n"; + + File dataDir = new File(benchmarkAppDirectory + File.separator + "data" + File.separator); + if(!dataDir.exists()) { + dataDir.mkdir(); + } + + file = new File(benchmarkAppDirectory + File.separator + "data" + File.separator + fileName); + + if (file.exists() && createNewFile) { + file.delete(); + file.createNewFile(); + } + + fw = new FileWriter(file.getAbsoluteFile(), true); + bw = new BufferedWriter(fw); + + if (!file.exists()) { + file.createNewFile(); + } + + if (file.length() == 0) { + + file.setReadable(true); + file.setWritable(true); + if (type == FileType.MEMORY_HEAP_USED) { + bw.write("Date, Heap Space Used (MB)\n"); + } else if (type == FileType.PROCESS_CPU_LOAD) { + bw.write("Date, Process CPU Load (%)\n"); + }else if (type == FileType.STANDALONE_CREATE_COLLECTION_MAIN || type == FileType.CLOUD_CREATE_COLLECTION_MAIN) { + bw.write("Date, milliseconds, CommitID, Commit_Information\n"); + } else if (type == FileType.STANDALONE_INDEXING_MAIN) { + bw.write("Date, seconds, CommitID, Commit_Information\n"); + } else if (type == FileType.TEST_ENV_FILE) { + // Don't add any header + } else if (type == FileType.STANDALONE_INDEXING_THROUGHPUT || type == FileType.CLOUD_SERIAL_INDEXING_THROUGHPUT || type == FileType.CLOUD_CONCURRENT_INDEXING_THROUGHPUT) { + bw.write("Date, Throughput (doc/sec)\n"); + } + + } + + bw.write(data); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (bw != null) + bw.close(); + if (fw != null) + fw.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + } + +} \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java new file mode 100644 index 000000000000..170896f730d0 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java @@ -0,0 +1,142 @@ +package org.apache.solr.tests.nightlybenchmarks; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.ws.rs.core.MediaType; + +import org.apache.solr.tests.nightlybenchmarks.BenchmarkAppConnector.FileType; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +public class MetricEstimation extends Thread { + + public static String metricsURL; + + public MetricEstimation(String commitID, TestType testType, String port) { + this.testType = testType; + this.commitID = commitID; + this.port = port; + } + + public enum MetricType { MEM_ESTIMATION, CPU_ESTIMATION } + public enum MetricSubType { MEMORY_HEAP_USED, PROCESS_CPU_LOAD } + + public TestType testType; + public String commitID; + public String port; + + public void run(){ + + if(testType == TestType.STANDALONE_INDEXING) { + + + while(true) { + try { + + String response = Util.getResponse("http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", MediaType.APPLICATION_JSON); + JSONObject jsonObject = (JSONObject) JSONValue.parse(response); + + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" + testType + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.used").toString()) / (1024 * 1024)), false, FileType.MEMORY_HEAP_USED); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" + testType + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("os.processCpuLoad").toString()) * 100), false, FileType.PROCESS_CPU_LOAD); + + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + + if(testType == TestType.STANDALONE_CREATE_COLLECTION) { + + + while(true) { + try { + + String response = Util.getResponse("http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", MediaType.APPLICATION_JSON); + JSONObject jsonObject = (JSONObject) JSONValue.parse(response); + + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" + TestType.STANDALONE_CREATE_COLLECTION + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.used").toString()) / (1024 * 1024)), false, FileType.MEMORY_HEAP_USED); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" + TestType.STANDALONE_CREATE_COLLECTION + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("os.processCpuLoad").toString()) * 100), false, FileType.PROCESS_CPU_LOAD); + + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + + if(testType == TestType.CLOUD_CREATE_COLLECTION) { + + + while(true) { + try { + + String response = Util.getResponse("http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", MediaType.APPLICATION_JSON); + JSONObject jsonObject = (JSONObject) JSONValue.parse(response); + + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" + TestType.CLOUD_CREATE_COLLECTION + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.used").toString()) / (1024 * 1024)), false, FileType.MEMORY_HEAP_USED); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" + TestType.CLOUD_CREATE_COLLECTION + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("os.processCpuLoad").toString()) * 100), false, FileType.PROCESS_CPU_LOAD); + + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + + if(testType == TestType.CLOUD_INDEXING_REGULAR) { + + + while(true) { + try { + + String response = Util.getResponse("http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", MediaType.APPLICATION_JSON); + JSONObject jsonObject = (JSONObject) JSONValue.parse(response); + + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" + TestType.CLOUD_INDEXING_REGULAR + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.used").toString()) / (1024 * 1024)), false, FileType.MEMORY_HEAP_USED); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" + TestType.CLOUD_INDEXING_REGULAR + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("os.processCpuLoad").toString()) * 100), false, FileType.PROCESS_CPU_LOAD); + + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + + if(testType == TestType.CLOUD_INDEXING_CONCURRENT) { + + + while(true) { + try { + + String response = Util.getResponse("http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", MediaType.APPLICATION_JSON); + JSONObject jsonObject = (JSONObject) JSONValue.parse(response); + + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" + TestType.CLOUD_INDEXING_CONCURRENT + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.used").toString()) / (1024 * 1024)), false, FileType.MEMORY_HEAP_USED); + BenchmarkAppConnector.writeToWebAppDataFile(this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" + TestType.CLOUD_INDEXING_CONCURRENT + "_dump.csv", ft.format(dNow) + ", " + (Double.parseDouble(((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("os.processCpuLoad").toString()) * 100), false, FileType.PROCESS_CPU_LOAD); + + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + + } +} diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java new file mode 100644 index 000000000000..67aec88785d9 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java @@ -0,0 +1,32 @@ +package org.apache.solr.tests.nightlybenchmarks; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class ProcessStreamReader extends Thread { + + InputStream is; + String type; + + ProcessStreamReader(InputStream is, String type) { + this.is = is; + this.type = type; + } + + public void run() { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String line = null; + while ((line = br.readLine()) != null) { + Util.postMessage(" >> " + line, MessageType.RESULT_SUCCESS, false); + } + + } catch (IOException ioe) { + Util.postMessage(ioe.getMessage(), MessageType.RESULT_ERRROR, false); + } + } + +} diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java new file mode 100644 index 000000000000..d0530521cbec --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java @@ -0,0 +1,255 @@ +package org.apache.solr.tests.nightlybenchmarks; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.CloudSolrClient; +import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient; +import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.tests.nightlybenchmarks.BenchmarkAppConnector.FileType; + +public class SolrClient { + + public enum SolrClientType { HTTP_SOLR_CLIENT, CLOUD_SOLR_CLIENT, CONCURRENT_UPDATE_SOLR_CLIENT }; + + @SuppressWarnings("unused") + private String host; + private String port; + @SuppressWarnings("unused") + private String collection; + public static String solrCommitHistoryData; + public static String amazonFoodDataLocation; + private String commitId; + + public SolrClient(String host, String port, String collection, String commitId) { + super(); + this.host = host; + this.port = port; + this.collection = collection; + this.commitId = commitId; + } + + @SuppressWarnings("deprecation") + public void indexAmazonFoodData(int numDocuments, String urlString) { + + Util.postMessage("** Indexing documents (Amazon Food Reviews) ...", MessageType.ACTION, false); + + HttpSolrClient solrClient = new HttpSolrClient.Builder(urlString).build(); + + long start = 0; + long end = 0; + int numberOfDocuments = 0; + String line = ""; + String cvsSplitBy = ","; + + Thread thread =new Thread(new MetricEstimation(this.commitId, TestType.STANDALONE_INDEXING, this.port)); + thread.start(); + + try (BufferedReader br = new BufferedReader(new FileReader(amazonFoodDataLocation))) { + + start = System.nanoTime(); + while ((line = br.readLine()) != null) { + + String[] foodData = line.split(cvsSplitBy); + SolrInputDocument document = new SolrInputDocument(); + + document.addField("Id", foodData[0]); + document.addField("ProductId", foodData[1]); + document.addField("UserId", foodData[2]); + document.addField("ProfileName", foodData[3].replaceAll("'", "").replaceAll("\"", "")); + document.addField("HelpfulnessNumerator", foodData[4]); + document.addField("HelpfulnessDenominator", foodData[5]); + document.addField("Score", foodData[6]); + document.addField("Time", foodData[7]); + document.addField("Summary", foodData[8].replaceAll("'", "").replaceAll("\"", "")); + document.addField("Text", foodData[9].replaceAll("'", "").replaceAll("\"", "")); + + solrClient.add(document); + numberOfDocuments++; + if (numDocuments == numberOfDocuments) { + break; + } + if(numberOfDocuments%5000 == 0) { + Util.postMessageOnLine("|"); + } + Util.postMessageOnLine("" + numberOfDocuments + " "); + } + solrClient.commit(); + end = System.nanoTime(); + Util.postMessage("", MessageType.GENERAL, false); + Util.postMessage("** Committing the documents ...", MessageType.ACTION, false); + + Util.postMessage("** Closing the Solr connection ...", MessageType.RESULT_SUCCESS, false); + solrClient.close(); + Util.postMessage("** Time taken to index " + numberOfDocuments + " documents is: " + (end-start) + " nanosecond(s)" , MessageType.RESULT_ERRROR, false); + + + } catch (IOException e) { + e.printStackTrace(); + } catch (SolrServerException e) { + e.printStackTrace(); + } + + Date dNow = new Date( ); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile("indexing_data_standalone_regular.csv", ft.format(dNow) + ", " + ((end-start)/1000000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.STANDALONE_INDEXING_MAIN); + BenchmarkAppConnector.writeToWebAppDataFile("indexing_throughput_data_standalone_regular.csv", ft.format(dNow) + ", " + numberOfDocuments/((end-start)/1000000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.STANDALONE_INDEXING_THROUGHPUT); + + thread.stop(); + + Util.postMessage("** Indexing documents (Amazon Food Reviews Data) COMPLETE ...", MessageType.ACTION, false); + } + + + @SuppressWarnings("deprecation") + public void indexAmazonFoodData(int numDocuments, String urlString, String zookeeperIp, String zookeeperPort, String collectionName) { + + Util.postMessage("** Indexing documents (Amazon Food Reviews) ...", MessageType.ACTION, false); + + CloudSolrClient solrClient = new CloudSolrClient(zookeeperIp + ":" + zookeeperPort); + solrClient.connect(); + solrClient.setDefaultCollection(collectionName); + + long start = 0; + long end = 0; + int numberOfDocuments = 0; + String line = ""; + String cvsSplitBy = ","; + + Thread thread =new Thread(new MetricEstimation(this.commitId, TestType.CLOUD_INDEXING_REGULAR, this.port)); + thread.start(); + + try (BufferedReader br = new BufferedReader(new FileReader(amazonFoodDataLocation))) { + + start = System.nanoTime(); + while ((line = br.readLine()) != null) { + + String[] foodData = line.split(cvsSplitBy); + SolrInputDocument document = new SolrInputDocument(); + + document.addField("Id", foodData[0]); + document.addField("ProductId", foodData[1]); + document.addField("UserId", foodData[2]); + document.addField("ProfileName", foodData[3].replaceAll("'", "").replaceAll("\"", "")); + document.addField("HelpfulnessNumerator", foodData[4]); + document.addField("HelpfulnessDenominator", foodData[5]); + document.addField("Score", foodData[6]); + document.addField("Time", foodData[7]); + document.addField("Summary", foodData[8].replaceAll("'", "").replaceAll("\"", "")); + document.addField("Text", foodData[9].replaceAll("'", "").replaceAll("\"", "")); + + solrClient.add(document); + numberOfDocuments++; + if (numDocuments == numberOfDocuments) { + break; + } + if(numberOfDocuments%5000 == 0) { + Util.postMessageOnLine("|"); + } + Util.postMessageOnLine("" + numberOfDocuments + " "); + } + solrClient.commit(); + end = System.nanoTime(); + Util.postMessage("", MessageType.GENERAL, false); + Util.postMessage("** Committing the documents ...", MessageType.ACTION, false); + + Util.postMessage("** Closing the Solr connection ...", MessageType.RESULT_SUCCESS, false); + solrClient.close(); + Util.postMessage("** Time taken to index " + numberOfDocuments + " documents is: " + (end-start) + " nanosecond(s)" , MessageType.RESULT_ERRROR, false); + + + } catch (IOException e) { + e.printStackTrace(); + } catch (SolrServerException e) { + e.printStackTrace(); + } + + Date dNow = new Date( ); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile("indexing_data_cloud_regular.csv", ft.format(dNow) + ", " + ((end-start)/1000000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.STANDALONE_INDEXING_MAIN); + BenchmarkAppConnector.writeToWebAppDataFile("indexing_throughput_data_cloud_serial.csv", ft.format(dNow) + ", " + numberOfDocuments/((end-start)/1000000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.CLOUD_SERIAL_INDEXING_THROUGHPUT); + + thread.stop(); + + Util.postMessage("** Indexing documents (Amazon Food Reviews Data) COMPLETE ...", MessageType.ACTION, false); + } + + + @SuppressWarnings("deprecation") + public void indexAmazonFoodData(int numDocuments, String urlString, String zookeeperIp, String zookeeperPort, String collectionName, int queueSize, int threadCount) { + + Util.postMessage("** Indexing documents (Amazon Food Reviews) ...", MessageType.ACTION, false); + + ConcurrentUpdateSolrClient solrClient = new ConcurrentUpdateSolrClient(urlString, queueSize, threadCount); + solrClient.setConnectionTimeout(1000000); + + long start = 0; + long end = 0; + int numberOfDocuments = 0; + String line = ""; + String cvsSplitBy = ","; + + Thread thread =new Thread(new MetricEstimation(this.commitId, TestType.CLOUD_INDEXING_CONCURRENT, this.port)); + thread.start(); + + try (BufferedReader br = new BufferedReader(new FileReader(amazonFoodDataLocation))) { + + start = System.nanoTime(); + while ((line = br.readLine()) != null) { + + String[] foodData = line.split(cvsSplitBy); + SolrInputDocument document = new SolrInputDocument(); + + document.addField("Id", foodData[0]); + document.addField("ProductId", foodData[1]); + document.addField("UserId", foodData[2]); + document.addField("ProfileName", foodData[3].replaceAll("'", "").replaceAll("\"", "")); + document.addField("HelpfulnessNumerator", foodData[4]); + document.addField("HelpfulnessDenominator", foodData[5]); + document.addField("Score", foodData[6]); + document.addField("Time", foodData[7]); + document.addField("Summary", foodData[8].replaceAll("'", "").replaceAll("\"", "")); + document.addField("Text", foodData[9].replaceAll("'", "").replaceAll("\"", "")); + + solrClient.add(document); + numberOfDocuments++; + if (numDocuments == numberOfDocuments) { + break; + } + if(numberOfDocuments%5000 == 0) { + Util.postMessageOnLine("|"); + } + Util.postMessageOnLine("" + numberOfDocuments + " "); + } + solrClient.commit(); + end = System.nanoTime(); + Util.postMessage("", MessageType.GENERAL, false); + Util.postMessage("** Committing the documents ...", MessageType.ACTION, false); + + Util.postMessage("** Closing the Solr connection ...", MessageType.RESULT_SUCCESS, false); + solrClient.close(); + Util.postMessage("** Time taken to index " + numberOfDocuments + " documents is: " + (end-start) + " nanosecond(s)" , MessageType.RESULT_ERRROR, false); + + + } catch (IOException e) { + e.printStackTrace(); + } catch (SolrServerException e) { + e.printStackTrace(); + } + + Date dNow = new Date( ); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + BenchmarkAppConnector.writeToWebAppDataFile("indexing_data_cloud_concurrent.csv", ft.format(dNow) + ", " + ((end-start)/1000000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.STANDALONE_INDEXING_MAIN); + BenchmarkAppConnector.writeToWebAppDataFile("indexing_throughput_data_cloud_concurrent.csv", ft.format(dNow) + ", " + numberOfDocuments/((end-start)/1000000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.CLOUD_CONCURRENT_INDEXING_THROUGHPUT); + + thread.stop(); + + Util.postMessage("** Indexing documents (Amazon Food Reviews Data) COMPLETE ...", MessageType.ACTION, false); + } + +} diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java new file mode 100644 index 000000000000..45316dd186a1 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java @@ -0,0 +1,104 @@ +package org.apache.solr.tests.nightlybenchmarks; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import org.eclipse.jgit.api.errors.GitAPIException; + +public class SolrCloud { + + public int solrNodes; + public String shards; + public String replicas; + public String port; + public Zookeeper zookeeperNode; + public String zookeeperPort; + public String zookeeperIp; + public String commitId; + public String collectionName; + public String configName; + public SolrNode masterNode; + public List nodes; + public String url; + public String host; + public boolean createADefaultCollection; + + public SolrCloud(int solrNodes, String shards, String replicas, String commitId, String configName, String host, boolean creatADefaultCollection) { + super(); + this.solrNodes = solrNodes; + this.shards = shards; + this.replicas = replicas; + this.commitId = commitId; + this.configName = configName; + this.host = host; + this.collectionName = "Collection_" + UUID.randomUUID(); + this.createADefaultCollection = creatADefaultCollection; + nodes = new LinkedList(); + this.init(); + } + + private void init() { + + try { + + zookeeperNode = new Zookeeper(); + int initValue = zookeeperNode.start(); + if (initValue == 0) { + this.zookeeperIp = zookeeperNode.getZookeeperIp(); + this.zookeeperPort = zookeeperNode.getZookeeperPort(); + } else { + throw new RuntimeException("Failed to start Zookeeper!"); + } + + for (int i = 1; i <= solrNodes; i++) { + + SolrNode node = new SolrNode(commitId, this.zookeeperIp, this.zookeeperPort, true); + node.start(); + nodes.add(node); + } + + if (this.createADefaultCollection) { + nodes.get(0).createCollection(this.collectionName, this.configName, this.shards, this.replicas); + } + + this.port = nodes.get(0).port; + + this.url = "http://" + this.host + ":" + this.port + "/solr/" + this.collectionName; + + } catch (IOException e) { + e.printStackTrace(); + } catch (GitAPIException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + public void createCollection(String collectionName, String configName, String shards, String replicas) { + try { + nodes.get(0).createCollection(collectionName, configName, shards, replicas); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + + public String getuRL() { + if (createADefaultCollection) { + return "http://" + this.host + ":" + this.port + "/solr/" + this.collectionName; + } else { + return "http://" + this.host + ":" + this.port + "/solr/"; + } + } + + public void shutdown() { + for (SolrNode node: nodes) { + node.stop(); + node.cleanup(); + } + zookeeperNode.stop(); + } + +} diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java new file mode 100644 index 000000000000..271e14be0d74 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -0,0 +1,74 @@ +package org.apache.solr.tests.nightlybenchmarks; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class SolrNightlyBenchmarks { + + public static void main(String[] args) throws IOException, InterruptedException { + + + Map argM = new HashMap(); + for (int i = 0; i < args.length; i += 2) { + argM.put(args[i], args[i + 1]); + } + + Util.getProperties(); + Util.checkWebAppFiles(); + Util.checkBaseAndTempDir(); + Util.getSystemEnvironmentInformation(); + + File statusFile = new File(BenchmarkAppConnector.benchmarkAppDirectory + "iamalive.txt"); + if (!statusFile.exists()) { + statusFile.createNewFile(); + } + + try { + + String commitID = ""; + if(argM.containsKey("-commitID")) { + commitID = argM.get("-commitID"); + } else { + commitID = Util.getLatestCommitID(); + Util.postMessage("The latest commit ID is: " + commitID, MessageType.RESULT_ERRROR, false); + } + Util.commitId = commitID; + + + // Sample Test + + SolrNode node = new SolrNode(commitID, "", "", false); + node.start(); + Util.getEnvironmentInformationFromMetricAPI(commitID, node.port); + node.createCore("Core-" + UUID.randomUUID(), "Collection-" + UUID.randomUUID()); + + SolrClient client = new SolrClient("localhost", node.port, node.collectionName, commitID); + client.indexAmazonFoodData(10000, node.getBaseUrl() + node.collectionName); + + node.stop(); + node.cleanup(); + + SolrCloud cloud = new SolrCloud(5, "2", "2", commitID, null, "localhost", true); + SolrClient cloudClient = new SolrClient("localhost", cloud.port, cloud.collectionName, commitID); + cloudClient.indexAmazonFoodData(10000, cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName); + cloudClient.indexAmazonFoodData(10000, cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName, 10000, 10); + cloud.shutdown(); + + // End Sample Test + + } catch (Exception e) { + e.printStackTrace(); + } + + statusFile = new File(BenchmarkAppConnector.benchmarkAppDirectory + "iamalive.txt"); + if (statusFile.exists()) { + statusFile.delete(); + } + + if(argM.containsKey("-Housekeeping")) { + Util.cleanUpSrcDirs(); + } + } +} \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java new file mode 100644 index 000000000000..1f64d2035ca6 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java @@ -0,0 +1,283 @@ +package org.apache.solr.tests.nightlybenchmarks; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.UUID; + +import org.apache.log4j.Logger; +import org.apache.solr.tests.nightlybenchmarks.BenchmarkAppConnector.FileType; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; + +public class SolrNode { + + final static Logger logger = Logger.getLogger(SolrNode.class); + public static final String URL_BASE = "http://archive.apache.org/dist/lucene/solr/"; + + private String nodeDirectory; + public String port; + private String commitId; + private String zooKeeperIp; + private String zooKeeperPort; + public String collectionName; + public String baseDirectory; + public boolean isRunningInCloudMode; + + private String gitDirectoryPath = Util.TEMP_DIR + "git-repository-"; + + public SolrNode(String commitId, String zooKeeperIp, String zooKeeperPort, boolean isRunningInCloudMode) throws IOException, GitAPIException { + super(); + this.commitId = commitId; + this.zooKeeperIp = zooKeeperIp; + this.zooKeeperPort = zooKeeperPort; + this.isRunningInCloudMode = isRunningInCloudMode; + this.gitDirectoryPath = Util.TEMP_DIR + "git-repository-" + commitId; + Util.gitRepositoryPath = this.gitDirectoryPath; + this.install(); + } + + private void install() throws IOException, GitAPIException { + + Util.postMessage("** Installing Solr Node ...", MessageType.ACTION, true); + this.port = String.valueOf(Util.getFreePort()); + + this.baseDirectory = Util.BASE_DIR + UUID.randomUUID().toString() + File.separator; + + this.nodeDirectory = this.baseDirectory + "solr-7.0.0-SNAPSHOT/bin/"; + + try { + + Util.postMessage("** Checking if SOLR node directory exists ...", + MessageType.ACTION, true); File node = new File(nodeDirectory); + + if (!node.exists()) { + + Util.postMessage("Node directory does not exist, creating it ...", + MessageType.ACTION, true); node.mkdir(); + Util.postMessage("Directory Created: " + nodeDirectory, + MessageType.RESULT_SUCCESS, true); + + } + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + + } + + this.checkoutCommitAndBuild(); + Util.extract(Util.TEMP_DIR + "solr-" + commitId + ".zip", baseDirectory); + } + + void checkoutCommitAndBuild() throws IOException, GitAPIException { + Util.postMessage("** Checking out Solr: " + commitId + " ...", MessageType.ACTION, true); + + File gitDirectory = new File(gitDirectoryPath); + + Git repository; + + if (gitDirectory.exists()) { + repository = Git.open(gitDirectory); + + repository.checkout().setName(commitId).call(); + + } else { + repository = Git.cloneRepository().setURI("https://github.com/apache/lucene-solr") + .setDirectory(gitDirectory).call(); + repository.checkout().setName(commitId).call(); + } + + String packageFilename = gitDirectoryPath + "/solr/package/solr-7.0.0-SNAPSHOT.zip"; + String tarballLocation = Util.TEMP_DIR + "solr-" + commitId + ".zip"; + + if (new File(tarballLocation).exists() == false) { + if (new File(packageFilename).exists() == false) { + Util.postMessage("** There were new changes, need to rebuild ...", MessageType.ACTION, true); + Util.execute("ant ivy-bootstrap", gitDirectoryPath); + // Util.execute("ant compile", gitDirectoryPath); + Util.execute("ant package", gitDirectoryPath + File.separator + "solr"); + } + + if (new File(packageFilename).exists()) { + System.out.println("Trying to copy: " + packageFilename + " to " + tarballLocation); + Files.copy(Paths.get(packageFilename), Paths.get(tarballLocation)); + System.out.println("File copied!"); + } else { + throw new IOException("Couldn't build the package"); // nocommit + // fix, + // better + // exception + } + } + + Util.postMessage( + "** Do we have packageFilename? " + (new File(tarballLocation).exists() ? "yes" : "no") + " ...", + MessageType.ACTION, true); + } + + @SuppressWarnings("finally") + public int start() { + + Util.postMessage("** Starting Solr Node ...", MessageType.ACTION, true); + + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + long start = 0; + long end = 0; + + try { + + if (isRunningInCloudMode) { + start = System.nanoTime(); + + new File(nodeDirectory + "solr").setExecutable(true); + proc = rt.exec(nodeDirectory + "solr start -force " + "-p " + port + " -m 4g" + " -z " + zooKeeperIp + + ":" + zooKeeperPort); + end = System.nanoTime(); + + } else { + + new File(nodeDirectory + "solr").setExecutable(true); + start = System.nanoTime(); + proc = rt.exec(nodeDirectory + "solr start -force " + "-p " + port + " -m 4g"); + end = System.nanoTime(); + + } + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + + Util.postMessage("** Time taken to start the Solr Node is: " + (end-start) + " nanosecond(s)", MessageType.RESULT_ERRROR, false); + return proc.exitValue(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + return -1; + + } finally { + + return proc.exitValue(); + + } + + } + + public void stop() { + + Util.postMessage("** Stopping Solr Node ...", MessageType.ACTION, true); long start = 0; + long end = 0; + + + if (isRunningInCloudMode) { + start = System.nanoTime(); + + Util.execute( + nodeDirectory + "solr stop -p " + port + " -z " + zooKeeperIp + ":" + zooKeeperPort + " -force", + nodeDirectory); + + end = System.nanoTime(); + + } else { + start = System.nanoTime(); + + Util.execute(nodeDirectory + "solr stop -p " + port + " -force", nodeDirectory); end = System.nanoTime(); + } + Util.postMessage("** Time taken to stop the node is: " + (end-start) + " nanosecond(s)", MessageType.RESULT_ERRROR, false); + + + } + + + @SuppressWarnings("deprecation") + public void createCore(String coreName, String collectionName) throws IOException, InterruptedException { + + Thread thread =new Thread(new MetricEstimation(this.commitId, TestType.STANDALONE_CREATE_COLLECTION, this.port)); + thread.start(); + + this.collectionName = collectionName; + Util.postMessage("** Creating core ... ", MessageType.ACTION, true); + + long start; + long end; + + start = System.nanoTime(); + Util.execute("./solr create_core -c " + coreName + " -p " + port + " -collection " + collectionName + " -force", nodeDirectory); + end = System.nanoTime(); + + Util.postMessage("** Time for creating the core is: " + (end-start) + " nanosecond(s)", MessageType.RESULT_ERRROR, false); + + Date dNow = new Date( ); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + + BenchmarkAppConnector.writeToWebAppDataFile("create_collection_data_standalone_regular.csv", ft.format(dNow) + ", " + ((end-start)/1000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.STANDALONE_CREATE_COLLECTION_MAIN); + + thread.stop(); + } + + @SuppressWarnings("deprecation") + public int createCollection(String collectionName, String configName, String shards, String replicationFactor) + throws IOException, InterruptedException { + + Thread thread =new Thread(new MetricEstimation(this.commitId, TestType.CLOUD_CREATE_COLLECTION, this.port)); + thread.start(); + + this.collectionName = collectionName; + Util.postMessage("** Creating collection ... ", MessageType.ACTION, true); + + long start; + long end; + int returnVal; + + if (configName != null) { + start = System.nanoTime(); + returnVal = Util.execute("./solr create_collection -collection " + + collectionName + " -shards " + shards + + " -n " + configName + + " -replicationFactor " + replicationFactor + " -force", nodeDirectory); + end = System.nanoTime(); + } else { + start = System.nanoTime(); + returnVal = Util.execute("./solr create_collection -collection " + + collectionName + " -shards " + shards + + " -replicationFactor " + replicationFactor + " -force", nodeDirectory); + end = System.nanoTime(); + } + + Util.postMessage("** Time for creating the collection is: " + (end-start) + " nanosecond(s)", MessageType.RESULT_ERRROR, false); + + Date dNow = new Date( ); + SimpleDateFormat ft = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); + + BenchmarkAppConnector.writeToWebAppDataFile("create_collection_data_cloud_regular.csv", ft.format(dNow) + ", " + ((end-start)/1000000) + ", " + this.commitId + ", " + Util.getCommitInformation(), false, FileType.CLOUD_CREATE_COLLECTION_MAIN); + + thread.stop(); + return returnVal; + } + + + public String getNodeDirectory() { + return nodeDirectory; + } + + public String getBaseUrl() { + return "http://localhost:" + port + "/solr/"; + } + + public void cleanup() { + try { + Util.deleteDirectory(baseDirectory); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java new file mode 100644 index 000000000000..5f56fed28e45 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java @@ -0,0 +1,7 @@ +package org.apache.solr.tests.nightlybenchmarks; + +public enum TestType { + + STANDALONE_CREATE_COLLECTION, STANDALONE_INDEXING, CLOUD_CREATE_COLLECTION, CLOUD_INDEXING_REGULAR, CLOUD_INDEXING_CONCURRENT + +} diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java new file mode 100644 index 000000000000..6fc8041daf26 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -0,0 +1,590 @@ +package org.apache.solr.tests.nightlybenchmarks; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.math.BigInteger; +import java.net.DatagramSocket; +import java.net.ServerSocket; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ThreadLocalRandom; +import java.util.zip.ZipInputStream; + +import javax.ws.rs.core.MediaType; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; +import org.apache.solr.tests.nightlybenchmarks.BenchmarkAppConnector.FileType; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; + +import net.lingala.zip4j.core.ZipFile; +import net.lingala.zip4j.exception.ZipException; + +enum MessageType { + PROCESS, ACTION, RESULT_SUCCESS, RESULT_ERRROR, GENERAL +}; + +public class Util { + + public static String WORK_DIRECTORY = System.getProperty("user.dir"); + public static String DNAME = "SolrNightlyBenchmarks"; + public static String BASE_DIR = WORK_DIRECTORY + File.separator + DNAME + File.separator; + public static String TEMP_DIR = BASE_DIR + "temp" + File.separator; + public static String ZOOKEEPER_DOWNLOAD_URL = "http://www.us.apache.org/dist/zookeeper/"; + public static String ZOOKEEPER_RELEASE = "3.4.6"; + public static String ZOOKEEPER_DIR = BASE_DIR + "ZOOKEEPER" + File.separator; + public static String ZOOKEEPER_IP = "127.0.0.1"; + public static String ZOOKEEPER_PORT = "2181"; + + final static Logger logger = Logger.getLogger(Util.class); + public static String gitRepositoryPath; + public static String commitId; + + public static void postMessage(String message, MessageType type, boolean printInLog) { + + String ANSI_RESET = "\u001B[0m"; + String ANSI_RED = "\u001B[31m"; + String ANSI_GREEN = "\u001B[32m"; + String ANSI_YELLOW = "\u001B[33m"; + String ANSI_BLUE = "\u001B[34m"; + String ANSI_WHITE = "\u001B[37m"; + + if (type.equals(MessageType.ACTION)) { + System.out.println(ANSI_WHITE + message + ANSI_RESET); + } else if (type.equals(MessageType.GENERAL)) { + System.out.println(ANSI_BLUE + message + ANSI_RESET); + } else if (type.equals(MessageType.PROCESS)) { + System.out.println(ANSI_YELLOW + message + ANSI_RESET); + } else if (type.equals(MessageType.RESULT_ERRROR)) { + System.out.println(ANSI_RED + message + ANSI_RESET); + } else if (type.equals(MessageType.RESULT_SUCCESS)) { + System.out.println(ANSI_GREEN + message + ANSI_RESET); + } + + if (printInLog) { + logger.info(message); + } + + } + + public static int execute(String command, String workingDirectoryPath) { + Util.postMessage("Executing: " + command, MessageType.ACTION, true); + Util.postMessage("Working dir: " + workingDirectoryPath, MessageType.ACTION, true); + File workingDirectory = new File(workingDirectoryPath); + + workingDirectory.setExecutable(true); + + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + proc = rt.exec(command, new String[] {}, workingDirectory); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + return proc.exitValue(); + } catch (Exception e) { + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + return -1; + } + } + + @SuppressWarnings("finally") + public static int deleteDirectory(String directory) throws IOException, InterruptedException { + + postMessage("Deleting directory: " + directory, MessageType.ACTION, true); + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + + proc = rt.exec("rm -r -f " + directory); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + return proc.exitValue(); + + } catch (Exception e) { + + postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + return -1; + + } finally { + + proc.destroy(); + return proc.exitValue(); + + } + + } + + @SuppressWarnings("finally") + public static int createDirectory(String directory) throws IOException, InterruptedException { + + postMessage("Creating directory: " + directory, MessageType.ACTION, true); + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + + proc = rt.exec("mkdir " + directory); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + return proc.exitValue(); + + } catch (Exception e) { + + postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + return -1; + + } finally { + + proc.destroy(); + return proc.exitValue(); + + } + } + + public static void postMessageOnLine(String message) { + + System.out.print(message); + + } + + public static void checkBaseAndTempDir() { + BasicConfigurator.configure(); + File baseDirectory = new File(BASE_DIR); + baseDirectory.mkdir(); + File tempDirectory = new File(TEMP_DIR); + tempDirectory.mkdir(); + } + + public static int getFreePort() { + + int port = ThreadLocalRandom.current().nextInt(10000, 60000); + Util.postMessage("Looking for a free port ... Checking availability of port number: " + port, + MessageType.ACTION, true); + ServerSocket serverSocket = null; + DatagramSocket datagramSocket = null; + try { + serverSocket = new ServerSocket(port); + serverSocket.setReuseAddress(true); + datagramSocket = new DatagramSocket(port); + datagramSocket.setReuseAddress(true); + Util.postMessage("Port " + port + " is free to use. Using this port !!", MessageType.RESULT_SUCCESS, true); + return port; + } catch (IOException e) { + } finally { + if (datagramSocket != null) { + datagramSocket.close(); + } + + if (serverSocket != null) { + try { + serverSocket.close(); + } catch (IOException e) { + } + } + } + + Util.postMessage("Port " + port + " looks occupied trying another port number ... ", MessageType.RESULT_ERRROR, + true); + return getFreePort(); + } + + static public String md5(String plaintext) { + MessageDigest m; + String hashtext = null; + try { + m = MessageDigest.getInstance("MD5"); + m.reset(); + m.update(plaintext.getBytes()); + byte[] digest = m.digest(); + BigInteger bigInt = new BigInteger(1, digest); + hashtext = bigInt.toString(16); + // Now we need to zero pad it if you actually want the full 32 + // chars. + while (hashtext.length() < 32) { + hashtext = "0" + hashtext; + } + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return hashtext; + } + + public static void extractFile(ZipInputStream zipIn, String filePath) throws IOException { + + BufferedOutputStream bos = null; + try { + + bos = new BufferedOutputStream(new FileOutputStream(filePath)); + byte[] bytesIn = new byte[4096]; + int read = 0; + while ((read = zipIn.read(bytesIn)) != -1) { + bos.write(bytesIn, 0, read); + } + bos.close(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + + } finally { + + bos.close(); + + } + } + + public static void extract(String filename, String filePath) throws IOException { + Util.postMessage("** Attempting to unzip the downloaded release ...", MessageType.ACTION, true); + try { + ZipFile zip = new ZipFile(filename); + zip.extractAll(filePath); + } catch (ZipException ex) { + throw new IOException(ex); + } + } + + public static String getLatestCommitID() throws IOException { + Util.postMessage("** Getting the latest commit ID from remote repository", MessageType.GENERAL, false); + return new BufferedReader(new InputStreamReader( + Runtime.getRuntime().exec("git ls-remote https://github.com/apache/lucene-solr HEAD").getInputStream())) + .readLine().split("HEAD")[0].trim(); + } + + public static String getCommitInformation() { + Util.postMessage("** Getting the latest commit Information from local repository", MessageType.GENERAL, false); + File directory = new File(Util.gitRepositoryPath); + directory.setExecutable(true); + BufferedReader reader; + try { + reader = new BufferedReader(new InputStreamReader(Runtime.getRuntime() + .exec("git show --no-patch " + Util.commitId, new String[] {}, directory).getInputStream())); + + reader.readLine(); + String returnString; + returnString = reader.readLine().replaceAll("<", " ").replaceAll(">", " ").trim() + ", " + + reader.readLine().trim(); + reader.readLine(); + returnString += ", " + reader.readLine().trim(); + return returnString; + + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } + + public static void getSystemEnvironmentInformation() { + + Util.postMessage("** Getting the test environment information", MessageType.GENERAL, false); + + BufferedReader reader; + try { + String returnString = ""; + String line = ""; + + reader = new BufferedReader( + new InputStreamReader(Runtime.getRuntime().exec("sudo lshw -short").getInputStream())); + while ((line = reader.readLine()) != null) { + returnString += line.replaceAll("\\p{C}", " ") + "
"; + } + + returnString += "
"; + + returnString += "Java Version: " + System.getProperty("java.version"); + + returnString += "
"; + + reader = new BufferedReader( + new InputStreamReader(Runtime.getRuntime().exec("ant -version").getInputStream())); + while ((line = reader.readLine()) != null) { + returnString += line.replaceAll(" ", " ") + "
"; + } + + returnString += "
"; + + reader = new BufferedReader( + new InputStreamReader(Runtime.getRuntime().exec("cat /proc/version").getInputStream())); + while ((line = reader.readLine()) != null) { + returnString += line.replaceAll(" ", " ") + "
"; + } + + BenchmarkAppConnector.writeToWebAppDataFile("testEnv.csv", returnString, true, FileType.TEST_ENV_FILE); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static Map getMemoryState() { + + Map aMap = new HashMap(); + + try { + + String line = ""; + BufferedReader reader = new BufferedReader( + new InputStreamReader(Runtime.getRuntime().exec("cat /proc/meminfo").getInputStream())); + + while ((line = reader.readLine()) != null) { + aMap.put(line.split(":")[0].trim(), Long.parseLong(line.split(":")[1].trim().replaceAll("[^0-9]", ""))); + } + + } catch (NumberFormatException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return aMap; + + } + + public static void getProperties() { + + Properties prop = new Properties(); + InputStream input = null; + + try { + + input = new FileInputStream("config.properties"); + prop.load(input); + + // get the property value and print it out + BenchmarkAppConnector.benchmarkAppDirectory = prop + .getProperty("SolrNightlyBenchmarks.benchmarkAppDirectory"); + Util.postMessage( + "Getting Property Value for benchmarkAppDirectory: " + BenchmarkAppConnector.benchmarkAppDirectory, + MessageType.PROCESS, false); + SolrClient.solrCommitHistoryData = prop.getProperty("SolrNightlyBenchmarks.solrCommitHistoryData"); + Util.postMessage("Getting Property Value for solrCommitHistoryData: " + SolrClient.solrCommitHistoryData, + MessageType.PROCESS, false); + SolrClient.amazonFoodDataLocation = prop.getProperty("SolrNightlyBenchmarks.amazonFoodDataLocation"); + Util.postMessage("Getting Property Value for amazonFoodDataLocation: " + SolrClient.amazonFoodDataLocation, + MessageType.PROCESS, false); + MetricEstimation.metricsURL = prop.getProperty("SolrNightlyBenchmarks.metricsURL"); + Util.postMessage("Getting Property Value for metricsURL: " + MetricEstimation.metricsURL, + MessageType.PROCESS, false); + Util.ZOOKEEPER_DOWNLOAD_URL = prop.getProperty("SolrNightlyBenchmarks.zookeeperDownloadURL"); + Util.postMessage("Getting Property Value for zookeeperDownloadURL: " + Util.ZOOKEEPER_DOWNLOAD_URL, + MessageType.PROCESS, false); + Util.ZOOKEEPER_RELEASE = prop.getProperty("SolrNightlyBenchmarks.zookeeperDownloadVersion"); + Util.postMessage("Getting Property Value for zookeeperDownloadVersion: " + Util.ZOOKEEPER_RELEASE, + MessageType.PROCESS, false); + Util.ZOOKEEPER_IP = prop.getProperty("SolrNightlyBenchmarks.zookeeperHostIp"); + Util.postMessage("Getting Property Value for zookeeperHostIp: " + Util.ZOOKEEPER_IP, + MessageType.PROCESS, false); + Util.ZOOKEEPER_PORT = prop.getProperty("SolrNightlyBenchmarks.zookeeperHostPort"); + Util.postMessage("Getting Property Value for zookeeperHostPort: " + Util.ZOOKEEPER_PORT, + MessageType.PROCESS, false); + + + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + } + + public static String getResponse(String url, String type) { + + try { + Client client = Client.create(); + WebResource webResource = client.resource(url); + + ClientResponse response = webResource.accept(type).get(ClientResponse.class); + + if (response.getStatus() != 200) { + throw new RuntimeException("Failed : HTTP error code : " + response.getStatus()); + } + + return response.getEntity(String.class); + + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + public static void getEnvironmentInformationFromMetricAPI(String commitID, String port) { + + String response = Util.getResponse("http://localhost:" + port + "/solr/admin/metrics?wt=json&group=jvm", MediaType.APPLICATION_JSON); + JSONObject jsonObject = (JSONObject) JSONValue.parse(response); + + String printString = ""; + printString += "Memory Heap Committed: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.committed") + " Bytes
\n"; + printString += "Memory Heap Init: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.init") + " Bytes
\n"; + printString += "Memory Heap Max: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.heap.max") + " Bytes
\n"; + + printString += "Memory Non-Heap Committed:" + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.non-heap.committed") + " Bytes
\n"; + printString += "Memory Non-Heap Init: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.non-heap.init") + " Bytes
\n"; + printString += "Memory Non-Heap Max: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.non-heap.max") + " Bytes
\n"; + + printString += "Memory Total Committed: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.total.committed") + " Bytes
\n"; + printString += "Memory Total Init: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.total.init") + " Bytes
\n"; + printString += "Memory Total Max: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("memory.total.max") + " Bytes
\n"; + + printString += "Total Physical Memory: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("os.totalPhysicalMemorySize") + " Bytes
\n"; + printString += "Total Swap Space: " + ((JSONObject)((JSONObject)jsonObject.get("metrics")).get("solr.jvm")).get("os.totalSwapSpaceSize") + " Bytes
\n"; + + + BenchmarkAppConnector.writeToWebAppDataFile(commitID + "_" + FileType.TEST_ENV_FILE + "_dump.csv", printString, true, FileType.TEST_ENV_FILE); + + } + + public static void cleanUpSrcDirs() { + + Util.postMessage("** Initiating Housekeeping activities! ... ", MessageType.RESULT_ERRROR, false); + + try { + Util.deleteDirectory(TEMP_DIR); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public static void checkWebAppFiles() { + + Util.postMessage("** Verifying that the Webapp files are present ... ", MessageType.GENERAL, false); + + File webAppSourceDir = new File("WebAppSource"); + File webAppTargetDir = new File(BenchmarkAppConnector.benchmarkAppDirectory); + + try { + + if(!webAppTargetDir.exists()) { + Util.postMessage("** Webapp target directory not present creating now! ... ", MessageType.RESULT_ERRROR, false); + webAppTargetDir.mkdir(); + + if (!new File(BenchmarkAppConnector.benchmarkAppDirectory + File.separator + "UPDATED_WEB_APP_FILES_EXIST").exists()) { + Util.postMessage("** Copying updated/new webapp files ...", MessageType.GENERAL, false); + Util.copyFolder(webAppSourceDir, webAppTargetDir); + } + + File flagFile = new File(BenchmarkAppConnector.benchmarkAppDirectory + File.separator + "UPDATED_WEB_APP_FILES_EXIST"); + flagFile.createNewFile(); + + } else if (!new File(BenchmarkAppConnector.benchmarkAppDirectory + File.separator + "UPDATED_WEB_APP_FILES_EXIST").exists()) { + Util.postMessage("** Copying updated/new webapp files ...", MessageType.GENERAL, false); + Util.copyFolder(webAppSourceDir, webAppTargetDir); + + File flagFile = new File(BenchmarkAppConnector.benchmarkAppDirectory + File.separator + "UPDATED_WEB_APP_FILES_EXIST"); + flagFile.createNewFile(); + + } else { + Util.postMessage("** Webapp files seems present, skipping copying webapp files ...", MessageType.RESULT_SUCCESS, false); + } + + } catch (IOException e) { + e.printStackTrace(); + } + + + } + + public static void copyFolder(File source, File destination) + { + if (source.isDirectory()) + { + if (!destination.exists()) + { + destination.mkdirs(); + } + + String files[] = source.list(); + + for (String file : files) + { + File srcFile = new File(source, file); + File destFile = new File(destination, file); + + copyFolder(srcFile, destFile); + } + } + else + { + InputStream in = null; + OutputStream out = null; + + try + { + in = new FileInputStream(source); + out = new FileOutputStream(destination); + + byte[] buffer = new byte[1024]; + + int length; + while ((length = in.read(buffer)) > 0) + { + out.write(buffer, 0, length); + } + } + catch (Exception e) + { + try + { + in.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + + try + { + out.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java new file mode 100644 index 000000000000..0444673e6ee9 --- /dev/null +++ b/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java @@ -0,0 +1,248 @@ +package org.apache.solr.tests.nightlybenchmarks; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +public class Zookeeper { + + public static String zooCommand; + + static { + + zooCommand = System.getProperty("os.name") != null && System.getProperty("os.name").startsWith("Windows") + ? "bin" + File.separator + "zkServer.cmd " : "bin" + File.separator + "zkServer.sh "; + + } + + Zookeeper() throws IOException { + super(); + this.install(); + } + + private void install() throws IOException { + + Util.postMessage("** Installing Zookeeper Node ...", MessageType.ACTION, false); + + File base = new File(Util.ZOOKEEPER_DIR); + if (!base.exists()) { + base.mkdir(); + base.setExecutable(true); + } + + File release = new File(Util.TEMP_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + ".tar.gz"); + if (!release.exists()) { + + String fileName = null; + URL link = null; + InputStream in = null; + FileOutputStream fos = null; + + try { + + Util.postMessage("** Attempting to download zookeeper release ..." + " : " + Util.ZOOKEEPER_RELEASE, + MessageType.ACTION, true); + fileName = "zookeeper-" + Util.ZOOKEEPER_RELEASE + ".tar.gz"; + link = new URL(Util.ZOOKEEPER_DOWNLOAD_URL + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + fileName); + Util.postMessage(Util.ZOOKEEPER_DOWNLOAD_URL + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + fileName, + MessageType.ACTION, true); + in = new BufferedInputStream(link.openStream()); + fos = new FileOutputStream(Util.TEMP_DIR + fileName); + byte[] buf = new byte[1024 * 1024]; // 1mb blocks + int n = 0; + long size = 0; + while (-1 != (n = in.read(buf))) { + size += n; + Util.postMessageOnLine(size + " "); + fos.write(buf, 0, n); + } + fos.close(); + in.close(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, false); + + } + } else { + Util.postMessage("** Release present nothing to download ...", + MessageType.RESULT_SUCCESS, false); + } + + File urelease = new File(Util.TEMP_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE); + if (!urelease.exists()) { + + { + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + + proc = rt.exec("tar -xf " + Util.TEMP_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + ".tar.gz" + " -C " + + Util.ZOOKEEPER_DIR); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + + } + } + + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + + proc = rt.exec("mv " + Util.ZOOKEEPER_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + "conf" + + File.separator + "zoo_sample.cfg " + Util.ZOOKEEPER_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + + File.separator + "conf" + File.separator + "zoo.cfg"); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + + } + + } else { + Util.postMessage("** Release extracted already nothing to do ..." + " : " + Util.ZOOKEEPER_RELEASE, + MessageType.RESULT_SUCCESS, false); + } + } + + @SuppressWarnings("finally") + public int start() { + + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + + Util.postMessage("** Attempting to start zookeeper ...", MessageType.ACTION, false); + + new File(Util.ZOOKEEPER_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + zooCommand) + .setExecutable(true); + proc = rt.exec(Util.ZOOKEEPER_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + zooCommand + " start"); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + + return proc.exitValue(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + + } finally { + + return proc.exitValue(); + + } + + } + + @SuppressWarnings("finally") + public int stop() { + + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + + Util.postMessage("** Attempting to stop zookeeper ...", MessageType.ACTION, false); + + new File(Util.ZOOKEEPER_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + zooCommand) + .setExecutable(true); + proc = rt.exec(Util.ZOOKEEPER_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + zooCommand + " stop"); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + + return proc.exitValue(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, false); + + } finally { + + return proc.exitValue(); + + } + + } + + @SuppressWarnings("finally") + public int clean() throws IOException, InterruptedException { + + Util.postMessage("** Deleting directory for zookeeper data ...", MessageType.ACTION, false); + Runtime rt = Runtime.getRuntime(); + Process proc = null; + ProcessStreamReader errorGobbler = null; + ProcessStreamReader outputGobbler = null; + + try { + + proc = rt.exec("rm -r -f " + Util.ZOOKEEPER_DIR); + + errorGobbler = new ProcessStreamReader(proc.getErrorStream(), "ERROR"); + outputGobbler = new ProcessStreamReader(proc.getInputStream(), "OUTPUT"); + + errorGobbler.start(); + outputGobbler.start(); + proc.waitFor(); + return proc.exitValue(); + + } catch (Exception e) { + + Util.postMessage(e.getMessage(), MessageType.RESULT_ERRROR, true); + + } finally { + + return proc.exitValue(); + + } + + } + + public String getZookeeperIp() { + return Util.ZOOKEEPER_IP; + } + + public String getZookeeperPort() { + return Util.ZOOKEEPER_PORT; + } + +} \ No newline at end of file From 7519a62af45375065be0caa3261b93bdcd5aaa31 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 21 May 2017 13:05:37 -0400 Subject: [PATCH 002/276] shifting the SolrNightlyBenchmark folder --- .../CreateCollectionBenchmarkCloud.html | 0 .../CreateCollectionBenchmarkStandalone.html | 0 .../WebAppSource/IndexingBenchmarkCloud.html | 0 .../IndexingBenchmarkCloudConcurrent.html | 0 .../WebAppSource/IndexingBenchmarkStandalone.html | 0 .../IndexingThroughputBenchmarkCloud.html | 0 .../IndexingThroughputBenchmarkCloudConcurrent.html | 0 .../IndexingThroughputBenchmarkStandalone.html | 0 .../WebAppSource/images/loading.gif | Bin .../WebAppSource/images/running.gif | Bin .../WebAppSource/images/solr.png | Bin .../WebAppSource/images/solr_logo_rgb.png | Bin .../SolrNightlyBenchmarks/config.properties | 0 .../nightlybenchmarks/BenchmarkAppConnector.java | 0 .../tests/nightlybenchmarks/MetricEstimation.java | 0 .../nightlybenchmarks/ProcessStreamReader.java | 0 .../solr/tests/nightlybenchmarks/SolrClient.java | 0 .../solr/tests/nightlybenchmarks/SolrCloud.java | 0 .../nightlybenchmarks/SolrNightlyBenchmarks.java | 0 .../solr/tests/nightlybenchmarks/SolrNode.java | 0 .../solr/tests/nightlybenchmarks/TestType.java | 0 .../apache/solr/tests/nightlybenchmarks/Util.java | 0 .../solr/tests/nightlybenchmarks/Zookeeper.java | 0 dev-tools/SolrNightlyBenchmarks/src/main/main.iml | 11 +++++++++++ 24 files changed, 11 insertions(+) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/images/loading.gif (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/images/running.gif (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/images/solr.png (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/config.properties (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java (100%) rename {solr/dev-tools => dev-tools}/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java (100%) create mode 100644 dev-tools/SolrNightlyBenchmarks/src/main/main.iml diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloud.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/loading.gif b/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/loading.gif similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/loading.gif rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/images/loading.gif diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/running.gif b/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/running.gif similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/running.gif rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/images/running.gif diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr.png b/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr.png similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr.png rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr.png diff --git a/solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png b/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png rename to dev-tools/SolrNightlyBenchmarks/WebAppSource/images/solr_logo_rgb.png diff --git a/solr/dev-tools/SolrNightlyBenchmarks/config.properties b/dev-tools/SolrNightlyBenchmarks/config.properties similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/config.properties rename to dev-tools/SolrNightlyBenchmarks/config.properties diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricEstimation.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ProcessStreamReader.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrClient.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrCloud.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestType.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java diff --git a/solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java b/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java similarity index 100% rename from solr/dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java rename to dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java diff --git a/dev-tools/SolrNightlyBenchmarks/src/main/main.iml b/dev-tools/SolrNightlyBenchmarks/src/main/main.iml new file mode 100644 index 000000000000..908ad4f521a2 --- /dev/null +++ b/dev-tools/SolrNightlyBenchmarks/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file From 224b52feca7b3e78cd53e1aba2115174df062528 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Fri, 26 May 2017 15:40:26 -0400 Subject: [PATCH 003/276] update . add numeric query benchmark... --- .../CreateCollectionBenchmarkCloud.html | 8 +- .../CreateCollectionBenchmarkStandalone.html | 8 +- .../WebAppSource/IndexingBenchmarkCloud.html | 8 +- .../IndexingBenchmarkCloudConcurrent.html | 10 +- .../IndexingBenchmarkStandalone.html | 10 +- .../IndexingThroughputBenchmarkCloud.html | 8 +- ...ingThroughputBenchmarkCloudConcurrent.html | 16 +- ...IndexingThroughputBenchmarkStandalone.html | 8 +- .../NumericQueryBenchmarkCloud.html | 330 ++++++++++++++++++ .../BenchmarkAppConnector.java | 106 +++++- .../BenchmarkReportData.java | 26 ++ .../solr/tests/nightlybenchmarks/OutPort.java | 36 ++ .../tests/nightlybenchmarks/SolrCloud.java | 14 +- .../nightlybenchmarks/SolrIndexingClient.java | 316 +++++++++++++++++ .../SolrNightlyBenchmarks.java | 80 ++--- .../tests/nightlybenchmarks/SolrNode.java | 38 +- .../solr/tests/nightlybenchmarks/Tests.java | 117 +++++++ .../ThreadedNumericQueryClient.java | 118 +++++++ .../solr/tests/nightlybenchmarks/Util.java | 57 ++- 19 files changed, 1208 insertions(+), 106 deletions(-) create mode 100644 dev-tools/SolrNightlyBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html create mode 100644 dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java create mode 100644 dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/OutPort.java create mode 100644 dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java create mode 100644 dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java create mode 100644 dev-tools/SolrNightlyBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/ThreadedNumericQueryClient.java diff --git a/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html index ce4a7390356d..888c088b0d72 100644 --- a/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html +++ b/dev-tools/SolrNightlyBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -41,6 +41,12 @@

  • Create Collection
  • + + + + + + + diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html index a67517a68d5a..5688cf7135ad 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -68,6 +68,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html index e544070b4eee..87892af5024d 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -67,6 +67,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html index ead54cda5ec3..2bed353b8569 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -63,6 +63,13 @@
  • Create Collection
  • + diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html index bc103dde4872..4a913f5f928b 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -67,6 +67,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html index 063728baaee3..5447c762bdd1 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -67,6 +67,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html index fd08af6eb38b..c9682c8e6391 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -67,6 +67,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index f8daafec491e..e95f98bc0ebb 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -67,6 +67,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html new file mode 100644 index 000000000000..a6f638006409 --- /dev/null +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html @@ -0,0 +1,355 @@ + + + + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    +
    Numeric Query - QPS
    +
    +
    +
    + +
    + +
    + +
    +
    Test Runtime Information
    +
    +
    +
    + +
    +
    Graph Information
    +
    + X-Axis: Day/Time | Y-Axis: Seconds
    +

    +
    Please hover on the graph to get more information!
    +
    +
    + +
    + +
    + +
    + + + + + + + \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index 90591ba7f82b..a947a0138705 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -229,25 +229,44 @@ public static void publishDataForWebApp() { false, FileType.CLOUD_CREATE_COLLECTION_MAIN); } - if (BenchmarkReportData.numericQueryTNQMetric != null) { + if (BenchmarkReportData.numericQueryTNQMetricC != null) { BenchmarkAppConnector.writeToWebAppDataFile("numeric_query_benchmark_cloud.csv", - BenchmarkReportData.numericQueryTNQMetric.get("TimeStamp") + ", " + Util.TEST_ID + ", " - + BenchmarkReportData.numericQueryTNQMetric.get("CommitID") + ", " - + BenchmarkReportData.numericQueryTNQMetric.get("QueriesPerSecond") + ", " - + BenchmarkReportData.numericQueryTNQMetric.get("MinQTime") + ", " - + BenchmarkReportData.numericQueryTNQMetric.get("MaxQTime") + ", " - + BenchmarkReportData.numericQueryRNQMetric.get("QueriesPerSecond") + ", " - + BenchmarkReportData.numericQueryRNQMetric.get("MinQTime") + ", " - + BenchmarkReportData.numericQueryRNQMetric.get("MaxQTime") + ", " - + BenchmarkReportData.numericQueryLNQMetric.get("QueriesPerSecond") + ", " - + BenchmarkReportData.numericQueryLNQMetric.get("MinQTime") + ", " - + BenchmarkReportData.numericQueryLNQMetric.get("MaxQTime") + ", " - + BenchmarkReportData.numericQueryGNQMetric.get("QueriesPerSecond") + ", " - + BenchmarkReportData.numericQueryGNQMetric.get("MinQTime") + ", " - + BenchmarkReportData.numericQueryGNQMetric.get("MaxQTime"), + BenchmarkReportData.numericQueryTNQMetricC.get("TimeStamp") + ", " + Util.TEST_ID + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("CommitID") + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryRNQMetricC.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryRNQMetricC.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryRNQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryLNQMetricC.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryLNQMetricC.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryLNQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryGNQMetricC.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryGNQMetricC.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryGNQMetricC.get("MaxQTime"), false, FileType.NUMERIC_QUERY_CLOUD); } + if (BenchmarkReportData.numericQueryTNQMetricS != null) { + BenchmarkAppConnector.writeToWebAppDataFile("numeric_query_benchmark_standalone.csv", + BenchmarkReportData.numericQueryTNQMetricS.get("TimeStamp") + ", " + Util.TEST_ID + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("CommitID") + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryRNQMetricS.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryRNQMetricS.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryRNQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryLNQMetricS.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryLNQMetricS.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryLNQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryGNQMetricS.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryGNQMetricS.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryGNQMetricS.get("MaxQTime"), + false, FileType.NUMERIC_QUERY_STANDALONE); + } + Util.postMessage("** Publishing data for webapp [COMPLETE] ..", MessageType.WHITE_TEXT, false); } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java index a4629cf890ee..d3013ad0a6bf 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java @@ -30,9 +30,13 @@ public class BenchmarkReportData { public static Map metricMapCloudConcurrent6; public static Map metricMapCloudConcurrent8; public static Map metricMapCloudConcurrent10; - public static Map numericQueryTNQMetric; - public static Map numericQueryRNQMetric; - public static Map numericQueryLNQMetric; - public static Map numericQueryGNQMetric; + public static Map numericQueryTNQMetricC; + public static Map numericQueryRNQMetricC; + public static Map numericQueryLNQMetricC; + public static Map numericQueryGNQMetricC; + public static Map numericQueryTNQMetricS; + public static Map numericQueryRNQMetricS; + public static Map numericQueryLNQMetricS; + public static Map numericQueryGNQMetricS; } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index 1018e6a0f25b..b02952653449 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -27,18 +27,40 @@ public static void main(String[] args) throws IOException, InterruptedException Util.init(args); - Tests.indexingTests(Util.COMMIT_ID, 10000); - - Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2"); - BenchmarkReportData.numericQueryTNQMetric = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, 1, 180, 120); - BenchmarkReportData.numericQueryRNQMetric = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120); - BenchmarkReportData.numericQueryLNQMetric = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120); - BenchmarkReportData.numericQueryGNQMetric = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120); - Tests.shutDown(); + //Tests.indexingTests(Util.COMMIT_ID, 10000); + +/* Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2", 10000); + BenchmarkReportData.numericQueryTNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + BenchmarkReportData.numericQueryRNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + BenchmarkReportData.numericQueryLNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + Tests.shutDownCloud(); +*/ + Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); + + BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + BenchmarkReportData.numericQueryRNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + BenchmarkReportData.numericQueryLNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + + Tests.shutDownStandalone(); + BenchmarkAppConnector.publishDataForWebApp(); Util.destroy(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index cce58c77e758..4834e8fdee8f 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -26,12 +26,14 @@ import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - import org.apache.solr.tests.nightlybenchmarks.QueryClient.QueryType; +enum ConfigurationType { STANDALONE, CLOUD } + public class Tests { public static SolrCloud cloud; + public static SolrNode node; public static boolean indexingTests(String commitID, int numDocuments) { @@ -80,7 +82,7 @@ public static boolean indexingTests(String commitID, int numDocuments) { } public static Map numericQueryTests(String commitID, QueryType queryType, int numberOfThreads, - int secondsToWait, long delayEstimationBySeconds) { + int secondsToWait, long delayEstimationBySeconds, ConfigurationType confType, String baseURL, String collectionName) { try { @@ -88,7 +90,7 @@ public static Map numericQueryTests(String commitID, QueryType q LinkedList list = new LinkedList(); for (int i = 0; i < numberOfThreads; i++) { - QueryClient client = new QueryClient(cloud.getBaseURL(), 10000, 10, cloud.collectionName, queryType, + QueryClient client = new QueryClient(baseURL, 10000, 10, collectionName, queryType, numberOfThreads, delayEstimationBySeconds); list.add(client); } @@ -134,19 +136,40 @@ public static Map numericQueryTests(String commitID, QueryType q } public static void setUpCloudForFeatureTests(String commitID, int documentCount, int solrNodes, String shards, - String replicas) { + String replicas, int numDocuments) { SolrCloud cloud = new SolrCloud(solrNodes, shards, replicas, commitID, null, "localhost", true); Tests.cloud = cloud; SolrIndexingClient cloudClient = new SolrIndexingClient("localhost", cloud.port, cloud.collectionName, commitID); cloudClient.indexAmazonFoodData(documentCount, cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, - cloud.collectionName, 10000, 10); + cloud.collectionName, numDocuments, 10); } + + public static void setUpStandaloneNodeForFeatureTests(String commitID, int numDocuments) { + + try { + SolrNode snode = new SolrNode(commitID, "", "", false); + snode.doAction(SolrNodeAction.NODE_START); + snode.createCollection("Core-" + UUID.randomUUID(),"Collection-" + UUID.randomUUID()); + + SolrIndexingClient client = new SolrIndexingClient("localhost", snode.port, snode.collectionName, commitID); + client.indexAmazonFoodData(numDocuments, snode.getBaseUrl() + snode.collectionName); + + node = snode; + } catch(Exception e) { + e.printStackTrace(); + } + } - public static void shutDown() throws IOException, InterruptedException { + public static void shutDownCloud() throws IOException, InterruptedException { cloud.shutdown(); } + public static void shutDownStandalone() throws IOException, InterruptedException { + node.doAction(SolrNodeAction.NODE_STOP); + node.cleanup(); + } + } \ No newline at end of file From 211ab2d3dcaead10f370b374d12d877c23387701 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sat, 3 Jun 2017 00:28:17 -0400 Subject: [PATCH 014/276] Run failure detection mechanism bug fix ... --- .../nightlybenchmarks/BenchmarkAppConnector.java | 16 ++++++++-------- .../nightlybenchmarks/SolrNightlyBenchmarks.java | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index a947a0138705..3071d317758d 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -49,15 +49,15 @@ public static boolean isRunningFolderEmpty() { public static void deleteFile(FileType type) { if (type == FileType.LAST_RUN_COMMIT) { - Util.execute( - "rm -r -f " + BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "lastrun" - + File.separator + "*", - BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "lastrun" + File.separator); + File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "lastrun" + File.separator); + for (File file: dir.listFiles()) { + if (!file.isDirectory()) file.delete(); + } } else if (type == FileType.IS_RUNNING_FILE) { - Util.execute( - "rm -r -f " + BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "running" - + File.separator + "*", - BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "running" + File.separator); + File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "running" + File.separator); + for (File file: dir.listFiles()) { + if (!file.isDirectory()) file.delete(); + } } } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index b02952653449..0d3f4b7d3197 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -44,7 +44,7 @@ public static void main(String[] args) throws IOException, InterruptedException Tests.cloud.collectionName); Tests.shutDownCloud(); */ - Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); +/* Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), @@ -62,7 +62,7 @@ public static void main(String[] args) throws IOException, InterruptedException Tests.shutDownStandalone(); BenchmarkAppConnector.publishDataForWebApp(); - +*/ Util.destroy(); } } \ No newline at end of file From 5ad1e7a6542f4a972a27928da808cddf05d6f34c Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sat, 3 Jun 2017 01:04:01 -0400 Subject: [PATCH 015/276] menu items update, alive indicator bug fix ... --- .../CreateCollectionBenchmarkCloud.html | 44 ++++++++---------- .../CreateCollectionBenchmarkStandalone.html | 44 ++++++++---------- .../WebAppSource/IndexingBenchmarkCloud.html | 44 ++++++++---------- .../IndexingBenchmarkCloudConcurrent.html | 44 ++++++++---------- .../IndexingBenchmarkStandalone.html | 46 ++++++++----------- .../IndexingThroughputBenchmarkCloud.html | 44 ++++++++---------- ...ingThroughputBenchmarkCloudConcurrent.html | 44 ++++++++---------- ...IndexingThroughputBenchmarkStandalone.html | 44 ++++++++---------- .../NumericQueryBenchmarkCloud.html | 44 ++++++++---------- .../NumericQueryBenchmarkStandalone.html | 10 ++-- 10 files changed, 183 insertions(+), 225 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html index 037382fc70d6..4a176140b2f2 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -48,17 +48,14 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html index 11d638233bf8..b6f4c7283d98 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -50,6 +50,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html index 4706f2eb82be..0ce336ee16f5 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html index 64688a7449e0..65f68f69dac8 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html index 28efa662da6f..18c98ed7d017 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html index 8ae7c767367f..e037636098fa 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html index 649932547b69..fb36ad8e96ad 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html index e82859faf12a..0a4b3b119df3 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html new file mode 100644 index 000000000000..033e4b7874ed --- /dev/null +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html @@ -0,0 +1,358 @@ + + + + + + Solr Nightly Benchmarks + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    +
    Indexing Throughput Solr Standalone With Concurrent Client (doc/sec)
    +
    +
    +
    + +
    + +
    + +
    +
    Test Runtime Information
    +
    +
    +
    + +
    +
    Graph Information
    +
    + X-Axis: Date/Time | Y-Axis: Documents/Sec
    +

    +
    Please hover on the graph to get more information!
    +
    +
    + +
    + +
    + +
    + + + + + + + \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index 2e49d24110cc..2022ac89b407 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html index 8fd884606447..42deb6478452 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html @@ -49,6 +49,7 @@ diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index 07430386049f..f2d249da97c0 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -211,6 +211,27 @@ public static void publishDataForWebApp() { false, FileType.CLOUD_CONCURRENT_INDEXING_THROUGHPUT); } + if (BenchmarkReportData.metricMapStandaloneConcurrent2 != null) { + BenchmarkAppConnector.writeToWebAppDataFile("indexing_data_standalone_concurrent.csv", + BenchmarkReportData.metricMapStandaloneConcurrent2.get("TimeStamp") + ", " + Util.TEST_ID + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent2.get("CommitID") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent2.get("IndexingTime") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent4.get("IndexingTime") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent6.get("IndexingTime") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent8.get("IndexingTime") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent10.get("IndexingTime"), + false, FileType.CLOUD_INDEXING_CONCURRENT); + BenchmarkAppConnector.writeToWebAppDataFile("indexing_throughput_data_standalone_concurrent.csv", + BenchmarkReportData.metricMapStandaloneConcurrent2.get("TimeStamp") + ", " + Util.TEST_ID + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent2.get("CommitID") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent2.get("IndexingThroughput") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent4.get("IndexingThroughput") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent6.get("IndexingThroughput") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent8.get("IndexingThroughput") + ", " + + BenchmarkReportData.metricMapStandaloneConcurrent10.get("IndexingThroughput"), + false, FileType.CLOUD_CONCURRENT_INDEXING_THROUGHPUT); + } + if (BenchmarkReportData.returnStandaloneCreateCollectionMap != null) { BenchmarkAppConnector.writeToWebAppDataFile("create_collection_data_standalone_regular.csv", BenchmarkReportData.returnStandaloneCreateCollectionMap.get("TimeStamp") + ", " + Util.TEST_ID diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java index d3013ad0a6bf..97f346cdd636 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java @@ -23,17 +23,27 @@ public class BenchmarkReportData { public static Map returnStandaloneCreateCollectionMap; public static Map returnCloudCreateCollectionMap; + public static Map metricMapStandalone; public static Map metricMapCloudSerial; + public static Map metricMapCloudConcurrent2; public static Map metricMapCloudConcurrent4; public static Map metricMapCloudConcurrent6; public static Map metricMapCloudConcurrent8; public static Map metricMapCloudConcurrent10; + + public static Map metricMapStandaloneConcurrent2; + public static Map metricMapStandaloneConcurrent4; + public static Map metricMapStandaloneConcurrent6; + public static Map metricMapStandaloneConcurrent8; + public static Map metricMapStandaloneConcurrent10; + public static Map numericQueryTNQMetricC; public static Map numericQueryRNQMetricC; public static Map numericQueryLNQMetricC; public static Map numericQueryGNQMetricC; + public static Map numericQueryTNQMetricS; public static Map numericQueryRNQMetricS; public static Map numericQueryLNQMetricS; diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java index c9ceabbb9180..ef09a73b4fc1 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java @@ -235,8 +235,7 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin } @SuppressWarnings("deprecation") - public Map indexAmazonFoodData(int numDocuments, String urlString, String zookeeperIp, - String zookeeperPort, String collectionName, int queueSize, int threadCount) { + public Map indexAmazonFoodData(int numDocuments, String urlString, String collectionName, int queueSize, int threadCount) { documentCount = numDocuments; diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index 28e6be8956ce..ae87b5356f29 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -19,8 +19,6 @@ import java.io.IOException; -import org.apache.solr.tests.nightlybenchmarks.QueryClient.QueryType; - public class SolrNightlyBenchmarks { public static void main(String[] args) throws IOException, InterruptedException { @@ -28,42 +26,10 @@ public static void main(String[] args) throws IOException, InterruptedException Util.init(args); - //Tests.indexingTests(Util.COMMIT_ID, 10000); - -/* Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2", 10000); - BenchmarkReportData.numericQueryTNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryRNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryLNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - Tests.shutDownCloud(); -*/ - Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); + Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); - BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - BenchmarkReportData.numericQueryRNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - BenchmarkReportData.numericQueryLNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - - Tests.shutDownStandalone(); - BenchmarkAppConnector.publishDataForWebApp(); - + Util.destroy(); } } \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java index 2e0dfa45b9bc..a61bc9c33013 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java @@ -47,7 +47,7 @@ public class SolrNode { public String baseDirectory; public boolean isRunningInCloudMode; - private String gitDirectoryPath = Util.TEMP_DIR + "git-repository-"; + private String gitDirectoryPath = Util.DOWNLOAD_DIR + "git-repository-"; public SolrNode(String commitId, String zooKeeperIp, String zooKeeperPort, boolean isRunningInCloudMode) throws IOException, GitAPIException { @@ -56,7 +56,7 @@ public SolrNode(String commitId, String zooKeeperIp, String zooKeeperPort, boole this.zooKeeperIp = zooKeeperIp; this.zooKeeperPort = zooKeeperPort; this.isRunningInCloudMode = isRunningInCloudMode; - this.gitDirectoryPath = Util.TEMP_DIR + "git-repository-" + commitId; + this.gitDirectoryPath = Util.DOWNLOAD_DIR + "git-repository-" + commitId; Util.GIT_REPOSITORY_PATH = this.gitDirectoryPath; this.install(); } @@ -90,7 +90,7 @@ private void install() throws IOException, GitAPIException { } this.checkoutCommitAndBuild(); - Util.extract(Util.TEMP_DIR + "solr-" + commitId + ".zip", baseDirectory); + Util.extract(Util.DOWNLOAD_DIR + "solr-" + commitId + ".zip", baseDirectory); } void checkoutCommitAndBuild() throws IOException, GitAPIException { @@ -112,7 +112,7 @@ void checkoutCommitAndBuild() throws IOException, GitAPIException { } String packageFilename = gitDirectoryPath + "/solr/package/solr-7.0.0-SNAPSHOT.zip"; - String tarballLocation = Util.TEMP_DIR + "solr-" + commitId + ".zip"; + String tarballLocation = Util.DOWNLOAD_DIR + "solr-" + commitId + ".zip"; if (new File(tarballLocation).exists() == false) { if (new File(packageFilename).exists() == false) { @@ -260,6 +260,10 @@ public String getBaseUrl() { return "http://localhost:" + port + "/solr/"; } + public String getBaseUrlC() { + return "http://localhost:" + port + "/solr/" + this.collectionName; + } + public void cleanup() { Util.execute("rm -r -f " + baseDirectory, baseDirectory); } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index 4834e8fdee8f..fb160fa6ce2f 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -26,6 +26,7 @@ import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; + import org.apache.solr.tests.nightlybenchmarks.QueryClient.QueryType; enum ConfigurationType { STANDALONE, CLOUD } @@ -35,10 +36,9 @@ public class Tests { public static SolrCloud cloud; public static SolrNode node; - public static boolean indexingTests(String commitID, int numDocuments) { + public static boolean indexingTestsStandalone(String commitID, int numDocuments) { try { - SolrNode node = new SolrNode(commitID, "", "", false); node.doAction(SolrNodeAction.NODE_START); @@ -53,6 +53,49 @@ public static boolean indexingTests(String commitID, int numDocuments) { node.doAction(SolrNodeAction.NODE_STOP); node.cleanup(); + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + public static boolean indexingTestsStandaloneConcurrent(String commitID, int numDocuments) { + + try { + SolrNode node = new SolrNode(commitID, "", "", false); + node.doAction(SolrNodeAction.NODE_START); + node.createCollection("Core-" + UUID.randomUUID(),"Collection-" + UUID.randomUUID()); + SolrIndexingClient client = new SolrIndexingClient("localhost", node.port, node.collectionName, commitID); + + + BenchmarkReportData.metricMapStandaloneConcurrent2 = client.indexAmazonFoodData(numDocuments, + node.getBaseUrlC(), node.collectionName, 10000, 2); + BenchmarkReportData.metricMapStandaloneConcurrent4 = client.indexAmazonFoodData(numDocuments, + node.getBaseUrlC(), node.collectionName, 10000, 4); + BenchmarkReportData.metricMapStandaloneConcurrent6 = client.indexAmazonFoodData(numDocuments, + node.getBaseUrlC(), node.collectionName, 10000, 6); + BenchmarkReportData.metricMapStandaloneConcurrent8 = client.indexAmazonFoodData(numDocuments, + node.getBaseUrlC(), node.collectionName, 10000, 8); + BenchmarkReportData.metricMapStandaloneConcurrent10 = client.indexAmazonFoodData(numDocuments, + node.getBaseUrlC(), node.collectionName, 10000, 10); + + + node.doAction(SolrNodeAction.NODE_STOP); + node.cleanup(); + + + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + public static boolean indexingTestsCloudSerial(String commitID, int numDocuments) { + + try { + SolrCloud cloud = new SolrCloud(5, "2", "2", commitID, null, "localhost", true); Tests.cloud = cloud; SolrIndexingClient cloudClient = new SolrIndexingClient("localhost", cloud.port, cloud.collectionName, @@ -60,19 +103,37 @@ public static boolean indexingTests(String commitID, int numDocuments) { BenchmarkReportData.metricMapCloudSerial = cloudClient.indexAmazonFoodData(numDocuments, cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName); + cloud.shutdown(); + BenchmarkReportData.returnCloudCreateCollectionMap = cloud.returnMapCreateCollection; + + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + public static boolean indexingTestsCloudConcurrent(String commitID, int numDocuments) { + + try { + + SolrCloud cloud = new SolrCloud(5, "2", "2", commitID, null, "localhost", true); + Tests.cloud = cloud; + SolrIndexingClient cloudClient = new SolrIndexingClient("localhost", cloud.port, cloud.collectionName, + commitID); + BenchmarkReportData.metricMapCloudConcurrent2 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName, 10000, 2); + cloud.getuRL(), cloud.collectionName, 10000, 2); BenchmarkReportData.metricMapCloudConcurrent4 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName, 10000, 4); + cloud.getuRL(), cloud.collectionName, 10000, 4); BenchmarkReportData.metricMapCloudConcurrent6 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName, 10000, 6); + cloud.getuRL(), cloud.collectionName, 10000, 6); BenchmarkReportData.metricMapCloudConcurrent8 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName, 10000, 8); + cloud.getuRL(), cloud.collectionName, 10000, 8); BenchmarkReportData.metricMapCloudConcurrent10 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName, 10000, 10); + cloud.getuRL(), cloud.collectionName, 10000, 10); cloud.shutdown(); - BenchmarkReportData.returnCloudCreateCollectionMap = cloud.returnMapCreateCollection; } catch (Exception e) { e.printStackTrace(); @@ -80,7 +141,7 @@ public static boolean indexingTests(String commitID, int numDocuments) { return true; } - + public static Map numericQueryTests(String commitID, QueryType queryType, int numberOfThreads, int secondsToWait, long delayEstimationBySeconds, ConfigurationType confType, String baseURL, String collectionName) { @@ -142,8 +203,7 @@ public static void setUpCloudForFeatureTests(String commitID, int documentCount, Tests.cloud = cloud; SolrIndexingClient cloudClient = new SolrIndexingClient("localhost", cloud.port, cloud.collectionName, commitID); - cloudClient.indexAmazonFoodData(documentCount, cloud.getuRL(), cloud.zookeeperIp, cloud.zookeeperPort, - cloud.collectionName, numDocuments, 10); + cloudClient.indexAmazonFoodData(documentCount, cloud.getuRL(), cloud.collectionName, numDocuments, 10); } @@ -171,5 +231,46 @@ public static void shutDownStandalone() throws IOException, InterruptedException node.doAction(SolrNodeAction.NODE_STOP); node.cleanup(); } + + public static void runNumericTestsCloud() throws IOException, InterruptedException { + + Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2", 10000); + BenchmarkReportData.numericQueryTNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + BenchmarkReportData.numericQueryRNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + BenchmarkReportData.numericQueryLNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + Tests.shutDownCloud(); + + } + + public static void runNumericQueryTestsStandalone() throws IOException, InterruptedException { + + + Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); + + BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + BenchmarkReportData.numericQueryRNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + BenchmarkReportData.numericQueryLNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + + Tests.shutDownStandalone(); + + } } \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index dedbf80bd72d..c1a5e4d0eaea 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -67,7 +67,7 @@ public class Util { public static String DNAME = "SolrNightlyBenchmarksWorkDirectory"; public static String BASE_DIR = WORK_DIRECTORY + File.separator + DNAME + File.separator; public static String RUN_DIR = BASE_DIR + "RunDirectory" + File.separator; - public static String TEMP_DIR = BASE_DIR + "Download" + File.separator; + public static String DOWNLOAD_DIR = BASE_DIR + "Download" + File.separator; public static String ZOOKEEPER_DOWNLOAD_URL = "http://www.us.apache.org/dist/zookeeper/"; public static String ZOOKEEPER_RELEASE = "3.4.6"; public static String ZOOKEEPER_DIR = RUN_DIR; @@ -152,7 +152,7 @@ public static void checkBaseAndTempDir() { BasicConfigurator.configure(); File baseDirectory = new File(BASE_DIR); baseDirectory.mkdir(); - File tempDirectory = new File(TEMP_DIR); + File tempDirectory = new File(DOWNLOAD_DIR); tempDirectory.mkdir(); // Marking for GC @@ -696,7 +696,7 @@ public static void destroy() { try { if (argM.containsKey("-Housekeeping")) { Util.postMessage("** Initiating Housekeeping activities! ... ", MessageType.RED_TEXT, false); - Util.execute("rm -r -f " + Util.TEMP_DIR, Util.TEMP_DIR); + Util.execute("rm -r -f " + Util.DOWNLOAD_DIR, Util.DOWNLOAD_DIR); } Util.setDeadFlag(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java index ab4267b3ce25..255cebf86f2f 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Zookeeper.java @@ -51,7 +51,7 @@ private void install() throws IOException { base.setExecutable(true); } - File release = new File(Util.TEMP_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + ".tar.gz"); + File release = new File(Util.DOWNLOAD_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + ".tar.gz"); if (!release.exists()) { Util.postMessage("** Attempting to download zookeeper release ..." + " : " + Util.ZOOKEEPER_RELEASE, @@ -60,16 +60,16 @@ private void install() throws IOException { Util.download( Util.ZOOKEEPER_DOWNLOAD_URL + "zookeeper-" + Util.ZOOKEEPER_RELEASE + File.separator + fileName, - Util.TEMP_DIR + fileName); + Util.DOWNLOAD_DIR + fileName); } else { Util.postMessage("** Release present nothing to download ...", MessageType.GREEN_TEXT, false); } - File urelease = new File(Util.TEMP_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE); + File urelease = new File(Util.DOWNLOAD_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE); if (!urelease.exists()) { - Util.execute("tar -xf " + Util.TEMP_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + ".tar.gz" + " -C " + Util.execute("tar -xf " + Util.DOWNLOAD_DIR + "zookeeper-" + Util.ZOOKEEPER_RELEASE + ".tar.gz" + " -C " + Util.ZOOKEEPER_DIR, Util.ZOOKEEPER_DIR); Util.execute( From 99e169ac25317f19c579b3d0d5819a36e1fb50e9 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sat, 3 Jun 2017 16:07:02 -0400 Subject: [PATCH 020/276] Graph color pallete change for better readability ... --- .../CreateCollectionBenchmarkCloud.html | 17 +++++++++-------- .../CreateCollectionBenchmarkStandalone.html | 17 +++++++++-------- .../WebAppSource/IndexingBenchmarkCloud.html | 17 +++++++++-------- .../IndexingBenchmarkCloudConcurrent.html | 17 +++++++++-------- .../IndexingBenchmarkStandalone.html | 17 +++++++++-------- .../IndexingThroughputBenchmarkCloud.html | 17 +++++++++-------- ...exingThroughputBenchmarkCloudConcurrent.html | 17 +++++++++-------- .../IndexingThroughputBenchmarkStandalone.html | 17 +++++++++-------- ...ThroughputBenchmarkStandaloneConcurrent.html | 17 +++++++++-------- .../NumericQueryBenchmarkCloud.html | 17 +++++++++-------- .../NumericQueryBenchmarkStandalone.html | 17 +++++++++-------- 11 files changed, 99 insertions(+), 88 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html index 042a27117b7e..671609cd08ce 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/create_collection_data_cloud_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], + labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html index b6f4c7283d98..5a2b4d5e7523 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -74,7 +74,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -155,8 +156,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -213,7 +214,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/create_collection_data_standalone_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], + labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); @@ -227,8 +228,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -249,7 +250,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -274,7 +275,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_CREATE_COLLECTION_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html index 0ce336ee16f5..2c63d7461044 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_data_cloud_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], + labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html index 65f68f69dac8..8f3ec75f3649 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_data_cloud_concurrent.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], + labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html index 18c98ed7d017..f41e6ef05098 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_data_standalone_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], + labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html index e037636098fa..42d4cc840464 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_cloud_serial.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], + labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html index fb36ad8e96ad..30aea43c2646 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_cloud_concurrent.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], + labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html index 0a4b3b119df3..010f8f24d77d 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_standalone_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], + labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html index 033e4b7874ed..a4712d5d8a7a 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_standalone_concurrent.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], + labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); @@ -226,8 +227,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -248,7 +249,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -273,7 +274,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index 2022ac89b407..9310ad9664fe 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/numeric_query_benchmark_cloud.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], + labelsDiv: document.getElementById('status'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); @@ -225,8 +226,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -247,7 +248,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -272,7 +273,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html index 42deb6478452..dde31030881f 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html @@ -73,7 +73,8 @@
  •    
  • -
  • Home
  • +
  • Solr Wiki
  • +
  • Solr JIRA
  • @@ -154,8 +155,8 @@
    -
    -
    Test Runtime Information
    +
    +
    Test Information
    @@ -212,7 +213,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/numeric_query_benchmark_standalone.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], + labelsDiv: document.getElementById('status'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); @@ -225,8 +226,8 @@ document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -247,7 +248,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -272,7 +273,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } From 2cc8d29b4dc39d19f87a78b4b3601c5dd82d5e2e Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sat, 3 Jun 2017 16:08:03 -0400 Subject: [PATCH 021/276] Tests code refactoring ... --- .../BenchmarkAppConnector.java | 2 +- .../SolrNightlyBenchmarks.java | 1 + .../tests/nightlybenchmarks/SolrNode.java | 4 ++-- .../solr/tests/nightlybenchmarks/Tests.java | 23 +++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index f2d249da97c0..ad8f145d66cd 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -111,7 +111,7 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c fw.write("Date, Test_ID, Process CPU Load (%)\n"); } else if (type == FileType.STANDALONE_CREATE_COLLECTION_MAIN || type == FileType.CLOUD_CREATE_COLLECTION_MAIN) { - fw.write("Date, Test_ID, Milliseconds, CommitID\n"); + fw.write("Date, Test_ID, Seconds, CommitID\n"); } else if (type == FileType.STANDALONE_INDEXING_MAIN || type == FileType.CLOUD_INDEXING_SERIAL) { fw.write("Date, Test_ID, Seconds, CommitID\n"); } else if (type == FileType.TEST_ENV_FILE) { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index ae87b5356f29..338b14446d82 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -26,6 +26,7 @@ public static void main(String[] args) throws IOException, InterruptedException Util.init(args); + Tests.createCollectionTestStandalone(Util.COMMIT_ID); Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); BenchmarkAppConnector.publishDataForWebApp(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java index a61bc9c33013..a156d4876b23 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java @@ -205,7 +205,7 @@ public Map createCollection(String coreName, String collectionNa returnMap.put("ProcessExitValue", "" + returnVal); returnMap.put("TimeStamp", "" + Util.TEST_TIME); - returnMap.put("CreateCollectionTime", "" + (double) ((double) (end - start) / (double) 1000000)); + returnMap.put("CreateCollectionTime", "" + (double) ((double) (end - start) / (double) 1000000000)); returnMap.put("CommitID", this.commitId); return returnMap; @@ -246,7 +246,7 @@ public Map createCollection(String collectionName, String config returnMap.put("ProcessExitValue", "" + returnVal); returnMap.put("TimeStamp", "" + Util.TEST_TIME); - returnMap.put("CreateCollectionTime", "" + (double) ((double) (end - start) / (double) 1000000)); + returnMap.put("CreateCollectionTime", "" + (double) ((double) (end - start) / (double) 1000000000)); returnMap.put("CommitID", this.commitId); return returnMap; diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index fb160fa6ce2f..5c22d816697e 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -35,6 +35,29 @@ public class Tests { public static SolrCloud cloud; public static SolrNode node; + + + public static boolean createCollectionTestStandalone(String commitID) { + + try { + SolrNode node = new SolrNode(commitID, "", "", false); + + node.doAction(SolrNodeAction.NODE_START); + + Util.getEnvironmentInformationFromMetricAPI(commitID, node.port); + + BenchmarkReportData.returnStandaloneCreateCollectionMap = node.createCollection("Core-" + UUID.randomUUID(), + "Collection-" + UUID.randomUUID()); + + node.doAction(SolrNodeAction.NODE_STOP); + node.cleanup(); + + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } public static boolean indexingTestsStandalone(String commitID, int numDocuments) { From 0d3f6fd243e11f39bc48550616aa03191dedf168 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sat, 3 Jun 2017 18:20:40 -0400 Subject: [PATCH 022/276] Util refactoring: no folder bug fix ... + Webapp index html redirect file ... --- .../CreateCollectionBenchmarkCloud.html | 2 +- .../WebAppSource/images/greenlight.gif | Bin 0 -> 6196 bytes .../WebAppSource/images/indicator.webp | Bin 0 -> 856790 bytes .../WebAppSource/index.html | 10 ++++++++++ .../solr/tests/nightlybenchmarks/Util.java | 12 ++++++++++-- 5 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 dev-tools/SolrNightBenchmarks/WebAppSource/images/greenlight.gif create mode 100644 dev-tools/SolrNightBenchmarks/WebAppSource/images/indicator.webp create mode 100644 dev-tools/SolrNightBenchmarks/WebAppSource/index.html diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html index 671609cd08ce..00a62e1e323b 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -72,7 +72,7 @@
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html index 5a2b4d5e7523..4f205c8cc099 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -167,7 +167,7 @@
    X-Axis: Day/Time | Y-Axis: Seconds

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html index 2c63d7461044..313927b99f9e 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -166,7 +166,7 @@
    X-Axis: Day/Time | Y-Axis: Seconds

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html index 8f3ec75f3649..19363b4b0d64 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -166,7 +166,7 @@
    X-Axis: Day/Time | Y-Axis: Seconds

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html index f41e6ef05098..2417676b7efc 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html @@ -166,7 +166,7 @@
    X-Axis: Day/Time | Y-Axis: Seconds

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html index 42d4cc840464..b279739c5a41 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -166,7 +166,7 @@
    X-Axis: Date/Time | Y-Axis: Documents/Sec

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html index 30aea43c2646..2af73579795b 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -166,7 +166,7 @@
    X-Axis: Date/Time | Y-Axis: Documents/Sec

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html index 010f8f24d77d..f76a856bc1a2 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -166,7 +166,7 @@
    X-Axis: Date/Time | Y-Axis: Documents/Sec

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html index a4712d5d8a7a..9480d39a8338 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html @@ -166,7 +166,7 @@
    X-Axis: Date/Time | Y-Axis: Documents/Sec

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index 9310ad9664fe..e7bd2fb35c41 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -166,7 +166,7 @@
    X-Axis: Day/Time | Y-Axis: Seconds

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html index dde31030881f..953218a686c1 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html @@ -166,7 +166,7 @@
    X-Axis: Day/Time | Y-Axis: Seconds

    -
    Please hover on the graph to get more information!
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    From 35d4c9f29192ad82231d49fa6b1c6b594660b5f2 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 01:15:02 -0400 Subject: [PATCH 025/276] refactoring on the webapp, bringing the commit information back ... populating the right side box with commit information ... --- .../CreateCollectionBenchmarkCloud.html | 28 ++++++++++++----- .../CreateCollectionBenchmarkStandalone.html | 30 ++++++++++++++----- .../WebAppSource/IndexingBenchmarkCloud.html | 30 ++++++++++++++----- .../IndexingBenchmarkCloudConcurrent.html | 28 ++++++++++++----- .../IndexingBenchmarkStandalone.html | 30 ++++++++++++++----- .../IndexingThroughputBenchmarkCloud.html | 30 ++++++++++++++----- ...ingThroughputBenchmarkCloudConcurrent.html | 28 ++++++++++++----- ...IndexingThroughputBenchmarkStandalone.html | 30 ++++++++++++++----- ...roughputBenchmarkStandaloneConcurrent.html | 28 ++++++++++++----- .../NumericQueryBenchmarkCloud.html | 27 +++++++++++++---- .../NumericQueryBenchmarkStandalone.html | 27 +++++++++++++---- 11 files changed, 236 insertions(+), 80 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html index 6cc60c5e4524..0c7c90550f21 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    -
    +
    Graph Information
    - X-Axis: Day/Time | Y-Axis: Seconds
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Day/Time | Y-Axis: Seconds

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/create_collection_data_cloud_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[3] + ""; + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html index 4f205c8cc099..c5fb8775feeb 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -158,16 +158,18 @@
    Test Information
    -
    +
    +
    +
    -
    +
    Graph Information
    - X-Axis: Day/Time | Y-Axis: Seconds
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Day/Time | Y-Axis: Seconds

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -214,13 +216,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/create_collection_data_standalone_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[3] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html index 313927b99f9e..98c19937eaf9 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    -
    +
    Graph Information
    - X-Axis: Day/Time | Y-Axis: Seconds
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Day/Time | Y-Axis: Seconds

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_data_cloud_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[3] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html index 19363b4b0d64..23e45076fc36 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    Graph Information
    - X-Axis: Day/Time | Y-Axis: Seconds
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Day/Time | Y-Axis: Seconds

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_data_cloud_concurrent.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[2] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html index 2417676b7efc..479e6cb7ef8e 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    -
    +
    Graph Information
    - X-Axis: Day/Time | Y-Axis: Seconds
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Day/Time | Y-Axis: Seconds

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_data_standalone_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[3] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html index b279739c5a41..75fa1bcc403b 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    -
    +
    Graph Information
    - X-Axis: Date/Time | Y-Axis: Documents/Sec
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Date/Time | Y-Axis: Documents/Sec

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_cloud_serial.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[3] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html index 2af73579795b..1466f1f1fbc1 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    Graph Information
    - X-Axis: Date/Time | Y-Axis: Documents/Sec
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Date/Time | Y-Axis: Documents/Sec

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_cloud_concurrent.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[2] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html index f76a856bc1a2..7aaa3c723e88 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    -
    +
    Graph Information
    - X-Axis: Date/Time | Y-Axis: Documents/Sec
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Date/Time | Y-Axis: Documents/Sec

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_standalone_regular.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, true, false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[3].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[3] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html index 9480d39a8338..f48fd414e0ba 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    Graph Information
    - X-Axis: Date/Time | Y-Axis: Documents/Sec
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Date/Time | Y-Axis: Documents/Sec

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,13 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/indexing_throughput_data_standalone_concurrent.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, true, true, true, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[2] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index e7bd2fb35c41..5d51360afa19 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    Graph Information
    - X-Axis: Day/Time | Y-Axis: Seconds
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Day/Time | Y-Axis: Seconds

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,12 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/numeric_query_benchmark_cloud.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[2] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html index 953218a686c1..9797e044af65 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html @@ -157,16 +157,18 @@
    Test Information
    -
    +
    +
    +
    Graph Information
    - X-Axis: Day/Time | Y-Axis: Seconds
    -

    -
    Please hover on the graph and click on a specific point on the graph to get more details ...
    + X-Axis: Day/Time | Y-Axis: Seconds

    +
    +
    Please hover on the graph and click on a specific point on the graph to get more details ...
    @@ -213,12 +215,25 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/numeric_query_benchmark_standalone.csv", { - labelsDiv: document.getElementById('status'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); testID = fileData[(row + 1)].split(",")[1].trim(); - document.getElementById("pointData").innerHTML = "Commit ID: " + fileData[(row + 1)].split(",")[2] + ""; + + $.ajax({ + + type: "GET", + url: "data/" + testID + "_" + commitID + "_COMMIT_INFORMATION_dump.csv", + dataType: "text", + success: function(data) { + document.getElementById("testCommitInformation").innerHTML = data; + } + + }); + + document.getElementById("welcomeMessage").innerHTML = ""; + }, clickCallback: function (e, x, pts) { From 4cbceeb2cd3e51d2d9a1c200a8cb290a6db2d2ba Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 01:15:43 -0400 Subject: [PATCH 026/276] Adding utility to get commit information and fixing a bug in that ... --- .../nightlybenchmarks/BenchmarkAppConnector.java | 4 ++-- .../nightlybenchmarks/SolrNightlyBenchmarks.java | 7 +++++-- .../solr/tests/nightlybenchmarks/Util.java | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index ad8f145d66cd..76960dcf8e71 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -14,7 +14,7 @@ public BenchmarkAppConnector() { public enum FileType { - MEMORY_HEAP_USED, PROCESS_CPU_LOAD, TEST_ENV_FILE, STANDALONE_INDEXING_MAIN, STANDALONE_CREATE_COLLECTION_MAIN, STANDALONE_INDEXING_THROUGHPUT, CLOUD_CREATE_COLLECTION_MAIN, CLOUD_SERIAL_INDEXING_THROUGHPUT, CLOUD_CONCURRENT_INDEXING_THROUGHPUT, CLOUD_INDEXING_SERIAL, CLOUD_INDEXING_CONCURRENT, NUMERIC_QUERY_STANDALONE, NUMERIC_QUERY_CLOUD, LAST_RUN_COMMIT, IS_RUNNING_FILE + MEMORY_HEAP_USED, PROCESS_CPU_LOAD, TEST_ENV_FILE, STANDALONE_INDEXING_MAIN, STANDALONE_CREATE_COLLECTION_MAIN, STANDALONE_INDEXING_THROUGHPUT, CLOUD_CREATE_COLLECTION_MAIN, CLOUD_SERIAL_INDEXING_THROUGHPUT, CLOUD_CONCURRENT_INDEXING_THROUGHPUT, CLOUD_INDEXING_SERIAL, CLOUD_INDEXING_CONCURRENT, NUMERIC_QUERY_STANDALONE, NUMERIC_QUERY_CLOUD, LAST_RUN_COMMIT, IS_RUNNING_FILE, COMMIT_INFORMATION_FILE } @@ -114,7 +114,7 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c fw.write("Date, Test_ID, Seconds, CommitID\n"); } else if (type == FileType.STANDALONE_INDEXING_MAIN || type == FileType.CLOUD_INDEXING_SERIAL) { fw.write("Date, Test_ID, Seconds, CommitID\n"); - } else if (type == FileType.TEST_ENV_FILE) { + } else if (type == FileType.TEST_ENV_FILE || type == FileType.COMMIT_INFORMATION_FILE) { // Don't add any header } else if (type == FileType.STANDALONE_INDEXING_THROUGHPUT || type == FileType.CLOUD_SERIAL_INDEXING_THROUGHPUT) { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index 4e0fc4f86d13..c1f3eeb3aa44 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -26,9 +26,11 @@ public static void main(String[] args) throws IOException, InterruptedException Util.init(args); + Util.getAndPublishCommitInformation(); + Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); - Tests.createCollectionTestStandalone(Util.COMMIT_ID); +/* Tests.createCollectionTestStandalone(Util.COMMIT_ID); Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); @@ -41,9 +43,10 @@ public static void main(String[] args) throws IOException, InterruptedException Tests.runNumericTestsCloud(); - +*/ BenchmarkAppConnector.publishDataForWebApp(); + Util.destroy(); } } \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index a498fe0c46b5..b04000175173 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -287,12 +287,20 @@ public static String getLatestCommitID(String repositoryURL) throws IOException Runtime.getRuntime().exec("git ls-remote " + repositoryURL + " HEAD").getInputStream())).readLine() .split("HEAD")[0].trim(); } - + + public static String getLocalRepoPath() { + Util.GIT_REPOSITORY_PATH = Util.DOWNLOAD_DIR + "git-repository-" + Util.COMMIT_ID; + return Util.GIT_REPOSITORY_PATH; + } + + public static void getAndPublishCommitInformation() { + BenchmarkAppConnector.writeToWebAppDataFile(Util.TEST_ID + "_" + Util.COMMIT_ID + "_COMMIT_INFORMATION_dump.csv", Util.getCommitInformation(), true, FileType.COMMIT_INFORMATION_FILE); + } + public static String getCommitInformation() { - // This method is failing need to check ! Util.postMessage("** Getting the latest commit Information from local repository", MessageType.BLUE_TEXT, false); - File directory = new File(Util.GIT_REPOSITORY_PATH); + File directory = new File(Util.getLocalRepoPath()); directory.setExecutable(true); BufferedReader reader; String line = ""; @@ -303,7 +311,7 @@ public static String getCommitInformation() { .exec("git show --no-patch " + Util.COMMIT_ID, new String[] {}, directory).getInputStream())); while ((line = reader.readLine()) != null) { - returnString += line.replaceAll("<", " ").replaceAll(">", " ").replaceAll(",", "").trim() + ","; + returnString += line.replaceAll("<", " ").replaceAll(">", " ").replaceAll(",", "").trim() + "
    "; } return returnString; From 14c7fbf13c4d4cb36c576730113d426d1a8c876c Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 01:53:38 -0400 Subject: [PATCH 027/276] getcommitinformation order bug fix ... --- .../SolrNightlyBenchmarks.java | 6 ++-- .../solr/tests/nightlybenchmarks/Util.java | 33 ++++++++++--------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index c1f3eeb3aa44..7bc6851c20c7 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -26,11 +26,9 @@ public static void main(String[] args) throws IOException, InterruptedException Util.init(args); - Util.getAndPublishCommitInformation(); - Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); -/* Tests.createCollectionTestStandalone(Util.COMMIT_ID); + Tests.createCollectionTestStandalone(Util.COMMIT_ID); Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); @@ -43,7 +41,7 @@ public static void main(String[] args) throws IOException, InterruptedException Tests.runNumericTestsCloud(); -*/ + BenchmarkAppConnector.publishDataForWebApp(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index b04000175173..23471a209324 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -666,6 +666,21 @@ public static void init(String[] args) { Util.checkBaseAndTempDir(); + if (!BenchmarkAppConnector.isRunningFolderEmpty()) { + Util.postMessage("** It looks like the last test session failed or was aborted ..", + MessageType.RED_TEXT, false); + + Util.killProcesses("zookeeper"); + Util.killProcesses("Dsolr.jetty.https.port"); + + Thread.sleep(5000); + + Util.cleanRunDirectory(); + Util.deleteRunningFile(); + } + + Util.createIsRunningFile(); + Util.setAliveFlag(); argM = Util.getArgs(args); @@ -685,22 +700,6 @@ public static void init(String[] args) { Util.COMMIT_ID = commitID; Util.getSystemEnvironmentInformation(); - - if (!BenchmarkAppConnector.isRunningFolderEmpty()) { - Util.postMessage("** It looks like the last test session failed or was aborted ..", - MessageType.RED_TEXT, false); - - Util.killProcesses("zookeeper"); - Util.killProcesses("Dsolr.jetty.https.port"); - - Thread.sleep(5000); - - Util.cleanRunDirectory(); - Util.deleteRunningFile(); - } - - Util.createIsRunningFile(); - } catch (Exception e) { e.printStackTrace(); } @@ -710,6 +709,8 @@ public static void init(String[] args) { public static void destroy() { try { + Util.getAndPublishCommitInformation(); + if (argM.containsKey("-Housekeeping")) { Util.postMessage("** Initiating Housekeeping activities! ... ", MessageType.RED_TEXT, false); Util.execute("rm -r -f " + Util.DOWNLOAD_DIR, Util.DOWNLOAD_DIR); From 3ce38d0bc503f13895a706fda07bdd783e2072ed Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 01:58:02 -0400 Subject: [PATCH 028/276] replacing the getCommitInformation in app connector ... --- .../solr/tests/nightlybenchmarks/BenchmarkAppConnector.java | 3 ++- .../java/org/apache/solr/tests/nightlybenchmarks/Util.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index 76960dcf8e71..7e7498fb237c 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -286,8 +286,9 @@ public static void publishDataForWebApp() { false, FileType.NUMERIC_QUERY_STANDALONE); } - Util.postMessage("** Publishing data for webapp [COMPLETE] ..", MessageType.WHITE_TEXT, false); + Util.getAndPublishCommitInformation(); + Util.postMessage("** Publishing data for webapp [COMPLETE] ..", MessageType.WHITE_TEXT, false); } } \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 23471a209324..ddf7e3d4f1cc 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -709,7 +709,6 @@ public static void init(String[] args) { public static void destroy() { try { - Util.getAndPublishCommitInformation(); if (argM.containsKey("-Housekeeping")) { Util.postMessage("** Initiating Housekeeping activities! ... ", MessageType.RED_TEXT, false); From 1181d883cf810939abfab42854c2f73bdba3a042 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 02:22:27 -0400 Subject: [PATCH 029/276] Metric Estimator refactoring ... --- .../SolrNightBenchmarks/config.properties | 3 +- .../nightlybenchmarks/MetricCollector.java | 162 +----------------- .../solr/tests/nightlybenchmarks/Util.java | 6 +- 3 files changed, 8 insertions(+), 163 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/config.properties b/dev-tools/SolrNightBenchmarks/config.properties index c10b87475f1d..7fc26dbc8722 100644 --- a/dev-tools/SolrNightBenchmarks/config.properties +++ b/dev-tools/SolrNightBenchmarks/config.properties @@ -6,4 +6,5 @@ SolrNightlyBenchmarks.zookeeperDownloadURL=http://www.us.apache.org/dist/zookeep SolrNightlyBenchmarks.zookeeperDownloadVersion=3.4.6 SolrNightlyBenchmarks.zookeeperHostIp=127.0.0.1 SolrNightlyBenchmarks.zookeeperHostPort=2181 -SolrNightlyBenchmarks.luceneSolrRepositoryURL=https://github.com/apache/lucene-solr \ No newline at end of file +SolrNightlyBenchmarks.luceneSolrRepositoryURL=https://github.com/apache/lucene-solr +SolrNightlyBenchmarks.metricEstimationPeriod=1000 \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java index 18c05e02a0f8..ffd5579a4da3 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java @@ -56,8 +56,6 @@ public enum MetricSubType { public void run() { - if (testType == TestType.STANDALONE_INDEXING) { - while (true) { try { @@ -87,169 +85,11 @@ public void run() { * 100), false, FileType.PROCESS_CPU_LOAD); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - } - - if (testType == TestType.STANDALONE_CREATE_COLLECTION) { - - while (true) { - try { - - String response = Util.getResponse( - "http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", - MediaType.APPLICATION_JSON); - JSONObject jsonObject = (JSONObject) JSONValue.parse(response); - - Date dNow = new Date(); - SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" - + TestType.STANDALONE_CREATE_COLLECTION + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("memory.heap.used").toString()) - / (1024 * 1024)), - false, FileType.MEMORY_HEAP_USED); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" - + TestType.STANDALONE_CREATE_COLLECTION + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("os.processCpuLoad").toString()) - * 100), - false, FileType.PROCESS_CPU_LOAD); - - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - } - - if (testType == TestType.CLOUD_CREATE_COLLECTION) { - - while (true) { - try { - - String response = Util.getResponse( - "http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", - MediaType.APPLICATION_JSON); - JSONObject jsonObject = (JSONObject) JSONValue.parse(response); - - Date dNow = new Date(); - SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" - + TestType.CLOUD_CREATE_COLLECTION + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("memory.heap.used").toString()) - / (1024 * 1024)), - false, FileType.MEMORY_HEAP_USED); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" - + TestType.CLOUD_CREATE_COLLECTION + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("os.processCpuLoad").toString()) - * 100), - false, FileType.PROCESS_CPU_LOAD); - - Thread.sleep(1000); + Thread.sleep(Integer.parseInt(Util.METRIC_ESTIMATION_PERIOD)); } catch (InterruptedException e) { e.printStackTrace(); } } - } - - if (testType == TestType.CLOUD_INDEXING_REGULAR) { - - while (true) { - try { - - String response = Util.getResponse( - "http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", - MediaType.APPLICATION_JSON); - JSONObject jsonObject = (JSONObject) JSONValue.parse(response); - - Date dNow = new Date(); - SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" - + TestType.CLOUD_INDEXING_REGULAR + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("memory.heap.used").toString()) - / (1024 * 1024)), - false, FileType.MEMORY_HEAP_USED); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" - + TestType.CLOUD_INDEXING_REGULAR + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("os.processCpuLoad").toString()) - * 100), - false, FileType.PROCESS_CPU_LOAD); - - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - } - - if (testType == TestType.CLOUD_INDEXING_CONCURRENT) { - - while (true) { - try { - - String response = Util.getResponse( - "http://localhost:" + this.port + "/solr/admin/metrics?wt=json&group=jvm", - MediaType.APPLICATION_JSON); - JSONObject jsonObject = (JSONObject) JSONValue.parse(response); - - Date dNow = new Date(); - SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.MEM_ESTIMATION + "_" - + TestType.CLOUD_INDEXING_CONCURRENT + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("memory.heap.used").toString()) - / (1024 * 1024)), - false, FileType.MEMORY_HEAP_USED); - BenchmarkAppConnector.writeToWebAppDataFile( - Util.TEST_ID + "_" + this.commitID + "_" + MetricType.CPU_ESTIMATION + "_" - + TestType.CLOUD_INDEXING_CONCURRENT + "_dump.csv", - ft.format(dNow) + ", " + Util.TEST_ID + ", " - + (Double.parseDouble( - ((JSONObject) ((JSONObject) jsonObject.get("metrics")).get("solr.jvm")) - .get("os.processCpuLoad").toString()) - * 100), - false, FileType.PROCESS_CPU_LOAD); - - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - } - } } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index ddf7e3d4f1cc..87bf2df0428f 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -77,9 +77,10 @@ public class Util { public static String LUCENE_SOLR_REPOSITORY_URL = "https://github.com/apache/lucene-solr"; public static String GIT_REPOSITORY_PATH; public static String COMMIT_ID; - public static boolean SILENT = false; public static String TEST_ID = UUID.randomUUID().toString(); public static String TEST_TIME = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()); + public static String METRIC_ESTIMATION_PERIOD = "1000"; + public static boolean SILENT = false; final static Logger logger = Logger.getLogger(Util.class); @@ -421,6 +422,9 @@ public static void getPropertyValues() { Util.LUCENE_SOLR_REPOSITORY_URL = prop.getProperty("SolrNightlyBenchmarks.luceneSolrRepositoryURL"); Util.postMessage("Getting Property Value for luceneSolrRepositoryURL: " + Util.LUCENE_SOLR_REPOSITORY_URL, MessageType.YELLOW_TEXT, false); + Util.METRIC_ESTIMATION_PERIOD = prop.getProperty("SolrNightlyBenchmarks.metricEstimationPeriod"); + Util.postMessage("Getting Property Value for metricEstimationPeriod: " + Util.METRIC_ESTIMATION_PERIOD, + MessageType.YELLOW_TEXT, false); if (BenchmarkAppConnector.benchmarkAppDirectory .charAt(BenchmarkAppConnector.benchmarkAppDirectory.length() - 1) != File.separator.charAt(0)) { From 76845902b44d4b45876eccfc3b8cd67d152f8eec Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 03:05:53 -0400 Subject: [PATCH 030/276] Solr Node refactoring ... partial cloning handle mechanism ... --- .../tests/nightlybenchmarks/SolrNode.java | 4 +- .../solr/tests/nightlybenchmarks/Util.java | 37 +++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java index a156d4876b23..a28d399a6948 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java @@ -102,11 +102,9 @@ void checkoutCommitAndBuild() throws IOException, GitAPIException { if (gitDirectory.exists()) { repository = Git.open(gitDirectory); - repository.checkout().setName(commitId).call(); - } else { - repository = Git.cloneRepository().setURI("https://github.com/apache/lucene-solr") + repository = Git.cloneRepository().setURI(Util.LUCENE_SOLR_REPOSITORY_URL) .setDirectory(gitDirectory).call(); repository.checkout().setName(commitId).call(); } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 87bf2df0428f..961793709e88 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -294,6 +294,11 @@ public static String getLocalRepoPath() { return Util.GIT_REPOSITORY_PATH; } + public static String getLocalLastRepoPath() { + Util.GIT_REPOSITORY_PATH = Util.DOWNLOAD_DIR + "git-repository-" + BenchmarkAppConnector.getLastRunCommitID(); + return Util.GIT_REPOSITORY_PATH; + } + public static void getAndPublishCommitInformation() { BenchmarkAppConnector.writeToWebAppDataFile(Util.TEST_ID + "_" + Util.COMMIT_ID + "_COMMIT_INFORMATION_dump.csv", Util.getCommitInformation(), true, FileType.COMMIT_INFORMATION_FILE); } @@ -669,21 +674,6 @@ public static void init(String[] args) { Util.checkWebAppFiles(); Util.checkBaseAndTempDir(); - - if (!BenchmarkAppConnector.isRunningFolderEmpty()) { - Util.postMessage("** It looks like the last test session failed or was aborted ..", - MessageType.RED_TEXT, false); - - Util.killProcesses("zookeeper"); - Util.killProcesses("Dsolr.jetty.https.port"); - - Thread.sleep(5000); - - Util.cleanRunDirectory(); - Util.deleteRunningFile(); - } - - Util.createIsRunningFile(); Util.setAliveFlag(); argM = Util.getArgs(args); @@ -704,6 +694,23 @@ public static void init(String[] args) { Util.COMMIT_ID = commitID; Util.getSystemEnvironmentInformation(); + + if (!BenchmarkAppConnector.isRunningFolderEmpty()) { + Util.postMessage("** It looks like the last test session failed or was aborted ..", + MessageType.RED_TEXT, false); + + Util.killProcesses("zookeeper"); + Util.killProcesses("Dsolr.jetty.https.port"); + Util.execute("rm -r -f " + getLocalRepoPath(), Util.getLocalRepoPath()); + + Thread.sleep(5000); + + Util.cleanRunDirectory(); + Util.deleteRunningFile(); + } + + Util.createIsRunningFile(); + } catch (Exception e) { e.printStackTrace(); } From fac1dd011a9676ee50256b16239847fa29f5e77a Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 18:32:58 -0400 Subject: [PATCH 031/276] Git clone fail mechanism ... --- .../BenchmarkAppConnector.java | 28 ++++++++++++++++++- .../SolrNightlyBenchmarks.java | 16 ++++++----- .../tests/nightlybenchmarks/SolrNode.java | 9 ++++-- .../solr/tests/nightlybenchmarks/Util.java | 9 ++++-- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index 7e7498fb237c..eac152127ff4 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -14,7 +14,7 @@ public BenchmarkAppConnector() { public enum FileType { - MEMORY_HEAP_USED, PROCESS_CPU_LOAD, TEST_ENV_FILE, STANDALONE_INDEXING_MAIN, STANDALONE_CREATE_COLLECTION_MAIN, STANDALONE_INDEXING_THROUGHPUT, CLOUD_CREATE_COLLECTION_MAIN, CLOUD_SERIAL_INDEXING_THROUGHPUT, CLOUD_CONCURRENT_INDEXING_THROUGHPUT, CLOUD_INDEXING_SERIAL, CLOUD_INDEXING_CONCURRENT, NUMERIC_QUERY_STANDALONE, NUMERIC_QUERY_CLOUD, LAST_RUN_COMMIT, IS_RUNNING_FILE, COMMIT_INFORMATION_FILE + MEMORY_HEAP_USED, PROCESS_CPU_LOAD, TEST_ENV_FILE, STANDALONE_INDEXING_MAIN, STANDALONE_CREATE_COLLECTION_MAIN, STANDALONE_INDEXING_THROUGHPUT, CLOUD_CREATE_COLLECTION_MAIN, CLOUD_SERIAL_INDEXING_THROUGHPUT, CLOUD_CONCURRENT_INDEXING_THROUGHPUT, CLOUD_INDEXING_SERIAL, CLOUD_INDEXING_CONCURRENT, NUMERIC_QUERY_STANDALONE, NUMERIC_QUERY_CLOUD, LAST_RUN_COMMIT, IS_RUNNING_FILE, COMMIT_INFORMATION_FILE, IS_CLONING_FILE } @@ -34,6 +34,17 @@ public static boolean isRunningFolderEmpty() { return dir.listFiles().length == 0 ? true : false; } + public static boolean isCloningFolderEmpty() { + + File dir = new File(benchmarkAppDirectory + "data" + File.separator + "cloning" + File.separator); + + if (!dir.exists()) { + dir.mkdir(); + } + + return dir.listFiles().length == 0 ? true : false; + } + public static void deleteFile(FileType type) { if (type == FileType.LAST_RUN_COMMIT) { @@ -49,6 +60,16 @@ public static void deleteFile(FileType type) { } else if (type == FileType.IS_RUNNING_FILE) { File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "running" + File.separator); + if (!dir.exists()) { + dir.mkdir(); + } else { + for (File file: dir.listFiles()) { + if (!file.isDirectory()) file.delete(); + } + } + } else if (type == FileType.IS_CLONING_FILE) { + File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "cloning" + File.separator); + if (!dir.exists()) { dir.mkdir(); } else { @@ -72,6 +93,8 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c dataDir = new File(benchmarkAppDirectory + "data" + File.separator + "running" + File.separator); } else if (type == FileType.LAST_RUN_COMMIT) { dataDir = new File(benchmarkAppDirectory + "data" + File.separator + "lastrun" + File.separator); + } else if (type == FileType.IS_CLONING_FILE) { + dataDir = new File(benchmarkAppDirectory + "data" + File.separator + "cloning" + File.separator); } else { dataDir = new File(benchmarkAppDirectory + "data" + File.separator); } @@ -86,6 +109,9 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c } else if (type == FileType.LAST_RUN_COMMIT) { file = new File( benchmarkAppDirectory + "data" + File.separator + "lastrun" + File.separator + fileName); + } else if (type == FileType.IS_CLONING_FILE) { + file = new File( + benchmarkAppDirectory + "data" + File.separator + "cloning" + File.separator + fileName); } else { file = new File(benchmarkAppDirectory + "data" + File.separator + fileName); } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index 7bc6851c20c7..9a5c4b167aac 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -26,25 +26,27 @@ public static void main(String[] args) throws IOException, InterruptedException Util.init(args); - Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); +// Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); - Tests.createCollectionTestStandalone(Util.COMMIT_ID); +// Tests.createCollectionTestStandalone(Util.COMMIT_ID); - Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); +// Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); - Tests.runNumericQueryTestsStandalone(); +// Tests.runNumericQueryTestsStandalone(); - Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); +// Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); - Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); +// Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); - Tests.runNumericTestsCloud(); +// Tests.runNumericTestsCloud(); + Tests.runNumericQueryTestsStandalone(); BenchmarkAppConnector.publishDataForWebApp(); Util.destroy(); } + } \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java index a28d399a6948..ab3bfbb7f2f3 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java @@ -26,6 +26,7 @@ import java.util.UUID; import org.apache.log4j.Logger; +import org.apache.solr.tests.nightlybenchmarks.BenchmarkAppConnector.FileType; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -104,9 +105,11 @@ void checkoutCommitAndBuild() throws IOException, GitAPIException { repository = Git.open(gitDirectory); repository.checkout().setName(commitId).call(); } else { - repository = Git.cloneRepository().setURI(Util.LUCENE_SOLR_REPOSITORY_URL) - .setDirectory(gitDirectory).call(); - repository.checkout().setName(commitId).call(); + BenchmarkAppConnector.writeToWebAppDataFile("iamcloning.txt", "", true, FileType.IS_CLONING_FILE); + repository = Git.cloneRepository().setURI(Util.LUCENE_SOLR_REPOSITORY_URL) + .setDirectory(gitDirectory).call(); + repository.checkout().setName(commitId).call(); + BenchmarkAppConnector.deleteFile(FileType.IS_CLONING_FILE); } String packageFilename = gitDirectoryPath + "/solr/package/solr-7.0.0-SNAPSHOT.zip"; diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 961793709e88..c27f22b0f9da 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -701,8 +701,13 @@ public static void init(String[] args) { Util.killProcesses("zookeeper"); Util.killProcesses("Dsolr.jetty.https.port"); - Util.execute("rm -r -f " + getLocalRepoPath(), Util.getLocalRepoPath()); - + + if (!BenchmarkAppConnector.isCloningFolderEmpty()) { + Util.postMessage("** Looks like a broken clone exists removing it ..", + MessageType.RED_TEXT, false); + Util.execute("rm -r -f " + Util.getLocalRepoPath(), Util.getLocalRepoPath()); + } + Thread.sleep(5000); Util.cleanRunDirectory(); From 00d00c5ac1a2d270e89550f51ddff11b88e1c9ce Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 20:46:44 -0400 Subject: [PATCH 032/276] making query method synchronized ... and query count configurable ... --- .../SolrNightBenchmarks/config.properties | 3 ++- .../tests/nightlybenchmarks/QueryClient.java | 14 +++++++++---- .../solr/tests/nightlybenchmarks/Tests.java | 20 ++++++++++--------- .../solr/tests/nightlybenchmarks/Util.java | 4 ++++ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/config.properties b/dev-tools/SolrNightBenchmarks/config.properties index 7fc26dbc8722..076d55a29d25 100644 --- a/dev-tools/SolrNightBenchmarks/config.properties +++ b/dev-tools/SolrNightBenchmarks/config.properties @@ -7,4 +7,5 @@ SolrNightlyBenchmarks.zookeeperDownloadVersion=3.4.6 SolrNightlyBenchmarks.zookeeperHostIp=127.0.0.1 SolrNightlyBenchmarks.zookeeperHostPort=2181 SolrNightlyBenchmarks.luceneSolrRepositoryURL=https://github.com/apache/lucene-solr -SolrNightlyBenchmarks.metricEstimationPeriod=1000 \ No newline at end of file +SolrNightlyBenchmarks.metricEstimationPeriod=1000 +SolrNightlyBenchmarks.queryThreadCount=2 \ No newline at end of file diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java index 8c51e87c69f1..eaf2f0656d3d 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java @@ -86,7 +86,7 @@ public void run() { if (running == true) { // Critical Section .... - SolrResponse response; + SolrResponse response = null; try { NamedList list = new NamedList<>(); list.add("defType", "edismax"); @@ -117,9 +117,9 @@ public void run() { } params = SolrParams.toSolrParams(list); - - response = solrClient.query(collectionName, params); - + + response = this.fireQuery(collectionName, params); + if ((System.nanoTime() - startTime) >= (delayEstimationBySeconds * 1000000000)) { setQueryCounter(); elapsedTime = response.getElapsedTime(); @@ -147,6 +147,12 @@ public void run() { solrClient.close(); return; } + + private synchronized SolrResponse fireQuery(String collectionName, SolrParams params) throws SolrServerException, IOException { + + return solrClient.query(collectionName, params); + + } private synchronized void setQueryCounter() { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index 7cd8830c19c1..7121db876fdb 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -35,6 +35,8 @@ public class Tests { public static SolrCloud cloud; public static SolrNode node; + public static int threadCount = Integer.parseInt(Util.QUERY_THREAD_COUNT); + public static boolean createCollectionTestStandalone(String commitID) { @@ -259,37 +261,37 @@ public static void runNumericTestsCloud() throws IOException, InterruptedExcepti Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2", 10000); BenchmarkReportData.numericQueryTNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.TERM_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); BenchmarkReportData.numericQueryRNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.RANGE_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); BenchmarkReportData.numericQueryLNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.LESS_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.GREATER_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); Tests.shutDownCloud(); } public static void runNumericQueryTestsStandalone() throws IOException, InterruptedException { - + Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.TERM_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); BenchmarkReportData.numericQueryRNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.RANGE_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); BenchmarkReportData.numericQueryLNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.LESS_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, 1, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.GREATER_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); Tests.shutDownStandalone(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index c27f22b0f9da..668de30ab713 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -80,6 +80,7 @@ public class Util { public static String TEST_ID = UUID.randomUUID().toString(); public static String TEST_TIME = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()); public static String METRIC_ESTIMATION_PERIOD = "1000"; + public static String QUERY_THREAD_COUNT = "1"; public static boolean SILENT = false; final static Logger logger = Logger.getLogger(Util.class); @@ -430,6 +431,9 @@ public static void getPropertyValues() { Util.METRIC_ESTIMATION_PERIOD = prop.getProperty("SolrNightlyBenchmarks.metricEstimationPeriod"); Util.postMessage("Getting Property Value for metricEstimationPeriod: " + Util.METRIC_ESTIMATION_PERIOD, MessageType.YELLOW_TEXT, false); + Util.QUERY_THREAD_COUNT = prop.getProperty("SolrNightlyBenchmarks.queryThreadCount"); + Util.postMessage("Getting Property Value for queryThreadCount: " + Util.QUERY_THREAD_COUNT, + MessageType.YELLOW_TEXT, false); if (BenchmarkAppConnector.benchmarkAppDirectory .charAt(BenchmarkAppConnector.benchmarkAppDirectory.length() - 1) != File.separator.charAt(0)) { From b5b4d026a5343b54184ab223ca03c184b5f1f151 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 21:26:49 -0400 Subject: [PATCH 033/276] Reducting delay at index.html --- dev-tools/SolrNightBenchmarks/WebAppSource/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html index aeb9f174f87b..8ae45d2dfb27 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html @@ -1,7 +1,7 @@ Solr Nightly Benchmarks - +




    From a5fb683ffa2b034b649dae7a7101d8e5fe1925cd Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 23:03:49 -0400 Subject: [PATCH 034/276] update ... --- .../tests/nightlybenchmarks/QueryClient.java | 2 +- .../SolrNightlyBenchmarks.java | 2 -- .../solr/tests/nightlybenchmarks/Tests.java | 18 +++++++++--------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java index eaf2f0656d3d..579ad87471a6 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java @@ -128,7 +128,7 @@ public void run() { Util.postMessage("\r" + this.toString() + " < " + elapsedTime + " > ", MessageType.WHITE_TEXT, false); } else { - Util.postMessage("\rWaiting For Estimation to start ...", MessageType.BLUE_TEXT, false); + Util.postMessageOnLine("\rWaiting For Estimation to start ..."); } } catch (SolrServerException | IOException e) { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index 9a5c4b167aac..f280451913d3 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -33,7 +33,6 @@ public static void main(String[] args) throws IOException, InterruptedException // Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); // Tests.runNumericQueryTestsStandalone(); - // Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); @@ -45,7 +44,6 @@ public static void main(String[] args) throws IOException, InterruptedException BenchmarkAppConnector.publishDataForWebApp(); - Util.destroy(); } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index 7121db876fdb..eb98a06ce1f6 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -35,7 +35,7 @@ public class Tests { public static SolrCloud cloud; public static SolrNode node; - public static int threadCount = Integer.parseInt(Util.QUERY_THREAD_COUNT); + public static int queryThreadCount = Integer.parseInt(Util.QUERY_THREAD_COUNT); @@ -261,16 +261,16 @@ public static void runNumericTestsCloud() throws IOException, InterruptedExcepti Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2", 10000); BenchmarkReportData.numericQueryTNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.TERM_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); BenchmarkReportData.numericQueryRNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.RANGE_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); BenchmarkReportData.numericQueryLNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.LESS_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); Tests.shutDownCloud(); @@ -282,16 +282,16 @@ public static void runNumericQueryTestsStandalone() throws IOException, Interrup Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.TERM_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); BenchmarkReportData.numericQueryRNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.RANGE_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); BenchmarkReportData.numericQueryLNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.LESS_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, threadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); Tests.shutDownStandalone(); From eb19b5cc7aeb3388664627b7bb9633b28285f0dd Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 23:46:56 -0400 Subject: [PATCH 035/276] reducing index delay to two seconds ... --- dev-tools/SolrNightBenchmarks/WebAppSource/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html index 8ae45d2dfb27..cf088c254b65 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html @@ -1,7 +1,7 @@ Solr Nightly Benchmarks - +




    From 3b757ea74bb7b4d4d50bd609596bf5c03424ec70 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 4 Jun 2017 23:50:57 -0400 Subject: [PATCH 036/276] Reducing index delay to 1 second ... --- dev-tools/SolrNightBenchmarks/WebAppSource/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html index cf088c254b65..4f36e2d8e9fa 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html @@ -1,7 +1,7 @@ Solr Nightly Benchmarks - +




    From 30f882cfceb02edac3552baae31edde0eb111296 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Tue, 6 Jun 2017 08:19:36 -0400 Subject: [PATCH 037/276] adding commit queue registry sub-utility ... --- .../BenchmarkAppConnector.java | 48 +++++++++++++++++-- .../tests/nightlybenchmarks/SolrNode.java | 2 +- .../solr/tests/nightlybenchmarks/Util.java | 31 ++++++++++-- 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index eac152127ff4..d41d3508debb 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -14,7 +14,7 @@ public BenchmarkAppConnector() { public enum FileType { - MEMORY_HEAP_USED, PROCESS_CPU_LOAD, TEST_ENV_FILE, STANDALONE_INDEXING_MAIN, STANDALONE_CREATE_COLLECTION_MAIN, STANDALONE_INDEXING_THROUGHPUT, CLOUD_CREATE_COLLECTION_MAIN, CLOUD_SERIAL_INDEXING_THROUGHPUT, CLOUD_CONCURRENT_INDEXING_THROUGHPUT, CLOUD_INDEXING_SERIAL, CLOUD_INDEXING_CONCURRENT, NUMERIC_QUERY_STANDALONE, NUMERIC_QUERY_CLOUD, LAST_RUN_COMMIT, IS_RUNNING_FILE, COMMIT_INFORMATION_FILE, IS_CLONING_FILE + MEMORY_HEAP_USED, PROCESS_CPU_LOAD, TEST_ENV_FILE, STANDALONE_INDEXING_MAIN, STANDALONE_CREATE_COLLECTION_MAIN, STANDALONE_INDEXING_THROUGHPUT, CLOUD_CREATE_COLLECTION_MAIN, CLOUD_SERIAL_INDEXING_THROUGHPUT, CLOUD_CONCURRENT_INDEXING_THROUGHPUT, CLOUD_INDEXING_SERIAL, CLOUD_INDEXING_CONCURRENT, NUMERIC_QUERY_STANDALONE, NUMERIC_QUERY_CLOUD, LAST_RUN_COMMIT, IS_RUNNING_FILE, COMMIT_INFORMATION_FILE, IS_CLONING_FILE, COMMIT_QUEUE } @@ -45,10 +45,35 @@ public static boolean isCloningFolderEmpty() { return dir.listFiles().length == 0 ? true : false; } - public static void deleteFile(FileType type) { + public static boolean isCommitQueueEmpty() { + + File dir = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator); + + if (!dir.exists()) { + dir.mkdir(); + } + + return dir.listFiles().length == 0 ? true : false; + } + + public static boolean isDeleteCommitFromQueue(String commit) { + + File file = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator + commit); + return file.delete(); + + } + + public static boolean isCommitInQueue(String commit) { + + File file = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator + commit); + return file.exists(); + + } + + public static void deleteFolder(FileType type) { if (type == FileType.LAST_RUN_COMMIT) { - File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "lastrun" + File.separator); + File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + type + File.separator); if (!dir.exists()) { dir.mkdir(); @@ -70,6 +95,16 @@ public static void deleteFile(FileType type) { } else if (type == FileType.IS_CLONING_FILE) { File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "cloning" + File.separator); + if (!dir.exists()) { + dir.mkdir(); + } else { + for (File file: dir.listFiles()) { + if (!file.isDirectory()) file.delete(); + } + } + } else if (type == FileType.COMMIT_QUEUE) { + File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator); + if (!dir.exists()) { dir.mkdir(); } else { @@ -95,6 +130,8 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c dataDir = new File(benchmarkAppDirectory + "data" + File.separator + "lastrun" + File.separator); } else if (type == FileType.IS_CLONING_FILE) { dataDir = new File(benchmarkAppDirectory + "data" + File.separator + "cloning" + File.separator); + } else if (type == FileType.COMMIT_QUEUE) { + dataDir = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator); } else { dataDir = new File(benchmarkAppDirectory + "data" + File.separator); } @@ -112,6 +149,9 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c } else if (type == FileType.IS_CLONING_FILE) { file = new File( benchmarkAppDirectory + "data" + File.separator + "cloning" + File.separator + fileName); + } else if (type == FileType.COMMIT_QUEUE) { + file = new File( + benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator + fileName); } else { file = new File(benchmarkAppDirectory + "data" + File.separator + fileName); } @@ -140,7 +180,7 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c fw.write("Date, Test_ID, Seconds, CommitID\n"); } else if (type == FileType.STANDALONE_INDEXING_MAIN || type == FileType.CLOUD_INDEXING_SERIAL) { fw.write("Date, Test_ID, Seconds, CommitID\n"); - } else if (type == FileType.TEST_ENV_FILE || type == FileType.COMMIT_INFORMATION_FILE) { + } else if (type == FileType.TEST_ENV_FILE || type == FileType.COMMIT_INFORMATION_FILE || type == FileType.COMMIT_QUEUE) { // Don't add any header } else if (type == FileType.STANDALONE_INDEXING_THROUGHPUT || type == FileType.CLOUD_SERIAL_INDEXING_THROUGHPUT) { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java index ab3bfbb7f2f3..ee0698cb59c1 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java @@ -109,7 +109,7 @@ void checkoutCommitAndBuild() throws IOException, GitAPIException { repository = Git.cloneRepository().setURI(Util.LUCENE_SOLR_REPOSITORY_URL) .setDirectory(gitDirectory).call(); repository.checkout().setName(commitId).call(); - BenchmarkAppConnector.deleteFile(FileType.IS_CLONING_FILE); + BenchmarkAppConnector.deleteFolder(FileType.IS_CLONING_FILE); } String packageFilename = gitDirectoryPath + "/solr/package/solr-7.0.0-SNAPSHOT.zip"; diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 668de30ab713..853dd64985a0 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -284,7 +284,7 @@ public static void extract(String filename, String filePath) throws IOException } public static String getLatestCommitID(String repositoryURL) throws IOException { - Util.postMessage("** Getting the latest commit ID from remote repository", MessageType.BLUE_TEXT, false); + Util.postMessage("** Getting the latest commit ID from: " + repositoryURL, MessageType.BLUE_TEXT, false); return new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec("git ls-remote " + repositoryURL + " HEAD").getInputStream())).readLine() .split("HEAD")[0].trim(); @@ -671,16 +671,37 @@ public static Map getArgs(String[] args) { public static void init(String[] args) { + Util.postMessage("", MessageType.WHITE_TEXT, false); + Util.postMessage("--------------------------------------------------------------------", MessageType.WHITE_TEXT, false); + Util.postMessage(" *** Solr Nightly Benchmarks *** HOLA !!! ", MessageType.RED_TEXT, false); + Util.postMessage("--------------------------------------------------------------------", MessageType.WHITE_TEXT, false); + Util.postMessage("", MessageType.WHITE_TEXT, false); + try { + argM = Util.getArgs(args); Util.getPropertyValues(); + if (argM.containsKey("-RegisterLatestCommit")) { + Util.postMessage("** SolrNightlyBenchmarks Commit Registry Updater ...", MessageType.WHITE_TEXT, false); + String commit = Util.getLatestCommitID(Util.LUCENE_SOLR_REPOSITORY_URL); + + if (!BenchmarkAppConnector.isCommitInQueue(commit)) { + Util.postMessage("** Registering the latest commit in the queue ...", MessageType.RED_TEXT, false); + BenchmarkAppConnector.writeToWebAppDataFile(commit, "", true, FileType.COMMIT_QUEUE); + } else { + Util.postMessage("** Skipping Registering the latest commit in the queue since it already exists ...", MessageType.GREEN_TEXT, false); + } + + Util.postMessage("** SolrNightlyBenchmarks Commit Registry Updater [COMPLETE] now EXIT...", MessageType.WHITE_TEXT, false); + System.exit(0); + } + Util.checkWebAppFiles(); Util.checkBaseAndTempDir(); Util.setAliveFlag(); - argM = Util.getArgs(args); String commitID = ""; if (argM.containsKey("-commitID")) { @@ -746,20 +767,20 @@ public static void destroy() { public static void createLastRunFile() { - BenchmarkAppConnector.deleteFile(FileType.LAST_RUN_COMMIT); + BenchmarkAppConnector.deleteFolder(FileType.LAST_RUN_COMMIT); BenchmarkAppConnector.writeToWebAppDataFile(Util.COMMIT_ID, "", true, FileType.LAST_RUN_COMMIT); } public static void createIsRunningFile() { - BenchmarkAppConnector.deleteFile(FileType.IS_RUNNING_FILE); + BenchmarkAppConnector.deleteFolder(FileType.IS_RUNNING_FILE); BenchmarkAppConnector.writeToWebAppDataFile(Util.COMMIT_ID, "", true, FileType.IS_RUNNING_FILE); } public static void deleteRunningFile() { - BenchmarkAppConnector.deleteFile(FileType.IS_RUNNING_FILE); + BenchmarkAppConnector.deleteFolder(FileType.IS_RUNNING_FILE); } public static void cleanRunDirectory() { From 40e294c6b0d109257b7a0209f0fd1444b920e29e Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Tue, 6 Jun 2017 20:28:41 -0400 Subject: [PATCH 038/276] CRITICAL query threading client update, noise and fluctuation reduced to almost zero .... --- dev-tools/SolrNightBenchmarks/pom.xml | 7 ++- .../tests/nightlybenchmarks/QueryClient.java | 53 +++++++++++++------ .../nightlybenchmarks/SolrIndexingClient.java | 12 ----- .../solr/tests/nightlybenchmarks/Tests.java | 4 ++ 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/pom.xml b/dev-tools/SolrNightBenchmarks/pom.xml index 865c5e747822..b355df131679 100644 --- a/dev-tools/SolrNightBenchmarks/pom.xml +++ b/dev-tools/SolrNightBenchmarks/pom.xml @@ -135,7 +135,12 @@ 1.4 - + + + org.apache.commons + commons-math3 + 3.0 + diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java index 579ad87471a6..5ad9cf6ad7f6 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java @@ -18,8 +18,10 @@ */ import java.io.IOException; +import java.util.Arrays; import java.util.Random; +import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient; @@ -51,6 +53,10 @@ public enum QueryType { public static long maxQtime = Long.MIN_VALUE; public static long queryFailureCount = 0; public static long threadReadyCount = 0; + public static DescriptiveStatistics percentiles; + public static boolean percentilesObjectCreated = false; + public static long[] qTimePercentileList = new long[10000000]; + public static int qTimePercentileListPointer = 0; Random random = new Random(); @@ -63,13 +69,11 @@ public QueryClient(String urlString, int queueSize, int threadCount, String coll this.threadCount = threadCount; this.collectionName = collectionName; this.queryType = queryType; - minQtime = Long.MAX_VALUE; - maxQtime = Long.MIN_VALUE; this.numberOfThreads = numberOfThreads; this.delayEstimationBySeconds = delayEstimationBySeconds; solrClient = new ConcurrentUpdateSolrClient(urlString, queueSize, threadCount); - Util.postMessage("\r" + this.toString() + "** CREATING CLIENT ...", MessageType.RED_TEXT, false); + Util.postMessage("\r" + this.toString() + "** QUERY CLIENT CREATED ...", MessageType.RED_TEXT, false); } public void run() { @@ -117,22 +121,16 @@ public void run() { } params = SolrParams.toSolrParams(list); - + response = this.fireQuery(collectionName, params); - + if ((System.nanoTime() - startTime) >= (delayEstimationBySeconds * 1000000000)) { setQueryCounter(); elapsedTime = response.getElapsedTime(); setMinMaxQTime(elapsedTime); - Util.postMessage("\r" + response.toString(), MessageType.BLUE_TEXT, false); - Util.postMessage("\r" + this.toString() + " < " + elapsedTime + " > ", MessageType.WHITE_TEXT, - false); - } else { - Util.postMessageOnLine("\rWaiting For Estimation to start ..."); } } catch (SolrServerException | IOException e) { - // e.printStackTrace(); setQueryFailureCount(); } @@ -147,11 +145,12 @@ public void run() { solrClient.close(); return; } - - private synchronized SolrResponse fireQuery(String collectionName, SolrParams params) throws SolrServerException, IOException { - + + private synchronized SolrResponse fireQuery(String collectionName, SolrParams params) + throws SolrServerException, IOException { + return solrClient.query(collectionName, params); - + } private synchronized void setQueryCounter() { @@ -180,7 +179,9 @@ private synchronized void setMinMaxQTime(long QTime) { if (running == false) { return; } - + + qTimePercentileList[qTimePercentileListPointer++] = QTime; + if (QTime < minQtime) { minQtime = QTime; } @@ -191,6 +192,24 @@ private synchronized void setMinMaxQTime(long QTime) { } + public static double getNthPercentileQTime(double percentile) { + + if(!percentilesObjectCreated) { + + double[] finalQtime = new double[qTimePercentileListPointer]; + System.out.println(qTimePercentileListPointer); + for (int i = 0; i < (finalQtime.length); i++) { + finalQtime[i] = qTimePercentileList[i]; + } + Arrays.sort(finalQtime); + percentiles = new DescriptiveStatistics(finalQtime); + percentilesObjectCreated = true; + } + + return percentiles.getPercentile(percentile); + + } + public static void reset() { running = false; queryCount = 0; @@ -198,6 +217,8 @@ public static void reset() { maxQtime = Long.MIN_VALUE; queryFailureCount = 0; threadReadyCount = 0; + percentiles = null; + percentilesObjectCreated = false; } } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java index ef09a73b4fc1..59d5f39717c2 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java @@ -107,10 +107,6 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin if (numDocuments == numberOfDocuments) { break; } - if (numberOfDocuments % 5000 == 0) { - Util.postMessageOnLine("|"); - } - Util.postMessageOnLine("\r" + numberOfDocuments + " "); } solrClient.commit(); end = System.nanoTime(); @@ -196,10 +192,6 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin if (numDocuments == numberOfDocuments) { break; } - if (numberOfDocuments % 5000 == 0) { - Util.postMessageOnLine("|"); - } - Util.postMessageOnLine("\r" + numberOfDocuments + " "); } solrClient.commit(); end = System.nanoTime(); @@ -282,10 +274,6 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin if (numDocuments == numberOfDocuments) { break; } - if (numberOfDocuments % 5000 == 0) { - Util.postMessageOnLine("|"); - } - Util.postMessageOnLine("\r" + numberOfDocuments + " "); } solrClient.blockUntilFinished(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index eb98a06ce1f6..be76c8e8860a 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -208,6 +208,10 @@ private static Map numericQueryTests(String commitID, QueryType returnMap.put("MinQTime", "" + QueryClient.minQtime); returnMap.put("MaxQTime", "" + QueryClient.maxQtime); returnMap.put("QueryFailureCount", "" + QueryClient.queryFailureCount); + returnMap.put("75thQtime", "" + QueryClient.getNthPercentileQTime(75)); + returnMap.put("95thQtime", "" + QueryClient.getNthPercentileQTime(95)); + returnMap.put("99thQtime", "" + QueryClient.getNthPercentileQTime(99)); + returnMap.put("99.9thQtime", "" + QueryClient.getNthPercentileQTime(99.9)); Util.postMessage(returnMap.toString(), MessageType.RED_TEXT, false); QueryClient.reset(); From 6b5246e57f24d5f648df82870e2c6fc9fb2f3f65 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Wed, 7 Jun 2017 05:26:14 -0400 Subject: [PATCH 039/276] Git batch processing mechanism first commit ... --- .../BenchmarkAppConnector.java | 19 ++++++++++- .../BenchmarkReportData.java | 33 +++++++++++++++++++ .../tests/nightlybenchmarks/QueryClient.java | 3 +- .../SolrNightlyBenchmarks.java | 17 ---------- .../tests/nightlybenchmarks/TestPlans.java | 31 +++++++++++++++++ .../solr/tests/nightlybenchmarks/Tests.java | 3 +- .../solr/tests/nightlybenchmarks/Util.java | 14 ++++++++ 7 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index d41d3508debb..46f5978f484c 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -3,6 +3,9 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.Arrays; + +import org.apache.commons.io.comparator.LastModifiedFileComparator; public class BenchmarkAppConnector { @@ -56,12 +59,26 @@ public static boolean isCommitQueueEmpty() { return dir.listFiles().length == 0 ? true : false; } - public static boolean isDeleteCommitFromQueue(String commit) { + public static boolean deleteCommitFromQueue(String commit) { File file = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator + commit); return file.delete(); } + + public static String getOldestCommitFromQueue() { + + File directory = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator); + + File[] files = directory.listFiles(); + + if (files.length == 0) { + return null; + } + + Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR); + return files[0].getName(); + } public static boolean isCommitInQueue(String commit) { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java index 97f346cdd636..1a5fa470e1f0 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java @@ -48,5 +48,38 @@ public class BenchmarkReportData { public static Map numericQueryRNQMetricS; public static Map numericQueryLNQMetricS; public static Map numericQueryGNQMetricS; + + + public static void reset() { + + returnStandaloneCreateCollectionMap = null; + returnCloudCreateCollectionMap = null; + + metricMapStandalone = null; + metricMapCloudSerial = null; + + metricMapCloudConcurrent2 = null; + metricMapCloudConcurrent4 = null; + metricMapCloudConcurrent6 = null; + metricMapCloudConcurrent8 = null; + metricMapCloudConcurrent10 = null; + + metricMapStandaloneConcurrent2 = null; + metricMapStandaloneConcurrent4 = null; + metricMapStandaloneConcurrent6 = null; + metricMapStandaloneConcurrent8 = null; + metricMapStandaloneConcurrent10 = null; + + numericQueryTNQMetricC = null; + numericQueryRNQMetricC = null; + numericQueryLNQMetricC = null; + numericQueryGNQMetricC = null; + + numericQueryTNQMetricS = null; + numericQueryRNQMetricS = null; + numericQueryLNQMetricS = null; + numericQueryGNQMetricS = null; + + } } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java index 5ad9cf6ad7f6..e9b6f83e9e30 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java @@ -197,7 +197,6 @@ public static double getNthPercentileQTime(double percentile) { if(!percentilesObjectCreated) { double[] finalQtime = new double[qTimePercentileListPointer]; - System.out.println(qTimePercentileListPointer); for (int i = 0; i < (finalQtime.length); i++) { finalQtime[i] = qTimePercentileList[i]; } @@ -219,6 +218,8 @@ public static void reset() { threadReadyCount = 0; percentiles = null; percentilesObjectCreated = false; + qTimePercentileList = new long[10000000]; + qTimePercentileListPointer = 0; } } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java index f280451913d3..095e2ba365a3 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNightlyBenchmarks.java @@ -25,24 +25,7 @@ public static void main(String[] args) throws IOException, InterruptedException Util.init(args); - -// Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); - -// Tests.createCollectionTestStandalone(Util.COMMIT_ID); - -// Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); - -// Tests.runNumericQueryTestsStandalone(); - -// Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); - -// Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); - -// Tests.runNumericTestsCloud(); - - Tests.runNumericQueryTestsStandalone(); - BenchmarkAppConnector.publishDataForWebApp(); Util.destroy(); } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java new file mode 100644 index 000000000000..642a3259d0a3 --- /dev/null +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java @@ -0,0 +1,31 @@ +package org.apache.solr.tests.nightlybenchmarks; + +import java.io.IOException; + +public class TestPlans { + + public static void execute(String commitID) throws IOException, InterruptedException { + + Util.postMessage("** Executing the benchmark test plan ...", MessageType.BLUE_TEXT, false); + + Util.COMMIT_ID = commitID; + + Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); + + Tests.createCollectionTestStandalone(Util.COMMIT_ID); + + Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); + + Tests.runNumericQueryTestsStandalone(); + + Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); + + Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); + + Tests.runNumericTestsCloud(); + + Util.postMessage("** Executing the benchmark test plan [COMPLETE]...", MessageType.BLUE_TEXT, false); + + } + +} diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index be76c8e8860a..fc5b5041bea8 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -171,7 +171,8 @@ private static Map numericQueryTests(String commitID, QueryType int secondsToWait, long delayEstimationBySeconds, ConfigurationType confType, String baseURL, String collectionName) { try { - + QueryClient.reset(); + ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads); LinkedList list = new LinkedList(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 853dd64985a0..dc15c2567f50 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -740,6 +740,20 @@ public static void init(String[] args) { } Util.createIsRunningFile(); + + if (argM.containsKey("-ProcessCommitsFromQueue")) { + Util.postMessage("** Initiating processing from commit queueu ...", MessageType.BLUE_TEXT, false); + while (BenchmarkAppConnector.getOldestCommitFromQueue() != null) { + String commitIDFromQueue = BenchmarkAppConnector.getOldestCommitFromQueue(); + Util.postMessage("** Processing benchmarks for commit: " + commitIDFromQueue, MessageType.RED_TEXT, false); + TestPlans.execute(commitIDFromQueue); + BenchmarkAppConnector.publishDataForWebApp(); + BenchmarkReportData.reset(); + BenchmarkAppConnector.deleteCommitFromQueue(commitIDFromQueue); + } + Util.postMessage("** Processing from commit queue [COMPLETE] ...", MessageType.BLUE_TEXT, false); + } + } catch (Exception e) { e.printStackTrace(); From dd99d566be9360d96c54f384be42c66acf998f15 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Wed, 7 Jun 2017 14:09:29 -0400 Subject: [PATCH 040/276] double data entry bug fix + timestamp bug fix ... --- .../BenchmarkAppConnector.java | 11 ----------- .../nightlybenchmarks/SolrIndexingClient.java | 17 ++++++++++++++--- .../solr/tests/nightlybenchmarks/SolrNode.java | 12 ++++++++++-- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index 46f5978f484c..f7d05d602f94 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -247,17 +247,6 @@ public static void publishDataForWebApp() { + BenchmarkReportData.metricMapStandalone.get("IndexingThroughput") + ", " + BenchmarkReportData.metricMapStandalone.get("CommitID"), false, FileType.STANDALONE_INDEXING_THROUGHPUT); - - BenchmarkAppConnector.writeToWebAppDataFile("indexing_data_standalone_regular.csv", - BenchmarkReportData.metricMapStandalone.get("TimeStamp") + ", " + Util.TEST_ID + ", " - + BenchmarkReportData.metricMapStandalone.get("IndexingTime") + ", " - + BenchmarkReportData.metricMapStandalone.get("CommitID"), - false, FileType.STANDALONE_INDEXING_MAIN); - BenchmarkAppConnector.writeToWebAppDataFile("indexing_throughput_data_standalone_regular.csv", - BenchmarkReportData.metricMapStandalone.get("TimeStamp") + ", " + Util.TEST_ID + ", " - + BenchmarkReportData.metricMapStandalone.get("IndexingThroughput") + ", " - + BenchmarkReportData.metricMapStandalone.get("CommitID"), - false, FileType.STANDALONE_INDEXING_THROUGHPUT); } if (BenchmarkReportData.metricMapCloudSerial != null) { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java index 59d5f39717c2..bc66210599ea 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java @@ -20,6 +20,8 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -126,7 +128,10 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin Map returnMetricMap = new HashMap(); - returnMetricMap.put("TimeStamp", Util.TEST_TIME); + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + + returnMetricMap.put("TimeStamp", ft.format(dNow)); returnMetricMap.put("TimeFormat", "yyyy/MM/dd HH:mm:ss"); returnMetricMap.put("IndexingTime", "" + (double) ((double) (end - start) / (double) 1000000000)); returnMetricMap.put("IndexingThroughput", @@ -211,7 +216,10 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin Map returnMetricMap = new HashMap(); - returnMetricMap.put("TimeStamp", Util.TEST_TIME); + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + + returnMetricMap.put("TimeStamp", ft.format(dNow)); returnMetricMap.put("TimeFormat", "yyyy/MM/dd HH:mm:ss"); returnMetricMap.put("IndexingTime", "" + (double) ((double) (end - start) / (double) 1000000000)); returnMetricMap.put("IndexingThroughput", @@ -297,7 +305,10 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin Map returnMetricMap = new HashMap(); - returnMetricMap.put("TimeStamp", Util.TEST_TIME); + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + + returnMetricMap.put("TimeStamp", ft.format(dNow)); returnMetricMap.put("TimeFormat", "yyyy/MM/dd HH:mm:ss"); returnMetricMap.put("IndexingTime", "" + (double) ((double) (end - start) / (double) 1000000000)); returnMetricMap.put("IndexingThroughput", diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java index ee0698cb59c1..5238ba11b953 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrNode.java @@ -21,6 +21,8 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -204,8 +206,11 @@ public Map createCollection(String coreName, String collectionNa Map returnMap = new HashMap(); + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + returnMap.put("ProcessExitValue", "" + returnVal); - returnMap.put("TimeStamp", "" + Util.TEST_TIME); + returnMap.put("TimeStamp", "" + ft.format(dNow)); returnMap.put("CreateCollectionTime", "" + (double) ((double) (end - start) / (double) 1000000000)); returnMap.put("CommitID", this.commitId); @@ -245,8 +250,11 @@ public Map createCollection(String collectionName, String config Map returnMap = new HashMap(); + Date dNow = new Date(); + SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + returnMap.put("ProcessExitValue", "" + returnVal); - returnMap.put("TimeStamp", "" + Util.TEST_TIME); + returnMap.put("TimeStamp", "" + ft.format(dNow)); returnMap.put("CreateCollectionTime", "" + (double) ((double) (end - start) / (double) 1000000000)); returnMap.put("CommitID", this.commitId); From 1e661f6043353a70e895f76969472fa6e404d118 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Wed, 7 Jun 2017 15:49:11 -0400 Subject: [PATCH 041/276] commit queue pickup logic change implementation ... --- .../BenchmarkAppConnector.java | 17 +++++++++++++++++ .../solr/tests/nightlybenchmarks/Util.java | 9 +++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index f7d05d602f94..8604d75bfbf8 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -61,6 +61,7 @@ public static boolean isCommitQueueEmpty() { public static boolean deleteCommitFromQueue(String commit) { + Util.postMessage("** Deleting registered commit " + commit + " from the queue ...", MessageType.RED_TEXT, false); File file = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator + commit); return file.delete(); @@ -80,6 +81,22 @@ public static String getOldestCommitFromQueue() { return files[0].getName(); } + public static File[] getRegisteredCommitsFromQueue() { + + File directory = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator); + + File[] files = directory.listFiles(); + + if (files.length == 0) { + return null; + } + + Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR); + Util.postMessage("** Number of registered commits in the history: " + files.length, MessageType.RED_TEXT, false); + + return files; + } + public static boolean isCommitInQueue(String commit) { File file = new File(benchmarkAppDirectory + "data" + File.separator + "commit_queue" + File.separator + commit); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index dc15c2567f50..7a852e43ea13 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -743,13 +743,18 @@ public static void init(String[] args) { if (argM.containsKey("-ProcessCommitsFromQueue")) { Util.postMessage("** Initiating processing from commit queueu ...", MessageType.BLUE_TEXT, false); - while (BenchmarkAppConnector.getOldestCommitFromQueue() != null) { - String commitIDFromQueue = BenchmarkAppConnector.getOldestCommitFromQueue(); + + File[] currentCommits = BenchmarkAppConnector.getRegisteredCommitsFromQueue(); + + for (int i = 0; i < currentCommits.length; i++) { + + String commitIDFromQueue = currentCommits[i].getName(); Util.postMessage("** Processing benchmarks for commit: " + commitIDFromQueue, MessageType.RED_TEXT, false); TestPlans.execute(commitIDFromQueue); BenchmarkAppConnector.publishDataForWebApp(); BenchmarkReportData.reset(); BenchmarkAppConnector.deleteCommitFromQueue(commitIDFromQueue); + } Util.postMessage("** Processing from commit queue [COMPLETE] ...", MessageType.BLUE_TEXT, false); } From 8c559d30238c801ecd7619e99d2a4dfb5f5514d1 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Wed, 7 Jun 2017 22:30:20 -0400 Subject: [PATCH 042/276] Numeric Query: Adding AND and OR query types ... --- .../tests/nightlybenchmarks/QueryClient.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java index e9b6f83e9e30..674767dc8e23 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/QueryClient.java @@ -31,7 +31,7 @@ public class QueryClient implements Runnable { public enum QueryType { - TERM_NUMERIC_QUERY, RANGE_NUMERIC_QUERY, GREATER_THAN_NUMERIC_QUERY, LESS_THAN_NUMERIC_QUERY + TERM_NUMERIC_QUERY, RANGE_NUMERIC_QUERY, GREATER_THAN_NUMERIC_QUERY, LESS_THAN_NUMERIC_QUERY, AND_NUMERIC_QUERY, OR_NUMERIC_QUERY } String urlString; @@ -118,7 +118,21 @@ public void run() { list.add("q", "RandomIntField:[* TO " + SolrIndexingClient.intList.get(random.nextInt(SolrIndexingClient.documentCount)) + "]"); - } + } else if (this.queryType == QueryType.AND_NUMERIC_QUERY) { + + int ft_1 = SolrIndexingClient.intList.get(random.nextInt(SolrIndexingClient.documentCount)); + int ft_2 = SolrIndexingClient.intList.get(random.nextInt(SolrIndexingClient.documentCount)); + + list.add("q", "RandomIntField:[" + ft_1 + " AND " + ft_2 + "]"); + + } else if (this.queryType == QueryType.OR_NUMERIC_QUERY) { + + int ft_1 = SolrIndexingClient.intList.get(random.nextInt(SolrIndexingClient.documentCount)); + int ft_2 = SolrIndexingClient.intList.get(random.nextInt(SolrIndexingClient.documentCount)); + + list.add("q", "RandomIntField:[" + ft_1 + " OR " + ft_2 + "]"); + + } params = SolrParams.toSolrParams(list); From 2f6665b9ef8d218ffdd1116da7f65df1b183541d Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Wed, 7 Jun 2017 22:31:26 -0400 Subject: [PATCH 043/276] SolrNightlyBenchmarks font change ... --- dev-tools/SolrNightBenchmarks/WebAppSource/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html index 4f36e2d8e9fa..2c7d81f40913 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/index.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/index.html @@ -5,6 +5,6 @@




    -

    Solr Nightly Benchmarks

    +

    Solr Nightly Benchmarks

    \ No newline at end of file From 1713a476f8c044ed47349bb22e32a673213272b4 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Thu, 8 Jun 2017 02:30:10 -0400 Subject: [PATCH 044/276] lastrun folder naming bug fix ... --- .../solr/tests/nightlybenchmarks/BenchmarkAppConnector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index 8604d75bfbf8..adfb19460a31 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -107,7 +107,7 @@ public static boolean isCommitInQueue(String commit) { public static void deleteFolder(FileType type) { if (type == FileType.LAST_RUN_COMMIT) { - File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + type + File.separator); + File dir = new File(BenchmarkAppConnector.benchmarkAppDirectory + "data" + File.separator + "lastrun" + File.separator); if (!dir.exists()) { dir.mkdir(); From 33e1b1839919e6f8ce367462636a18ed3d5aaee7 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Thu, 8 Jun 2017 03:12:47 -0400 Subject: [PATCH 045/276] duplicate commit in queue processing bug fix ... --- .../solr/tests/nightlybenchmarks/Util.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 7a852e43ea13..816be8eb14a0 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -721,14 +721,14 @@ public static void init(String[] args) { Util.getSystemEnvironmentInformation(); if (!BenchmarkAppConnector.isRunningFolderEmpty()) { - Util.postMessage("** It looks like the last test session failed or was aborted ..", + Util.postMessage("** It looks like the last test session failed or was aborted ...", MessageType.RED_TEXT, false); Util.killProcesses("zookeeper"); Util.killProcesses("Dsolr.jetty.https.port"); if (!BenchmarkAppConnector.isCloningFolderEmpty()) { - Util.postMessage("** Looks like a broken clone exists removing it ..", + Util.postMessage("** Looks like a broken clone exists removing it ...", MessageType.RED_TEXT, false); Util.execute("rm -r -f " + Util.getLocalRepoPath(), Util.getLocalRepoPath()); } @@ -749,11 +749,18 @@ public static void init(String[] args) { for (int i = 0; i < currentCommits.length; i++) { String commitIDFromQueue = currentCommits[i].getName(); - Util.postMessage("** Processing benchmarks for commit: " + commitIDFromQueue, MessageType.RED_TEXT, false); - TestPlans.execute(commitIDFromQueue); - BenchmarkAppConnector.publishDataForWebApp(); - BenchmarkReportData.reset(); - BenchmarkAppConnector.deleteCommitFromQueue(commitIDFromQueue); + String lastRun = BenchmarkAppConnector.getLastRunCommitID(); + + if (commitIDFromQueue.equals(lastRun)) { + Util.postMessage("** The commit: " + commitIDFromQueue + " has already been processed skipping ...", MessageType.RED_TEXT, false); + BenchmarkAppConnector.deleteCommitFromQueue(commitIDFromQueue); + } else { + Util.postMessage("** Processing benchmarks for commit: " + commitIDFromQueue, MessageType.GREEN_TEXT, false); + TestPlans.execute(commitIDFromQueue); + BenchmarkAppConnector.publishDataForWebApp(); + BenchmarkReportData.reset(); + BenchmarkAppConnector.deleteCommitFromQueue(commitIDFromQueue); + } } Util.postMessage("** Processing from commit queue [COMPLETE] ...", MessageType.BLUE_TEXT, false); From eccf60ca2af17352b521cce6cd1b5e7400906d84 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Thu, 8 Jun 2017 20:47:29 -0400 Subject: [PATCH 046/276] Adding liscense header ... --- .../solr/tests/nightlybenchmarks/TestPlans.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java index 642a3259d0a3..983ebafe131e 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java @@ -1,5 +1,22 @@ package org.apache.solr.tests.nightlybenchmarks; +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + *

    + * http://www.apache.org/licenses/LICENSE-2.0 + *

    + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import java.io.IOException; public class TestPlans { From 3aa6c6b4b1dac1fdf228a5c2caab6df3c3b36a48 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sat, 10 Jun 2017 10:22:16 -0400 Subject: [PATCH 047/276] modifying Util class --- .../solr/tests/nightlybenchmarks/Util.java | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 816be8eb14a0..7e1ce73e11d8 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -679,7 +679,6 @@ public static void init(String[] args) { try { argM = Util.getArgs(args); - Util.getPropertyValues(); if (argM.containsKey("-RegisterLatestCommit")) { @@ -695,6 +694,12 @@ public static void init(String[] args) { Util.postMessage("** SolrNightlyBenchmarks Commit Registry Updater [COMPLETE] now EXIT...", MessageType.WHITE_TEXT, false); System.exit(0); + + } + + if (argM.containsKey("-RunSilently")) { + Util.postMessage("** Running silently since -RunSilently parameter is set ...", MessageType.BLUE_TEXT, false); + Util.SILENT = true; } Util.checkWebAppFiles(); @@ -703,21 +708,6 @@ public static void init(String[] args) { Util.setAliveFlag(); - String commitID = ""; - if (argM.containsKey("-commitID")) { - commitID = argM.get("-commitID"); - } else { - commitID = Util.getLatestCommitID(Util.LUCENE_SOLR_REPOSITORY_URL); - Util.postMessage("The latest commit ID is: " + commitID, MessageType.RED_TEXT, false); - } - - if (argM.containsKey("-RunSilently")) { - Util.postMessage("** Running silently since -RunSilently is set ...", MessageType.BLUE_TEXT, false); - Util.SILENT = true; - } - - Util.COMMIT_ID = commitID; - Util.getSystemEnvironmentInformation(); if (!BenchmarkAppConnector.isRunningFolderEmpty()) { @@ -740,7 +730,7 @@ public static void init(String[] args) { } Util.createIsRunningFile(); - + if (argM.containsKey("-ProcessCommitsFromQueue")) { Util.postMessage("** Initiating processing from commit queueu ...", MessageType.BLUE_TEXT, false); @@ -764,8 +754,21 @@ public static void init(String[] args) { } Util.postMessage("** Processing from commit queue [COMPLETE] ...", MessageType.BLUE_TEXT, false); - } - + } else if (argM.containsKey("-ProcessLatestCommit")) { + + Util.COMMIT_ID = Util.getLatestCommitID(Util.LUCENE_SOLR_REPOSITORY_URL); + Util.postMessage("The latest commit ID is: " + Util.COMMIT_ID, MessageType.YELLOW_TEXT, false); + + TestPlans.execute(Util.COMMIT_ID); + BenchmarkAppConnector.publishDataForWebApp(); + } else if (argM.containsKey("-ProcessWithcommitID")) { + + Util.COMMIT_ID = argM.get("-ProcessWithcommitID"); + + TestPlans.execute(Util.COMMIT_ID); + BenchmarkAppConnector.publishDataForWebApp(); + } + } catch (Exception e) { e.printStackTrace(); From ce3165f18d40a38e11534f46bd98ca97116b591b Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sat, 10 Jun 2017 23:24:43 -0400 Subject: [PATCH 048/276] AND-OR numeric queries --- .../NumericQueryBenchmarkCloud.html | 2 +- .../NumericQueryBenchmarkStandalone.html | 2 +- .../BenchmarkAppConnector.java | 69 ++++++++++++++++++- .../BenchmarkReportData.java | 9 ++- .../tests/nightlybenchmarks/TestPlans.java | 12 ++-- .../solr/tests/nightlybenchmarks/Tests.java | 13 ++++ .../solr/tests/nightlybenchmarks/Util.java | 6 +- 7 files changed, 98 insertions(+), 15 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index 5d51360afa19..e137abd7426a 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -215,7 +215,7 @@

    g2 = new Dygraph(document.getElementById("graphdiv2"), "data/numeric_query_benchmark_cloud.csv", { - labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F','#00FFFF'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html index 9797e044af65..700d2d409ef6 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html @@ -215,7 +215,7 @@ g2 = new Dygraph(document.getElementById("graphdiv2"), "data/numeric_query_benchmark_standalone.csv", { - labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, false, false, true, false, false, true, false, false, true, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], + labelsDiv: document.getElementById('pointData'), visibility: [false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F','#00FFFF'], highlightCallback: function (e, x, pts, row) { commitID = fileData[(row + 1)].split(",")[2].trim(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java index adfb19460a31..23f0fd8bc089 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkAppConnector.java @@ -227,7 +227,7 @@ public static void writeToWebAppDataFile(String fileName, String data, boolean c "Date, Test_ID, CommitID, Throughput (2 Threads), Throughput (4 Threads), Throughput (6 Threads), Throughput (8 Threads), Throughput (10 Threads) \n"); } else if (type == FileType.NUMERIC_QUERY_CLOUD || type == FileType.NUMERIC_QUERY_STANDALONE) { fw.write( - "Date, Test_ID, CommitID, QPS(Term), QTime-Min(Term), QTime-Max(Term), QPS(Range), QTime-Min(Range), QTime-Max(Range), QPS(Less Than), QTime-Min(Less Than), QTime-Max(Less Than), QPS(Greater Than), QTime-Min(Greater Than), QTime-Max(Greater Than)\n"); + "Date, Test_ID, CommitID, QPS(Term), QTime-Min(Term), QTime-Max(Term), QTime-75th-Percentile(Term), QTime-95th-Percentile(Term), QTime-99th-Percentile(Term), QTime-99.9th-Percentile(Term), QPS(Range), QTime-Min(Range), QTime-Max(Range), QTime-75th-Percentile(Range), QTime-95th-Percentile(Range), QTime-99th-Percentile(Range), QTime-99.9th-Percentile(Range), QPS(Less Than), QTime-Min(Less Than), QTime-Max(Less Than), QTime-75th-Percentile(Less Than), QTime-95th-Percentile(Less Than), QTime-99th-Percentile(Less Than), QTime-99.9th-Percentile(Less Than), QPS(Greater Than), QTime-Min(Greater Than), QTime-Max(Greater Than), QTime-75th-Percentile(Greater Than), QTime-95th-Percentile(Greater Than), QTime-99th-Percentile(Greater Than), QTime-99.9th-Percentile(Greater Than), QPS(AND), QTime-Min(AND), QTime-Max(AND), QTime-75th-Percentile(And), QTime-95th-Percentile(And), QTime-99th-Percentile(And), QTime-99.9th-Percentile(And), QPS(OR), QTime-Min(OR), QTime-Max(OR), QTime-75th-Percentile(OR), QTime-95th-Percentile(OR), QTime-99th-Percentile(OR), QTime-99.9th-Percentile(OR)\n"); } } @@ -344,15 +344,47 @@ public static void publishDataForWebApp() { + BenchmarkReportData.numericQueryTNQMetricC.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryTNQMetricC.get("MinQTime") + ", " + BenchmarkReportData.numericQueryTNQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryTNQMetricC.get("99.9thQtime") + ", " + BenchmarkReportData.numericQueryRNQMetricC.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryRNQMetricC.get("MinQTime") + ", " + BenchmarkReportData.numericQueryRNQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryRNQMetricC.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryRNQMetricC.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryRNQMetricC.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryRNQMetricC.get("99.9thQtime") + ", " + BenchmarkReportData.numericQueryLNQMetricC.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryLNQMetricC.get("MinQTime") + ", " + BenchmarkReportData.numericQueryLNQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryLNQMetricC.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryLNQMetricC.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryLNQMetricC.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryLNQMetricC.get("99.9thQtime") + ", " + BenchmarkReportData.numericQueryGNQMetricC.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryGNQMetricC.get("MinQTime") + ", " - + BenchmarkReportData.numericQueryGNQMetricC.get("MaxQTime"), + + BenchmarkReportData.numericQueryGNQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryGNQMetricC.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryGNQMetricC.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryGNQMetricC.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryGNQMetricC.get("99.9thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricC.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryANQMetricC.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryANQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryANQMetricC.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricC.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricC.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricC.get("99.9thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricC.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryONQMetricC.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryONQMetricC.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryONQMetricC.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricC.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricC.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricC.get("99.9thQtime"), + + false, FileType.NUMERIC_QUERY_CLOUD); } @@ -363,15 +395,46 @@ public static void publishDataForWebApp() { + BenchmarkReportData.numericQueryTNQMetricS.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryTNQMetricS.get("MinQTime") + ", " + BenchmarkReportData.numericQueryTNQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryTNQMetricS.get("99.9thQtime") + ", " + BenchmarkReportData.numericQueryRNQMetricS.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryRNQMetricS.get("MinQTime") + ", " + BenchmarkReportData.numericQueryRNQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryRNQMetricS.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryRNQMetricS.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryRNQMetricS.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryRNQMetricS.get("99.9thQtime") + ", " + BenchmarkReportData.numericQueryLNQMetricS.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryLNQMetricS.get("MinQTime") + ", " + BenchmarkReportData.numericQueryLNQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryLNQMetricS.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryLNQMetricS.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryLNQMetricS.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryLNQMetricS.get("99.9thQtime") + ", " + BenchmarkReportData.numericQueryGNQMetricS.get("QueriesPerSecond") + ", " + BenchmarkReportData.numericQueryGNQMetricS.get("MinQTime") + ", " - + BenchmarkReportData.numericQueryGNQMetricS.get("MaxQTime"), + + BenchmarkReportData.numericQueryGNQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryGNQMetricS.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryGNQMetricS.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryGNQMetricS.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryGNQMetricS.get("99.9thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricS.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryANQMetricS.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryANQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryANQMetricS.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricS.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricS.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryANQMetricS.get("99.9thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricS.get("QueriesPerSecond") + ", " + + BenchmarkReportData.numericQueryONQMetricS.get("MinQTime") + ", " + + BenchmarkReportData.numericQueryONQMetricS.get("MaxQTime") + ", " + + BenchmarkReportData.numericQueryONQMetricS.get("75thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricS.get("95thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricS.get("99thQtime") + ", " + + BenchmarkReportData.numericQueryONQMetricS.get("99.9thQtime"), + false, FileType.NUMERIC_QUERY_STANDALONE); } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java index 1a5fa470e1f0..cf1d971b4581 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/BenchmarkReportData.java @@ -43,12 +43,15 @@ public class BenchmarkReportData { public static Map numericQueryRNQMetricC; public static Map numericQueryLNQMetricC; public static Map numericQueryGNQMetricC; + public static Map numericQueryANQMetricC; + public static Map numericQueryONQMetricC; public static Map numericQueryTNQMetricS; public static Map numericQueryRNQMetricS; public static Map numericQueryLNQMetricS; public static Map numericQueryGNQMetricS; - + public static Map numericQueryANQMetricS; + public static Map numericQueryONQMetricS; public static void reset() { @@ -74,11 +77,15 @@ public static void reset() { numericQueryRNQMetricC = null; numericQueryLNQMetricC = null; numericQueryGNQMetricC = null; + numericQueryANQMetricC = null; + numericQueryONQMetricC = null; numericQueryTNQMetricS = null; numericQueryRNQMetricS = null; numericQueryLNQMetricS = null; numericQueryGNQMetricS = null; + numericQueryANQMetricS = null; + numericQueryONQMetricS = null; } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java index 983ebafe131e..55acc30a1f2f 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java @@ -27,19 +27,19 @@ public static void execute(String commitID) throws IOException, InterruptedExcep Util.COMMIT_ID = commitID; - Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); + //Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); - Tests.createCollectionTestStandalone(Util.COMMIT_ID); + //Tests.createCollectionTestStandalone(Util.COMMIT_ID); - Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); + //Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); Tests.runNumericQueryTestsStandalone(); - Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); + //Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); - Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); + //Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); - Tests.runNumericTestsCloud(); + //Tests.runNumericTestsCloud(); Util.postMessage("** Executing the benchmark test plan [COMPLETE]...", MessageType.BLUE_TEXT, false); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index fc5b5041bea8..8e31d375dfcd 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -277,6 +277,13 @@ public static void runNumericTestsCloud() throws IOException, InterruptedExcepti BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), Tests.cloud.collectionName); + BenchmarkReportData.numericQueryANQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.AND_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + BenchmarkReportData.numericQueryONQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.OR_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + Tests.shutDownCloud(); } @@ -298,6 +305,12 @@ public static void runNumericQueryTestsStandalone() throws IOException, Interrup BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); + BenchmarkReportData.numericQueryANQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.AND_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + BenchmarkReportData.numericQueryONQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.OR_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); Tests.shutDownStandalone(); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java index 7e1ce73e11d8..703c13708a3b 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Util.java @@ -761,10 +761,10 @@ public static void init(String[] args) { TestPlans.execute(Util.COMMIT_ID); BenchmarkAppConnector.publishDataForWebApp(); - } else if (argM.containsKey("-ProcessWithcommitID")) { + } else if (argM.containsKey("-ProcessWithCommitID")) { - Util.COMMIT_ID = argM.get("-ProcessWithcommitID"); - + Util.COMMIT_ID = argM.get("-ProcessWithCommitID"); + Util.postMessage("** Executing benchmarks with commit: " + Util.COMMIT_ID, MessageType.BLUE_TEXT, false); TestPlans.execute(Util.COMMIT_ID); BenchmarkAppConnector.publishDataForWebApp(); } From d1f1ac75938c9d240cc21d38af26c7315ad1d65c Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 11 Jun 2017 03:53:50 -0400 Subject: [PATCH 049/276] CRITICAL CPU HEAP Grap Overlap bugs fixed batch ... --- .../CreateCollectionBenchmarkCloud.html | 3 +- .../CreateCollectionBenchmarkStandalone.html | 3 +- .../WebAppSource/IndexingBenchmarkCloud.html | 3 +- .../IndexingBenchmarkCloudConcurrent.html | 2 +- .../IndexingBenchmarkStandalone.html | 2 +- .../IndexingThroughputBenchmarkCloud.html | 10 +- ...ingThroughputBenchmarkCloudConcurrent.html | 51 ++++- ...IndexingThroughputBenchmarkStandalone.html | 11 +- ...roughputBenchmarkStandaloneConcurrent.html | 50 ++++- .../NumericQueryBenchmarkCloud.html | 55 ++++- .../NumericQueryBenchmarkStandalone.html | 63 +++++- .../nightlybenchmarks/MetricCollector.java | 2 +- .../nightlybenchmarks/SolrIndexingClient.java | 12 +- .../tests/nightlybenchmarks/TestPlans.java | 12 +- .../solr/tests/nightlybenchmarks/Tests.java | 193 +++++++++++++----- 15 files changed, 368 insertions(+), 104 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html index 0c7c90550f21..9408fb87d673 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -235,7 +235,8 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + + pointClickCallback: function(e, p) { $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html index c5fb8775feeb..96086a6351d8 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -236,7 +236,8 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + + pointClickCallback: function(e, p) { $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html index 98c19937eaf9..4d993f22724e 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -235,7 +235,8 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + + pointClickCallback: function(e, p) { $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html index 23e45076fc36..ab90acc4c084 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -235,7 +235,7 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + pointClickCallback: function(e, p) { $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html index 479e6cb7ef8e..b5132cdfebaf 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html @@ -235,7 +235,7 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + pointClickCallback: function(e, p) { $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html index 75fa1bcc403b..3a8486c29d84 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -235,14 +235,14 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + pointClickCallback: function(e, p) { $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -263,7 +263,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -288,7 +288,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_REGULAR_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html index 1466f1f1fbc1..9a56fdb9ef63 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -185,6 +185,7 @@ var fileData; var commitID; var testID; + var point; $(document).ready(function () { @@ -235,15 +236,31 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { - + pointClickCallback: function(e, p) { + point = p.name; $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); - }, 250); + + if (p.name.includes("Throughput (10 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (8 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (6 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (4 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (2 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } + + }, 250); } @@ -263,7 +280,17 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + if (point.includes("Throughput (10 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (8 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (6 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (4 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (2 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } } @@ -288,7 +315,17 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + if (point.includes("Throughput (10 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (8 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (6 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (4 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (2 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html index 7aaa3c723e88..1814aacc7adf 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -235,14 +235,15 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + + pointClickCallback: function(e, p) { $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); }, 250); } @@ -263,7 +264,7 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); } @@ -288,7 +289,7 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_SERIAL_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html index f48fd414e0ba..27d069038d91 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html @@ -185,6 +185,7 @@ var fileData; var commitID; var testID; + var point; $(document).ready(function () { @@ -235,15 +236,32 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + pointClickCallback: function(e, p) { + point = p.name; $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); - }, 250); + + if (p.name.includes("Throughput (10 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (8 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (6 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (4 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("Throughput (2 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } + + }, 250); } @@ -263,7 +281,17 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + if (point.includes("Throughput (10 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (8 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (6 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (4 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("Throughput (2 Threads)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } } @@ -288,7 +316,17 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + if (point.includes("Throughput (10 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_10_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (8 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_8_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (6 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_6_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (4 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_4_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("Throughput (2 Threads)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_2_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index e137abd7426a..c91e9a87f820 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -185,6 +185,7 @@ var fileData; var commitID; var testID; + var point; $(document).ready(function () { @@ -235,14 +236,34 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { + pointClickCallback: function(e, p) { + point = p.name; $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + + if (p.name.includes("QPS(Term)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_TERM_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_TERM_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(Range)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_RANGE_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_RANGE_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(Less Than)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_LT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_LT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(Greater Than)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_GT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_GT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(AND)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_AND_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_AND_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(OR)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_OR_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_OR_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } + }, 250); } @@ -263,7 +284,19 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + if (point.includes("QPS(Term)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_TERM_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(Range)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_RANGE_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(Less Than)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_LT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(Greater Than)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_GT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(AND)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_AND_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(OR)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_OR_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } } @@ -288,7 +321,19 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + if (point.includes("QPS(Term)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_TERM_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(Range)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_RANGE_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(Less Than)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_LT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(Greater Than)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_GT_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(AND)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_AND_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(OR)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_OR_NUMERIC_QUERY_CLOUD_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } } diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html index 700d2d409ef6..7065e63d22e6 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkStandalone.html @@ -185,6 +185,7 @@ var fileData; var commitID; var testID; + var point; $(document).ready(function () { @@ -235,14 +236,40 @@ document.getElementById("welcomeMessage").innerHTML = ""; }, - clickCallback: function (e, x, pts) { - + + pointClickCallback: function(e, p) { + point = p.name; $('#memProfile').modal(); document.getElementById('memProfileFileChangeListLink').setAttribute('href', "https://git-wip-us.apache.org/repos/asf?p=lucene-solr.git;h=" + commitID); setTimeout(function () { - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + + if (p.name.includes("QPS(Term)")) { + + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_TERM_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_TERM_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(Range)")) { + + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_RANGE_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_RANGE_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(Less Than)")) { + + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_LT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_LT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(Greater Than)")) { + + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_GT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_GT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(AND)")) { + + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_AND_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_AND_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (p.name.includes("QPS(OR)")) { + + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_OR_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_OR_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } + }, 250); } @@ -263,7 +290,19 @@ $("#HeapMemoryUsageTab").addClass("active"); - g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + if (point.includes("QPS(Term)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_TERM_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(Range)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_RANGE_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(Less Than)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_LT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(Greater Than)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_GT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(AND)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_AND_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } else if (point.includes("QPS(OR)")) { + g3 = new Dygraph(document.getElementById("memProfileGraph"), "data/" + testID + "_" + commitID + "_MEM_ESTIMATION_OR_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('memProfileStats') }); + } } @@ -288,7 +327,19 @@ $("#ProcessCPULoadTab").addClass("active"); - g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_CLOUD_INDEXING_CONCURRENT_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + if (point.includes("QPS(Term)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_TERM_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(Range)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_RANGE_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(Less Than)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_LT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(Greater Than)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_GT_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(AND)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_AND_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } else if (point.includes("QPS(OR)")) { + g4 = new Dygraph(document.getElementById("cpuProfileGraph"), "data/" + testID + "_" + commitID + "_CPU_ESTIMATION_OR_NUMERIC_QUERY_STANDALONE_dump.csv", { visibility: [false, true], colors: ['#6B8E23','#4B0082','#FF0000','#DA70D6','#CD853F'], labelsDiv: document.getElementById('cpuProfileStats') }); + } } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java index ffd5579a4da3..f7affc65fe3a 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/MetricCollector.java @@ -28,7 +28,7 @@ enum TestType { - STANDALONE_CREATE_COLLECTION, STANDALONE_INDEXING, CLOUD_CREATE_COLLECTION, CLOUD_INDEXING_REGULAR, CLOUD_INDEXING_CONCURRENT + STANDALONE_CREATE_COLLECTION, STANDALONE_INDEXING_THROUGHPUT_SERIAL, STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_2, STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_4, STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_6, STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_8, STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_10, CLOUD_CREATE_COLLECTION, CLOUD_INDEXING_THROUGHPUT_SERIAL, CLOUD_INDEXING_THROUGHPUT_CONCURRENT_2, CLOUD_INDEXING_THROUGHPUT_CONCURRENT_4, CLOUD_INDEXING_THROUGHPUT_CONCURRENT_6, CLOUD_INDEXING_THROUGHPUT_CONCURRENT_8, CLOUD_INDEXING_THROUGHPUT_CONCURRENT_10 ,TERM_NUMERIC_QUERY_CLOUD, TERM_NUMERIC_QUERY_STANDALONE, RANGE_NUMERIC_QUERY_CLOUD, RANGE_NUMERIC_QUERY_STANDALONE, GT_NUMERIC_QUERY_CLOUD, GT_NUMERIC_QUERY_STANDALONE, LT_NUMERIC_QUERY_CLOUD, LT_NUMERIC_QUERY_STANDALONE, AND_NUMERIC_QUERY_CLOUD, AND_NUMERIC_QUERY_STANDALONE, OR_NUMERIC_QUERY_CLOUD, OR_NUMERIC_QUERY_STANDALONE } diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java index bc66210599ea..34c5c6e72b55 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/SolrIndexingClient.java @@ -62,7 +62,7 @@ public SolrIndexingClient(String host, String port, String collection, String co } @SuppressWarnings("deprecation") - public Map indexAmazonFoodData(int numDocuments, String urlString) { + public Map indexAmazonFoodData(int numDocuments, String urlString, boolean captureMetrics) { documentCount = numDocuments; @@ -77,7 +77,7 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin String cvsSplitBy = ","; int value; - Thread thread = new Thread(new MetricCollector(this.commitId, TestType.STANDALONE_INDEXING, this.port)); + Thread thread = new Thread(new MetricCollector(this.commitId, TestType.STANDALONE_INDEXING_THROUGHPUT_SERIAL, this.port)); thread.start(); try (BufferedReader br = new BufferedReader(new FileReader(amazonFoodDataLocation))) { @@ -148,7 +148,7 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin @SuppressWarnings("deprecation") public Map indexAmazonFoodData(int numDocuments, String urlString, String zookeeperIp, - String zookeeperPort, String collectionName) { + String zookeeperPort, String collectionName, boolean captureMetrics) { documentCount = numDocuments; Util.postMessage("** Indexing documents (Amazon Food Reviews) ...", MessageType.WHITE_TEXT, false); @@ -165,7 +165,7 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin String cvsSplitBy = ","; int value; - Thread thread = new Thread(new MetricCollector(this.commitId, TestType.CLOUD_INDEXING_REGULAR, this.port)); + Thread thread = new Thread(new MetricCollector(this.commitId, TestType.CLOUD_INDEXING_THROUGHPUT_SERIAL, this.port)); thread.start(); try (BufferedReader br = new BufferedReader(new FileReader(amazonFoodDataLocation))) { @@ -235,7 +235,7 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin } @SuppressWarnings("deprecation") - public Map indexAmazonFoodData(int numDocuments, String urlString, String collectionName, int queueSize, int threadCount) { + public Map indexAmazonFoodData(int numDocuments, String urlString, String collectionName, int queueSize, int threadCount, TestType type, boolean captureMetrics) { documentCount = numDocuments; @@ -250,7 +250,7 @@ public Map indexAmazonFoodData(int numDocuments, String urlStrin String cvsSplitBy = ","; int value; - Thread thread = new Thread(new MetricCollector(this.commitId, TestType.CLOUD_INDEXING_CONCURRENT, this.port)); + Thread thread = new Thread(new MetricCollector(this.commitId, type, this.port)); thread.start(); try (BufferedReader br = new BufferedReader(new FileReader(amazonFoodDataLocation))) { diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java index 55acc30a1f2f..983ebafe131e 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/TestPlans.java @@ -27,19 +27,19 @@ public static void execute(String commitID) throws IOException, InterruptedExcep Util.COMMIT_ID = commitID; - //Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); + Tests.indexingTestsStandalone(Util.COMMIT_ID, 10000); - //Tests.createCollectionTestStandalone(Util.COMMIT_ID); + Tests.createCollectionTestStandalone(Util.COMMIT_ID); - //Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); + Tests.indexingTestsStandaloneConcurrent(Util.COMMIT_ID, 10000); Tests.runNumericQueryTestsStandalone(); - //Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); + Tests.indexingTestsCloudSerial(Util.COMMIT_ID, 10000); - //Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); + Tests.indexingTestsCloudConcurrent(Util.COMMIT_ID, 10000); - //Tests.runNumericTestsCloud(); + Tests.runNumericTestsCloud(); Util.postMessage("** Executing the benchmark test plan [COMPLETE]...", MessageType.BLUE_TEXT, false); diff --git a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java index 8e31d375dfcd..bf65f160633e 100644 --- a/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java +++ b/dev-tools/SolrNightBenchmarks/src/main/java/org/apache/solr/tests/nightlybenchmarks/Tests.java @@ -73,7 +73,7 @@ public static boolean indexingTestsStandalone(String commitID, int numDocuments) SolrIndexingClient client = new SolrIndexingClient("localhost", node.port, node.collectionName, commitID); BenchmarkReportData.metricMapStandalone = client.indexAmazonFoodData(numDocuments, - node.getBaseUrl() + node.collectionName); + node.getBaseUrl() + node.collectionName, true); node.doAction(SolrNodeAction.NODE_STOP); node.cleanup(); @@ -95,15 +95,15 @@ public static boolean indexingTestsStandaloneConcurrent(String commitID, int num BenchmarkReportData.metricMapStandaloneConcurrent2 = client.indexAmazonFoodData(numDocuments, - node.getBaseUrlC(), node.collectionName, 10000, 2); + node.getBaseUrlC(), node.collectionName, 10000, 2, TestType.STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_2, true); BenchmarkReportData.metricMapStandaloneConcurrent4 = client.indexAmazonFoodData(numDocuments, - node.getBaseUrlC(), node.collectionName, 10000, 4); + node.getBaseUrlC(), node.collectionName, 10000, 4, TestType.STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_4, true); BenchmarkReportData.metricMapStandaloneConcurrent6 = client.indexAmazonFoodData(numDocuments, - node.getBaseUrlC(), node.collectionName, 10000, 6); + node.getBaseUrlC(), node.collectionName, 10000, 6, TestType.STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_6, true); BenchmarkReportData.metricMapStandaloneConcurrent8 = client.indexAmazonFoodData(numDocuments, - node.getBaseUrlC(), node.collectionName, 10000, 8); + node.getBaseUrlC(), node.collectionName, 10000, 8, TestType.STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_8, true); BenchmarkReportData.metricMapStandaloneConcurrent10 = client.indexAmazonFoodData(numDocuments, - node.getBaseUrlC(), node.collectionName, 10000, 10); + node.getBaseUrlC(), node.collectionName, 10000, 10, TestType.STANDALONE_INDEXING_THROUGHPUT_CONCURRENT_10, true); node.doAction(SolrNodeAction.NODE_STOP); @@ -126,7 +126,7 @@ public static boolean indexingTestsCloudSerial(String commitID, int numDocuments SolrIndexingClient cloudClient = new SolrIndexingClient("localhost", cloud.port, cloud.collectionName, commitID); BenchmarkReportData.metricMapCloudSerial = cloudClient.indexAmazonFoodData(numDocuments, cloud.getuRL(), - cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName); + cloud.zookeeperIp, cloud.zookeeperPort, cloud.collectionName, true); cloud.shutdown(); BenchmarkReportData.returnCloudCreateCollectionMap = cloud.returnMapCreateCollection; @@ -148,15 +148,15 @@ public static boolean indexingTestsCloudConcurrent(String commitID, int numDocum commitID); BenchmarkReportData.metricMapCloudConcurrent2 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.collectionName, 10000, 2); + cloud.getuRL(), cloud.collectionName, 10000, 2, TestType.CLOUD_INDEXING_THROUGHPUT_CONCURRENT_2, true); BenchmarkReportData.metricMapCloudConcurrent4 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.collectionName, 10000, 4); + cloud.getuRL(), cloud.collectionName, 10000, 4, TestType.CLOUD_INDEXING_THROUGHPUT_CONCURRENT_4, true); BenchmarkReportData.metricMapCloudConcurrent6 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.collectionName, 10000, 6); + cloud.getuRL(), cloud.collectionName, 10000, 6, TestType.CLOUD_INDEXING_THROUGHPUT_CONCURRENT_6, true); BenchmarkReportData.metricMapCloudConcurrent8 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.collectionName, 10000, 8); + cloud.getuRL(), cloud.collectionName, 10000, 8, TestType.CLOUD_INDEXING_THROUGHPUT_CONCURRENT_8, true); BenchmarkReportData.metricMapCloudConcurrent10 = cloudClient.indexAmazonFoodData(numDocuments, - cloud.getuRL(), cloud.collectionName, 10000, 10); + cloud.getuRL(), cloud.collectionName, 10000, 10, TestType.CLOUD_INDEXING_THROUGHPUT_CONCURRENT_10, true); cloud.shutdown(); @@ -226,18 +226,19 @@ private static Map numericQueryTests(String commitID, QueryType return null; } - private static void setUpCloudForFeatureTests(String commitID, int documentCount, int solrNodes, String shards, + private static String setUpCloudForFeatureTests(String commitID, int documentCount, int solrNodes, String shards, String replicas, int numDocuments) { SolrCloud cloud = new SolrCloud(solrNodes, shards, replicas, commitID, null, "localhost", true); Tests.cloud = cloud; SolrIndexingClient cloudClient = new SolrIndexingClient("localhost", cloud.port, cloud.collectionName, commitID); - cloudClient.indexAmazonFoodData(documentCount, cloud.getuRL(), cloud.collectionName, numDocuments, 10); - + cloudClient.indexAmazonFoodData(documentCount, cloud.getuRL(), cloud.collectionName, numDocuments, 10, TestType.CLOUD_INDEXING_THROUGHPUT_CONCURRENT_10, false); + + return cloud.port; } - private static void setUpStandaloneNodeForFeatureTests(String commitID, int numDocuments) { + private static String setUpStandaloneNodeForFeatureTests(String commitID, int numDocuments) { try { SolrNode snode = new SolrNode(commitID, "", "", false); @@ -245,12 +246,17 @@ private static void setUpStandaloneNodeForFeatureTests(String commitID, int numD snode.createCollection("Core-" + UUID.randomUUID(),"Collection-" + UUID.randomUUID()); SolrIndexingClient client = new SolrIndexingClient("localhost", snode.port, snode.collectionName, commitID); - client.indexAmazonFoodData(numDocuments, snode.getBaseUrl() + snode.collectionName); + client.indexAmazonFoodData(numDocuments, snode.getBaseUrl() + snode.collectionName, false); node = snode; + + return node.port; + } catch(Exception e) { e.printStackTrace(); } + + return "0"; } private static void shutDownCloud() throws IOException, InterruptedException { @@ -262,56 +268,139 @@ private static void shutDownStandalone() throws IOException, InterruptedExceptio node.cleanup(); } + @SuppressWarnings("deprecation") public static void runNumericTestsCloud() throws IOException, InterruptedException { - Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2", 10000); - BenchmarkReportData.numericQueryTNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryRNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryLNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryANQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.AND_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); - BenchmarkReportData.numericQueryONQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.OR_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), - Tests.cloud.collectionName); + String port = Tests.setUpCloudForFeatureTests(Util.COMMIT_ID, 50000, 1, "2", "2", 10000); + + Thread numericQueryTNQMetricC = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.TERM_NUMERIC_QUERY_CLOUD, port)); + numericQueryTNQMetricC.start(); + + BenchmarkReportData.numericQueryTNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.TERM_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + + numericQueryTNQMetricC.stop(); + + Thread numericQueryRNQMetricC = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.RANGE_NUMERIC_QUERY_CLOUD, port)); + numericQueryRNQMetricC.start(); + + BenchmarkReportData.numericQueryRNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.RANGE_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + + numericQueryRNQMetricC.stop(); + + Thread numericQueryLNQMetricC = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.LT_NUMERIC_QUERY_CLOUD, port)); + numericQueryLNQMetricC.start(); + + + BenchmarkReportData.numericQueryLNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.LESS_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + + + numericQueryLNQMetricC.stop(); + + Thread numericQueryGNQMetricC = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.GT_NUMERIC_QUERY_CLOUD, port)); + numericQueryGNQMetricC.start(); + + + BenchmarkReportData.numericQueryGNQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + + numericQueryGNQMetricC.stop(); + + Thread numericQueryANQMetricC = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.AND_NUMERIC_QUERY_CLOUD, port)); + numericQueryANQMetricC.start(); + + + BenchmarkReportData.numericQueryANQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.AND_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + + numericQueryANQMetricC.stop(); + + Thread numericQueryONQMetricC = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.OR_NUMERIC_QUERY_CLOUD, port)); + numericQueryONQMetricC.start(); + + + BenchmarkReportData.numericQueryONQMetricC = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.OR_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.CLOUD, Tests.cloud.getBaseURL(), + Tests.cloud.collectionName); + + numericQueryONQMetricC.stop(); + Tests.shutDownCloud(); } + @SuppressWarnings("deprecation") public static void runNumericQueryTestsStandalone() throws IOException, InterruptedException { - Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); + String port = Tests.setUpStandaloneNodeForFeatureTests(Util.COMMIT_ID, 10000); - BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.TERM_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - BenchmarkReportData.numericQueryRNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.RANGE_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - BenchmarkReportData.numericQueryLNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.LESS_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); - BenchmarkReportData.numericQueryANQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, - QueryType.AND_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), - Tests.node.collectionName); + Thread numericQueryTNQMetricS = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.TERM_NUMERIC_QUERY_STANDALONE, port)); + numericQueryTNQMetricS.start(); + + BenchmarkReportData.numericQueryTNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.TERM_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + + numericQueryTNQMetricS.stop(); + + Thread numericQueryRNQMetricS = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.RANGE_NUMERIC_QUERY_STANDALONE, port)); + numericQueryRNQMetricS.start(); + + BenchmarkReportData.numericQueryRNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.RANGE_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + + numericQueryRNQMetricS.stop(); + + Thread numericQueryLNQMetricS = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.LT_NUMERIC_QUERY_STANDALONE, port)); + numericQueryLNQMetricS.start(); + + + BenchmarkReportData.numericQueryLNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.LESS_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + + numericQueryLNQMetricS.stop(); + + + Thread numericQueryGNQMetricS = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.GT_NUMERIC_QUERY_STANDALONE, port)); + numericQueryGNQMetricS.start(); + + + BenchmarkReportData.numericQueryGNQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.GREATER_THAN_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + + numericQueryGNQMetricS.stop(); + + Thread numericQueryANQMetricS = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.AND_NUMERIC_QUERY_STANDALONE, port)); + numericQueryANQMetricS.start(); + + BenchmarkReportData.numericQueryANQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, + QueryType.AND_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), + Tests.node.collectionName); + + numericQueryANQMetricS.stop(); + + Thread numericQueryONQMetricS = new Thread(new MetricCollector(Util.COMMIT_ID, TestType.OR_NUMERIC_QUERY_STANDALONE, port)); + numericQueryONQMetricS.start(); + BenchmarkReportData.numericQueryONQMetricS = Tests.numericQueryTests(Util.COMMIT_ID, QueryType.OR_NUMERIC_QUERY, queryThreadCount, 180, 120, ConfigurationType.STANDALONE, Tests.node.getBaseUrl(), Tests.node.collectionName); + numericQueryONQMetricS.stop(); + + Tests.shutDownStandalone(); } From 0c91cc85c93e4f56a30595283a73db400e46a762 Mon Sep 17 00:00:00 2001 From: Vivek Narang Date: Sun, 11 Jun 2017 06:59:32 -0400 Subject: [PATCH 050/276] Tab text change + First Commit: Qtime Percentile ... --- .../CreateCollectionBenchmarkCloud.html | 4 +- .../CreateCollectionBenchmarkStandalone.html | 4 +- .../WebAppSource/IndexingBenchmarkCloud.html | 4 +- .../IndexingBenchmarkCloudConcurrent.html | 4 +- .../IndexingBenchmarkStandalone.html | 4 +- .../IndexingThroughputBenchmarkCloud.html | 4 +- ...ingThroughputBenchmarkCloudConcurrent.html | 4 +- ...IndexingThroughputBenchmarkStandalone.html | 4 +- ...roughputBenchmarkStandaloneConcurrent.html | 4 +- .../NumericQueryBenchmarkCloud.html | 123 ++++++++++++++++-- .../NumericQueryBenchmarkStandalone.html | 122 +++++++++++++++-- 11 files changed, 247 insertions(+), 34 deletions(-) diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html index 9408fb87d673..87348b9fb471 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkCloud.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html index 96086a6351d8..996eacbf0ee0 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/CreateCollectionBenchmarkStandalone.html @@ -65,8 +65,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html index 4d993f22724e..2845eed3c1f6 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloud.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html index ab90acc4c084..302f9271a60a 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkCloudConcurrent.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html index b5132cdfebaf..d26ccb4c2455 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingBenchmarkStandalone.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html index 3a8486c29d84..c78a1a852543 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloud.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html index 9a56fdb9ef63..156b6df5c7d4 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkCloudConcurrent.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html index 1814aacc7adf..0640a5ca1d93 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandalone.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html index 27d069038d91..58c548deeaf2 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/IndexingThroughputBenchmarkStandaloneConcurrent.html @@ -64,8 +64,8 @@ diff --git a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html index c91e9a87f820..e2c909217a2f 100644 --- a/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html +++ b/dev-tools/SolrNightBenchmarks/WebAppSource/NumericQueryBenchmarkCloud.html @@ -64,8 +64,8 @@ @@ -114,9 +114,10 @@