KRL Testing Tab
Begin your journey by understanding the basics.
If you are reading this, then it’s assumed that you are brand new to the KRL language. You have jumped into a world of words you have perhaps never heard. Pico engines, rulesets, wovyn sensors, and maybe the Internet of Things is even a new concept to you. As a programmer, you are expected to learn new computer languages on demand, and the sooner you grasp some core functionality of a language, your learning seems to be catapulted — everything seems to start clicking.
Below, we will go through a simple example of creating a ruleset that has one function, and one rule. We will then make sure that both our ruleset and our pico engine are set up correctly so that we can begin testing them. Since we are just starting out on our KRL journey, it is easy to get lost along the way. If you find that this is not making much sense, no worries, you can also visit the KRL documentation to solidify anything that is unclear. Among all things, be patient with yourself as you continue to practice.
If you are not new to KRL, then please leave a comment below if you have anything else that you would like to contribute!
The Testing Tab
It is a well known rule in the software development world that the sooner you can get your application ready for testing, the better. This rule also applies with KRL. The sooner you set up one of your rulesets for testing, the better off you will be, and the more understanding you will have with how your picos are behaving.
After you have set up your Pico Engine and run it, visit localhost:8080
to find a nice UI that makes it easy to visualize all the moving parts of your pico engine. If you have just set it up, then you should only have one root pico. To begin our example, click on the root pico then on the “Rulesets” tab. At the bottom, you can then click on “Engine Rulesets” to begin creating your own rulesets. Let’s begin our example by creating a ruleset called fruits
to understand the basics of connecting a ruleset with the pico engine UI testing tab.
ruleset fruits {
meta {
name "Hello World"
description <<
The first ruleset for the Quickstart
>>
author "Albert Brennaman"
logging on
shares __testing
}global {
__testing = {
"queries": [ { "name": "__testing" } ],
"events": [ ]
}
}
In ruleset fruit
, the first thing to notice is the shares keyword in the meta block of the ruleset, which allows your __testing
attribute to be queried. In simple terms, when you add shares __testing
to the meta block, your ruleset will be eligible to show up in the pico engine UI testing tab. If you fail to add it, then you may spend unnecessary time trying to figure out why it is not showing up. Just because it is eligible to appear in the UI testing tab, this does not mean it is completely ready. You must now focus on the instantiation of the __testing
attribute located in the global block of the ruleset.
Once you have added shares __testing
to your code, you will need something to actually test. The __testing
attribute in the global block of the ruleset is in charge of this. When you create a ruleset, __testing
is created automatically with a blueprint of how to fill it out. It is a map of queries and events. Functions will be queries while rules will be events.
Queries and Functions
Suppose my task is to create a function where a user can specify a fruit as a parameter, and the function returns the string “My favorite fruit is (fruit_name)”, where fruit_name
is whatever the user passed in. If I create this function and wish to test its functionality before deploying it, I would place it in the queries
section of the __testing
attribute. Since the function needs a parameter passed to it, then I also need to specify the “args”
keyword with an array of the parameters. In this case, the parameter is fruit_name
. The resulting code would look like this:
ruleset fruits {
meta {
name "Hello World"
description <<
The first ruleset for the Quickstart
>>
author "Albert Brennaman"
logging on
shares __testing, favorite_fruit
}global {
__testing = {
"queries": [ { "name": "__testing" },
{ "name": "favorite_fruit", "args": ["fruit_name"]}
],
"events": [ ]
} favorite_fruit = function(fruit_name) {
message = "My favorite fruit is " + fruit_name
message
}
}
Here we have created a function that accomplishes its purpose, and in the __testing
attribute, in the queries map, we have specified the name of the function and the arguments that it needs. Of course, this is a very basic function and would need some error checking to make sure it handles null or erroneous input, but hopefully this makes it a little more clear on how to set up a function for testing.
The last two things you need to do in order to have your function ready for testing is to share it in the meta section (This is where you specify what parts of your code need to be able to be queried), and you need to install the ruleset into your pico. If you have done these last two steps, your function is ready to be tested.
Before we test the favorite_fruit
function, we are going to focus on testing rules instead of functions. Other than one small step, the setup to testing rules is identical to that of functions, so we will move a little faster. While following along please continue to pay close attention to what is in bold print in the code.
Events and Rules
Rulesets (and the rules in them) are event-based driven, meaning that a rule is in charge of handling one event and will sit and wait until its domain and type is called by some outside rule or function. When this happens, we say that an event has been “raised”.
Once an event is raised, often times it is necessary to look for event attributes that were sent along with it. Think of the event attributes as parameters that are passed to a function. The event attributes are either sent, or they are not. You can then handle the error checking appropriately or continue to process the information however you please.
Continuing with the fruit example, we will make a rule that begins code execution on an event with a domain of fruit
, and the type directive
. The rule will then check for the fruit
and color
attributes and simply send a directive that contains a sentence telling us the fruit and the color that the rule received. In a more functional rule, you would most likely want to check for certain attributes and have the proper code blocks (pre, fired, not_fired, always, etc.) to handle different scenarios.
ruleset fruits {
meta {
shares __testing, favorite_fruit
}
global {
__testing = { "queries":
[ { "name": "__testing" }
, { "name": "favorite_fruit", "args": [ "fruit_name" ] }
] , "events":
[ //{ "domain": "d1", "type": "t1" }
//, { "domain": "d2", "type": "t2", "attrs": [ "a1", "a2" ] }
]
}
favorite_fruit = function(fruit_name) {
message = "My favorite fruit is " + fruit_name
message
}
}
rule fruit_color {
select when fruit directive
pre {
fruit = event:attr("fruit")
color = event:attr("color")
}
send_directive("fruit_directive", {"body" : "The color of " + fruit + " is " + color + "!"})
}
}
Here we have the rule which performs this task. The important things to note are that the rule selects on the domain of fruit
, and the type of directive
and that the rule is expecting event attributes fruit
and color
which are then stored in their corresponding local variables. The directive is then sent back with the info we received.
To test a rule, it is not required that you share it in the meta block. All you need to do is make sure the __testing
attribute is shared and update its events section with the rules domain and type, in our case these are fruit
and directive
respectively.
The final version of the ruleset that is ready to test both the favorite_fruit
function and the fruit_color
rule looks like the following:
ruleset fruits {
meta {
shares __testing, favorite_fruit
}
global {
__testing = { "queries":
[ { "name": "__testing" }
, { "name": "favorite_fruit", "args": [ "fruit_name" ] }
] , "events":
[ { "domain": "fruit", "type": "directive", "attrs" : [ "fruit", "color" ] }
]
}
favorite_fruit = function(fruit_name) {
message = "My favorite fruit is " + fruit_name
message
}
}
rule fruit_color {
select when fruit directive
pre {
fruit = event:attr("fruit")
color = event:attr("color")
}
send_directive("fruit_directive", {"body" : "The color of " + fruit + " is " + color + "!"})
}
}
Make sure to save the ruleset before going to the testing tab!
Testing the Ruleset
Finally, you are ready to test the functionality of your shiny new ruleset you have created. To do so:
- Navigate to your pico in the pico engine UI.
- Click on the “Rulesets” tab and install your ruleset.
- Click on the “Testing” tab.
- Click on the box to the left of the name of your ruleset. If you have done everything correctly, your Testing tab should look like this:
Start fiddling around with fruit_name
, fruit
, and color
and see what shows up in the right half of the tab, and you will find that your ruleset is responding to your input and working as expected.
Congratulations! If you have made it this far, hopefully you have a better understanding of how to set up a ruleset for testing. Whenever you are asked to create a new ruleset, focus on getting the functions and rules ready to test ASAP. Doing this will not only help you maintain your sanity in distributed systems programming, but it will help you grasp difficult concepts of KRL and understand what your picos are doing.
TL;DR
Steps to test a function:
- Share both the
__testing
attribute and the function name in the meta block of the ruleset - Update the queries section of the
__testing
attribute in the global block of the ruleset. If your function needs parameters, don’t forget to pass in the“args” : [""]
array with the correct parameter names that the function needs. - Install the ruleset in your pico.
Steps to test a rule
- Update the events section of the
__testing
attribute in the global block of the ruleset. If your rule needs event attributes, don’t forget to pass in the“attrs” : [""]
array with the correct event attribute names that the rule needs. - Send a directive or raise another event. Do something that will show up in the results of the testing tab when you test your rule with your input.
- Install the ruleset in your pico.
Stay tuned for more daring adventures!