Conf42 Rustlang 2023 - Online

A journey of Journey Programming Language written in Rust by Tester

Video size:

Abstract

There are so many programming languages out there, yet i felt need for writing another one, specially for catering Testing needs. And then I chose rust which I had no idea about. And it turned out as successful choice as the language is being consumed for testing needs by my past clients.

Summary

  • Atmaram will talk on the topic of journey of journey programming language written in rust by tester. He will talk about all his experiences in writing this language in rust. Don't forget to subscribe to Atmaram's blog.
  • Journey programming language allows you to create commands for multiple or repetitive use. Program which core compiler requires can be written in journey programming language. These commands could be created for multiple tasks or automating multiple activities like test data creation or creation of mock server.
  • A lazy tester wanted to automate mundane activities. He decided to write the tool in a different programming language. He chose three systems programming languages: C plus plus, Rust and Go. The tool can be easily distributed across various platforms.
  • I added CI CD pipeline to automatically create platform specific installables like Homebu, formula, windows installers and debian installers. Throughout this all writing journey of this tool I had really good experiences with Rust. Writing unit integration and end to end test provided necessary safety net to modify features regularly.
  • Writing a programming language in rust was a very rewarding experience. The tool created has been used by my past employers and present for service virtualization test data creation load testing. The whole rust ecosystem is a great place for experiments, tools and projects like this.

Transcript

