Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds shared-state rpcd data,error output format and shared-state-async rpcd reimplementation #1103

Merged
merged 2 commits into from
Apr 24, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
adds shared-state rpcd data,error output format
  • Loading branch information
javierbrk committed Apr 8, 2024
commit bae6594517fc641a7d9e04744cc28238faafbc18
106 changes: 43 additions & 63 deletions packages/shared-state-async/files/usr/libexec/rpcd/shared-state-async
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using shell instead of Lua resulted in a much nicer code as anticipated :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much better, I was worried about json parsing but some else was also worried before me.

Original file line number Diff line number Diff line change
@@ -1,63 +1,43 @@
#!/usr/bin/env lua

--[[
Shared State Async

Copyright (c) 2024 Javier Jorge <jjorge@inti.gob.ar>
Copyright (c) 2024 Instituto Nacional de Tecnolog..a Industrial
Copyright (C) 2024 Asociacion Civil Altermundi <info@altermundi.net>

This is free software, licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3
]]
--
local utils = require('lime.utils')
local json = require 'luci.jsonc'

local function get(msg)
local error = os.execute("shared-state-async get " ..
msg.data_type .. " 2>/dev/null ")
-- if os.execute dont fail will print the output and rpcd wont execute
-- the following lines. If there is an error the above code wont print
-- anything and this code will return the error code.
utils.printJson({
error = error
})
end

local function sync(msg)
local error = os.execute("shared-state-async sync " ..
msg.data_type .. " " .. table.concat(msg.peers_ip or {}, " ") .. " 2>/dev/null ")
utils.printJson({
error = error
})
end

--{"data_type":"data","peers_ip":["10.0.0.1","10.0.0.2"]}
--{"data_type":"data","peers_ip":["10.0.0.1"]}
local methods = {
get = {
data_type = 'value'
},
sync = {
data_type = 'value',
peers_ip = 'value'
}
}

if arg[1] == 'list' then
utils.printJson(methods)
end

if arg[1] == 'call' then
local msg = utils.rpcd_readline()
msg = json.parse(msg)
if arg[2] == 'get' then
get(msg)
elseif arg[2] == 'sync' then
sync(msg)
else
utils.printJson({
error = "Method not found"
})
end
end
#!/bin/sh
# --[[
# Shared State Async
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line should now be blank


# Copyright (c) 2024 Javier Jorge <jjorge@inti.gob.ar>
# Copyright (c) 2024 Instituto Nacional de Tecnologia Industrial
# Copyright (C) 2024 Asociacion Civil Altermundi <info@altermundi.net>

# SPDX-License-Identifier: AGPL-3.0-only
# ]]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this like show now go away

sinc_args=""

