Bisecting Python unit test errors to find test interdependencies

Categories: English Geeky

Many of our test runs use parallelization to run faster. Sometimes we see test failures which we can’t reproduce locally, because locally we usually run sequentially; and even then, the test ordering seems to be somewhat unpredictable so it’s hard to reproduce the exact test ordering seen in our test runner.

Most of the time these failures are due to unidentified test interdependencies: either test A causes test B to pass (where running test B in isolation would fail), or test A causes B to fail (where running B in isolation would pass). And we have seen more complex scenarios where C passes, A-B-C passes, but A-C fails (because A sets C up for failure, while B would set C up for success). We added some diagnostic output to our test runner so it would show exactly the list of tests each process runs. This way we can copy the list and run it locally, which usually reproduces the failure.

But we needed a tool to then determine exactly which of the tests preceding the failing one was setting up the failure conditions. So I wrote this simple bisecter script, which expects a list of test names, which must contain the faily test “A”, and of course, the name of the faily test “A”. It looks for “A” in the list and will use bisection to determine which of the tests preceding “A” is causing the failure.

As an example, I used it to find a test failure in Ubuntu SSO:

python bisecter.py  test-orders/loadbad1.txt webui.tests.test_decorators.SSOLoginRequiredTestCase.test_account_must_require_two_factor
273 elements in the list, about 8 iterations left
Test causing failure is in second half of given list
137 elements in the list, about 7 iterations left
Test causing failure is in second half of given list
69 elements in the list, about 6 iterations left
Test causing failure is in first half of given list
34 elements in the list, about 5 iterations left
Test causing failure is in second half of given list
17 elements in the list, about 4 iterations left
Test causing failure is in second half of given list
9 elements in the list, about 3 iterations left
Test causing failure is in second half of given list
5 elements in the list, about 2 iterations left
Test causing failure is in second half of given list
3 elements in the list, about 1 iterations left
Test causing failure is in second half of given list
2 elements in the list, about 1 iterations left
Test causing failure is in first half of given list
The test that causes the failure is webui.tests.test_views_account.AccountTemplateTestCase.test_backup_device_warning

Buying a house in Montreal – Purchase plus Renovations Loan

Categories: English House buying

Renovations We were initially reluctant to consider non-move-in-ready properties, reasoning that we preferred to devote money to a down payment and not have to contend with either moving delays or  construction crews around the house. But if the occupancy dates allow for it, considering a renovation job may be worth it, because it could allow you to snatch a more affordable property (perhaps one that buyers are overlooking because of quirky layouts or being in bad condition, needing a kitchen or bathroom renovation, and so on) and use the saved money to renovate, which instantly raises the property’s value.

If you’re concerned that this will leave you somewhat cash-strapped, there’s an option called “Purchase plus Improvements mortgage”. Essentially it allows you to borrow an extra amount (up to 10% of the value the home will have after the improvements) which will be added to the mortgage.

The rules are somewhat complex, particularly the part where you need a quote from a contractor before finalizing the purchase and loan, and the fact that the money is not advanced to you, but paid after the work is done and an appraiser has verified it’s done as requested, meaning you may need to pay for it upfront – it does defeat the purpose a bit, but consider that you could pay for this work with consumer credit or a line of credit, repay that once the extra mortgage amount is released, and then benefit from the very low mortgage interest rates.

In any case, it’s an option which opens up a good set of properties you may pass over because they need renovation.

I suggest googling for “Purchase plus Improvements mortgage” for more information on the rules, process and limitations.

Buying a house in Montreal – Getting a realtor

Categories: House buying Uncategorized

After visiting the mortgage broker and getting an idea of how much we can afford (oh I just found this link with some very sensible advice on how much you can afford), I wanted to go looking for a realtor to help me wade through the house-buying process. When I mentioned I didn’t yet have one, the mortgage broker offered to refer me to an agency. Sure enough, a few days later I got a call from a realtor who asked about my basic needs and signed me up for Centris, the Quebec equivalent of MLS.

The realtor enters your search criteria, such as price range, number of bedrooms/bathrooms, type of construction, desired neighborhoods and some other features. Then the system will e-mail you when new listings are published. Supposedly you’ll have access to “pre-listings”, but in practice I’ve been able to see the same listings that are published in http://centris.ca.

However, the Realtor-managed site does show a lot of additional information, like more detail on the rooms, better data on building/lot areas, and very importantly, information about closing dates, which may even influence the interest rate you’ll get for the loan.

Additionally, I sent my realtor a list we wrote with the requirements we had for a property. We indicated general building requirements, possible locations, and other wishlist items such as “no creepy basements”, closeness to parks, river and amenities, distance to public transport and so on. She thought this was quite useful to fine-tune the criteria, although since the process is mechanized, there are some criteria the system is not able to verify (e.g. no concept of creepiness on basements).

