未验证 提交 b1d921c3 编写于 作者: 温铭 WenMing 提交者: GitHub

feature: add ngx lua github action and test cases. (#7)

* add test cases for ngx lua.

* add more test cases.

* add ngx lua to github action.

* Compatible with lua and ngx lua
上级 87855e42
......@@ -19,11 +19,10 @@ name: CI
on:
pull_request:
push:
branches:
branches:
- master
tags:
- 'v*'
jobs:
CI:
......@@ -49,10 +48,28 @@ jobs:
run: |
sudo luarocks install luaunit
sudo luarocks install lua-cjson 2.1.0-1
- name: 'Run Tests'
- name: "Install OpenResty"
run: |
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
sudo apt-get -y update --fix-missing
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
sudo apt-get update
sudo apt-get install openresty-debug
- name: "Install test::nginx for testing"
run: |
sudo apt-get install -y cpanminus
sudo cpanm --notest Test::Nginx >build.log 2>&1 || (cat build.log && exit 1)
git clone https://github.com/iresty/test-nginx.git test-nginx
- name: 'Run Lua Tests'
run: |
cd lib/skywalking
lua util_test.lua
lua span_test.lua
lua tracing_context_test.lua
lua segment_ref_test.lua
\ No newline at end of file
lua span_test.lua
lua tracing_context_test.lua
lua segment_ref_test.lua
cd ..
- name: 'Run Nginx Lua Tests'
run: |
export PATH=/usr/local/openresty-debug/nginx/sbin:/usr/local/openresty-debug/luajit/bin:$/usr/local/openresty-debug/bin:$PATH
prove -Itest-nginx/lib -r t
--
--
-- 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.
--
--
-- Segment represents a finished tracing context
-- Including all information to send to the SkyWalking OAP server.
......@@ -78,4 +78,4 @@ function Segment:transform()
return segmentBuilder
end
return Segment
\ No newline at end of file
return Segment
--
--
-- 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.
--
--
local Util = require('util')
local Base64 = require('dependencies/base64')
......@@ -71,13 +70,13 @@ end
-- Deserialize value from the propagated context and initialize the SegmentRef
function SegmentRef:fromSW6Value(value)
local parts = Util: split(value, '-')
local parts = Util.split(value, '-')
if #parts ~= 9 then
return nil
end
self.trace_id = Util:formatID(Base64.decode(parts[2]))
self.segment_id = Util:formatID(Base64.decode(parts[3]))
self.trace_id = Util.formatID(Base64.decode(parts[2]))
self.segment_id = Util.formatID(Base64.decode(parts[3]))
self.span_id = tonumber(parts[4])
self.parent_service_instance_id = tonumber(parts[5])
self.entry_service_instance_id = tonumber(parts[6])
......@@ -106,13 +105,13 @@ end
-- Return string to represent this ref.
function SegmentRef:serialize()
local encodedRef = '1'
encodedRef = encodedRef .. '-' .. Base64.encode(Util:id2String(self.trace_id))
encodedRef = encodedRef .. '-' .. Base64.encode(Util:id2String(self.segment_id))
encodedRef = encodedRef .. '-' .. Base64.encode(Util.id2String(self.trace_id))
encodedRef = encodedRef .. '-' .. Base64.encode(Util.id2String(self.segment_id))
encodedRef = encodedRef .. '-' .. self.span_id
encodedRef = encodedRef .. '-' .. self.parent_service_instance_id
encodedRef = encodedRef .. '-' .. self.entry_service_instance_id
local networkAddress
local networkAddress
if self.network_address_id ~= 0 then
networkAddress = self.network_address_id .. ''
else
......
--
--
-- 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.
--
--
local Util = require('util')
local Span = require('span')
......@@ -58,7 +58,7 @@ function TracingContext:new(serviceId, serviceInstID)
return TracingContext:newNoOP()
end
o.trace_id = Util:newID()
o.trace_id = Util.newID()
o.segment_id = o.trace_id
o.service_id = serviceId
o.service_inst_id = serviceInstID
......@@ -99,8 +99,8 @@ end
-- After all active spans finished, this segment will be treated as finished status.
-- Notice, it is different with Java agent, a finished context is still able to recreate new span, and be checked as finished again.
-- This gives the end user more flexibility. Unless it is a real reasonable case, don't call #drainAfterFinished multiple times.
--
-- Return (boolean isSegmentFinished, Segment segment).
--
-- Return (boolean isSegmentFinished, Segment segment).
-- Segment has value only when the isSegmentFinished is true
-- if isSegmentFinished == false, SpanList = nil
function TracingContext:drainAfterFinished()
......@@ -163,7 +163,7 @@ function Internal:addActive(span)
self.first_span = span
end
-- span id starts at 0, to fit LUA, we need to plus one.
-- span id starts at 0, to fit LUA, we need to plus one.
self.active_spans[span.span_id + 1] = span
self.active_count = self.active_count + 1
return self.owner
......@@ -186,4 +186,4 @@ function Internal:nextSpanID()
end
---------------------------------------------
return TracingContext
\ No newline at end of file
return TracingContext
--
--
-- 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.
--
--
local _M = {}
-- for pure Lua
local split = function(str, delimiter)
local t = {}
for substr in string.gmatch(str, "[^".. delimiter.. "]*") do
if substr ~= nil and string.len(substr) > 0 then
table.insert(t,substr)
end
end
return t
end
local timestamp = function()
local _, b = math.modf(os.clock())
if b==0 then
b='000'
else
b=tostring(b):sub(3,5)
end
return os.time() * 1000 + b
end
-- for Nginx Lua
local ok, ngx_re = pcall(require, "ngx.re")
if ok then
split = ngx_re.split
timestamp = function()
return ngx.now() * 1000
end
end
_M.split = split
_M.timestamp = timestamp
_M.is_ngx_lua = ok
local Util = {}
local MAX_ID_PART2 = 1000000000
local MAX_ID_PART3 = 100000
local SEQ = 1
function Util:newID()
SEQ = SEQ + 1
return {Util.timestamp(), math.random( 0, MAX_ID_PART2), math.random( 0, MAX_ID_PART3) + SEQ}
local random_seed = function ()
local seed
local frandom = io.open("/dev/urandom", "rb")
if frandom then
local str = frandom:read(4)
frandom:close()
if str then
local s = 0
for i = 1, 4 do
s = 256 * s + str:byte(i)
end
seed = s
end
end
if not seed then
if _M.is_ngx_lua then
seed = ngx.now() * 1000 + ngx.worker.pid()
else
seed = os.clock()
end
end
return seed
end
math.randomseed(random_seed())
function _M.newID()
return {timestamp(), math.random(0, MAX_ID_PART2), math.random(0, MAX_ID_PART3)}
end
-- Format a trace/segment id into an array.
-- An official ID should have three parts separated by '.' and each part of it is a number
function Util:formatID(str)
local parts = Util:split(str, '.')
function _M.formatID(str)
local regex = '.'
if _M.is_ngx_lua then
regex = [[\.]]
end
local parts = split(str, regex)
if #parts ~= 3 then
return nil
end
......@@ -41,36 +106,8 @@ function Util:formatID(str)
end
-- @param id is an array with length = 3
function Util:id2String(id)
function _M.id2String(id)
return id[1] .. '.' .. id[2] .. '.' .. id[3]
end
-- A simulation implementation of Java's System.currentTimeMillis() by following the SkyWalking protocol.
-- Return the difference as string, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
-- But in using os.clock(), I am not sure whether it is accurate enough.
function Util:timestamp()
local a,b = math.modf(os.clock())
if b==0 then
b='000'
else
b=tostring(b):sub(3,5)
end
return os.time() * 1000 + b
end
-- Split the given string by the delimiter. The delimiter should be a literal string, such as '.', '-'
function Util:split(str, delimiter)
local t = {}
for substr in string.gmatch(str, "[^".. delimiter.. "]*") do
if substr ~= nil and string.len(substr) > 0 then
table.insert(t,substr)
end
end
return t
end
return Util
\ No newline at end of file
return _M
--
--
-- 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.
--
--
local lu = require('luaunit')
local Util = require('util')
TestUtil = {}
function TestUtil:testNewID()
function TestUtil.testNewID()
local id = Util.newID()
lu.assertNotNil(id[1])
......@@ -27,11 +27,11 @@ TestUtil = {}
lu.assertNotNil(id[3])
end
function TestUtil:testTimestamp()
function TestUtil.testTimestamp()
local id = Util.timestamp()
lu.assertNotNil(id)
end
-- end TestUtil
os.exit( lu.LuaUnit.run() )
\ No newline at end of file
os.exit( lu.LuaUnit.run() )
use Test::Nginx::Socket 'no_plan';
use Cwd qw(cwd);
my $pwd = cwd();
repeat_each(1);
no_long_string();
no_shuffle();
no_root_location();
log_level('info');
our $HttpConfig = qq{
lua_package_path "$pwd/lib/skywalking/?.lua;;";
error_log logs/error.log debug;
resolver 114.114.114.114 8.8.8.8 ipv6=off;
lua_shared_dict tracing_buffer 100m;
};
run_tests;
__DATA__
=== TEST 1: timestamp
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
local util = require('util')
local timestamp = util.timestamp()
local regex = [[^\d+$]]
local m = ngx.re.match(timestamp, regex)
if m and tonumber(m[0]) == timestamp then
ngx.say(true)
else
ngx.say(false)
end
}
}
--- request
GET /t
--- response_body
true
--- no_error_log
[error]
=== TEST 2: newID
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
local util = require('util')
local new_id = util.newID()
local regex = [[^\d+$]]
ngx.say(#new_id)
for i = 1, #new_id, 1 do
local m = ngx.re.match(new_id[i], regex)
if m and tonumber(m[0]) == new_id[i] then
ngx.say(i)
end
end
}
}
--- request
GET /t
--- response_body
3
1
2
3
--- no_error_log
[error]
=== TEST 3: id2String
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
local util = require('util')
local id = util.newID()
local id_str = util.id2String(id)
local regex = [[^\d+\.\d+\.\d+$]]
local m = ngx.re.match(id_str, regex)
if m then
ngx.say(true)
end
}
}
--- request
GET /t
--- response_body
true
--- no_error_log
[error]
=== TEST 4: formatID
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua_block {
local util = require('util')
local id = util.newID()
local id_str = util.id2String(id)
local parts = util.formatID(id_str)
ngx.say(#parts)
}
}
--- request
GET /t
--- response_body
3
--- no_error_log
[error]
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册