Saturday, February 1, 2014

Animated Javascript Julia fractals

Let us start from something basic. Let's take x with the initial value of 1. The next value will be computed by multiplying the previous value by 2. This gives us a new x and we apply the same rule to it.

More formally,
        x0 = 1
        xn+1 = 2 * xn
gives us the sequence: 1, 2, 4, 8, 16, 32 ...

What if the initial value was not 1 but, for example, 1.0001? The second value would be 2.0002, then 4.0004, 8.0008, 16.0016 ... The sequence is predictable, although we have started from different initial value, we can easily predict the n-th value.

Let's examine another sequence:
        xn+1 = 4 * xn * (1-xn)
If an initial value is from the [0,1] range, all sequence values also belong to [0,1] (why?). Similarily to what we have done before, let us examine two sequences starting with two different but close initial values, for example 0.2 i 0.2000001. We will see how sequences are related.

Few initial iterations don't reveal anything suspicious:
 xa=0.2000000, xb=0.2000001, difference=0.0000001
 xa=0.6400000, xb=0.6400002, difference=0.0000002
 xa=0.9216000, xb=0.9215997, difference=0.0000003
 xa=0.2890138, xb=0.2890147, difference=0.0000009
 xa=0.8219392, xb=0.8219408, difference=0.0000015
 xa=0.5854205, xb=0.5854166, difference=0.0000039
 xa=0.9708133, xb=0.9708160, difference=0.0000027
 xa=0.1133392, xb=0.1133291, difference=0.0000101
... but somewhere around 20-th iteration we have
 ...
 xa=0.8708927, xb=0.0382300, błąd=0.8326627
 xa=0.4497544, xb=0.1470737, błąd=0.3026806
 xa=0.9899015, xb=0.5017722, błąd=0.4881293
 xa=0.0399860, xb=0.9999874, błąd=0.9600014
 xa=0.1535486, xb=0.0000503, błąd=0.1534983
 ...
Both sequences seem unrelated at all. A disaster!

Such behavior of sequences is called chaotic. The discovery of chaotic sequences was quite a shock for scientists who believed that this is only a matter of time to create formulas for all laws of nature. It turned out however that many simple formulas behave in such chaotic way.

Imagine that we would like to predict weather. We'd like to have a formula that given some measured values (temperature, atmospheric pressure, humidity) computes the temperature for tomorrow and then next week or next year.

For years scientists believed this is possible. However, our simple experiment proves that if such hypothetical formula would be chaotic (and would it be?) then the formula could possibly give quite a good prediction for the very next day and the day after but could completely fail to predict weather for 20th day and later.

But the story continues. Such simple sequences could have a beautiful graphical interpretation - fractals! Such fractals are parts of the world that surrounds us, just like atoms. And unlike atoms - which are not eternal - fractals are perfect and eternal.

Fractal Julia Sets "live" on the two-dimensional plane. They are graphical interpretations of a following sequence:
        x0 = coordinates of a point from the plane
        xn+1 = xn * xn + c       (1)
(where c is a fixed complex number)

We assume that the fractal image is the [-2,2] x [-2,2] subset of the comple plane. Each point from the image corresponds to one and only one point from the subset (with a simple linear correspondence).

Well then, we have a point, the x. How do we compute x * x? What does it mean to multiply point by a point?

Well, each point from a plane can be interpreted as a complex number. Complex numbers can be added, subtracted, multiplied and divided. For example, a square of point (1,1) is (0,2), and (1,2)*(2,-4) gives (10,0).

The algorithm of generating a Julia set consist in computing the sequence (1) for each point of our complex subplane. The sequence either reaches a bounded orbit or values "run away" to infinity.

We color points that give a bounded orbit as black and points that "run away" to infinity as white.

And that's all. We can create our very first Julia set for the c of the definition (1) equal to 0 (complex 0 + 0i).


Wow, a circle! Is this even a fractal? Well, let's have another Julia for c equal to (0,1) (complex 0 + 1i).
What happened to the circle? Well, this is a perfect example of chaos. Those points of the complex subplane that give sequences with bound orbits create the dendrite.

Another interesting thing about Julias is that these sets are symmetric, consist of two identical parts reflected by the origin of the plane. This is not a coincidence - a sequence x -> x * x * x + c would give three symmetric parts, x -> x^4 + c - four and so on.

The code:
$.noConflict();
 
var cx = 0, cy = 0, kat1 = 0, kat2 = 1;
var WJulia = 768;
var HJulia = 768;
var contextJulia;
var pixJulia;
var imgdJulia;
var idJulia;
var frame = 0;
 
function SetupJulia()
{
    clearInterval( idJulia );
 
    var elemJulia = document.getElementById('JuliaCanvas');
    if (elemJulia && elemJulia.getContext)
    {
        contextJulia = elemJulia.getContext('2d');
        if (contextJulia)
        {
            if (contextJulia.createImageData)
                imgdJulia = contextJulia.createImageData(WJulia, HJulia);
            else
                imgdJulia = contextJulia.getImageData(0, 0, WJulia, HJulia);
 
            pixJulia = imgdJulia.data;
        }
    }
 
    idJulia = setInterval(LoopJulia, 3);
}
 