Keep in mind that the data captured in Centris may be inaccurate, and that could affect the results of filtering. Example: initially we specified we wanted to have a driveway (though not necessarily a garage) and there were very few listings. After we removed the driveway criteria, a lot more popped up, and a lot of them did have driveways! The issue here is that the listing brokers didn’t capture that information. So try to make your criteria as broad as possible, and do part of the filtering yourself, when going through the listings.

Another example: we wanted two bathrooms (even if one of them is a half-bathroom with no shower), but if you ask the system for 2 bathrooms, sometimes it doesn’t consider halfs in the criteria. So even though it’s super important for us, we decided to leave this criteria out and are focusing on visually checking for a second bathroom and/or possibility of building one.

Once listings start landing in my inbox, we compiled a list of houses we wanted to visit and told the realtor about them.

Buying a house in Montreal – the credit report

Categories: English House buying

The credit report

A few of the resources I read mentioned it was a good idea to get a credit report prior to visiting the mortgage lender/broker, so any inaccuracies can be corrected in advance. They indicate the credit report can be obtained free of charge through Equifax or TransUnion.

I went to Equifax (note this was before their 2017 breach – I obviously now recommend you go to TransUnion instead). And their home page is a bit scary offering products protecting you from identity theft (I guess that didn’t help or protect those affected in 2017). But I was only interested in the credit report and score (the score is not necessary but it’s a nice single-number summary of your credit and I though it worth it). They have an option to purchase on-line for $23 so I went with that.

But remember the report can be obtained for free? understandably, this is not terribly visible in their front page, but there it is: “You can receive a free credit file disclosure from Equifax Canada Co. via Canada Post“. That link will take you to a form you can fill out and mail or fax (Fax, really?). So for the cost of a stamp and a bit of waiting you can also have your free credit report.

I was impatient and paid the $23, only to get a scary error when trying to get the report, which necessitated calling Equifax, in the course of the call they tried to upsell me on their credit report monitoring service (it’s cheaper, they said, only $16/month instead of the $23 you’re paying – conveniently not mentioning than the $23 is a one-shot charge). Which product you choose is up to you, just remember to stand your ground if you’re not interested in the more expensive one.

The credit report indicated a reasonably high score and no unusual activity, and should look good to any prospective lenders, so this phase is complete and we’re good to go!

Buying a house in Montreal – the stress test

Categories: English House buying

Stress test

One of the changes to mortgage rules for 2016 in Canada is the creation of the “stress test“, meant to cool down hot real estate markets and keep people from buying houses that stretch their financial capabilities.

If you’re going for a high-ratio (less than 20% down payment) mortgage, lenders are required by law to check your payment capacity as if your loan interest rate were as high as the standard five-year rate (which currently is 4.94%), even if your eventual mortgage will actually be at a much lower (currently around 2-2.5%) rate.

The FCAC calculator makes it very easy to check what your maximum loan will be, once this rule is taken into account. Just enter your information and your expected interest rate to calculate your real maximum mortgage. Next, change the interest rate to 4.95% (I went super safe and put in 5%). It will tell you you won’t qualify, but you can now play with the maximum property value until it shows you you’re likely to be approved.

In my case, it resulted in a reduction of 18% in the maximum price I could afford, which is not terrible because all my previous calculations were taking this into account. Some people may be surprised, and discouraged out of the house hunting process by this, but if you know about this rule and factor it in your calculations prior to starting the process, you’ll know what to expect and how to compensate (get more money, save up for a larger down payment, lower your house price range).

 

Buying a house in Montreal – where to start?

Categories: English House buying

For sale
For sale

So we decided to buy a house, what will the journey look like?

There are plenty of easily-googlable resources on the house buying process in Canada and in Québec more specifically (here’s the two most detailed I’ve seen: FCAC and CMHC), so I won’t try to repeat that information, but I’ll document the specifics of our process which will invariably result in a brief outline of the steps to follow.

Roughly what we’ll try to do:

  1. Get a relatively good family income so we can qualify for a reasonable mortgage loan.
  2. Build up a credit history.
  3. Save up for a down payment.

We’ve worked on those first three steps since we moved to Canada: I’ve been fortunate enough to have a stable and well-paid job, which has allowed us to use consumer credit responsibly, so should have a pretty good rating. It also allowed us to save for a down payment. So at this point we should be ready for the next parts of the process:

  1. See a lender to get financially checked and pre-approved for a loan. You can go for a well-known financial institution, perhaps your bank, or you can go to a mortgage broker, which is what I’m planning on doing.
  2. Once you know your price range, you can start looking at houses in your desired areas.

BUT before you can start with this, you should know roughly how much you can afford, be realistic with your inputs and use one of the available online calculators. I like this one which will tell you how much you should be able to afford, and this one which calculates your estimated payments. And this one is very simple but also very detailed as to the criteria used to estimate affordability. It makes sense to use this so you’re not disappointed when the broker tells you you can only afford a tiny shack in the boondocks :).

You should also have a pretty good idea of whether you like your target neighbourhood. Montreal is a geographically large city and neighbourhoods can differ, so it makes sense to check the ones you like and make a short list. If you don’t care where you buy, there’s something for almost any price range, but I don’t think that’s very common.

