vendredi 25 décembre 2020

Python Script for Running Hackerrank tests locally

I found this script for running Hackerrank tests locally. According to the instructions, I should "Just run it in the sample test cases folder that you downloaded from hackerrank."

I have not yet been able to get it to work. I'm not sure what arguments I should pass, and also whether I should unzip the test files first (the code uses rb mode so maybe the zipped ones?)

Can anyone please provide more detail about how to get this working?

# to use with a python3 tested on windows
import subprocess
import sys
cmd = [
    'python',
    sys.argv[1]
]
process = subprocess.Popen(
        cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        stdin=subprocess.PIPE, shell=True)

input = open(sys.argv[2], "rb").read()
out_file = open(sys.argv[3], "rb").read()
out, err = process.communicate(input)

if err:
    print(err.decode("utf-8"))

out = out[:-1]
if out == out_file:
    print("WIN")
print(out.decode("utf-8"))

load testing through wifi/lan + vpn

I really did not found answer on my question in the web. I am currently doing load tests for a web service, for example: how service will handle 15 threads in 1 seconds, for that I use Jmeter. I always get different average response times for 15 threads. When I'm in my company's inner network, I get wonderful results, but when I am at home, using lan/wifi + vpn to get access to that web services, I get horrible results. When I test it through vpn, web service can not handle 30 threads in 1 seconds, average response time is like 13 seconds, otherwise from company's network, average response time is 4-5 seconds. Also, that web service, would be also called from a system using vpn. My question is, what is correct result and correct way to test it. Test it from company's network, or though vpn?

How to mock or stub an external request, not necessarily an http one?

I want to mock or stub an external request. It’s not a simple HTTP request and there’s no direct access to an underlying library, nor information of how it’s implemented under the hood, therefore it should be treated as some external request that can be http, file, database. A simplified code is as follows:

def my_external_call
  Lib1::get_some_data()
end

I know what my_external_call() can return. How do I mock or stub it?

What is the time complexity of this for-loop case?

I'm trying to figure out what is the time complexity of the following for-loop case.

double n; //n > 0 and a real number

for(double i=1; i<n; i*=(1+(1/n))){//some O(1) statements};

I argued with my professor that the time complexity is still O(log n). But he says it's not so I'm confused. In for(double i=1; i<n; i*=2){//some O(1) statements};, the time complexity is indeed O(log n). Why isn't the former the same? Please help.

Difference between Laravel testing method assertRedirect($uri) and assertLocation($uri)?

I was reading Laravel document HTTP tests and a question occurred. I can't tell the difference between assertLocation($uri) and assertRedirect($uri), since both are for redirecting to specific uri.

Anyone could help would be so much appreciated.

jeudi 24 décembre 2020

How to check how many times a function has been called in a Golang test?

I'm working on a web server with an API which calls a function. This function does a heavy job and caches the result. I've designed it in a way that if there is no cache and multiple users call this API with the same parameters at the same time, the server call that function only once for the first request and all other requests wait for finishing the job and return response from the cache.

I've written a test for it in this way:


func TestConcurentRequests(t *testing.T) {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            // do the request
            wg.Done()
        }
    }
    wg.Wait()
}

I can check that my code works correctly by printing a value inside that heavy function and check the console to see if it appears only once, but I'm searching for a way to fail the test if this function has been called more times. Something like this:


if n := NumberOfCalls(MyHeavyFunction); n > 1 {
    t.Fatalf("Expected heavy function to run only once but called %d times", n)
}

Why Rust reset some variables after a loop?

I finished reading The Rust Programming Languange some time ago and I'm creating a simple http-server for the sake of teaching myself Rust.

In a function meant to parse a &[u8] and create a HttpRequest object, I noticed that a loop that should be parsing the headers is actually not updating some variables used to track the state of parsing:

