-- luacheck: ignore ngx local skynet_tracker = require("skynet.tracker") local valid_skylink = "AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA" local valid_status_code = 200 local valid_auth_headers = { ["Skynet-Api-Key"] = "foo" } local valid_ip = "12.34.56.78" describe("track_download", function() local valid_body_bytes_sent = 12345 before_each(function() stub(ngx.timer, "at") end) after_each(function() ngx.timer.at:revert() end) it("should schedule a timer when conditions are met", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_download(valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_download_timer, valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent ) end) it("should not schedule a timer if skylink is empty", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_download(nil, valid_status_code, valid_auth_headers, valid_body_bytes_sent) assert.stub(ngx.timer.at).was_not_called() end) it("should not schedule a timer if status code is not in 2XX range", function() ngx.timer.at.invokes(function() return true, nil end) -- couple of example of 4XX and 5XX codes skynet_tracker.track_download(valid_skylink, 401, valid_auth_headers, valid_body_bytes_sent) skynet_tracker.track_download(valid_skylink, 403, valid_auth_headers, valid_body_bytes_sent) skynet_tracker.track_download(valid_skylink, 490, valid_auth_headers, valid_body_bytes_sent) skynet_tracker.track_download(valid_skylink, 500, valid_auth_headers, valid_body_bytes_sent) skynet_tracker.track_download(valid_skylink, 502, valid_auth_headers, valid_body_bytes_sent) assert.stub(ngx.timer.at).was_not_called() end) it("should not schedule a timer if auth headers are empty", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_download(valid_skylink, valid_status_code, {}, valid_body_bytes_sent) assert.stub(ngx.timer.at).was_not_called() end) it("should log an error if timer failed to create", function() stub(ngx, "log") ngx.timer.at.invokes(function() return false, "such a failure" end) skynet_tracker.track_download(valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_download_timer, valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent ) assert.stub(ngx.log).was_called_with(ngx.ERR, "Failed to create timer: ", "such a failure") ngx.log:revert() end) describe("track_download_timer", function() before_each(function() stub(ngx, "log") end) after_each(function() local resty_http = require("resty.http") ngx.log:revert() resty_http.new:revert() end) it("should exit early on premature", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 200 } -- return 200 success end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_download_timer( true, valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent ) assert.stub(request_uri).was_not_called() assert.stub(ngx.log).was_not_called() end) it("should make a post request to tracker service", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 204 } -- return 204 success end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_download_timer( false, valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent ) local uri_params = "status=" .. valid_status_code .. "&bytes=" .. valid_body_bytes_sent local uri = "http://10.10.10.70:3000/track/download/" .. valid_skylink .. "?" .. uri_params assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers }) assert.stub(ngx.log).was_not_called() end) it("should log message on tracker request failure with response code", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 404, body = "baz" } -- return 404 failure end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_download_timer( false, valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent ) local uri_params = "status=" .. valid_status_code .. "&bytes=" .. valid_body_bytes_sent local uri = "http://10.10.10.70:3000/track/download/" .. valid_skylink .. "?" .. uri_params assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers }) assert.stub(ngx.log).was_called_with( ngx.ERR, "Failed accounts service request /track/download/" .. valid_skylink .. ": ", "[HTTP 404] baz" ) end) it("should log message on tracker request error", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return nil, "foo != bar" -- return error end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_download_timer( false, valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent ) local uri_params = "status=" .. valid_status_code .. "&bytes=" .. valid_body_bytes_sent local uri = "http://10.10.10.70:3000/track/download/" .. valid_skylink .. "?" .. uri_params assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers }) assert.stub(ngx.log).was_called_with( ngx.ERR, "Failed accounts service request /track/download/" .. valid_skylink .. ": ", "foo != bar" ) end) end) end) describe("track_upload", function() before_each(function() stub(ngx.timer, "at") end) after_each(function() ngx.timer.at:revert() end) it("should schedule a timer when conditions are met", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_upload(valid_skylink, valid_status_code, valid_auth_headers, valid_ip) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_upload_timer, valid_skylink, valid_auth_headers, valid_ip ) end) it("should not schedule a timer if skylink is empty", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_upload(nil, valid_status_code, valid_auth_headers, valid_ip) assert.stub(ngx.timer.at).was_not_called() end) it("should not schedule a timer if status code is not in 2XX range", function() ngx.timer.at.invokes(function() return true, nil end) -- couple of example of 4XX and 5XX codes skynet_tracker.track_upload(valid_skylink, 401, valid_auth_headers, valid_ip) skynet_tracker.track_upload(valid_skylink, 403, valid_auth_headers, valid_ip) skynet_tracker.track_upload(valid_skylink, 490, valid_auth_headers, valid_ip) skynet_tracker.track_upload(valid_skylink, 500, valid_auth_headers, valid_ip) skynet_tracker.track_upload(valid_skylink, 502, valid_auth_headers, valid_ip) assert.stub(ngx.timer.at).was_not_called() end) it("should schedule a timer if auth headers are empty", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_upload(valid_skylink, valid_status_code, {}, valid_ip) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_upload_timer, valid_skylink, {}, valid_ip ) end) it("should log an error if timer failed to create", function() stub(ngx, "log") ngx.timer.at.invokes(function() return false, "such a failure" end) skynet_tracker.track_upload(valid_skylink, valid_status_code, valid_auth_headers, valid_ip) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_upload_timer, valid_skylink, valid_auth_headers, valid_ip ) assert.stub(ngx.log).was_called_with(ngx.ERR, "Failed to create timer: ", "such a failure") ngx.log:revert() end) describe("track_upload_timer", function() before_each(function() stub(ngx, "log") end) after_each(function() local resty_http = require("resty.http") ngx.log:revert() resty_http.new:revert() end) it("should exit early on premature", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 200 } -- return 200 success end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_upload_timer( true, valid_skylink, valid_auth_headers, valid_ip ) assert.stub(request_uri).was_not_called() assert.stub(ngx.log).was_not_called() end) it("should make a post request to tracker service", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 204 } -- return 204 success end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_upload_timer( false, valid_skylink, valid_auth_headers, valid_ip ) local uri = "http://10.10.10.70:3000/track/upload/" .. valid_skylink assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = { ["Content-Type"] = "application/x-www-form-urlencoded", ["Skynet-Api-Key"] = "foo", }, body = "ip=" .. valid_ip }) assert.stub(ngx.log).was_not_called() end) it("should log message on tracker request failure with response code", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 404, body = "baz" } -- return 404 failure end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_upload_timer( false, valid_skylink, valid_auth_headers, valid_ip ) local uri = "http://10.10.10.70:3000/track/upload/" .. valid_skylink assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = { ["Content-Type"] = "application/x-www-form-urlencoded", ["Skynet-Api-Key"] = "foo", }, body = "ip=" .. valid_ip }) assert.stub(ngx.log).was_called_with( ngx.ERR, "Failed accounts service request /track/upload/" .. valid_skylink .. ": ", "[HTTP 404] baz" ) end) it("should log message on tracker request error", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return nil, "foo != bar" -- return error end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_upload_timer( false, valid_skylink, valid_auth_headers, valid_ip ) local uri = "http://10.10.10.70:3000/track/upload/" .. valid_skylink assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = { ["Content-Type"] = "application/x-www-form-urlencoded", ["Skynet-Api-Key"] = "foo", }, body = "ip=" .. valid_ip }) assert.stub(ngx.log).was_called_with( ngx.ERR, "Failed accounts service request /track/upload/" .. valid_skylink .. ": ", "foo != bar" ) end) end) end) describe("track_registry", function() local status_code_ok = 200 local status_code_not_found = 404 local request_method_write = "POST" local request_method_read = "GET" before_each(function() stub(ngx.timer, "at") end) after_each(function() ngx.timer.at:revert() end) it("should schedule a timer when status code was 200", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_registry(status_code_ok, valid_auth_headers, request_method_write) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_registry_timer, valid_auth_headers, request_method_write ) end) it("should schedule a timer when status code was 404", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_registry(status_code_not_found, valid_auth_headers, request_method_write) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_registry_timer, valid_auth_headers, request_method_write ) end) it("should not schedule a timer if status code is not in 200 or 404", function() ngx.timer.at.invokes(function() return true, nil end) -- couple of example of invalid 2XX, 4XX and 5XX codes skynet_tracker.track_registry(204, valid_auth_headers, request_method_write) skynet_tracker.track_registry(206, valid_auth_headers, request_method_write) skynet_tracker.track_registry(401, valid_auth_headers, request_method_write) skynet_tracker.track_registry(403, valid_auth_headers, request_method_write) skynet_tracker.track_registry(490, valid_auth_headers, request_method_write) skynet_tracker.track_registry(500, valid_auth_headers, request_method_write) skynet_tracker.track_registry(502, valid_auth_headers, request_method_write) assert.stub(ngx.timer.at).was_not_called() end) it("should not schedule a timer if auth headers are empty", function() ngx.timer.at.invokes(function() return true, nil end) skynet_tracker.track_registry(status_code_ok, {}, request_method_write) assert.stub(ngx.timer.at).was_not_called() end) it("should log an error if timer failed to create", function() stub(ngx, "log") ngx.timer.at.invokes(function() return false, "such a failure" end) skynet_tracker.track_registry(status_code_ok, valid_auth_headers, request_method_write) assert.stub(ngx.timer.at).was_called_with( 0, skynet_tracker.track_registry_timer, valid_auth_headers, request_method_write ) assert.stub(ngx.log).was_called_with(ngx.ERR, "Failed to create timer: ", "such a failure") ngx.log:revert() end) describe("track_registry_timer", function() before_each(function() stub(ngx, "log") end) after_each(function() local resty_http = require("resty.http") ngx.log:revert() resty_http.new:revert() end) it("should exit early on premature", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 200 } -- return 200 success end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_registry_timer( true, valid_auth_headers, request_method_write ) assert.stub(request_uri).was_not_called() assert.stub(ngx.log).was_not_called() end) it("should make a post request to registry write tracker service", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 204 } -- return 204 success end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_registry_timer( false, valid_auth_headers, request_method_write ) local uri = "http://10.10.10.70:3000/track/registry/write" assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers }) assert.stub(ngx.log).was_not_called() end) it("should make a post request to registry read tracker service", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 204 } -- return 204 success end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_registry_timer( false, valid_auth_headers, request_method_read ) local uri = "http://10.10.10.70:3000/track/registry/read" assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers }) assert.stub(ngx.log).was_not_called() end) it("should log message on tracker request failure with response code", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return { status = 404, body = "baz" } -- return 404 failure end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_registry_timer( false, valid_auth_headers, request_method_write ) local uri = "http://10.10.10.70:3000/track/registry/write" assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers }) assert.stub(ngx.log).was_called_with( ngx.ERR, "Failed accounts service request /track/registry/write: ", "[HTTP 404] baz" ) end) it("should log message on tracker request error", function() local resty_http = require("resty.http") local request_uri = spy.new(function() return nil, "foo != bar" -- return error end) local httpc = mock({ request_uri = request_uri }) stub(resty_http, "new").returns(httpc) skynet_tracker.track_registry_timer( false, valid_auth_headers, request_method_write ) local uri = "http://10.10.10.70:3000/track/registry/write" assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers }) assert.stub(ngx.log).was_called_with( ngx.ERR, "Failed accounts service request /track/registry/write: ", "foo != bar" ) end) end) end)