case "$1" in
list)
echo '{ "sync": { "data_type": "str", "peers_ip": "str" }, "get": { "data_type": "str" } }'
;;
call)
# source jshn shell library
. /usr/share/libubox/jshn.sh
read nmsg
json_load $nmsg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this variable name means? Either I miss something or a more readable name should be used (always remember what will I understand when I'll reopen this file a couple years after?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change it to match the name of the same variable in all the other rpcd scripts "msg"

json_get_vars data_type
json_get_vars peers_ip
case "$2" in
get)
if output=$(shared-state-async get $data_type 2>/dev/null)
then
echo {\"data\": $output , \"error\" :$?}
else
echo {\"data\": {} , \"error\": $? }
fi
;;
sync)
shared-state-async sync $data_type ${peers_ip//,/ } > /dev/null 2>&1
echo {\"data\": {} , \"error\": $? }
;;
*)
echo '{\"data\" {} ,\"error\" = "Method not found"}'
;;
esac
;;
esac
23 changes: 7 additions & 16 deletions packages/shared-state-async/tests/test_rpcd_shared-state-async.lua
Original file line number Diff line number Diff line change
@@ -3,32 +3,23 @@ local sharedState = require("shared-state")
local json = require("luci.jsonc")

local testFileName = "packages/shared-state-async/files/usr/libexec/rpcd/shared-state-async"
local sharedStateRpc = testUtils.load_lua_file_as_function(testFileName)
local rpcdCall = testUtils.rpcd_call


--since there is no Shared State async binary, testing possiblities are reduced
--also testing the full
--manual testing can be done on a router with bat-hosts package using this commands:
--ubus -S call shared-state-async get "{'data_type': 'bat-hosts'}"
--ubus -S call shared-state-async sync "{'data_type': 'bat-hosts'}"
--ubus -S call shared-state-async sync "{'data_type': 'bat-hosts' ,'peers_ip':['10.0.0.1','10.0.0.2']}'"


describe('ubus-shared-state tests #ubus-shared-state', function()
before_each('', function()
testDir = testUtils.setup_test_dir()
sharedState.DATA_DIR = testDir
sharedState.PERSISTENT_DATA_DIR = testDir
end)

after_each('', function()
testUtils.teardown_test_dir()
end)

it('test list methods', function()
local response = rpcdCall(sharedStateRpc, {'list'})
assert.is.equal("value", response.get.data_type)
assert.is.equal("value", response.sync.data_type)
assert.is.equal("value", response.sync.peers_ip)

local response = utils.unsafe_shell(testFileName.." list")
response = json.parse(response)
assert.is.equal("str", response.get.data_type)
assert.is.equal("str", response.sync.data_type)
assert.is.equal("str", response.sync.peers_ip)
end)
end)
46 changes: 26 additions & 20 deletions packages/shared-state/files/usr/libexec/rpcd/shared-state
Original file line number Diff line number Diff line change
@@ -1,45 +1,51 @@
#!/usr/bin/env lua
--[[
#!/usr/bin/env lua
--[[
Shared State

Copyright (c) 2023 Javier Jorge <jjorge@inti.gob.ar>
Copyright (c) 2023 Instituto Nacional de Tecnología Industrial
Copyright (C) 2023 Asociación Civil Altermundi <info@altermundi.net>

This is free software, licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3
]] --
]]
--
local ubus = require "ubus"
javierbrk marked this conversation as resolved.
Show resolved Hide resolved
local utils = require('lime.utils')
local shared_state = require("shared-state")
local json = require 'luci.jsonc'

require("nixio.util")

local function getFromSharedState(msg)
local sharedState = shared_state.SharedState:new(msg.data_type,
nixio.syslog)
local response_template = {data = {}, error = 500}

local function showData(sharedState)
local resultTable = sharedState:get()
local response ={}
for k,v in pairs(resultTable) do
response[k]=v.data
if next(resultTable) == nill then
response_template.error = 404
else
for k, v in pairs(resultTable) do
response_template.data[k] = v.data
end
response_template.error = 0
end
utils.printJson(response)
utils.printJson(response_template)
end

local function getFromSharedState(msg)
local sharedState = shared_state.SharedState:new(msg.data_type,
nixio.syslog)
showData(sharedState)
end

local function getFromSharedStateMultiWriter(msg)
local sharedState = shared_state.SharedStateMultiWriter:new(msg.data_type,
nixio.syslog)
local resultTable = sharedState:get()
local response ={}
for k,v in pairs(resultTable) do
response[k]=v.data
end
utils.printJson(response)
local sharedState = shared_state.SharedStateMultiWriter:new(msg.data_type,
nixio.syslog)
showData(sharedState)
end

local function insertIntoSharedStateMultiWriter(msg)
local sharedState = shared_state.SharedStateMultiWriter:new(msg.data_type,
nixio.syslog)
local sharedState = shared_state.SharedStateMultiWriter:new(msg.data_type,
nixio.syslog)
local inputTable = msg.json or {}
sharedState:insert(inputTable)
end
40 changes: 25 additions & 15 deletions packages/shared-state/tests/test_rpcd_shared-state.lua
Original file line number Diff line number Diff line change
@@ -38,11 +38,21 @@ describe('ubus-shared-state tests #ubus-shared-state', function()
assert.is.equal(dbA.zig.data, 'zag')
local response = rpcdCall(sharedStateRpc, {'call', 'getFromSharedState'},
'{"data_type": "wifi_links_info"}')
assert.is.equal(response.bar, 'foo')
assert.is.equal(response.baz, 'qux')
assert.is.equal(response.zig, 'zag')
assert.is.equal(response.data.bar, 'foo')
assert.is.equal(response.data.baz, 'qux')
assert.is.equal(response.data.zig, 'zag')
end)

it('test get multiwriter data from empty data_type ', function()
local sharedStateA = sharedState.SharedStateMultiWriter:new('EMPTY')

local response = rpcdCall(sharedStateRpc, {'call',
'getFromSharedStateMultiWriter'}, '{"data_type": "EMPTY"}')
assert.is.equal(response.error, 404)
assert.is.equal(next(response.data), next({}))
end)


it('test get multiwriter data ', function()
local sharedStateA = sharedState.SharedStateMultiWriter:new('A')
sharedStateA:insert({
@@ -55,9 +65,9 @@ describe('ubus-shared-state tests #ubus-shared-state', function()
assert.is.equal('zag', dbA.zig.data)
local response = rpcdCall(sharedStateRpc, {'call',
'getFromSharedStateMultiWriter'}, '{"data_type": "A"}')
assert.is.equal(response.bar, 'foo')
assert.is.equal(response.baz, 'qux')
assert.is.equal(response.zig, 'zag')
assert.is.equal(response.data.bar, 'foo')
assert.is.equal(response.data.baz, 'qux')
assert.is.equal(response.data.zig, 'zag')
end)

it('test insert multiwriter data ', function()
@@ -87,8 +97,8 @@ describe('ubus-shared-state tests #ubus-shared-state', function()
})
local response = rpcdCall(sharedStateRpc, {'call',
'getFromSharedStateMultiWriter'}, '{"data_type": "A"}')
assert.is.equal('foo', response.bar)
assert.is.equal('zag', response.zig)
assert.is.equal('foo', response.data.bar)
assert.is.equal('zag', response.data.zig)
response.zig="newzag"
callargs = '{"data_type": "A", "json": '..json.stringify(response)..'}'
local response = rpcdCall(sharedStateRpc, {'call',
@@ -143,16 +153,16 @@ describe('ubus-shared-state tests #ubus-shared-state', function()
'{"data_type": "A", "json": {"zig": "zag"}}')
response = rpcdCall(sharedStateRpc, {'call',
'getFromSharedStateMultiWriter'}, '{"data_type": "A"}')
assert.is.equal(response.zig, 'zag')
assert.is.equal(response.data.zig, 'zag')

response = rpcdCall(sharedStateRpc, {'call',
'insertIntoSharedStateMultiWriter'},
wifiStatusJsonsample23)
response = rpcdCall(sharedStateRpc, {'call',
'getFromSharedStateMultiWriter'},
'{"data_type": "ref_state_wifilinks"}')
assert.is.equal(response.primero.bleachTTL, 23)
assert.is.equal(response.primero.author, "primero")
assert.is.equal(response.data.primero.bleachTTL, 23)
assert.is.equal(response.data.primero.author, "primero")

response = rpcdCall(sharedStateRpc, {'call',
'insertIntoSharedStateMultiWriter'},wifiStatusJsonsample27)
@@ -161,16 +171,16 @@ describe('ubus-shared-state tests #ubus-shared-state', function()
'getFromSharedStateMultiWriter'},
'{"data_type": "ref_state_wifilinks"}')

assert.is.equal(response.primero.bleachTTL, 27)
assert.is.equal(response.primero.author, "primero")
assert.is.equal(response.data.primero.bleachTTL, 27)
assert.is.equal(response.data.primero.author, "primero")

response = rpcdCall(sharedStateRpc, {'call',
'insertIntoSharedStateMultiWriter'},
wifiStatusJsonsample23)
response = rpcdCall(sharedStateRpc, {'call',
'getFromSharedStateMultiWriter'},
'{"data_type": "ref_state_wifilinks"}')
assert.is.equal(response.primero.bleachTTL, 23)
assert.is.equal(response.primero.author, "primero")
assert.is.equal(response.data.primero.bleachTTL, 23)
assert.is.equal(response.data.primero.author, "primero")
end)
end)
Loading