drill icon indicating copy to clipboard operation
drill copied to clipboard

drill does not download the full body

Open bebehei opened this issue 1 year ago • 1 comments

I'm currently load-testing nginx with drill. It's always the same file, which is requested and always the same content delivered.

It came to my mind, that the logged $body_bytes_sent in the nginx access log vary from request to request. This should not be the case, since it's the same file.

I'm running the current master and build it with:

cargo run --release -- --benchmark example/benchmark.yml

# benchmark.yaml
---
base: 'https://domain'
iterations: 10
concurrency: 1
rampup: 0

plan:
  - name: Download 1MB
    request:
      url: /1m.bin

The file behind /1m.bin is 1 Megabyte of random data.

# nginx access log
# Executed: drill with benchmark.yml as refercenced above
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 229116 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 130812 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 196348 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 130812 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 147196 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 196348 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 147196 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 147196 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 163580 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:19 +0000] "GET /1m.bin HTTP/1.1" 200 147196 "-" "drill" "-"

# Executed: curl https://domain/1m.bin -O
172.17.0.1 - - [07/May/2023:19:10:30 +0000] "GET /1m.bin HTTP/2.0" 200 1048576 "-" "curl/7.86.0" "-"

# Adding `assign: memory` to the benchmark.yml and re-running it:
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"
172.17.0.1 - - [07/May/2023:19:10:33 +0000] "GET /1m.bin HTTP/1.1" 200 1048576 "-" "drill" "-"

As you can see, the body is only fully downloaded, if the body gets assigned. Obviously for some reasons, drill does behave different with the assign action.

I haven't been able to produce a working patch for drill yet, but the assign was my workaround.

What has to get patched, so that drill downloads the full file by default?

bebehei avatar May 07 '23 19:05 bebehei

So, I found a code fix for drill, but I'm not confident, this is working for every use-case in drill.

diff --git a/src/actions/request.rs b/src/actions/request.rs
index e81f427..2a2f1cd 100644
--- a/src/actions/request.rs
+++ b/src/actions/request.rs
@@ -293,17 +296,16 @@ impl Runnable for Request {
 
           context.insert("cookies".to_string(), json!(cookies));
         }
+        let mut headers = Map::new();
 
-        let data = if let Some(ref key) = self.assign {
-          let mut headers = Map::new();
-
-          response.headers().iter().for_each(|(header, value)| {
-            headers.insert(header.to_string(), json!(value.to_str().unwrap()));
-          });
+        response.headers().iter().for_each(|(header, value)| {
+          headers.insert(header.to_string(), json!(value.to_str().unwrap()));
+        });
+        let body_data = response.text().await.unwrap();
 
-          let data = response.text().await.unwrap();
+        let data = if let Some(ref key) = self.assign {
 
-          let body: Value = serde_json::from_str(&data).unwrap_or(serde_json::Value::Null);
+          let body: Value = serde_json::from_str(&body_data).unwrap_or(serde_json::Value::Null);
 
           let assigned = AssignedRequest {
             status,
@@ -315,7 +317,7 @@ impl Runnable for Request {
 
           context.insert(key.to_owned(), value);
 
-          Some(data)
+          Some(body_data)
         } else {
           None
         };

bebehei avatar May 07 '23 19:05 bebehei