local helpers = require "spec.helpers" local cjson = require "cjson" local TEST_NAME_HEADER = "X-PW-Test" local TESTS_FILTER_FILE = nil -- helpers.test_conf.wasm_filters_path .. "/tests.wasm" local fixtures = { dns_mock = helpers.dns_mock.new({ mocks_only = true }), http_mock = {}, stream_mock = {} } fixtures.dns_mock:A({ name = "mock.io", address = "127.0.0.1" }) fixtures.dns_mock:A({ name = "status.io", address = "127.0.0.1" }) local function add_service_and_route(bp, name, path) local service = assert(bp.services:insert({ name = name, url = helpers.mock_upstream_url, })) local route = assert(bp.routes:insert({ name = name .. "-route", service = { id = service.id }, paths = { path }, hosts = { name }, protocols = { "https" }, })) return service, route end local function add_filter_to_service(bp, filter_name, service) local filters = { { name = filter_name, enabled = true, config = {} }, } assert(bp.filter_chains:insert({ service = { id = service.id }, filters = filters, })) end for _, strategy in helpers.each_strategy() do -- TODO: replace these test cases with ones that assert the proper behavior -- after the feature is removed pending("Plugin: prometheus (metrics) [#" .. strategy .. "]", function() local admin_client lazy_setup(function() local filter_dir = helpers.make_temp_dir() local filter_file = filter_dir .. "/tests.wasm" local status_api_port = helpers.get_available_port() -- copy filter to a custom location to avoid filter metadata collision assert(helpers.file.copy(TESTS_FILTER_FILE, filter_file)) assert(helpers.file.write(filter_dir .. "/tests.meta.json", cjson.encode({ config_schema = { type = "object", properties = {} }, metrics = { label_patterns = { { label = "service", pattern = "(_s_id=([0-9a-z%-]+))" }, { label = "route", pattern = "(_r_id=([0-9a-z%-]+))" }, } } }))) require("kong.runloop.wasm").enable({ { name = "tests", path = filter_file }, }) local bp = helpers.get_db_utils(strategy, { "services", "routes", "plugins", "filter_chains", }) local service, _ = add_service_and_route(bp, "mock", "/") local service2, _ = add_service_and_route(bp, "mock2", "/v2") add_service_and_route(bp, "status.io", "/metrics") add_filter_to_service(bp, "tests", service) add_filter_to_service(bp, "tests", service2) assert(bp.plugins:insert({ name = "prometheus", config = { wasm_metrics = true }, })) assert(helpers.start_kong({ nginx_conf = "spec/fixtures/custom_nginx.template", wasm = true, wasm_filters_path = filter_dir, plugins = "bundled,prometheus", status_listen = '127.0.0.1:' .. status_api_port .. ' ssl', status_access_log = "logs/status_access.log", status_error_log = "logs/status_error.log" }, nil, nil, fixtures)) local proxy_client = helpers.proxy_ssl_client() local res = proxy_client:get("/", { headers = { host = "mock", [TEST_NAME_HEADER] = "update_metrics" }, }) assert.res_status(200, res) res = proxy_client:get("/v2", { headers = { host = "mock2", [TEST_NAME_HEADER] = "update_metrics" }, }) assert.res_status(200, res) proxy_client:close() end) lazy_teardown(function() if admin_client then admin_client:close() end helpers.stop_kong() end) before_each(function() admin_client = helpers.admin_client() end) after_each(function() if admin_client then admin_client:close() end end) it("exposes Proxy-Wasm counters", function() local res = assert(admin_client:send{ method = "GET", path = "/metrics" }) local body = assert.res_status(200, res) local expected_c = '# HELP pw_tests_a_counter\n' .. '# TYPE pw_tests_a_counter counter\n' .. 'pw_tests_a_counter 2' assert.matches(expected_c, body, nil, true) end) it("exposes Proxy-Wasm labeled counters", function() local res = assert(admin_client:send{ method = "GET", path = "/metrics" }) local body = assert.res_status(200, res) local expected_c = '# HELP pw_tests_a_labeled_counter\n' .. '# TYPE pw_tests_a_labeled_counter counter\n' .. 'pw_tests_a_labeled_counter{service="mock2",route="mock2-route"} 1\n' .. 'pw_tests_a_labeled_counter{service="mock",route="mock-route"} 1' assert.matches(expected_c, body, nil, true) end) it("exposes Proxy-Wasm gauges", function() local res = assert(admin_client:send{ method = "GET", path = "/metrics" }) local body = assert.res_status(200, res) local expected_g = '# HELP pw_tests_a_gauge\n' .. '# TYPE pw_tests_a_gauge gauge\n' .. 'pw_tests_a_gauge 1' assert.matches(expected_g, body, nil, true) end) it("exposes Proxy-Wasm labeled gauges", function() local res = assert(admin_client:send{ method = "GET", path = "/metrics" }) local body = assert.res_status(200, res) local expected_g = '# HELP pw_tests_a_labeled_gauge\n' .. '# TYPE pw_tests_a_labeled_gauge gauge\n' .. 'pw_tests_a_labeled_gauge{service="mock2",route="mock2-route"} 1\n' .. 'pw_tests_a_labeled_gauge{service="mock",route="mock-route"} 1' assert.matches(expected_g, body, nil, true) end) it("exposes Proxy-Wasm histograms", function() local res = assert(admin_client:send{ method = "GET", path = "/metrics" }) local body = assert.res_status(200, res) local expected_h = '# HELP pw_tests_a_histogram\n' .. '# TYPE pw_tests_a_histogram histogram\n' .. 'pw_tests_a_histogram{le="1"} 2\n' .. 'pw_tests_a_histogram{le="2"} 4\n' .. 'pw_tests_a_histogram{le="4"} 6\n' .. 'pw_tests_a_histogram{le="8"} 8\n' .. 'pw_tests_a_histogram{le="16"} 10\n' .. 'pw_tests_a_histogram{le="32"} 12\n' .. 'pw_tests_a_histogram{le="64"} 14\n' .. 'pw_tests_a_histogram{le="128"} 16\n' .. 'pw_tests_a_histogram{le="256"} 18\n' .. 'pw_tests_a_histogram{le="512"} 20\n' .. 'pw_tests_a_histogram{le="1024"} 22\n' .. 'pw_tests_a_histogram{le="2048"} 24\n' .. 'pw_tests_a_histogram{le="4096"} 26\n' .. 'pw_tests_a_histogram{le="8192"} 28\n' .. 'pw_tests_a_histogram{le="16384"} 30\n' .. 'pw_tests_a_histogram{le="32768"} 32\n' .. 'pw_tests_a_histogram{le="65536"} 34\n' .. 'pw_tests_a_histogram{le="+Inf"} 36\n' .. 'pw_tests_a_histogram_sum 524286\n' .. 'pw_tests_a_histogram_count 36' assert.matches(expected_h, body, nil, true) end) it("exposes Proxy-Wasm labeled histograms", function() local res = assert(admin_client:send{ method = "GET", path = "/metrics" }) local body = assert.res_status(200, res) local expected_h = '# HELP pw_tests_a_labeled_histogram\n' .. '# TYPE pw_tests_a_labeled_histogram histogram\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="1"} 1\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="2"} 2\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="4"} 3\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="8"} 4\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="16"} 5\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="32"} 6\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="64"} 7\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="128"} 8\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="256"} 9\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="512"} 10\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="1024"} 11\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="2048"} 12\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="4096"} 13\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="8192"} 14\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="16384"} 15\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="32768"} 16\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="65536"} 17\n' .. 'pw_tests_a_labeled_histogram{service="mock2",route="mock2-route",le="+Inf"} 18\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="1"} 1\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="2"} 2\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="4"} 3\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="8"} 4\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="16"} 5\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="32"} 6\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="64"} 7\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="128"} 8\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="256"} 9\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="512"} 10\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="1024"} 11\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="2048"} 12\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="4096"} 13\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="8192"} 14\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="16384"} 15\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="32768"} 16\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="65536"} 17\n' .. 'pw_tests_a_labeled_histogram{service="mock",route="mock-route",le="+Inf"} 18\n' .. 'pw_tests_a_labeled_histogram_sum{service="mock2",route="mock2-route"} 262143\n' .. 'pw_tests_a_labeled_histogram_sum{service="mock",route="mock-route"} 262143\n' .. 'pw_tests_a_labeled_histogram_count{service="mock2",route="mock2-route"} 18\n' .. 'pw_tests_a_labeled_histogram_count{service="mock",route="mock-route"} 18' assert.matches(expected_h, body, nil, true) end) end) end