Archive for the ‘Server Side’ Category

7Oct

Lately I’ve been working on a client/server side validation library. I had a need to chain a bunch of methods together, and what that meant was a need to modify how the original functions were called without changing them. This lead to a need to pass some variables into a function and still wait to accept more parameters later. I already knew about currying, which I will summarize as being able to pass as many variables as you feel into a function. A couple other techniques were needed to solve this.

First I learned about the apply and call functions (I know I am late to the party…). In this case apply was extremely helpful, it let me set a context (change the value of this) and collect some parameters together and pass them into a function.

Next I discovered partial applications. This is more of a technique than anything else. In iz we have the following source code:

function validator_partial(fn) {
    //get all arguments except the first, which is the function name
    var args = Array.prototype.slice.call(arguments, 1);
    //pass the "value" in as the first parameter so that the user of this library doesn't need to
    args.unshift(value);
    //return a new function
    return function() {
        //combine all arguments made to this function with the ones above
        var allArguments = args.concat(Array.prototype.slice.call(arguments)),
        //get the result
        result = validators[fn].apply(null, allArguments);
        //update this object
        if (!result) {
            if (typeof this.error_messages[fn] !== "undefined") {
                this.errors.push(this.error_messages[fn]);
            } else {
                this.errors.push(fn);
            }
            this.errors.push(fn);
            this.valid = false;
        }
        //return "this" to allow for chaining of methods
        return this;
   };
}

for (var fn in validators) {
    //for each function, call the partial and pass in the function
    if (validators.hasOwnProperty(fn)) {
        Iz.prototype[fn] = validator_partial(fn);
    }
}

At the bottom I am grabbing the validators, and assigning them to the prototype of the Iz object. Before the validators get called though they go through a partial. This partial is a function that returns a function. The closure allows you to house some variables within it. When the returned function gets called it has access to the outer one’s scope, which is how you are able to pass in parameters before and after the function is called. On top of that this system lets you pass in as many params as you need and it simply forwards everything on.