A possible problem with the neighbourhood you like is whether you can afford it. If you can’t just yet, there are two options: choose a different one or get more money (higher salary, larger down payment).

Once I identified our target neighbourhoods, I started scouring centris.ca frequently, looking for houses in (and out of) our price range, checking their pictures and prices, nearby amenities, and comparing several possible neighbourhoods. We ended up discarding one of those, even though it was cheaper and had more inventory, because we decided we didn’t really like it that much. So we’re focusing on one of the other candidates, and also looking at adjacent neighbourhoods, which can be cheaper while still being closer to the amenities we want.

OK, so knowing how much we can afford (per the calculators) having located (and lived in) a neighborhood we like and knowing the approximate price range for homes here, and knowing it is within our affordability, I’m ready to hit the mortgage broker.

Resources:

http://www.fcac-acfc.gc.ca/Eng/resources/publications/mortgages/Pages/home-accueil.aspx

Weechat trigger sounds based on specific keywords

Categories: Uncategorized

Weechat used to require some weird perl scripts to trigger on specific conditions, but since version 1.1 (from 2014) a trigger plugin can do all that without needing an external script.

This will create a trigger that runs a command when a specific word (or words) is mentioned in any channel you’re on:

/trigger addreplace warningword signal *,irc_in2_PRIVMSG "${message_without_tags} =~ (danger will robinson|stop the line|help me)" "" "/exec -bg /usr/bin/paplay /usr/share/sounds/ubuntu/notifications/Positive.ogg

Ansible task that retries

Categories: English
---
- name: Run a local task 
  hosts: 127.0.0.1
  connection: local
  tasks:
      - name: loop the loop
        uri:
            url: http://www.someurl.example.com/status.html
            return_content: yes
        register: foo
        until: foo.content.find("monkeys") != -1
        delay: 1
        retries: 5

The task can be whatever you want: I used uri but it’s more usually shell or something like that. The main thing is that you need to use register so you’ll have something to check in the until: condition.

 

Mocking iterators

Categories: Geeky

A colleague wanted to mock a Journal object which both has callable methods and works as an iterator itself. So it works like this:

j = Journal()
j.log_level(Journal.INFO)
for line in j:
   print(line)

We mocked it like this, to be able to pass an actual list of expected values the function will iterate over:

import mock

mock_journal = mock.Mock()
mock_journal.__next__ = mock.Mock(side_effect=[1,2,3,4])
mock_journal.__iter__ = mock.Mock(return_value=mock_journal)


for i in mock_journal:
    print(i)
# I don't call any methods in mock_journal, but I could,
# :and could then assert they were called.

So mock_journal is both a mock proper, where methods can be called (and then asserted on), and an iterable, which when called repeatedly will yield elements of the __next__ side_effect.

Forcing Python Requests to connect to a specific IP address

Categories: English Geeky Trabajo

Recently I ran into a script which tried to verify HTTPS connection and response to a specific IP address. The “traditional” way to do this is  (assuming I want http://example.com/some/path on IP 1.2.3.4):

    requests.get("http://1.2.3.4/some/path", headers={'Host': 'example.com'})

This is useful if I want to specifically test how 1.2.3.4 is responding; for instance, if example.com is DNS round-robined to several IP addresses and I want to hit one of them specifically.

This also works for https requests if using Python <2.7.9 because older versions don’t do SNI and thus don’t pass the requested hostname as part of the SSL handshake.

However, Python >=2.7.9 and >=3.4.x conveniently added SNI support, breaking this hackish way of connecting to the IP, because the IP address embedded in the URL is passed as part of the SSL handshake, causing errors (mainly, the server returns a 400 Bad Request because the SNI host 1.2.3.4 doesn’t match the one in the HTTP headers example.com).

The “easiest” way to achieve this is to force the IP address at the lowest possible level, namely when we do socket.create_connection. The rest of the “stack” is given the actual hostname. So the sequence is:

  1. Open a socket to 1.2.3.4
  2. SSL wrap this socket using the hostname.
  3. Do the rest of the HTTPS traffic, headers and all over this socket.

Unfortunately Requests hides the socket.create_connection call in the deep recesses of urllib3, so the specified chain of classes is needed to propagate the given dest_ip value all the way down the stack.

After wrestling with this for a bit, I wrote a TransportAdapter and accompanying stack of subclasses to be able to pass a specific IP for connection.

Use it like this:

session = requests.Session()
session.mount("https://example.com", ForcedIPHTTPSAdapter(dest_ip='1.2.3.4'))
response = session.get(
    '/some/path', headers={'Host': 'example.com'}, verify=False)

There are a good number of subtleties on how it works, because it messes with the connection stack at all levels, I suggest you read the README to see how to use it in detail and whether it applies to you need. I even included a complete example script that uses this adapter.

Resources that helped:

http://stackoverflow.com/questions/22609385/python-requests-library-define-specific-dns

https://github.com/RhubarbSin/example-requests-transport-adapter/blob/master/adapter.py