function LoopJulia()
{
 
    kat1 += 0.003;
    kat2 += 0.007;
    cx = 981 * Math.sin(kat1);
    cy = 983 * Math.cos(kat2);
    frame++;
 
    /* tworzenie bitowego obrazu */
    RysujJulie();
 
    /* kopiowanie bitowego obrazu do context/canvas */
    contextJulia.putImageData(imgdJulia, 0, 0);
    contextJulia.font = "bold 12px sans-serif";
    contextJulia.fillStyle = 0;
    contextJulia.fillText( frame, 20, 20 );
}
 
 
function RysujJulie()
{
    var px = 0;
    for (var i = -2304; i < 2304; i = i + 6)
    {
        var py = 0;
        for (var j = -2304; j < 2304; j = j + 6)
        {
            var c = 0;
            var x = i;
            var y = j;
            var x2 = x * x;
            var y2 = y * y;
 
            while (((x2 + y2) < 4000000) && (c < 31))
            {
                c++;
 
                y  = ((x * y) >> 9) + cy;
                x  = ((x2 - y2) >> 10) + cx;
                x2 = x * x;
                y2 = y * y;
 
            }
 
            SetPixelColor( pixJulia, (py * WJulia + px) << 2, 
              255, 255-(8*c), 255-(6 * c), 255 - c );
 
            py++;
        }
 
        px++;
    }
}
 
function SetPixelColor(pix,offs, a, r, g, b)
{            
    pix[offs++] = r;
    pix[offs++] = g;
    pix[offs++] = b;
    pix[offs] = a;
}
 
jQuery(function() {
  SetupJulia();
});

Enough theory, let's see it moving.

Monday, January 27, 2014

ADFS2.0 and the maximum number of groups

Another subtle issue with ADFS2.0. This time it turned out that the maximum allowed token size is set rather low to 8192 bytes. This means that ADFS is fixed to issue at most two federation cookies to persist its internal user session.

What if the token should be larger, for example user belongs to many security groups?

Well, ADFS just doesn’t issue its own cookies. As a result, user inputs her correct credentials and instead being redirected to a RP application, the ADFS login page is rendered (as there are no cookies indicating a correct authentication) again. The RP is even not hit at all.

In one of our environments, it turned out that somewhere around 100 security groups was the limit. For users with more groups, the login page is rendered forever, accepting credentials but returing to the very same page.

Fortunately, the limit can be changed. Unfortunately, it is stored in a internal class. To raise the limit, reflection has to be used. Put this in ADFS’s global.asax or even in the static constructor of the login page (FormsSignIn.aspx.cs):

public partial class FormsSignIn : FormsLoginPage
{
    // Static constructor, added to the existing class
    static FormsSignIn()
    {
            // raise the limit of the internal cookie size 
            Type federationPassiveAuthentication =
                typeof( FormsLoginPage ).Assembly.GetType( 
                    "Microsoft.IdentityServer.Web.FederationPassiveAuthentication" );
 
            federationPassiveAuthentication.InvokeMember( "SsoMaxSize",
                System.Reflection.BindingFlags.SetProperty |
                System.Reflection.BindingFlags.Public |
                System.Reflection.BindingFlags.Static,
                null,
                federationPassiveAuthentication,
                new object [] { 100000u } // new limit
                );           
    }
    
    // The untouched code
    protected void Page_Load( object sender, EventArgs e )
    {
    }
 