pub fn parse_request(buffer: &[u8]) -> Result<HttpRequest, &'static str> {
    let (mut line, mut curr_req_reader_pos) = next_req_line(buffer, 0);

    let (method, path, version) = parse_method_path_and_version(&line)?;

    let (line, curr_req_reader_pos) = next_req_line(buffer, curr_req_reader_pos);
    //eprintln!("--- got next line: {}, {} ---", curr_req_reader_pos, String::from_utf8_lossy(line));
    let mut headers = vec![];
    let mut lel = 0;
    while line.len() > 0 {
        //eprintln!("LOOP");
        let header = parse_header(&line);
        eprintln!("--- parsed header: {} ---", String::from_utf8_lossy(line));
        headers.push(header);
        let (line, curr_req_reader_pos) = next_req_line(buffer, curr_req_reader_pos);
        //eprintln!("--- got next line: {}, {} ---", curr_req_reader_pos, String::from_utf8_lossy(line));
        let (line, curr_req_reader_pos) = next_req_line(buffer, curr_req_reader_pos);
        //eprintln!("--- got next line: {}, {} ---", curr_req_reader_pos, String::from_utf8_lossy(line));
        //eprintln!("LOOP");
        lel += 10;
        //break;
    }

    let (line, curr_req_reader_pos) = next_req_line(buffer, curr_req_reader_pos);
    //eprintln!("--- got next line: {}, {} ---", curr_req_reader_pos, String::from_utf8_lossy(line));
    //eprintln!("{}", lel);

    let has_body;
    match method.as_ref() {
        "POST" | "PUT" | "PATCH" => has_body = true,
        _ => has_body = true
    };

    let body;
    if has_body {
        let (line, curr_req_reader_pos) = next_req_line(buffer, curr_req_reader_pos);
        body = String::from_utf8_lossy(line).to_string();
    } else  {
        body = String::new();
    }

    Ok(HttpRequest {
        method,
        path,
        version,
        headers,
        has_body,
        body
    })
}

There's also tests for each method:

#[test]
fn test_next_req_line() {
    let req = "GET / HTTP/1.1\r\nContent-Length: 3\r\n\r\n\r\n\r\nlel".as_bytes();

    let (mut lel, mut pos) = next_req_line(req, 0);
    assert_eq!("GET / HTTP/1.1", String::from_utf8_lossy(lel));
    assert!(lel.len() > 0);
    assert_eq!(16, pos);

    let (lel, pos) = next_req_line(req, pos);
    assert_eq!("Content-Length: 3", String::from_utf8_lossy(lel));
    assert!(lel.len() > 0);
    assert_eq!(35, pos);

    let (lel, pos) = next_req_line(req, pos);
    assert_eq!("", String::from_utf8_lossy(lel));
    assert!(lel.len() == 0);
    assert_eq!(37, pos);

    let (lel, pos) = next_req_line(req, pos);
    assert_eq!("", String::from_utf8_lossy(lel));
    assert!(lel.len() == 0);

    let (lel, pos) = next_req_line(req, pos);
    assert_eq!("", String::from_utf8_lossy(lel));
    assert!(lel.len() == 0);

    let (lel, pos) = next_req_line(req, pos);
    assert_eq!("lel", String::from_utf8_lossy(lel));
    assert!(lel.len() == 3);
}

    #[test]
    fn test_parse_request() {
        let mut request = String::from("GET / HTTP/1.1\r\n");
        request.push_str("Content-Length: 3\r\n");
        request.push_str("\r\n");
        request.push_str("lel");
        let request = request.as_bytes();

        match parse_request(&request) {
            Ok(http_request) => {
                assert_eq!(http_request.method, "GET");
                assert_eq!(http_request.path, "/");
                assert_eq!(http_request.version, "HTTP/1.1");
            },
            Err(_) => {
                println!("Failed");
            }
        }
    }

The commented lines are just to show what's happening, and that's where I saw this output:


    Finished test [unoptimized + debuginfo] target(s) in 0.53s
     Running target/debug/deps/rweb-6bbc2a3130f7e3d9

running 4 tests
test http::testing::test_next_req_line ... ok
test http::testing::test_parse_header ... ok
test http::testing::test_parse_method_path_and_version ... ok
--- parsed method path version  ---
--- got next line: 35, Content-Length: 3 ---
LOOP
--- parsed header: Content-Length: 3 ---
--- got next line: 37,  ---
--- got next line: 39, lel ---
LOOP
--- got next line: 37,  ---
10
test http::testing::test_parse_request ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

It seems that the while loop is not re-assigning the line and curr_req_reader_pos variables, but for me it made perfect sense to expect that the loop would update these variables and parse every header. However, it works perfecly outside a loop, as anyone can see in the tests.

I can't figure out why this happens with my current undertanding of Rust, why does it happen?