With this method I was able to replace all of the first parameters (the ‘values’ with the value from the Iz object. This means less typing, which is always nice!

Share/Save
12Jan

So, I read this article a couple days ago: http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way . As a result I started pulling my hair out. I decided that is too much work. Perhaps CakePHP 1.3 fixed some of the issues mentioned in that document, but no one has really documented anything. In any case, it took a few days of experimentation, but I got a nice template going. I see a ton of people interested in testing now a days, one thing to remember when you are starting out is that we are only testing controllers, and as such should only test what THIS controller is doing. Controllers in this sense only transfer data from one place to another, add a little bit of data, and really function as  glue between models, views, components, utility classes etc. SOOO you should not be testing auth methods or if data is saved (thats what the tests for those classes are for. Furthermore, don’t test cake internal functions.

A couple more notes before the code…
– You need to set your debug level to 3
– This was a test straight from a CakeTestCase I started working on
– I tried a few ways to get access to auth/session data. This seemed to be the easiest way to do this. Simply login to your site with the user level that you’d like to test (or stay logged out). I tried to manually set the session data. I think cake doesn’t like that, and kills your session as a result.

<?php
/**
* @author parris
*/
class LrapackagesControllerTest extends CakeTestCase{
    /**
    * These should go somewhere more global
    */
    private function genRandomString() {
        $length = 10;
        $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
        $string = '';
        for ($p = 0; $p < $length; $p++) {
            $string .= $characters[mt_rand(0, strlen($characters)-1)];
        }
        return $string;
    }

    private function genRandomDouble() {
        srand((double)microtime()*1000000);
        $randomnumber = rand(0,5);
        return $randomnumber;
    }

    function startCase(){
        echo "<h1>Starting LrapackagesController Test Case</h1>";
        $this->path = APP_PATH.'/lrabuilder/lrapackages/';
        $this->testPackage = array(
            'Lrapackage'=>array(
                'name'=>$this->genRandomString(),
                'part_number'=>$this->genRandomString(),
                'version'=>$this->genRandomDouble()
            ));
    }

    function endCase(){
        echo "<h1>Ending LrapackagesController Test Case</h1>";
    }

    function startTest($method){
        echo '<h3>Starting method '.$method.'</h3>';
    }

    function endTest($method){
        echo '<hr/>';
    }

    function testAdd(){
		$result = $this->testAction($this->path.'add',array('data'=>$this->testPackage,'method'=>'post','return'=>'vars'));
		if($_SESSION['Auth']['User']['role_id']==1 || $_SESSION['Auth']['User']['role_id']==2)
		  $this->tAddLoggedInUser($result['cakeDebug']->data['Lrapackage']);
		else
		  tAddPublicUser($result);
	}

    function tAddLoggedInUser($data){
        $this->assertEqual($data['name'],$this->testPackage['Lrapackage']['name']);
        $this->assertEqual($data['part_number'],$this->testPackage['Lrapackage']['part_number']);
        //I would assertWithinMargin, but since the data needs to be identical, I don't need that.
        $this->assertEqual($data['version'],$this->testPackage['Lrapackage']['version']);
        //1000 is selected arbitrarily, but I dont care about real accuracy here.
        $this->assertWithinMargin(strtotime($data['created']),strtotime(date('Y-m-d H:i:s')),1000);
        $this->assertEqual($data['user_id'],$_SESSION['Auth']['User']['id']);
    }

    function tAddPublicUser(){
    	//echo($result); the only bad thing about this method is that you need to decide what the return var is before you
    	//have the session info... however, assuming you have properly setup your acl you shouldn't even need this test...
        //let the acl tests confirm that logged out users dont have access to logged in areas!!
    }

    function testIndex(){
        $result = $this->testAction($this->path.'index');
        //debug($result); this results in an overwhelming amount of data, be selective of the output!!
    }
}

Questions?

Go forth and unit test :)!

Some useful docs:

http://simpletest.org/api/SimpleTest/

http://simpletest.org/api/SimpleTest/Extensions/PHPUnit_TestCase.html

http://simpletest.org/api/SimpleTest/UnitTester/UnitTestCase.htm

http://book.cakephp.org/view/1210/Testing-controllers

16Sep

credits: http://www.tipb.com/2010/03/03/google-comments-apple-htc-patent-lawsuit/

First of, sorry for not posting a ton lately everyone. Been busy with letswoosh.com, rockin with Doomsday Machines, and making cool stuff at NetApp. In any case, if you are on this page, you have probably been searching endlessly for a way to get flash on your iP[ad|hone]. At work, we had a request straight from the VP of our department that ended up on my desk. “We would like to get about 200+ sales people to view training through mobile devices, namely the iPad,” was essentially the gist of the request. Well it just so happens that all of our training is done in Flash,  and around here they don’t seem to be big fans of going back to javascript. They asked me to come up with solutions.

There are essentially three ways I found that differ vastly from on another.

  • Jailbreak, then “un-jailbreak” once you install flash (I am not going to go into all of that)
  • Use smokescreen (source), a javascript version of the flash plugin, but it does not seem to work for interactive flash apps.
  • Provide a browser through a “VM”. That is host an app through some software server in the cloud.

Jailbreaking is out. We are not about to go to war with apple (although someone should). Smokescreen won’t really work out, plus it is not very “corporate ready,” which leaves us with the VM/cloud/SaaS solution. So via iPhone/iTouch I found an app called Cloud Browse. This is pretty nifty it is essentially Firefox hosted up in the cloud. It works, but there are some pitfalls. First of all, its unsupportable. If one of our clients says “ITS NOT WORKING” angrily all we can say is try again later? Also, it could potentially cost a ton, and its not a fixed cost. That is we need to buy subscriptions for each person who wants to use the app so they don’t end up on the generic/anonymous connection pool that may or may not get a connection depending on popularity at that moment in time. Do I need to mention that if you are going through some VPN service you are essentially exposing all your delicious corporate secrets? Lastly, it looks like crap on the iPad.

I mentioned the VM solution to my manager, and he said “OH, that kinda sounds like something Citrix probably does.” I did some research and found 2 must have apps and a pretty rockin video that explains a few things.

Step One (setup a server that doesn’t quite work yet for practice and experimentation):

Time to take down a fighter jet... Credits to: http://www.graphicsdb.com/img77239.htm

First thing you should do is follow the steps in the video below to get your Amazon cloud account all setup with XenApp 5.0. The AMI mentioned in the video doesn’t work with the iP[hone|ad]. I believe the AMI mentioned in the last link will work out though.

Next, log in and open up your “desktop” app, which may take up to 10 minutes even if it says “running” in amazon, server error means its still starting up. You will see all sorts of warnings about XenApp not having licenses, logins failing, terminal services needing licenses, but this is all normal and if you can open internet explorer you are doing just fine. At this point you may want to try adding apps into Citrix Access Manager, which is extremely easy (if you have a question about it feel free to ask in the comment section). I installed Firefox, Adobe Reader, Flash and AIR. I then installed an AIR application and was able to create apps in the manager tool. I used Firefox, the air application, and adobe reader.

Step Two (configure apps and reconfigure iP[ad|hone] and try it out):

You may want to add a new user. We will use this user to connect to the server via the iPad. The cool thing about having individual accounts is the same as doing so on a normal machine. Users can save their own settings and preferences. The same is applicable here.

Now go through App Store on the iPad. You can just download the Citrix Receiver for free. Go ahead and use your IP address as both the address and domain. You need have your username in the format: ComputerName\Username. If you are now able to open your web browser and launch it. Everything is working fine. Go to youtube.com and open up a video. There should be some choppiness as is expected, but hell it works. It may not be 24->30fps, but it gets the job done, and its supportable/secure.

Pricing:

At an enterprise level. This is extremely affordable. You only pay for XenApp once. The receiver is free. You may need to purchase Windows Server 2008 if you are doing this internally. Then for about 60 concurrent users we are looking at around 5 grand total. This is much more affordable than redeveloping a ton of software. One thing to note though. You should assess how much interest there actually is around all of this. The last thing you want to do is have a person dedicate about a week of their time trying to set this thing up and have no one ever use it.

Disclaimer:

Finally, let me put up a little disclaimer. I know nothing of these sorts of things. I just had a business need and tried my best to figure out how to get this to work. Questions shouldn’t necessarily be directed at me. Honestly I am not a subject matter expert for XenApp, Citrix, Windows Servers or iP[ad|hone]. Most of this stuff was pulled from best guesses and gleaned information. I will do my best to answer questions if I do receive them. In any case, I hope this was helpful to someone :)! Now I open the forum… Any other ideas?