    ... untouched code follows
 

Looks ugly but works. With this technique, we are able to get ADFS to issue the maximum allowed number of cookies until ultimately the “Request Headers too long” exception is raised by IIS indicating that there are too many cookies to be handled.

(and unfortunately, I was not able to work this around)

In our scenario, this change allows users to have up to 300 security groups.

Thursday, December 12, 2013

C# Puzzle No.23 (intermediate)

Closures are interesting and helpful. In short, closure is a function that can be exposed to the outside world that captures part of its external environment, even though the environment could be private to outside world.

This puzzle involves following short snippet inspired by the Javascript: Definitive Guide book

// create array of 10 functions
static Func<int>[] constfuncs()
{
    Func<int>[] funcs = new Func<int>[10];
 
    for ( var i = 0; i < 10; i++ )
    {
        funcs[i] = () => i;
    }
 
    return funcs;
}
 
...
 
var funcs = constfuncs();
for ( int i = 0; i < 10; i++ )
    Console.WriteLine( funcs[i]() );
 
// output:
// 10
// 10
// ...
// 10

Side note: closures in Javascript work very similar and the output of corresponding Javascript snippet would be the same

function constfuncs() {
  var funcs = [];
  for(var i = 0; i < 10; i++)
  {
    funcs[i] = function() { return i; };
  }
  return funcs;
}
 
var funcs = constfuncs();
for ( var i = 0; i < 10; i++ )
    console.log( funcs[i]() );

End of side note

Your task here is not only to explain the behavior (easy part) but also correct the inner loop of the constfuncs method so that the code outputs

0
1
2
3
4
5
6
7
8
9

More specifically, you are allowed to modify only this line of code

funcs[i] = () => i;

You are free to propose a solution for the JavaScript version as well. The book doesn’t provide one, if you are interested.

Monday, December 2, 2013

Basic tests in Apache JMeter part 2/2

In the previous post we have recorded a basic JMeter test. This time we start with adding an assertion to validate test results.

Multiple assertions can be added to each requests. However, in our simple demo we need a single assertion on the last request just to check whether or not the user is succesfully logged into the application.

Right click the last request and add a Response Assertion. In my particular case, the last page renders the message with the logged in user name. In the response assertion page I add a Pattern to test, the message I expect to see at the last page of the session. If you run the test now it will most probably fail, as the controller lacks the cookie manager, so add one (Add/Config Element/HTTP Cookie Manager) and check the “Clear cookies at each iteration?” checkbox at the cookie manager configuration tab.

The screenshot shows the Response Assertion configuration tab with the pattern to test set to my custom expected message (it says “The logged in user is <username>” in Polish).

Response Assertion with custom text If you run the test now and check the results tree, you will most probably see a green icon beside all requests which is a notification of success. Play with the assertion pattern to verify that the assertion really works – a failed assertion marks the request with a red icon at the results tree view.

The last element of the tutorial is modification of POST requests. In my particular scenario, one of the responses returns a SAML token which should be posted in the very next request. However, the recorded session replays the same token every time, the token that was returned in the response body during the recording of my session. This is because JMeter only records and replays requests and it has no knowledge that one of returned parameters should be POSTed in the next request. Because of that, my recorded session works correctly for few hours and then the SAML token will no longer be accepted by the target server (the server will complain that the token is too old).

I start by locating the request that returns the SAML token. I can use the View Results Tree which shows detailed requests and responses. Here it is, the SAML returned in the response of one of my Default.aspx pages:

SAML token response

I right click the node corresponding to the request under my controller and add a post processor (Add/Postprocessors/Regular Expression Extractor). The postprocessor allows me to provide a regular expression and assign its match value to a variable I can use in consecutive requests. At the postprocessor configuration tab I provide necessary parameters: name – SAMLToken, regular expression – name=”wresult” value=”(.*)” /><input (to capture the whole SAML token), template – $1$, match – 1, default value – NOVALUE (more on the extractor here).

Extractor configuration

Then I go to the very next request (LoginPage.aspx) and at the Parameters tab I inspect the list of posted parameters. In my example there are three parameters sent to the server, wa, wresult and wctx, all three have fixed values taken from the recorded session. I am going to modify the wresult parameter to refer to the newly created variable, SAMLToken.

I have two options, I can provide a bare value (${SAMLToken}) or an unescaped value (${__unescapeHtml(${SAMLToken})}, I choose the latter.

Referencing the parameter And this is it, the token value read from the response is correctly referenced in the consecutive request. There are other JMeter fuctions that can be used there.

I can now configure the thread group to simulate more concurrent users and verify the correctness and the performance under different load conditions.

Basic tests in Apache JMeter part 1/2

Apache JMeter is a fine tool for different types of web tests – compatibility, performance, integration. This post is about recording, running and parametrizing basic tests.

First, start by running JMeter, you start with an empty Test Plan. Give it a name and add a Thread Group to the Test Plan (right click the Test Plan node and select Add/Threads/Thread Group).

Thread Group Thread Group represents a set of “users”. As you can see, you can modify the number of threads (users) and the ramp-up period. This is handy for testing your application for multiple concurrent clients.

Next step would be to set up an HTTP Proxy Server and a Recording Controller. These two will allow me to “record” the browser’s session instead of creating all requests manually.

Right-click the WorkBench node and add a Non-Test Element, HTTP Proxy Server. Add a Recording Controller to the Thread Group. In the HTTP Proxy’s settings tab, select the newly created Recording Controller as the target controller.

Target Controller Now start the proxy (Start button at the bottom of the settings tab), open up my web browser (any browser will do) and set the proxy to http://localhost:8080. If you are on Firefox, remember to set the proxy for each protocol (including HTTPS) (Tools/Options/Advanced/Network):

Firefox network setup

Now navigate to a web site you want to test. Each action is recorded under the recording controller.

To be able to replay the sequence of tests and see the results, add a listener to the thread group, the View Results Tree listener. Now you can click the Start button (or select Run/Start from the menu) and click your listener to see the replayed session. Use the Clear All button (Run/Clear All) to clear the listener.

Recorded session in the tree listener

In the next post we will create basic assertions and also modify the flow so that values returned from requests are used in consecutive posts.