Unit Tests - Task Scheduler for testing FTP Extension

I just got here from the other forum.

Here is a Unit Test that I just built for testing the functionality of the FTP extension.

Result: The extension works great, no problems for what I need to do.
Hitch: Of course, if you call it over and over quickly, you will not like your results, it is non-blocking.
Solution: Using a method like this you can Queue requests and fire them when ready, in order.

(others can show you a much better way, but this is simple and it works for Unit Tests)

(The picture is high definition, open in new tab and zoom if you want to see it)

High Level:
Since the functions are not blocking (which is good!) it is possible to crash them into each other. Lets say you have a button called “Create Directory”. IF you press that once. Great. If you press that 3 times fast, undefined behavior. This can be illustrated better by creating numbered directories using a for loop. If you try to create 20 directories quickly, you may get 3 or 10.

Adding a delay is awful. Dont do it.
Adding a blocking function is awful. Dont do it

The whole idea is to do other stuff (or sleep the CPU) between processing tasks which must be executed in order. If your code is nowhere doing nothing, THAT IS GOOD.


Novice Solution:

What I do is queue up button requests
The first request is acted on
The next request can not be acted on until the first completes… (but it is not lost or crashed)
If you press the button 5 times, you will get 5 consecutive FTP actions with no collision.

I also dump logs to the terminal

Drawback: This can create a nasty user interface, so don’t do this :slight_smile: If you do, set limits to how far in the hole your user can get. Nobody likes a bunch of stuff happening 20 seconds later (sigh).

Things of note: I process returns differently. Sometimes we expect an action to fail, sometimes we want to take drastic action if it does.

Decomposing the output: (Same picture as above)