This transcript was autogenerated. To make changes, submit a PR.
Hello there. Welcome to the Conf 42 Rust Lang two conference. My name is Atmaram and I am going to talk on the topic of journey of journey programming language written in rust by tester. None other than me. There are so many programming languages out there, yet I felt need of writing another one just for testing and I am going to talk about all my experiences in writing this language in rust. About me I am an occasional speaker. I talk at multiple conferences. I am blogger. I write lot of blogs about testing and systems engineering. I am passionate programmer. I like writing code, writing good code. I'm tester by profession. I do testing for earning money. I am open source contributor. I occasionally write on Twitter with the Twitter handle atmnk nine. Don't forget to subscribe and I work at Sedin Technologies as test manager. So I am going to walk you through the agenda of this topic. I am going to talk about the idea of journey programming language first. Then I'm going to quickly show you the demo of how journey programming language works with its quick application to sample application. Then I'm going to talk about how it came into existence into various phases, how it started as a pet project in Java, then in between how I felt need of writing the same tool in different programming language. Then I will talk about how I chose the rust for writing this tool. Then I will talk about how I created a project plan and how that project plan worked. Then throughout this journey of writing tool, how different features came into existence, got added and some of the feature got removed. Then I will talk about my experiences with Rust while writing this tool and I will show you an extended demo of the same tool and I will show you some rust code as well where this tool is written and I will conclude my talk. So let's talk about the idea of journey programming language. While I was doing testing, I felt a need of some tool. Why? Because I was doing so many mundane activities and routine activities repetitively, I failed need for automating those repetitive activities. I felt there should be some tool where I can automate these activities as command. To elaborate more on this idea, what I failed was I should be able to quickly create commands for multiple or repetitive use. The command should be parameterized means I should be able to invoke same command with multiple different values while running the command. If the tool doesn't know specific value, the tool should ask invoker of the command. The specific values and these commands could be created for multiple tasks or automating multiple activities like test data creation or creation of mock server. So that was all idea and I will show you how this idea came into existence with a demo. I'm going to show you a quick demo of core compiler which has programming abilities. Program which core compiler requires can be written in journey programming language which is an open source tool. So what I am going to do is I am going to switch to the postman. So I have created one server called as a to do server, our goto application for doing pet projects. Right. This to do server has rest APIs. So if you see the post method in this postman has localhost 9001 as an address. Now if I send a post request with a title bring milk, what happens? It creates a to do with a title bring milk. It gives it an id one and it sets its status as done as false. I can create one more to do bring eggs and it created one more to do. I can get all to dos using get method. So it gave me both the to dos bring milk and bring eggs. I can get a single to do like I need to provide the id of the to do. So I provided id as one and it gave me to do with id one which has title bring milk. So this is a sample application. Now I am going to show you while testing this application you will need to create so many data and all right what you can do with the tool which I have created. So I am going to go into the terminal now. Let's try to create a to do. So what I'm going to do is I'm going to run a command car, run create to do. Now if you see this command ran and this command is stuck at something, it's asking me please enter value for title of type catering so I can say bring vegetables. And it said it has done executing journey. Now let me see on postman whether this to do was created or not. So I'll say get all to dos and it has created a to do bring vegetables. That was the same to do that we created right over here on terminal, bring vegetables. Now to get all to dos I needed to go to postman, right? But same can be done with the command which I have created. What I am going to do is get all to dos. Now if I run this command, it is giving me all the to dos. If you see the response is a string which has to do with title, bring milk, bring eggs and bring vegetables. Now this is not what just the tool can do. I'm going to show you one more command, create multiple to dos. Now I want to create multiple to dos. Now how many to dos I want to create this is what tool is asking. Please enter value of to dos to create length. Now I'm going to give let's say I want to create twelve to dos. Now the tool is asking do you want random to do names? And the value which is asked is of type boolean. Do I want random to do names? Let's say yes and it said it's done executing the journey. Now let's get all to dos. Now you will see all to dos are over here. Whatever to dos these random to dos with random title were created. This is what tool can do. Now you must be wondering that is this tool just coded for to dos? No. In fact get all to dos create to do. These are all scripted. You can create multiple commands like this in the tool, how to script this and all. I'm going to show you in an extended demo. So let's switch back to the presentation. Now I am going to talk about how this idea started. It started with a lazy tester who wanted to automate mundane activities. Now this tester initially started this project with plain Java. Initial pilot was started with the java the tool which you see right now. The same tool was written in Java at the right hand side over here if you see there is a screenshot attached for how you going to create the commands. The entire tool was config driven right hand side. Whatever you see is just a config for creating commands. You needed to create folders and files in specific structure. All control structures were config driven. If you see all the control structures like block post all this info were config driven. It was highly designed on a specific convention that needed to be followed. Like you need to understand the convention with which these configurations to be created. To run a tool you needed to have specific version of Java and tool was bundled as a jar. It was used for real project as a productivity tool. So my past organization, in my past project I have used this Java based tool for creating multiple commands, productivity commands. Now what was the overall feedback? So I spread this tool across my colleagues and they started using this. And what was their feedback? They said the idea is really good tool like this simplifies lot of mundane activities but for creating actual command it is bit difficult and creator need to understand lot of convention followed. Also the tool has a dependency on specific version of Java and user needs to install Java. The tool is restrictive in terms of possibilities that can be done with it. So overall the feedback was this guy over at the right hand side saying then I felt I need to write this tool in a different programming language. Why? Because we need a language which can produce native tools. So I discarded Java. Not to bash Java. Java is useful in many places, but for this tool Java was not useful. Then I charted down what are the different needs from the programming language that I am being to write this tool in. So I said language should be able to produce cross platform executables because I needed a native binaries and I was intending to distribute this tool across Mac, Windows and Debian OS. So I needed a language which can produce cross platform executables. Language should be memory safe since tool is going to be highly programmable because we are going to write so I discarded the approach of config driven commands, rather I took the approach of code driven commands. So we are going to write a programming language or a domain specific language and as it is going to be highly programmable, the language in which we are going to code. This should be memory safe. Language should cater to high concurrency needs since tool can be further adapted for writing mock servers and load test because we are going to write mock servers which could be invoked with high concurrency and load tests with high concurrency. So language should cater to the high concurrency demand ecosystem around. Language should have ready made libraries for creating CLI tools. As you saw in the demo, we were invoking entire tool with the command line arguments, so we needed to create a CLI parsers and all language should be systems programming language since tool may be further extended for lower level programmability. Language should have low or no GC footprint since tool will be further extended for load testing because in load testing every user's interaction matters, right? So it should have low or no GC footprint and language should be typesafe. So based on this, I evaluated three systems programming language, C plus plus, Rust and Go. At that time, both all C plus plus, rust and Go are systems programming language. They can produce native binaries and they can support very high concurrencies and they have libraries for building CLI tools. Everything was same for all, chose three languages up till here. But when it comes to memory safety, memory safety is not a language feature and is programmer's job in case of C. In case of Rust, Rust is a memory safe language and memory safety is forced on a programmer. In case of Go is also memory safe, but it's not forced on a programmer and programmer can choose to escape memory safety. When it comes to C. C has no GC footprint and memory management is pure programmer's job when it comes to rust. It has no GC footprint and rust forces memory management via borrow checker when it comes to go. Go has a little bit of garbage collector which periodically scans heap for unused objects. So when I compared the need with the languages and the three languages, I thought like Rust will be matching most of the needs. I never knew how to write code in rust. I was new to the rust, but I still took that challenge and I started writing this tool in Rust. The lovely rust. Rust is called as the most loud programming language. I have heard this statement about Rust that Rust takes its type safety on steroids. Like you can't escape rust type safety. The code won't even compile if it is not type safe. And there was one exaggerated statement I had about trust that if your code compiles it will less likely have any issues. Like even to get your code into the compile state you need to fight lot with the compiler. That's what I have heard about trust. Although it is an exaggerated statement. Your code may still have functional issues and other issues, but you will have some sort of assurance if your code compiles then I created a project plan for this entire project. I designed the architecture which you can see on the right hand side. All the green boxes over here are the code blocks. All the blue boxes over here are the compilers and tools which I use for creating this project, and the black boxes which you see are the binaries which are produced. The pink box over here is a small plugin that I created, and the red box over here is an intellij idea for which this plugin was created. This entire tool was written in rust programming language, although there was some one more project where I created a plugin for this tool in a Kotlin programming language. But wool tool is written in rust programming language. The plugin which I was talking about is an intellij plugin which can be used with Intellij idea. So that Intellij idea understand this journey programming language and it provides intelligence around its syntaxes and other stuff. So in the project plan I designed and created architecture of this entire project. Writing unit integration and end to end test were necessary for this project because this was going to be an open source project and I may sometime have time or sometime may not have time and if there is a need for any feature then I should be quickly able to tweak the code with getting lot of backlog that I have lost my touch with the code. So I should be quickly run the test to verify whether I am not breaking anything. Creating Intellij idea plugin for adoption of language was also necessary. Adding more features as and when required was also necessary. Evaluating existing open source libraries for not reinventing the wheel like in the entire progress of this writing, this tool, I used so many libraries which I am going to talk about so that I don't need to write so many code, custom code by myself. This was a project plan that I had. I'm talking about the designing and architecture of this project. This project was built into four different components. There were three rust crates that were created which was one of those was server, other was compiler and other one was library and there was separate project for Intellij plugin which was Kotlin Brace project. The server which I called Cors was a websocket based server which can be interacted with. It can be integrated with any messaging application. So the tool which you were seeing, the commands which were invoking on item or command line can be invoked from any messaging application. The compiler or the core compiler that compiles project and creates distributable package which can be used with servers and other was also one of the crate and most meaty part of this code was a library that has most meaty parsing and execution logic which can be reused in server and compiler. And the plugin was an intellij plugin to provide intelligence around syntax of the language and I needed to write unit integration and end to end test as a safety net throughout this project progressed. This project started as a tool for test data creation by invoking rest APIs, but it saw lot of demand for the features. Like one of my employer asked me to add a feature of service virtualization because the product which we were testing had integrations with lot of third party systems and those third party systems were not providing good sandboxes. So we almost automated like ten plus third party systems. We service virtualized those ten plus third party systems with this tool with the added feature of service virtualization. I also added feature of test data creation directly into DB. So you saw I was creating test data using rEst APIs, but I can create test data directly into the DB using the tool as well. Then one of my employer was testing websocket based servers. While I was researching for any ready made tools for load testing websocket based server, there were some tools but they were not handling event loops properly because I used Tokyo in this project which was already having event loop. So I just needed to spawn the scripts in a load test manner. So load test feature also got added into this tool. Then later on I removed cores which is a server component which can be reintroduced later because it had low adoption, many people were not using it. I added CI CD pipeline to automatically create platform specific installables like Homebu, formula, windows installers and debian installers. And all these installers are being used because some of the folks from the teams were using Windows machines, some of the folks from the team were using Linux machine and some of the folks from the team were using Mac machines. Now throughout this all writing journey of this tool I had really good experiences with Rust. I had initial typical struggles of fighting with Rust compiler for code to compile entire async ecosystem in rust is highly customizable. Crates like Tokyo, Asyncrate, Norm, Clap Sud were highly used needed to use nightly since many language features and libraries used require nightly features. Some libraries were either nonexistent or were not in mature state. So I needed to create quick and dirty reusable libraries like async, rdbc, etc. Every time a code that was compiled was rewarding since it used to ensure something working has been reproduced. Writing unit integration and end to end test provided necessary safety net to modify features regularly without being anything so I can carelessly tweak the features and unit integration and e two e test used to give me enough safety net that I am not breaking anything because there were already users using this tool. I got all answers in community forums and on community discord server when was stuck. I used different libraries while coding for this tool. Like a norm for creating parsers and ast I used Tokyo as an asynchronous runtime. I used hypher for low level servers, I used cert and cert JSon for serialization and deserialization. The clap library came handy for cli parser futures and futures utils for some readymade futures features. With async code there is this very good trade called async trade for lot of async code with trades. I use async recursion as well because at some places I needed to write recursive code in async blocks. I use fake library for writing some fake data generators. I use Mokito as well for creating test doubles for test and I use many more other libraries. Now we will see the extended demo of this tool. So you must be wondering like how this code is written, right? So let me show you the code which is creating a to do. This is very small chose which is just eight lines of code. You can see I have a create to do which is parameterized which has title. I am calling post request. So if you see this looks like a programming language, you can see the syntax highlighting as well. Post request I can pass URL text this text is like a text template. I can pass. I can provide variables as well over here with body object title title. Now if you see over here, title is nowhere, nowhere asked for or nowhere coded. So this tool uses a principle of correlation. Whatever is not known it will ask the user. So I'll show you quickly what I mean by that. So when I say chose run create to do what is actually happening is it is looking for title within a code within its existing runtime. While this script is running, it didn't find title so it asked user please enter a value for title of type string. I can say bring tomatoes and it ran the journey. Similarly, when I am calling get all to Dos, you will see I'm calling a get request with URL text like this. Now here you will see there is one more correlation happening matching body object result. So this tool has ability to capture response from the rest APIs as well. So if you see get request is done over here. But this additional clause matching body object result will capture the response in the variable result. And here we are printing text template result. So if you see I have used text template with a variable result. So if I say get all to Dos, let's see what happens. Get all to Dos, you will see this code ran get request. It stored the response in result and it printed the result as a single line. You can see this code is just six lines of code and it can produce tremendous results. Now let's talk about get single to do. Okay? Before going showing you the script, I will just run get single to do. Now it is asking please enter value for Id of type positive integer. Like what is the id of the to do? If I say id is three, it gave me the to do with id three. Now let's see, what is the script written for this? So you'll see it is calling a get request. And as we said like this is a text template where we are passing id as a parameter and we are declaring that the id should be positive integer. So while you saw it asked me please enter value of Id of type positive integer. So let's call the same script and let's see if I provide text instead of integer. It says that invalid value. Please enter value of type positive integer, right? So if I say, let's say ten, it gave me to do with id ten. Now you are seeing all this is happening on a server, right? Like to do server. In fact this entire to do server is also written in the journey programming language. You can see how we can do service virtualization. So you can see here what we are doing is we are listening on 9001 with these scriptlets like we are saying on post with URL. This is again text template matching request body object title. So we are capturing variable title from body object and we are creating a to do object. We are pushing it into the temporary variable to Dos and we are responding with status 20 one and body object to do. So. This is like a dynamic service virtualization that we did for entire to do server. In fact we wrote entire to do server in this programming language. Similarly, when I say get all so I am just returning all the to DoS like respond with status 200 and body object to DoS. When I am asking for single to do. I have this text URL as a parameterized id as a positive integer. So it will automatically grab from the URL the number and it will assign id variable that value. The resultant status is 404 and resultant body is to do not found. If this loop doesn't succeed then this value will be remaining as it is. So you will see on the for loop what we are doing is we are searching for that to DoS for. So this variable is iterated and item Id is compared with this id. Now once this id is found then we are setting response body as item and response status as 200 and we are responding with a status r status and a body object r body. So this is how we did entire service virtualization. In case you are interested to have a look at the code of the server. So this is purely written in rust. As I said, there are three major crates which are written over here. One was deleted, course is deleted. So we have only two now. Chose and Corlin, I have examples over here and playground over here like playground. I created just for testing the scripts actually. But if I say chose, if I say cargo test, it will run all my test. The entire project is test driven and you will see all the code written over here has followed the rest structure. We are writing library in journey states, steps and all. So you have seen like this has passed so many test cases. 263 test cases are passed. So this was all about a presentation. Now I'm being to conclude my talk with this demo. Overall, writing a programming language in rust was a very rewarding experience. The tool created and a programming language created has been used by my past employers and present for service virtualization test data creation load testing, hence it had a very well adoption as well. The whole rust ecosystem is a great place for experiments, tools and projects like this. The feared learning curve with Rust had a minimal impact as the programming settles. With Rust, it feels more rewarding to create great code than initial struggle of fighting with language. No wonder why Rust is called most loud programming language and I consider journey programming language is as one of my best work and I feel really proud about creating something that is useful using Rust. I convey my sincere thanks for free peak and canva for all graphics for this illustration. I am thankful to confortito for opportunity to present and entire rust community for awesome support and ecosystem. Thank you.
...

Atmaram Naik

Test Manager @ Sedin Technologies

Atmaram Naik's LinkedIn account Atmaram Naik's twitter account



Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways