Openstack: nova resize

To change RAM size, VDISK size or VCPU count of an openstack instance you have to use nova resize. You can't change for e.g. just the RAM size with a parameter, you have to assign a new/other flavor. If there is no suitable flavor for the new properties of the VM, create a new one.

nova resize [--poll] <server> <flavor>

The resize could take a while, after it is finished, the VM boots up with the new specifications. SSH into the VM and check if everything is alright...

Jasmine: Testing complex types for equality

Jasmine comes with two matchers that test for equality. The first is toBe:

expect(first).toBe(second)

toBe passes when first === second. Unfortunately this is useless for non-primitive values because JavaScript is a horrible language.

However, Jasmine comes with another matcher toEqual:

expect(first).toEqual(second)

This matcher behaves as a human would expect for types like the following:

  • Arrays
  • Objects
  • Nested array/object constructs
  • Regular expressions...

Mocking time in Jasmine specs

The easiest way to freeze or travel through time in a Jasmine spec is to use the built-in jasmine.clock().

  • After jasmine.clock().install() you can use it to control setTimeout and setInterval.
  • Using jasmine.clock().mockDate() you can mock new Date() (which returns the current time in Javascript)

While you can use SinonJS Fake timers, using the built-in Jasmine clock will save you an extra dependency.

Pierce through Javascript closures and access private symbols

If you are writing any amount of Javascript, you are probably using closures to hide local state, e.g. to have private methods.

In tests you may find it necessary to inspect a variable that is hidden behind a closure, or to mock a private method using Jasmine spies.

You can use the attached Knife helper to punch a hole into your closure, through which you can read, write or mock local symbols:

klass = (->

 privateVariable = 0

 privateMethod = ->
   ...

Detecting N+1 queries with Bullet

The Bullet gem is designed to help you increase your application's
performance by reducing the number of queries it makes. It will watch
your queries while you develop your application and notify you when
you should add eager loading (N+1 queries), when you're using eager
loading that isn't necessary and when you should use counter cache.

Rails 4.2 Foreign Key Support

The migration DSL now supports adding and removing foreign keys. They are dumped to schema.rb as well. At this time, only the mysql, mysql2 and postgresql adapters support foreign keys. @rubyonrails

Workings

add_foreign_key(:comments, :users)

adds a database constraint

ALTER TABLE "comments" ADD CONSTRAINT comments_user_id_fk FOREIGN KEY ("user_id") REFERENCES "user" ("id")

Disadvantage

Foreign key constraints double the validatio...

Spreewald 1.2.11 fixes frequent "no alert open" errors on Chrome

When running capybara with Chrome you might start seeing frequent "no alert open" errors when trying to interact with browser dialogs. This seems to be triggered by a recent Chrome update.

Apparently these dialogs no longer appear instantly. Spreewald 1.2.11 fixes the "When I confirm the browser dialog" and similar steps by waiting for the dialog to appear.

How to fix a corrupt (zsh) history file

When you the following error:

zsh: corrupt history file /home/marc/.zsh_history

You can try and fix your history file by extracting only the valid strings:

cd ~
mv .zsh_history .zsh_history_bad
strings .zsh_history_bad > .zsh_history

fc -R .zsh_history # reloads the history

Capistrano 3 has slightly changed its symlink implementation

In Capistrano 2, directories in shared_children used to be symlinked to the shared directory during the finalize_update task.

# <capistrano>/lib/capistrano/recipes/deploy.rb

_cset :shared_children,   %w(public/system log tmp/pids)
# ...
task :finalize_update, :except => { :no_release => true } do
  # ...
  shared_children.map do |d|
    run "ln -s #{shared_path}/#{d.split('/').last} #{latest_release}/#{d}" # <-- symlinks only the last s...

JavaScript events: target vs currentTarget

tl;dr: Use event.currentTarget unless you are absolutely certain that you need event.target.


Since it hasn't been written down in this deck before, here it goes:

When working with JavaScript Event objects, the DOM element that triggered the event is attached to them. [1]
However, there are 2 "opinions" on which element that would be:

  • The element that the user interacted with (event.target),
  • or the element that the event listener is bound to (event.currentTarget).

Note that both can be, but not...

A commitment is not a guarantee - Pivotal Tracker

The team is responsible for building great software—that’s it. It’s the only thing the team is responsible for and it’s the only thing that they actually control. In other words, the development team is committed to quality software.

How to capture changes in after_commit

Your after_commit callbacks will not know about changes, as Rails discards them when committing.

The linked article shows a clever trick to work around that: It uses an after_save method that looks at changes and writes its decision to an instance variable. That instance variable can then be used in the after_commit method.

Note that while callbacks like after_save are not affected, there are valid reasons for using only after_commit, and not after_save. Enqueueing a Sidekiq job is just one of them.

Rails 5+

You can use ...

How to fix: iPad does not trigger click event on some elements

iPads will not trigger click events for all elements. You can fix that, but you don't want to know why.

Example: Capturing clicks on table rows (use case would be clicking the 1st link inside it for better UI). Consider this setup:

<table>
  <tr>
    <td>hello</td>
  </tr>
</table>

^

$(document).on('click', 'tr', function () {
  alert('row clicked')
});

While this works on a desktop browser, clicking the row/cell on an iPad will just do nothing.

Turns out, the iPad will only trigger such events for ...

24 little known CSS facts

This blew my mind today:

Please make sure to check browser support for CSS features on Can I Use and the Mozilla Development Network before using.

Favorites

  • outline-offset: specify how far away from the element an outline is rendered
  • ::first-letter: matches the first letter insid...

Parallel Rspec with RTeX

Running projects parallel makes some trouble with PDF generation. Use geordi rspec spec to force sequential tests for the whole application or failed specs only.


geordi rspec
RTeX::Document::GenerationError in '...'
Could not find result PDF document.pdf after generation.
Check .../document.log

The document will show you, that RTeX tries to generate a PDF document out of a HTML file, which won't work.

Padrino: "incompatible marshal file format (can't be read)"

If you see a stacktrace beginning with lines like this:

E, [2015-07-16T09:23:10.896146 #23308] ERROR -- : app error: "incompatible marshal file format (can't be read)\n\tformat version 4.8 required; 32.32 given" (TypeError)
E, [2015-07-16T09:23:10.896282 #23308] ERROR -- : /.../bundle/ruby/2.0.0/gems/moneta-0.7.20/lib/moneta/transformer.rb:132:in `load'
E, [2015-07-16T09:23:10.896311 #23308] ERROR -- : /.../bundle/ruby/2.0.0/gems/moneta-0.7.20/lib/moneta/transformer.rb:132:in `load'
E, [2015-07-16T09:23:10.896334 #23308] ERR...

emcien/iso_latte

Sometimes you need to run background jobs that you can't make important guarantees about - they may run out of memory and get killed, or produce segmentation faults, or exit! directly - and you need to be able to clean up after such problems.

IsoLatte is a gem that allows a block of code to be executed in a subprocess. Exceptions get passed back to the parent process through a pipe, and various exit conditions are handled via configurable callbacks.

Savon: Use complex SOAP types as arguments

If a SOAP API expects you to call a remote method with arguments of complex types, Savon lets you manually set the xsi:type attribute like this:

client.call(:rpc_method,
  message: {
    :some_object => {
      :name => 'foo',
      :other => 'bar',
      '@xsi:type' => 'somenamespace:SomeObject'
    }
  }
)

This is roughly equivalent to this in Javaland, where you have magic generated stub code:

SomeObject so = new SomeObject();
so.setName('foo');
so.setOther('bar');
client.rpcMethod(so);

Protip: Clone large projects multiple times

Large projects usually have large test suites that can run for a long time.
This can be annoying as running tests blocks you from picking up the next story -- but it doesn't have to be that way!

Simply clone your project's repo twice (or even more often).

When your work on a feature branch is done, simply push that branch and check it out on your 2nd copy to run tests there.
You can pick up a new story and work on that on your "main" project directory.

If you do it right, you will even be able to run tests in both your 2nd copy and your m...

Free advice: show up early

How can a client blame you for a cab driver’s mistake? How can a conference organizer hold you accountable for an airline’s cancelled flight?

They can do it because lateness is part of the order of things, and grownup professionals plan for it, just as they plan for budget shortfalls and extra rounds of revision.

Material Design Lite

CSS (+ some Javascript) framework, implementing Google's material design for static web pages.

Can be used for plain websites without requiring a full blown Javascript framework, unlike the (also excellent) Polymer paper elements, or Angular material.

Prelimiary impression:

I would recommend against using it at this stage, for a couple of reasons:

  • It is much less complete than you might expect from a CSS framewor...

FactoryGirl: How to easily create users with first and last name

In most of our applications, users have their first and last name stored in separate columns. However, specifying them separately quickly gets annoying, especially when proxying them from cucumber_factory:

Given there is a user with the first name "Dominik" and the last name "Schöler"

Wouldn't it be nice if you could just say:

Given there is a user with the name "Dominik Schöler"

and have FactoryGirl assign first and last name automatically? The code below achieves that!

##...

PostgreSQL: Ordering, NULLs, and indexes

When using ORDER BY "column" in PostgreSQL, NULL values will come last.

When using ORDER BY "column" DESC, NULLs will come first. This is often not useful.

Luckily, you can tell PostgeSQL where you want your NULLs, by saying

... ORDER BY "column" DESC NULLS LAST
... ORDER BY "column" ASC NULLS FIRST

Your indexes will have to specify this as well. In Rails, declare them using

add_index :table, :column, order: { column: 'DESC NULLS LAST' }

Multiple columns

When sorting by multiple columns, yo...