Create a new file
Try to create it again (fails of course)
Try again
delete the directory (works)
Try again (Throws Critical Error, blows out buffer)
Press Create 3 times in a row fast (all three run, runs as expected


I guess this is why Python folks have the concept of TRY.

Some things work
Some things may or may not work
Some things do not work
Some things must work (or you want to start over)

… A framework like this is how you can get past simple hurdles of testing. I am not saying it is good, I am saying that it works.

… End of the day? MIT AI2 is absolutely a TOOL and not a TOY. Ignore anyone who teases. Folks acted the same way about LabView, and LabView is a VERY POWERFUL tool.

(not posting the .aia because it requires a plugin to run)


1 Like

Please remove the “1 picture per post rule” for new members. That does not make a lot of sense.


after reading your posts in the old forum, I think, you are talking about my ftp extension?

without renaming the extension it would have been easier to identify...

thank you for your tests!


Trying to push the limits! Snippets, Tutorials and Extensions from Pura Vida Apps by Taifun.

Correct. This is the Tailfun FTP extension.
This is the second extension I have tried.
Both arrived quickly and both did exactly what they said they would do.

Here is Unit Test 2
“Datalogger that creates Folders and Files on an FTP site”

When you press “Add File” the following happens:

  • Year folder created or confirmed
  • Inside of that month folder created or confirmed
  • Inside of that day folder created or confirmed
  • Inside of that datalog file created and uploaded

Note that you can not create the Day folder inside of a month folder that does not exist yet. . . and you can not rely on every FTP server to act the same. So this script executes FTP commands one at a time in sequence.

If you press AddFile 30 times in a row, then in the background of your app, the actions will occur, in order. In the screen shot you can see that I started with a clean directory (which you can use until I delete it)

username: AI2
password: Sandbox#01

Dir created
Dir created
Dir created
File created
File uploaded

And on the second pass, we anticipate and accept that those folders already exist.

The purpose of these posts is to help people understand the difference between code that executes single thread and code which is multi-thread friendly. Multi-threading is obviously what you want, but when some folks first play with it they get confused.

Use a framework like this and your Validation become automated and more reliable.

The next step is to read in a .TXT file with a long list of “Unit Test” which exercises the interface, times the interactions, and provides a long PAS/FAIL list.

Pics in the next post


1 Like

Here is the function that executes and uses our FIFO queue.

I urge the young programmer not to get all wound up about being clever or doing something more and more efficient. There is always a more efficient way to do it and the important thing to do is get to MVP.

I always write 3 versions

  1. The rough cut to confirm everything works
  2. After feedback, the second cut which is looking pretty good
  3. The third cut, where some polish is allowed - this one ships

In the old days we would write everything very inefficient on the FIRST CUT. The reason was very simple. If you spent a bunch of time getting something working, then later had to add a bunch more code, it may turn out that it would not work. Back then there were slow processors, little memory, and no advanced compilers. (like doing ASM on microcontroller)

Anyhow - I still go that route.

Then, when Jr Engineer comes onto team… you allow them to go thru the code and make it better. This justifies the time they spend. Some refactor from scratch. Some replace repetitive functions. Some formalize. Some just fail and never figure it out.


1 Like

This is the code behind the screen shot that demonstrates that you can set up an automatic datalogger which is RELIABLE to an FTP sign-in (So Server Agnostic)

When you hear people gripe about FTP it is usually because they are using delays and not waiting for actions to complete, therefore losing data.

Obviously more checks are needed, but I do not do “retry”
My opinion is that it should work and if it does not, just start over.

The code as it rests will probably hang forever if there is no valid FTP target, so handle that case.


1 Like

My experience so far with MIT AI2

  • It works

  • Its functionality is growing, visibly

  • It can be extended, so it can do near anything

  • It does not scale super well. Frustrating. I would suggest the gods of this effort use LabView for a while to see some of the ways they overcame the limits of Graphical Programming.

  • The official documentation is hard to find or sparce in places, but the forums and Google cover just about any question that can not be answered by “run it and see”.

I use only MIT AI2 for development of all my phone apps. I have a 7yo, and by the time he is ready, I want to be a master of this so that I can make it look as easy as it is.


1 Like

If you see this code and thing “This is crazy man, his code makes no sense!”

You must ignore the names and think of it the way functions work on the stack behind the scenes on old computer - maybe Windows 95

blocks (16)

In School (undergrad 1998 - 2001) we studied Assembly Language and C++ language. We were given tasks like:

  1. Write function in Assembly Language
  2. Write function in C Language
  3. Go in and out of “Stack” to directly manipulate variables

… Dangerous business, but it teaches how functions pass arguments and how Reverse Polish Notation works.

The code above, just think of it as a Struc.
The List, to me, is just an array of 4 variables each Struc
Variable 1, is a key word
Variable 2-3 can be used however you like

It only makes sense when you look at it thru this lense

  1. We are only doing 1 thing at a time
  2. The FIFO queue pushes and pops

So… When you push something onto the queue… At that time… you pay attention
1st location, that is reserved for the key word, which is parsed by the execute function like a SWITCH

Location 2 and 3 hold arguments. . . and this is how it used to be… you would push onto Stack your function name followed by your arguments - only it was not 2D array like this, it was 1D array… so lots of counting forward and backward of Nibble, Byte, Char, Unsigned Int, Int, etc…

There were no floats or doubles, these did not even exist in Assembly Language. Not even Int, we only had Register.

… anyway

Have fun and write your code however you like. What is most important is NOT that you write the code just perfect like other people do.

What is MOST IMPORTANT is that you actually write your OWN CODE and do not copy others (if you are in school!) You will never learn if you do not write your own code, it is impossible.

When you graduate, someone like me will hire you. I WILL require you to write much code. . . and it will be apparent right away if you have not mastered programming.

I am old
I have already finished BSEE and MSEE programs then worked for 20 years in Engineering… so I get to cheat and use others code, like this FTP Extension.

My metrics for success are

  • Get something reliable working FAST!

Where as the students metrics for success are

  • Learn how to learn
  • Learn how to love to work hard
  • Learn that nobody is perfect and we only answer to
  1. LOGIC

So first your code must compile
Second your code must be rational and reasonable
Third… your code must execute quickly enough to meet requirements.


1 Like

Here are the Server Side results of the test above.
These correlate to the screen shot and code pictured

Notice the time stamps match.

So… I am going back to where I came from… but I am Test Engineer and we want more Test Engineers.

The Above File Upload method will be converted to the following:
-Folder for Part Number
-Sub Folders for Serial Number
-Test Reports time stamped by Server

Then, after that, a helper function on the server parses out the data from the files into SQL database so that Quality can graph and parse etc.

For this you need to use XML or JSON. . . as online server has no way to know what your CSV or TAB delimited datalog files are

Anyway - that is what real work looks like. I hope kids here learning do well in school and I promise you will get a job earning more than others if you apply yourself and become a valuable programmer.

See you next time.


the system is not used to a beginner in the community, who posts valuable contributions like you...
thank you for this...
usually beginners in the community only ask questions... :wink:

thank you for your feedback!

Hey Tailfun

I have seen you answer thousands of questions and help hundreds of people.  I have done that before on other forums and I know how much work it is.  I am only a lurk here.  I have helped no one.

I wanted to stop in and say hello because I know there are many young people who are nervous and confused...  not sure what to do in life.  I want them to know that if they work hard that their sacrifice will be rewarded.

Just like I am sure you are rewarded by the contributions you make… sometimes it takes years… but in the end… working hard to help others… is how the world becomes a better place.

… I am off to go produce Proofs of Concept and Minimum Viable Product to the people who employ me… but I always stop in to recognize the efforts of what I am building on and the efforts of those who support.

This is a good programming language with full support. Anyone who can not get it to work, they just need to keep working at it.

Real Engineers - we spend 20hrs at a time solving problems. Sometimes 20 days. Sometimes even 20 years.

Have fun

… When folks graduate with their degree in Science… you can find Hiring Engineers like myself who will give you your first job at a competitive rate. …

Then the real learning begins (sigh :slight_smile:



So the next question that the new Test Engineer asks is…

“How do I port my Unit Test over to my Working Code?”
This is hardest question to answer.
Here is “a” solution, which is not a good one, but works


This is not yet perfect, but I do the following:

  • Clearly mark all your Variables and Functions with what they are… like “FTP_xxxxxx”
  • Get rid of anything on the front panel that is not required
  • Get rid of any functions that you do not intend to use immediately
  • Put all the code in a clump
  • Put examples of the function calls with the arguments missing

… I am now going to try and copy that over to my working project.

I included only:

  • Create DIrectory
  • Upload File
  • Multithread to Single Thread task scheduler (to manage Synchronous FTP interface)

If I did my job well… then when I go back into my already working code, I can leverage these tools I built to meet my deliverable objectives.

… With time… AI2 will find better and better ways to merge codes in an Object Oriented way. The idea of “Importing a Class” will get to the user level.

… Then we can build infinite tools in any language. Eventually, it will not matter what language you write in if you have INPUT, OUTPUT, DEPENDENCIES.

Programming is fun

I will report back and show a version of my full code. It is QUITE LARGE - many screens. . . I am afraid I will reach the limits of AI2 but I have not yet.

I do this same work on Arduino
Arduino is FANTASTIC and it is extremely powerful, beyond what we ever hoped.

I use Adafruit Feathers with Featherwings to work with AI2. It is not easy, but it absolutely works… just as good as anything else I have ever seen.

Learning AI2 is a worthwhile investment. Invest in kids. Kids… they do not want to worry about all this syntax. Syntax is a distraction from the true hurdles of programming. Understanding the paradigms.


Here is the finished product.
The difference between ABOVE and BELOW is that I have stripped out all front panel interactions.

  • Created a Global Variable for DUMPLOG
  • Created a Global Variable for CURRENT_STATUS
    (So we stripped out all the green)

The dump log you can used… clear it and search it as needed
(Can be done better)

The current status can be used… say to show on the front screen.

Many times the demo’s people give are reliant on front panel objects. I imagine this causes grief while merging together two projects. Dont know, have not done it but once or twice.

I can say that what I have here WILL MERGE…


thank you for your kind words...
I would like to invite you to continue providing contributions in that high level...
we need more people like you!


1 Like

the extension only works using the playstore app installed no?. or you can download the extension for using inside your own aplicattion?