https://www.citrix.com/English/ss/downloads/details.asp?downloadId=1864025&productId=186
5Jan

So after much debate on how a useful CMS should function in this day and age I decided that a CMS is no longer something like joomla, and in fact should function like wordpress but allow for easy plugin development as well as management. Many of you already know my love for cakephp. I have many plugins already developed for cake, and other people do as well so my team’s current plan of action is to create a plugin manager of sorts… The way I see it, thats all a CMS essentially should be when everything in cakephp can essentially be a plugin. The plan is to load it up with some basic plug-ins that we have created (that can be replaced easily if desired); however, there may only be 1 or 2 core MVCs for settings purposes, auto updating and possibly a really slick GUI… I think the plugin manager as well as everything else can be a plugin, which allows for a great deal of modularity.

I feel that wordpress has it down right; however, services on linux machines like apt (synaptic) also work well to consider different repositories in existence, which I find ideal. Trying to host all plug-ins from 1 centralized source or even serve them through 1 centralized source isn’t the correct solution… instead it is better to simply allow different repositories to be added manually. That being said, we are currently trying to develop this plug-in we will see where it leads, but things are looking bright :).

Ideas? Comments?

10Nov

UPDATED: Nov 11th, 09 , changes: added python info

I have been struggling to find a way to get around selenium’s onload deficiencies. I tried all sorts of ways to hack up my script, but alas it mostly ended up in turmoil. Onload is one of the main ways most developers use to make sure certain actions happen in code, and my entire content bed was about go into flames before I found the light at the end of the tunnel. A magical gift from the heavens known as AutoIt saved me from a timely demise…

All retardedness aside… (sarcasm)..

AutoIt really did solve this problem for me. It may not work so well for others.. it depends on your situation. For me a simply wanted to close a popup window after it loaded from a different windows onload and then click the popup’s confirmation’s Ok button. Then close the original window that started all the madness…

The cool thing about running the code below is that it just runs as a daemon of sorts in the background waiting for some unruley popup to be struck down with Wrath of Kahn, plus it can also test for popups with different names. I am hoping I can do some sweet regex stuff, otherwise, life may prove difficult. In any case here is my AutoIt script:


While True
   If WinWait('Name of the final Popup', '', 1) == 1 Then
     ;Wait for page to load if found
     Sleep(10000)
     ;Close Page
     Send('!{F4}')
     Sleep(5000)
     ;Confirm Dialog
     Send('{ENTER}')
     Sleep(1000)
     ;Close Lanucher Page
     Send('!{F4}')
   EndIf
   ;Let another thread have a turn
   sleep(3)
WEnd

Now, lets say you want the above to be directly embedded into your script rather than have it constantly running externally. I personally use python for my Selenium scripting so in python you can do the follwoing (which is the equivalent of the above script).


from selenium import selenium
import unittest, re, time
from datetime import date, datetime
from xml.dom import minidom
from win32com.client import Dispatch

# Auto it window closing stuff
def autoItCloseWindows(self):
   auto = Dispatch("AutoItX3.Control")
   #Your Popup Name Here is the name of the window...
   #I did this because different windows could open for my project
   if (auto.WinWait("Your Popup Name Here", "", 1) == 1):
      # chill
      time.sleep(5)
      # close window
      auto.Send("!{F4}")
      # wait
      time.sleep(2)
      # confirm dialog box
      auto.Send("{ENTER}")
      time.sleep(5)
      # close the launcher window
      auto.Send("!{F4}")

To run this script you mainly need selenium, time, autoit3 and win32 dispatch. To download win32 stuff for python click here. Another thing to note is that this will only work for windows. There are similar solutions available for *nix. If you are using a mac to do things like this it is probably a waste of your mac ha, but there are also similar solutions.

Good luck oh weary travelers…