Sunday, May 31, 2015

more notes from the Thursday night talk

Chander Dhall's Thursday night presentation feeds notes I have here and here, and what is more...

  • Scalability, performance, responsiveness, availability, and downtime impact are all things to consider per Chander. This long list may be cleaned up a little perhaps to Consistency, Availability, and Partition Tolerance in Brewer's CAP Theorem in which CAP is an acronym for these three items. In a traditional project cost, quantity, and time are often the three variables and while two of them may be set in stone it's not realistic to expect success with all three locked. One of the three varies dependent on the others. In Brewer's CAP Theorem it's the same with the C, the A, and the P. Consistency suggests that nothing gets dropped while partition tolerance means that parts of the system will stay up even when one piece fails as defined in a whitepaper by Seth Gilbert and Nancy Lynch (following upon Eric Brewer's ideas) and that only total system failure should keep the system from being up. (Look for single points of failure and try to eliminate them.)
  • In a sticky session approach to load balancing there are many snapshots of the database and a particular snapshot will be kept in association with a specific user session for data consistency across the session, but the initial session distribution is randomized across the snapshots. This varies from round-robin DNS in which further upstream there are many different app servers and the DNS routing in is comparably varied. Part of Roy Fielding's REST spec is a requirement that no matter what server a hypertext transfer protocol request goes to, the next HTTP request should be able to go to ANY server. This does not cast a favorable light on round-robin DNS, but both of these ideas (sticky sessions too) are bad ideas per the consensus that emerged in Thursday night's talk.
  • fandango.com was praised for its search. It breaks searchable things into four categories that users care about and there isn't any random noise beyond the categorizations.
  • One scales out horizontally and up (adding more RAM and a bigger hard drive for instance) vertically. PolyglotPersistence (as exhibited at the second link I give in this blog posting at the very top) is an example of horizontal scaling. Polyglot as a term implies knowing many languages and I guess Chander's polyglot approach involves many data implementation means. I guess the syntax for interacting with the three merits three different languages.

Saturday, May 30, 2015

ten billion hits a day?

I saw Chander Dhall give a talk called "Best practices for scaling web apps (Platform Agnostic)" at the "Rockstar Developers/Designers Meetup" on Thursday night. The talk started out with theoretic "whiteboardings" in a slide presentation about how an architecture could start for a web application and how attempts are typically made to improve the architecture when it is not enough. Logical abstractions were collected together in dotted-lined circles and rectangles while straight lines denoted physical abstractions such as the app itself and the database starting out running at two different servers in the simplest example before any augmentations/enhancements. That is how we all start isn't it? Going through a list of debunked but once industry-embraced solutions for scaling, Chander eventually began to explain sticky sessions and at this point a member of the audience challenged that he didn't think there was anything bad about sticky sessions and that they were solving his company's scaling woes just fine with millions of hits a day being handled. Chander suggested the need to accommodate millions of hits a day was really a smaller problem than he aimed to tackle in his presentation and that he had his sights set on the biggest of challenges, handling ten billion hits a day in an ecommerce environment. In such a circumstance, yes, sticky sessions are just not enough. The real crème de la crème challenge (the one that really says: "If you can do this you can do anything.") lies in online sales at venues like amazon.com, and herein Chander suggests that one should set one's sights on handling ten billion hits a day, a number, yes, higher than the seven billion that is the population of Earth. The social media space may get the same volumes of traffic, but these guys handle the challenge by caving into it a bit and they can get away with that where online realtors cannot. If we attempt to post to Facebook and something screws up and we have to just try again, well, it's considered acceptable. We are all just numb to that now aren't we? It is not alright to lose sales here and there online. Beyond requests just failing, sales may be lost in lag. Chander sighted many metrics to point to how sales volume decays the slower a site may run, the longer it takes to load the home page, etc. One percent of sales fell off from Amazon when their process ended up taking a tenth of a second longer. There is big money at stake in performance. So let's jump right to the end and see Chander's solution. It involves using three different data solutions at three different pages of a web site at the first three different steps working inward in process. Why not use MSSQL everywhere? Well, joins are expensive. There are faster ways to go than using relational data. And so, three steps:

  1. The entry point should be assumed to be the home page of the site. While some may bookmark locales within ecommerce platforms it should be understood that most webfaring folk will just enter at the home page (the easiest URL to type and remember) and use the search box at the top of the navigation. Chander mentioned that he has never seen a home page hydrated by just one object, and indeed, beyond search, there is likely to be featured products on display at the home page of whatever.com and perhaps the menu system is also database driven. The important thing to keep in mind here is the search trumps all other objects in significance and you will want to get the search loaded and accessible first before you start pulling in the other stuff. Chander didn't explain how to do this, but I guess I'd pull in all secondary concerns by way of AJAX calls with JavaScript tags tucked away just before the closing body tag in HTML. This piece should be facilitated by Elasticsearch or Solr/Lucene. There will be an RDBMS (relational database management system) keeping records for the web site, yes, and to keep it jiving with this piece data we will have to be publishing data over, perhaps in a nightly process. At framesdirect.com this was being done, nightly, to facility Solr searching when I worked there.
  2. Every page one step in from the home page, including, for example, the "About Us" and "Contact Us" pages, but more importantly, the landing pages one finds from searching with products in exposition with pictures and descriptions are driven by NoSQL solutions such as MongoDB and RavenDB, but Chander did not have nice things to say about MongoDB and RavenDB and instead encouraged the use of Cassandra. He didn't spend too much time on why Cassandra, but he did suggest that Mongo drops records. Going back to my framesdirect.com experience, at this point we would be seeing data hydrated from MSSQL (not this middle step) and I wondered aloud how inventory data (i.e. is the product you are looking at actually available for purchase?) could make it up to these pages if the NoSQL data was also, I assume, pushed into place by a periodic process from the RDBMS. Chander suggested that inventory concerns should be addressed at the moment of checkout and not at the moment things are added to a shopping cart. He suggested that his wife will often spool things up in her shopping cart at amazon.com in a wishlist manner and wait days before checking out, so in this scenario the inventory would have to be rechecked at purchase time anyways and the possibility that something was not in stock would have to be addressed then too. If you think about it, the discrepancy between we-have-it-now and we-don't-have-anymore can happen even in the one second fast-as-possible trip between adding to cart and the checkout processing too, especially so at a web site with ten billion hits a day or perhaps in a scenario when tickets are being sold to a rock concert everyone is clamoring to see. You have to have the we-don't-have-anymore logic downstream from here.
  3. Next when we add stuff to a shopping cart we are in the RDBMS data's space. All of the pages to come downstream from here are driven by relational data. The real chokepoints have been addressed before these destinations.

Chander's final architecture looks like what is shown above. There were a lot more new (for me) things I learned about in this talk. Expect further blog postings on this subject matter.

a settings module in DotNetNuke

After one makes a module for the guts of a page as described here, one may give the web user control a separate web user control to drive its settings. While logged in as "host" one may see the settings for any one page by picking "Settings" from that menu which expands from the arrow at the upper left of any page. To make a "Settings" just make a new .ascx and then add a new moduleControl at the appropriate package at the .dnn file. This time the controlKey should contain "Settings" and the controlType should be "Edit" however. In the .ascx you may place controls and these controls may be interpreted at the other module. In the app I am looking at now we have some inheritance magic going on beyond the norm of DotNetNuke so a code snippet wouldn't really make sense assuming the default DotNetNuke wire-up. (sorry)

Make a new page in DotNetNuke!

  1. Strictly speaking, the .ascx which populates a page (comprises its guts) is not a part of the page itself. This piece is a module. Let's assume our new page is to have a new module though. Making both a new page and a new module is a bit more painful than just making a page standalone as there seems to be an assumption that in most circumstances administrators will just use the baked-in canned modules, but, doing things the hard way, the first step is to just make a new web user control in Visual Studio. Look at what the others inherit from at their code behinds and mimic this.
  2. The packages in a .dnn file are an important wireup for a page/module pairing. Copy and paste an existing entry into the file and then doctor it up to reference your .ascx at controlSrc. (There should be one module control in moduleControls and it should not define a controlKey, i.e. have an XML tag which just closes, and should have "View" as the controlType.)
  3. Make sure your templates are up to date from source control. In the root of your application folder there will be a "Portals" folder which will have a folder inside of it of your naming (er, your company's naming) which has your templates.
  4. Log in as host at the application.
  5. Make sure the templates are up to date within the application itself. Click the "admin" link at the ribbon at the top of the app and then the "Site Settings" icon on the page full of icons which appears. Finally, click the "Update" link at the very base of the "Site Settings" page which appears.
  6. Go back to the page full of icons and click on "Pages" instead of "Site Settings" this time. Make a page here.
  7. Edit Internal.sitemap back in Visual Studio to get the page to appear in the menu system.
  8. Visit your new page. From the arrow at the upper left (assuming you're logged in as "host") expand the menu and pick "Delete" to delete the default module. You will next add your module here.
  9. Click the "host" link at the ribbon at the top of the application and then click the "Portals" icon. You need to export the portal templates from here. As I type this I cannot really remember exactly how to do so. It looks like you may do so in an onesies and twosies way with the "Export Portal Template" option from the menu that expands from the arrow at the upper left.
  10. Commit to source control anew.

Addendum 7/12/2015: I believe "Module Definitions" will let you update templates. I have following notes on "Module Definitions" with regards to adding a module:

  1. Edit the .dnn file to add a module.
  2. Change the version number at the top of the .dnn file.
  3. Log in as host.
  4. Click the "Host" link at the top navigation and then the "Module Definitions" icon.
  5. Pick "Create New Module" from the menu that comes from that downward pointing arrow at the upper left.
  6. "Create Module From:" should be set to "Mainfest" and some of the other dropdowns should be comparably set to allow you to select your .dnn file.

Addendum 7/14/2015: "Module Definitions" will NOT let you update the templates. After you add a module, add it to a page to flip the No to a Yes for the line item at the list at Module Definitions. Make sure your new page isn't already in the sitemap in the wrong place too when trying to add a page to the sitemap.

Addendum 7/16/2015: Remember to click the "Include Content" checkbox when exporting a template.

Friday, May 29, 2015

My superior has a power supply for his Mac which doesn't plug in but instead sort of attaches to the side magnetically.

This keeps the end from being damaged when it is jerked away.

godaddy is no longer doing certificates for that which is not a public facing web site

modern, tricky security...

four things to say regarding AngularJS

  1. http://www.w3schools.com/angular/default.asp seems like a pretty good getting started guide.
  2. https://github.com/johnpapa/angular-styleguide is a guide for good code of sorts which Darryl Parker suggested in a meetup.com comment while also offering:
  3. "While in Rome, do as the Romans do. While working with Angular, I suggest following the Angular patterns. Angular has it's own dependency injection that works really well. " ...in response to a question I posed about whether it was wise to use an AMD pattern with Angular. I guess it is not wise.
  4. I saw Chander Dhall give a talk on "Best practices for scaling web apps (Platform Agnostic)" last night and he mentioned that he thinks Angular is dying. He said the two way binding has memory leaks and that the Angular team is to deal with it by just doing away with the two way binding in version 2.0. React is an emerging alternative. Chander seemed the most impressed with Aurelia however. A guy in the audience mentioned Meteor.js too. The link I provide here suggests it is of (tied to?) MongoDB and Node.js.

Thursday, May 28, 2015

sleep

Supposedly this is the kill code that one may text message to an iPhone to make it power off, but a coworker texted it to me in experimenting today and my phone didn't react at all.

Mung

...stands for "Mash Until No Good" or "Mung Until No Good" per Wikipedia which also suggests it may be spelled munge. dictionary.com suggests that the verb means to screw up or destroy. Both sources suggest the dirtying may be a reversable process. You'd mung a string to make it unreadable.

ng-view requires ngRoute in AngularJS.

...and by ngRoute I mean angular-route.js. The views for controllers will appear in the div decorated with ng-view in the ngRoute way of doing things.

Wednesday, May 27, 2015

Any unit tests which are not run as a part of a continuous integration process are worthless.

...or at least nearly worthless. They are like oysters that are never opened. They might have edible meat inside or even be spinning a pearl, but if they are never cracked then they are... I dunno, I guess the oysters could be paperweights. It's like a stock that trades at one percent of its real value. I guess it does have some value, but, well if you're using oysters as paperweights I think no one has showed you what to do with oysters. The continuous integration process should freak out whenever a developer checks in code that breaks a test "embarrassing" the developer and keeping developers from thus sabotaging the code base. Without this crashing behavior developers can just check in code that breaks a test and eventually will and eventually at least some of the written unit tests will break when run standalone. The team will notice too late and eventually become passively numb to the silly tests that provide no value because they haven't worked in three months.

Tuesday, May 26, 2015

chrome://extensions

...going to this URL in Google Chrome will show a list of your extensions and allow you to activate and deactivate them.

The ternary operator can come in handy in conditionally prepping a using statement in C#.

public void EnableOrDisableUser(User user, bool isToEnable)
{
   using (IFoo foo = _bar.CreateThing(isToEnable ? _constants.On : _constants.Off)
   {
      foo.Whatever(user, isToEnable);
   }
}

 
 

What is above seems superior to...

public void EnableOrDisableUser(User user, bool isToEnable)
{
   if(isToEnable)
   {
      using (IFoo foo = _bar.CreateThing(_constants.On)
      {
         foo.Whatever(user, true);
      }
   } else {
      using (IFoo foo = _bar.CreateThing(_constants.Off)
      {
         foo.Whatever(user, false);
      }
   }
}

Did you know that you may have a space after a dot in C#'s dot-dot-dot syntax?

For example this:

var foo = Bar.Baz.Qux;

 
 

...may be written like this:

var foo = Bar.Baz. Qux;

 
 

...and it will still work just fine.

Did you know that just typing the name of a .bat file will provide the command to run the .bat file in PowerShell?

.\Whatever.bat

...will run Whatever.bat, for example, assuming the Whatever.bat is in the folder at hand. Running the .bat file from PowerShell instead of just double-clicking on it will allow you to get some reporting if things go badly. Also, for more on PowerShell see: this

Monday, May 25, 2015

Make a new folder for bookmarks in Google Chrome.

  1. click on icon with three hotdogs at the upper right
  2. expand the Bookmarks submenu
  3. right-click within the Bookmarks submenu
  4. pick: "Add folder..."

Saturday, May 23, 2015

I saw Darryl Parker speak on Protractor testing for AngularJS on Wednesday night at eBay's offices.

When I attempt to retrace the steps he undertook in his setup at my own laptop like so:

  1. node --version
  2. npm --version
  3. npm install protractor -g
  4. webdriver-manager update
  5. webdriver-manager start
  6. mkdir e2eTest
  7. cd e2eTest
  8. touch config.js
  9. touch test.spec.js

 
 

I hit a brick wall at the third command (where g stands for global, FYI) and cannot continue making the rest of what is to come impossible to navigate. Grr. I guess I'll type up my notes nonetheless, huh? The last two lines create two files, the first a config file and the second a file which contains an actual test. One should then run the test with:

protractor config.js

 
 

webdriver-manager will run on port 4444. Jasmine (BDD stuff) is used as the default testing framework. Selenium is used by Protractor to empower the end-to-end testing. A Julie Ralph seems to have spearheaded Protractor's creation. By default, Protractor will only work with AngularJS and try to find (demand/require) the angular var, but this may be sidestepped with a particular setting allowing one to end-to-end test anything with Protractor. That said, the $httpBackend mocking for the backend (REST calls in a stereotypical AngularJS application that lives standalone and not as the frontend to a C# app) will obviously not work beyond AngularJS itself. Darryl prefers to use directive testing in AngularJS when he can but falls over to end-to-end testing when he cannot. In his presentation he walked us, the audience, through many red/green/refactor traditional approaches to writing tests. Anyways, the config file looks like this:

exports.config = {
   seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
   specs: ['*.spec.js']
};

 
 

The config file points to all files ending in .spec.js as tests to run. The one test we have so far looks like this:

describe{'Protractor Demo', function(){
   it('should show a title', function(){
      browser.get('http://juliemr.github.io/protractor-demo/');
      expect(browser.getTitle()).toEqual('Super Calculator');
   });
});

 
 

http://juliemr.github.io/protractor-demo/ is a super simple calculator app that Julie Ralph made in AngularJS that is being tested in this case. This URL could obviously be swapped out with your own. A more complicated example which puts values into the calculator, clicks the button, and then verifies the result will look like so:

describe{'Super Calculator', function(){
   it('should add two numbers', function(){
      browser.get('http://juliemr.github.io/protractor-demo/');
      element(by.model('first')).sendKeys(1);
      element(by.model('second')).sendKeys(2);
      element(by.id('gobutton')).click();
      expect(element(by.binding('latest')).getText()).toEqual('3');
   });
});

 
 

Alright, the button is found here by just having an id of gobutton, but the first and second inputs are found by ng-model settings, which, like the id, may just be observed as inline tag attributes by looking at the HTML itself. by.binding('latest') however matches up to {{latest}} in source code which will not be visible to observers looking directly at the HTML wrapping the 3 which just looks like this:

<h2 class="ng-binding">3</h2>

 
 

Darryl knew about the binding (yes, the thing in double curly braces) by way of pulling Julie's source code from her GitHub. If you are testing your own Angular app, obviously, you too will have access to and knowledge of these "invisible" bindings. The two tests above both pass.

Friday, May 22, 2015

.Trim() in C# will clean away trailing tabs and line breaks too.

not just spaces!

Make a YouTube movie loop endlessly.

I try to walk two miles every day, but when the weather outside is frightful I often just pace in my apartment. When I do, I like to zone out to the noise of a music video playing on YouTube in the background. This begs the question, how may I make such a video loop so that I do not have to keep touching my laptop as I pace? The trick is to go to a URL formatted like so:

http://www.youtube.com/v/CHANGEME?version=3&loop=1&playlist=CHANGEME

 
 

The CHANGEME part needs to be... changed out! For example, let's use this URL which contains the best thing I've ever seen on YouTube:

https://www.youtube.com/watch?v=ZLvIyme2MU4

 
 

To make this movie loop we take the part of the URL after the equals sign and replace the two CHANGEMEs with it like so:

http://www.youtube.com/v/ZLvIyme2MU4?version=3&loop=1&playlist=ZLvIyme2MU4

 
 

This how-to is stolen outright from this:

https://www.youtube.com/watch?v=NiFjxxwJp7M

Thursday, May 21, 2015

Looks like there was a problem. Not authorized to perform action: Invalid key

When this error materializes inappropriately in Rally, get out of it. Close the browser. Open a new browser. Log in anew. Try the thing you were doing again.

The old return false JavaScript trick should keep a DevExpress button from making the callback happen too.

<dx:ASPxButton ID="Button" runat="server" Text="save" AutoPostBack="false">
   <ClientSideEvents Click="whatever" />
</dx:ASPxButton>

...a super simple example might be if the button above utilized:

 
 

function whatever() {
   return false;
}

Your American credit card should work in Canada.

I was telling a coworker about last week's trip to Canada today and he said that when he went himself that he didn't exchange cash for cash and that instead he was able to just pay everywhere with his regular credit card. He didn't offhand know how the exchange rate behaved behind the scenes in these transactions. If just one U.S. dollar is spent like one Canadian dollar that would be a bit painful I suppose.

When I went I just immediately drove to a friend's house and then at her bank she exchanged cash on my behalf. I turned five hundred U.S. dollars into like five hundred sixty-nine in Canadian currency which would be a nearly fourteen percent increase I guess. This exchange rate is not so ridiculous that it would be fantastically painful if one gets cheated a little bit or even just pays the American price for everything really. You can handle it if it's just for a trip.

The friend I visited is one Felisha Storring. This photo was taken at: bon echo

This blog posting is really just an excuse to show off the pictures I took.

This was a mural in Kingston, Canada.

This is Collins Bay, a prison full of pedophiles and rapists, per Felisha, which is also in Kingston. It may be awful inside but the exterior is pretty cool... fun... aesthetic

This is Lake Ontario at Kingston. I was in the Ontario part of Canada during the whole of my trip.

Sharbot Lake also made for a good photo.

...or two!

I drove to Canada and I spent a night in Carrollton, Kentucky on the way. This is a gaudy piece of art there called: "Tree City"

This is a close up of the metal leaves on the tree.

This is yet more local crazy in Carrollton, Kentucky.

The goats seem peaceful.

I know Felisha because she has the child of my now deceased best friend from high school Ben Burns/Ben DeSilva/Ben Harris/Ace. His name is Kadence Martin.

Addendum 5/22/2015: Kadence is the younger of Ben's two sons, not THE child.

When editing with the web forms designer and using BOTH DevExpress controls and DotNetNuke...

Do not be shocked if the various projects in your solution at /DesktopModules/yourfolderhere/ start ending up with this in their Web.config files...

<handlers>
   <add type="DevExpress.Web.ASPxClasses.ASPxHttpHandlerModule,          DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,          PublicKeyToken=b88d1754d700e49a" verb="GET,POST" path="DX.ashx"          name="ASPxHttpHandlerModule" preCondition="integratedMode"/>
</handlers>

 
 

...and do not be shocked if a version conflict with the same line of code in the root Web.config causes DotNetNuke to fail to serve up .css and .js files. Weird gremlin. Fix the problem by stripping out this addition, not from the room Web.config but from the nested ones. You don't need this stuff, not here.

PIVOT is the strange magic to rotate a table in T-SQL.

I don't understand it yet. It will put the ids for rows as columns on a new in-memory table.

.ClientVisible versus .Visible for DevExpress controls

The .Visible does what .Visible does for regular ASP.NET web forms controls in that true is the default and causes no effect while false hides the control outright and ensures that not even a ghost of a control makes its way up into the HTML that gets rendered out. The audience beyond anyone who can see the .aspx markup and C# code behinds gets no inclination that the control exists. In the .ClientVisible implementations however the false state just decorates the control with a display:none; style to hide it from view, but the control is still there if you look at the HTML rendered out and values will still be passed from the controls. A hacker should be able to hack these controls into passing values other than their defaults.

When a falsy check against undefined returns a ReferenceError in JavaScript...

...something like this will bubble up to the console...

Uncaught ReferenceError: foo is not defined

 
 

...and something like this is a better way to deal with the falsy check:

if (typeof myThing != "undefined") {
   myThing.useMyMethod(true);
}

 
 

Interesting links to do with the same subject matter:

Tuesday, May 19, 2015

create a user in T-SQL

USE [My_Database]
GO
CREATE USER foouser FOR LOGIN [foo\myuser]
GO

Ctrl-I you search as you type in Visual Studio 2013.

A selection will jump around in the file at hand, finding the first match and adapting to your keystrokes as your keystrokes change up what the first match is. It's like Ctrl-F for find, but in an as-you-type way.

Unchecking "Enable Just My Code" may uncheck the "break on all exceptions" stuff.

Going to: DEBUG > Options and Settings... ...brings up the "Options" dialog box wherein going to: Debugging > General > Enable Just My Code ...one may find this checkbox. One should then doublecheck that at: DEBUG > Exceptions... ...all of the checkboxes have not become unchecked. You may wish to recheck them. When a DotNetNuke application fails to spin up and throws an opaque, unhelpful error unchecking "Enable Just My Code" and then doing the "break on all exceptions" trick might be a good way to figure out where the application is blowing up.

when a DotNetNuke app starts rerouting to /Install/InstallWizard.aspx

...it cannot see the DotNetNuke database for some reason. Make sure the database is up and then reset IIS. Today I went into "Services" and turned the SQL Server Agent (MSSQLSERVER) on and then back off again to jog MSSQL Server into shaking itself out of a funk.

Have a placeholder value in a fill-in-the-blank box until one starts typing in it in the name of being helpful.

http://www.html5tothepoint.com/placeholder.htm has the following example of a placeholder value at an input type HTML tag.

<input type="text" placeholder="sample text">

Monday, May 18, 2015

BULK INSERT in T-SQL

BULK INSERT dbo.MyTable
FROM 'C:\Whatever\stuff.txt'
WITH (ROWTERMINATOR='0x0a');

 
 

This assumes that MyTable has one column that is a varchar or nvarchar type and that stuff.txt is a WordPad file full of little blobs of copy separated by line breaks. Each line will end up as row value for the one column in MyTable which may then be queried anew to have its goodies (now in a database table and not a flat file) made sense of in other ways. MyTable will probably then just be dropped like so:

DROP TABLE dbo.MyTable

 
 

0x0a signifies the line breaks. This factoid makes this blog posting a little more informative than this one.

software for swipecards at doors

one example is: Doors.NET

The "Output" pane should appear when you debug in Visual Studio 2013. Start scrolling downward through it to find the first error.

This is a particularly good way to figure out what is really wrong when a solution won't compile and barfs back a hundred errors across numerous projects. Many of the errors exist because a project is dependent on another project which cannot compile. In this madness one must lay hands of the first error that is blocking up everything else. Find the first error in the "Output" pane. Read from top to bottom until you see an error.

Sunday, May 17, 2015

In C#, it seems easy enough to do .ToArray on an IEnumerable just like doing .ToArray on a List.

IEnumerable<int> foo = (new List<int>() {1,2,3,4,5}).Where(x => x > 1);
int[] bar = foo.ToArray();

Supposedly if you like General Mills on Facebook it makes it hard (impossible) to sue them.

They have a legal loophole for this apparently. It could be the beginning of lots of companies doing the same. It's terms-of-use engagement mischief.

Thursday, May 14, 2015

HDR stands for High Dynamic Range

This offers this explaination: "HDR, as its name implies, is a method that aims to add more "dynamic range" to photographs, where dynamic range is the ratio of light to dark in a photograph. Instead of just taking one photo, HDR uses three photos, taken at different exposures. You can then use image editing software to put those three images together and highlight the best parts of each photo. In the case of HDR on smartphones, your phone does all the work for you"

Wednesday, May 13, 2015

tech insights from Felisha Storring

Felisha mentioned Portrait Professional and TAAZ as tools she uses ontop of just Photoshop to clean up modeling photos. She said that TAAZ recently made it such that one could only upload web-sized images into it's online interface so it is now less awesome. She Felisha's handiwork at: http://www.lilythefairy.com/Photo-Gallery.html

Sunday, May 10, 2015

how to unit test the HttpResponseMessage "Content" handed back from an ASP.NET Web API controller

I found the async/await answer for the challenge I detail here and it looks like so:

[TestMethod]
public void test_controller()
{
   var task = Whatever();
   task.Wait();
   string stuff = task.Result;
   Assert.AreEqual(stuff,"I like cats!");
}
 
private async Task Whatever()
{
   var myModel = new MyModel();
   var myController = new MyController();
   HttpResponseMessage response = myController.Post(myModel);
   Byte[] myBytes = await response.Content.ReadAsByteArrayAsync();
   return System.Text.Encoding.Default.GetString(myBytes);
}

 
 

This is how one sniffs out a type. The type does not have to be a string.

how to remove a city from that "Weather" app on an iPhone

For iOS 8.1.3 (12B466), go to the list of cities by clicking the icon at the lower right that you see upon first entering the app and then swipe any one list item leftward when you get a list of items to expose a delete button. I'm not in love with Mac's UI. Maybe it makes sense once you know what you are doing, but this stuff is hard to self discover. I had to Google it. Also with the UI going flat and changing so much from version to version I am convinced that the "feel" for the mobile space is undefined and if one makes an HTML5 app which emulates iOS they are in fact making a copycat dinosaur. I digress.

LINQ stand for Language Integrated Query

This has some copy on it. I guess it is not just of C# and that VB.NET has it too.

 
 

Addendum 1/10/2019: The title should have the word "stands" in it not the word "stand" in it. Parallel LINQ is what PLINQ stands for.

Friday, May 8, 2015

still struggling to unit test HttpResponseMessage

Assume we want to return a HttpResponseMessage from a controller with a string inside of "Content" like so:

return new HttpResponseMessage
{
   Content = new StringContent("I like cats!")
};

 
 

Naturally, the string may be something a lot more useful than "I like cats!" as it could be a serialized type! How would we slurp this data back out in a unit test to affirm that it is what we expect. I don't know yet. I am able to get the "I like cats!" string back out into the cattyCopy variable below...

[TestMethod]
public void test_controller()
{
   Whatever();
}
 
private async void Whatever()
{
   var myModel = new MyModel();
   var myController = new MyController();
   HttpResponseMessage response = myController.Post(myModel);
   Byte[] myBytes = await response.Content.ReadAsByteArrayAsync();
   var cattyCopy = System.Text.Encoding.Default.GetString(myBytes);
}

 
 

But everything in the Whatever method happens asynchronously so there is no way to get an assertion inside to fail in a way that fails the test_controller method. The solution probably has to do with Tasks. I hardly ever play with async and await so I'm really green to it all.

When catching an exception in C#, if you're not going to do anything with the exception itself, you don't have to name it.

You might do something with...

catch (Exception exception)
{

 
 

...but if you're going to do nothing with it itself specifically you may just open the catch block like so:

catch (Exception)
{

Wednesday, May 6, 2015

getting back null from .Returns in NSubstitute

If this is normal mocking...

Repo.GetLastName(Arg.Any<string>()).Returns("Smith");

 
 

...why won't this work?

Repo.GetLastName(Arg.Any<string>()).Returns(null);

 
 

For some reason NSubstitute, in expecting to return a string in this example, cannot associate a null string with the string type. It's authors seem happy to let us do some of the work ourselves and thus we must undertake a wire-up like so to hack around the inability to use one line of intuitive code.

string nullString = null;
Repo.GetLastName(Arg.Any<string>()).Returns(nullString);

 
 

If you need an interface to come back null you have to do it the same way too.

Does the I in iFrame stand for Inline???

This suggests as much. I didn't know.

Citrix NetScaler

...is a tool for rolling out application deployments to a datacenter.

bash is a particular type of shell for Unix

This suggests the name means: Bourne Again SHell

Tuesday, May 5, 2015

throw exceptions from NSubstitute

Suppose you might normally mock a repository call in NSubstitute like so...

Repo.GetLastName(Arg.Any<string>()).Returns("Smith");

 
 

Alight, well how would you emulate the repository just blowing up as if the database were unaccessible. What then? Try this:

Repo.GetLastName(Arg.Any<string>()).Returns(x => { throw new Exception(); });

TTFB stands for Time To First Byte.

Wikipedia suggests this metric measures how responsive (speedy) a web server is in beginning to stream the bytes for a requested thing. TTYL is Talk To You Later.

Monday, May 4, 2015

interfaces as reference types in C#

In looking at some stack overflow threads it doesn't seem like interfaces must strictly behave as reference types, but they will in NSubstitute's Substitute.For implementations and that opens up some interesting approaches for testing long (or longish) workflows wherein there exists a series of hurdles to be cleared. Consider this controller...

using System.Net;
using System.Net.Http;
using System.Web.Http;
using Hurdles.Core.Interfaces;
using Hurdles.Core.Objects;
namespace Hurdles.UserInterface.Controllers
{
   public class PersonController : ApiController
   {
      private IPersonRepository _personRepository;
      
      public PersonController(IPersonRepository personRepository)
      {
         _personRepository = personRepository;
      }
      
      public HttpResponseMessage Post(Person person)
      {
         if (person == null)
         {
            return Request.CreateResponse(HttpStatusCode.NotImplemented, "Person not given.");
         }
         
         if (person.SocialSecurityNumber == null)
         {
            return Request.CreateResponse(HttpStatusCode.NotImplemented, "SSN not given.");
         }
         
         if (_personRepository.IsExisting(person))
         {
            return Request.CreateResponse(HttpStatusCode.NotImplemented, "SSN preexists.");
         }
         
         if (_personRepository.IsCriminal(person))
         {
            return Request.CreateResponse(HttpStatusCode.NotImplemented, "Criminal!");
         }
         
         person = _personRepository.SavePerson(person);
         return Request.CreateResponse(HttpStatusCode.Created, person);
      }
   }
}

Again, there are a few hurdles to be cleared here in the name of a happy pass success and two of them revolve around the external dependency on IPersonRepository which we will mock in test. For a happy pass test to succeed in which a person is created, a person must first pass a sanity check to ensure that it does not have a preexisting social security number and must then moreover pass a sanity check to ensure that the individual is not "looked up" to found to be a criminal. (It's a goofy example. I admit it. Whatever.) All of the tests below pass and they are listed sequentially in the order of a process which validates each step in the controller's workflow sequentially. Our workflow is really little more than a straight path with some hurdles set up upon it like so:

The thing to observe in the tests is how interface method signatures may be mocked only when the time finally comes to mock them, reconfigured when needed, and then left to be in future tests. For example, setting .IsExisting to return false needs to only to be done once in the second to last test even though .IsExisting must return false for both the last and second to last test. Once such a setting is made, the setting is stuck until reset. All the modifications befall the same pointer which is reassigned to a new controller at the beginning of each test. You can probably imagine how this might keep code clean in a sequence three or four times as long as the example here.

using System.Net.Http;
using System.Web.Http;
using Hurdles.Core.Interfaces;
using Hurdles.Core.Objects;
using Hurdles.UserInterface.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
namespace Hurdles.UserInterface.Tests.Controllers
{
   [TestClass]
   public class PersonControllerTests
   {
      private PersonController _director;
      private IPersonRepository _prop = Substitute.For<IPersonRepository>();
      private string _scene;
      
      [TestInitialize()]
      public void SetupTest()
      {
         _director = new PersonController(_prop);
      }
      
      [TestMethod]
      public void lack_of_person_causes_failure()
      {
         _director.Request = new HttpRequestMessage();
         _director.Configuration = new HttpConfiguration();
         HttpResponseMessage httpResponseMessage = _director.Post(null);
         httpResponseMessage.TryGetContentValue<string>(out _scene);
         Assert.AreEqual(_scene, "Person not given.");
      }
      
      [TestMethod]
      public void lack_of_social_security_number_causes_failure()
      {
         Person actor = new Person();
         _director.Request = new HttpRequestMessage();
         _director.Configuration = new HttpConfiguration();
         HttpResponseMessage httpResponseMessage = _director.Post(actor);
         httpResponseMessage.TryGetContentValue<string>(out _scene);
         Assert.AreEqual(_scene, "SSN not given.");
      }
      
      [TestMethod]
      public void preexisting_social_security_number_causes_failure()
      {
         Person actor = new Person() { SocialSecurityNumber = 457555462 };
         _prop.IsExisting(Arg.Any<Person>()).Returns(true);
         _director.Request = new HttpRequestMessage();
         _director.Configuration = new HttpConfiguration();
         HttpResponseMessage httpResponseMessage = _director.Post(actor);
         httpResponseMessage.TryGetContentValue<string>(out _scene);
         Assert.AreEqual(_scene, "SSN preexists.");
      }
      
      [TestMethod]
      public void preexisting_criminal_history_causes_failure()
      {
         Person actor = new Person() { SocialSecurityNumber = 457555462 };
         _prop.IsExisting(Arg.Any<Person>()).Returns(false);
         _prop.IsCriminal(Arg.Any<Person>()).Returns(true);
         _director.Request = new HttpRequestMessage();
         _director.Configuration = new HttpConfiguration();
         HttpResponseMessage httpResponseMessage = _director.Post(actor);
         httpResponseMessage.TryGetContentValue<string>(out _scene);
         Assert.AreEqual(_scene, "Criminal!");
      }
      
      [TestMethod]
      public void happy_pass()
      {
         Person actor = new Person() { SocialSecurityNumber = 457555462 };
         _prop.IsCriminal(Arg.Any<Person>()).Returns(false);
         _prop.SavePerson(Arg.Any<Person>()).Returns(new Person() {Id = 1} );
         _director.Request = new HttpRequestMessage();
         _director.Configuration = new HttpConfiguration();
         HttpResponseMessage httpResponseMessage = _director.Post(actor);
         httpResponseMessage.TryGetContentValue<Person>(out actor);
         Assert.AreEqual(actor.Id, 1);
      }
   }
}

Friday, May 1, 2015

Assert.Fail in C#

...is a way to make a unit test fail. Use it like this:

Assert.Fail("This thing went south.");