Notes on Fixing Incomplete Bitcode Error in TeamCity Automated Objective-c Builds

Notes I took while trying to fix the Incomplete Bitcode error in submission bug.  Not sure if it’s fixed yet as I haven’t tried submitting an app to the App Store yet.  Hopefully someone else will try it and confirm it’s fixed.

In summary when submitting an app to iTunes Connect that has the XPlugins.iOS.BEMCheckBox the user got the following error:

ERROR ITMS-90668: “Invalid Bundle Executable. The executable file ‘InstantApp.BoostOrder.Customer.Touch.app/Frameworks/BEMCheckBox.framework/BEMCheckBox’ contains incomplete bitcode. To compile binaries with complete bitcode, open Xcode and choose Archive in the Product menu.”

For some more background please see the previous post Today I Learned How to Automate Objective-c Builds in TeamCity for more information about how built the BEMCheckBox framework.

Current Build Settings

My build settings for compiling the BEMCheckBox framework look like:

TeamCity BEMCheckBox Current Build Actions

The look the same for compiling for both the device (ARM architecture) and the simulator (x86/x64 architecture).  I started with the build step that compiled the device and after some research I figured the problem was the build actions.  Instead of doing build I should do an archive.

Updating Compile for Device Settings

To create an archive requires change the build from Target-based to Schema-based.  There was a couple other changes required which are outlined below.

TeamCity BEMCheckBox Updated Build Actions

  1. Make sure the project build settings are up to date by clicking the Check/Reparse Project.
  2. Change to Scheme-based.
  3. Set the scheme to BEMCheckBox.
  4. Use the output directory or xCode will put the build god-knows-where.
  5. Change the build action from build to archive.

Did a build and everything compiled.  Lets do the same for the simulator build.

Updating Compile for Simulator Settings

Actually you don’t need to change anything for the simulator build.  You can’t create an archive for simulators.  As usual it took me some time to figure out nothing needs to be done.  Aren’t you glad you are reading this instead of wasting time like I did?

Update Script that Combines the Builds

After compiling for the device and the simulator the builds need to be combined into one package.  In my build this is done via a script and a minor update was required because the path changed when we built the archive for the device.

The current script looks like:

cp -r Sample\ Project/build/Release-iphoneos/BEMCheckBox.framework .
lipo -create -output BEMCheckBox.framework/BEMCheckBox Sample\ Project/build/Release-iphoneos/BEMCheckBox.framework/BEMCheckBox Sample\ Project/build/Release-iphonesimulator/BEMCheckBox.framework/BEMCheckBox

It now looks like:

cp -r build/Release-iphoneos/BEMCheckBox.framework .
lipo -create -output BEMCheckBox.framework/BEMCheckBox build/Release-iphoneos/BEMCheckBox.framework/BEMCheckBox Sample\ Project/build/Release-iphonesimulator/BEMCheckBox.framework/BEMCheckBox

Notice the path for the device build has been changed.  It no longer gets put in the Sample Project folder.  I couldn’t figure out a way to get the paths the same for both build so I just gave up.

Anyway, there are my notes on the changes I did.  Not sure if my changes fixed the orginial problem.  If you use XPlugins.iOS.BEMCheckBox please let me know either way.  Thank you to jjchoo for originally reporting the problem.

Posted in Notes, Software Development | Tagged , , , , | Comments Off on Notes on Fixing Incomplete Bitcode Error in TeamCity Automated Objective-c Builds

Family Vacation is Over

Our family vacation is over and the basement is back open for business.  Actually we where open on Monday but I forgot to remove the digital closed signed.  Sorry about that.

On this trip we visited Hong Kong and Shanghai, spending about a week in each city.  This is our second time to Honk Kong and we got to see and do things we missed on our first visit.  This includes hanging out at a beach and swimming, hiking the highest mountain in Hong Kong, a helicopter ride (sponsored by our daughter who saved her money for a year), and visiting the highest building in Hong Kong.

This was our first time to Shanghai and it contrasts nicely with Hong Kong.  Hong Kong is hilly and the population is concentrated in small pockets on the flatter parts.  Shanghai is flat with less hi-rises.  It reminds me of LA, a flat city that stretches for miles.

We stayed near the historic Old Town and did the usual tourist things like visiting People’s Square, toured The Bund, and looked out over Shanghai half a kilometer in the sky in the Shanghai Tower (the second highest building in the world).

Finally we visited both Hong Kong Disneyland, for a second time, and Shanghai Disneyland.  That means we have visited three of the six Disney Resorts having visited the original Disneyland in California in the past.  We have a family goal to visit all six Disney Resorts before my darling daughter turns 18 to help her become an Imagineer.  That and we really like the Disney parks.

Walt Disney Imagineering Logo

Thank you for your patience during our absence.  We have settled into our normal routine and look forward to serving you with refreshed enthusiasm.

Posted in Uncategorized | Comments Off on Family Vacation is Over

Closed for Family Vacation

Basement Office Closed SignSaturday MP is a small family business and like your local family run restaurant the entire family is involved in some way.  Currently it’s mostly me working at Saturday MP but Ada helps with some book keeping and in the past was a consultant.  Our daughter also used to clean the basement office and shred papers.

Also, like your local family restaurant, when we take a vacation the entire business closes.  Well, mostly closes, we can still be reached virtually but please expect delays in our response.  Thank you for your patience and we look forward to serving you when we get back to the basement on November 27th.

Posted in Business Side, Fun | Tagged , | Comments Off on Closed for Family Vacation

Today I Learned The Final Backslash is Important in Apache HTTPS Redirects

Lets start with the bug:

When requesting a download link via the Downloads page the link that is sent via e-mail is invalid.  It is missing a slash.

1) Enter a e-mail on the Downloads page (https://www.saturdaymp.com/downloads) that has already purchased Mini-Compressor.

2) E-mail should be sent but the link in the e-mail is incorrect.  For example the link I got was:

https://www.saturdaymp.comdownloads/show_products?link=blahblahblah

There should be a slash after the https://www.saturdaymp.com.

But when I looked closer at the actual e-mail, the link was correct.  It looked like:

http://saturdaymp.com/downloads/show_products?link=blahblahblah

It had the slash after the “.com” but was missing the www and didn’t have HTTPS.  At first I thought the problem was the missing www but I was wrong.  The problem was in the redirect from HTTP to HTTPS.  Lets take a look at the apache site config file for Saturday MP where the redirect lives.

<VirtualHost *:80>
  ServerName www.saturdaymp.com
  Redirect permanent / https://www.saturdaymp.com
</VirtualHost>

<VirtualHost *:443>
  # HTTPS config settings ...
</VirtualHost>

Notice the slash is missing at the end of the redirect?  That is the problem.  To fix it add a backslash so the redirect looks like:

Redirect permanent / https://www.saturdaymp.com/

After you add the backslash don’t forget to reboot your webserver, which I did.  You will also have to clear your browser cache, which I didn’t do.  It took me another hour to figure out the above fix actually did work because I didn’t clear out my browser cache.  Always clear our your browser cache when testing websites.

P.S. – For those not into 80’s hair bands Slash is the one with hat, curly hair, and memorable guitar licks.  The opening to Sweet Child O’ Mine is actually a guitar exercise Slash used for practice and warm-up.  Finally make sure you listen to the uncut version.  In the cut version almost a minute of Slash’s guitar solo is missing.

https://www.youtube.com/watch?v=YFQaUA-vBbI

Posted in Today I Learned | Tagged , | Comments Off on Today I Learned The Final Backslash is Important in Apache HTTPS Redirects

Degree of Temporalness

This post is part of a larger discussion about temporal databases.  Hopefully it stands on it’s own but for more context see the Temporal Database Design page.

Most of us have worked with database tables that track some historical information.  You add a EffectiveDate column or something similar and usually it’s just limited to a table to two.  A Temporal Database is designed so most or all of the tables can track historical information.

The important part is that you can access the historical database using a SQL query and don’t have to look elsewhere, such as audit log.  This is what makes a database a Temporal Database, at least according to me.

Degree of Database Temporalness

A database can either be non-temporal, partial temporal, or fully temporal.  You can measure the temporalness by the percentage of tables that store temporal data.

Non-Temporal (0% Temporalness): Database has no temporal capabilities.

Partially Temporal (1% – 99% Temporalness): The database has some tables store temporal data but not all.

Fully Temporal (100% Temporalness): All the tables in the database store temporal data.

Type of Table Temporalness

We don’t measure how temporal a table is by percentage.  Instead a table is defined by what type of historical data you can retrieve.  There are two types of historical data:

Continue reading

Posted in Software Development | Tagged | Comments Off on Degree of Temporalness

What is a Temporal Database?

You can read the official Wikipedia definition but for our purposes it’s a database where you can query for historical data using SQL.

For example, say you have someone named Chronos who lives in New York but on April 15, 2012 moves to Hong Kong.  If you don’t have an historical tracking then you will only be able to see that Chronos lives in Hong Kong.  You don’t know where he lived before Hong Kong or when he moved to Hong Kong.

Continue reading

Posted in Software Development | Tagged | Comments Off on What is a Temporal Database?

Today I Learned How to Create Custom NUnit Constraints – Part 2: Constraint Usage Syntax

In Part 1 we created a custom NUnit constraint but you where limited in using the constraint.  You could only write:

 
// Instantiate the constraint. 
Assert.That(expected, new EquivalentPropertyWiseToConstraint(actual)); 

// Matches syntax. 
Assert.That(expected, Is.Not.Matches(new EquivalentPropertyWiseToConstraint(actual)));

It would be nice to write:

// Directly access the constraint from Is.
Assert.That(expected, Is.EquivalentPropertyWiseTo(actual));

// Chain the constraint in Is.
Assert.That(expected, Is.Not.EquivalentPropertyWiseTo(actual));

To do that you should read the documentation.  End of blog post.

So is that joke still funny?  No, OK, no more.  Lets get back to what we are doing.  To access the method using Is you need to override the Is class and add a static method.  I recommended making the method name similar to your constraint name.  For example:

public class Is : NUnit.Framework.Is
{
  public static EquivalentPropertyWiseToConstraint EquivalentPropertyWiseTo(object expected)
  {
    return new EquivalentPropertyWiseToConstraint(expected);
  }
}

Now you can directly access your custom constraint via Is like:

// Directly access the constraint from Is.\
Assert.That(expected, Is.EquivalentPropertyWiseTo(actual));

However, if you try to chain the method it won’t work.  For example, this will throw an error:

// Won't compile
Assert.That(expected, Is.Not.EquivalentPropertyWiseTo(actual));

To fix this we need to create an extension method.  The name of the class is not important but the name of the extension method should match the name you used above when overriding the Is class.   The method needs to create your constraint and append it to the constraint expression.

public static class CustomConstraintExtensions
{
  public static EquivalentPropertyWiseToConstraint EquivalentPropertyWiseTo(this ConstraintExpression expression, object expected)
  {
    var constraint = new EquivalentPropertyWiseToConstraint(expected);
    expression.Append(constraint);

    return constraint;
  }
}

Now you can chain your customer constraint and the following will work:

 
// Will compile now that the extension method exists.
Assert.That(expected, Is.Not.EquivalentPropertyWiseTo(actual));

Now you have a fully working custom NUnit constraint.  For a working example please see the NConstraint project.  End of blog post.

 

P.S. – Another of my favourite Tragically Hip songs.  I used to listen to this song a lot when working late nights at my first programming job.

Everything is bleak
It’s the middle of the night
You’re all alone and
The dummies might be right
You feel like a jerk
My music at work
My music at work

Posted in Code Examples, Software Development, Today I Learned | Tagged , | Comments Off on Today I Learned How to Create Custom NUnit Constraints – Part 2: Constraint Usage Syntax

Today I Learned How to Create Custom NUnit Constraints – Part 1: Creating the Constraint

NUnit has has built in constraints for most the tests you will need to write so there is no need to create your own.  End of blog post.

OK, that was a bad joke.  The first step in creating a NUnit custom constraint is to read the documentation.  That’s it.  End of blog post.

Not as funny as the first time?  Not funny at all?  I won’t use that joke again.  But you did read the documentation right?  OK, good.

The example for this blog post is from the NConstraint project.  It shows how I created a custom constraint to compare the property values or two objects.  In my case I wanted to write something like:

var expected = new MyClass() { SomeProperty = 1};

// Property values match.
var actual = new MyClass() { SomeProperty = 1 };
Assert.That(expected, Is.EquivalentPropertyWiseTo(actual));

// Property values don't match.
actual.SomeProperty = 2
Assert.That(expected, Is.Not.EquivalentPropertyWiseTo(actual));

Lets start.  First you need to override the Constraint class.

public class EquivalentPropertyWiseToConstraint : Constraint
{
}

Then create a constructor that accepts the expected value for the test.  In our case it’s the object you want to compare but it could be anything.

public EquivalentPropertyWiseToConstraint(object expected)
{
  Expected = expected;
}

public object Expected { get; }

Notice that we save the expected object.  In my case I saved it to a public property for unit testing purposes but it could be a private variable.  I know, unit testing a new unit test constraint, very meta.

The next thing we have to implement is the logic for the constraint by overriding the ApplyTo method.

public override ConstraintResult ApplyTo<TActual>(TActual actual)
{
}

This method takes a the actual value from the test that you want to compare to the expected.  It returns a ConstraintResult contains a reference to the constraint, the actual value, and if the constraint passed or not.

Add whatever logic you need to to the ApplyTo method.  In my case I wrote some logic that loops through all the properties of both objects and compares the values.  It’s a bit long so I won’t include it in this blog post.  In general your method will look something like:

public override ConstraintResult ApplyTo<TActual>(TActual actual)
{
  // You code to do the comparison.

  // If the comparison succeeds.
  return new ConstraintResult(this, actual, true);

  // If the comparison fails.
  return new ConstraintResult(this, actual, false);
} 

Now you should be able to run your tests by instanciating your constraint or using the Matches syntax.

 
// Instantiate the constraint.
Assert.That(expected, new EquivalentPropertyWiseToConstraint(actual));

// Matches syntax.
Assert.That(expected, Is.Not.Matches(new EquivalentPropertyWiseToConstraint(actual)));

One thing you might notice is the error message is not very descriptive if the test fails.

Expected: 
But was: 1

The “But was” part is the actual value you passed into the constraint.  In my case I passed in the property value, which was an integer, hence the 1.  Your actual value might be different.

To get a better expected message you need to set the description value in the Constraint class.  If you have a simple test you could hard code the description.  For example the built in TrueConstraint always sets the description to “True” in the constructor.

public TrueConstraint()
{
  Description = "True";
}

In my case I needed to set the description in the ApplyTo method.  For example if a property does not exist then we set a different description then if the property values don’t match.

// Property does not exist message.
Description = $"expected property {expectedProperty.Name} does not exist.";

// Property values don't match message
Description = $"property {expectedProperty.Name} value to be {expectedValue}";

Once I set the descriptions my test failed messages looked better:

Expected: property IntegerProperty value to be 2
But was: 1

You can find the entire EquivalentPropertyWiseToConstraint class and example test client at the NConstraint project.

Now your custom constraint is complete but you might notice is that you can’t use the NUnit built in “Is” syntax.  For example, you currently can’t write:

Assert.That(expected, Is.EquivalentPropertyWiseTo(actual));

I’ll cover how to do this in a future post.  End of blog post.  No joke, this is really the end.  Unless you count the P.S. video.

 

P.S. – R.I.P. Gord Downie.  I had trouble picking my favourite Tragically Hip song but I think Bobcaygeon will do.  Read more about the lyrics and their meaning here.

So I’m at your house this morning
Just a little after nine
‘Cause it was in Bobcaygeon, where I saw the constellations
Reveal themselves one star at a time

Posted in Code Examples, Software Development, Today I Learned | Tagged , , | Comments Off on Today I Learned How to Create Custom NUnit Constraints – Part 1: Creating the Constraint

NConstraints Version 1.0.0 Released

A common unit test assert I need to do is compare all the property values of one object to another.  For example:

[Test]
public void TestSaveWorks()
{
  // Create a value to save.
  var expectedDto = new SomeDto() {ValueOne = 1, ValueTwo = "Blah"};

  // Save the value.
  _someDbService.Save(dtoToSave);

  // Load the value from the database.  The DTO ID
  // should have been set by the save.
  var actualDto = _someDbService.Find(expectedDto.Id);
  
  Assert.That(expectedDto.ValueOne, Is.EqualTo(actualDto.ValueOne));
  Assert.That(expectedDto.ValueTwo, Is.EqualTo(actualDto.ValueTwo));
}

In this test we only have two properties to test but if the object has 10 plus properties to test that would be quite onerous.   I often forget to update the tests after I add a new property to the object.

To fix this problem I created a custom constraint for NUnit called EquivalentProperyWiseTo that compares all the property values of two objects.   Now the above tests looks like:

[Test]
public void TestSaveWorks()
{
 // Create a value to save.
 var expectedDto = new SomeDto() {ValueOne = 1, ValueTwo = "Blah"};

 // Save the value.
 _someDbService.Save(dtoToSave);

 // Load the value from the database. The DTO ID
 // should have been set by the save.
 var actualDto = _someDbService.Find(expectedDto.Id);
 
 Assert.That(expectedDto, Is.EquivalentPropertyWiseTo(actualDto));
}

Notice you don’t need to test each property value independently.  Just pass in the two objects you want to test and you are done.  High Five!

The EquivalentPropertyWiseTo custom constraint can be found in the just released NConstraints.  You can find the latest stable version of the NConstraints on NuGet.  If you like living on the edge you can find the developer builds on MyGet.

If you have any questions, spot an bug, or have an enchantment for NConstraints let me know by:

  • opening an issue or pull request GitHub.
  • asking a question on StackOverlow with the tag nconstraints.
  • send me an e-mail to support@saturdaymp.com.

Finally thank you to the NUnit team for creating NUnit and continue to support it.  I’ve used NUnit for most of my career to properly test and improve my code.

Posted in Code Examples | Tagged , | Comments Off on NConstraints Version 1.0.0 Released

Today I Learned How to Run NUnit Tests for a .NET Core Project in TeamCity

In TeamCity you can’t use the usual NUnit Runner to run .NET Core unit tests.  At least I couldn’t get it to work.  I’m sure this will be fixed in the future but for now the below works for me.  I got lots of inspiration from this TeamCity blog post.

For this example I’ll use the NConstraints project.  It contains a .NET Standard project (SaturdayMP.Constraints) that we want to test and two .NET Core Test projects (SaturdayMP.Constratints.Test and TestClient).

NConstraint Solution Explorer

In TeamCity I created a project with the usual first two steps of NuGet Install and Compile.

TeamCity Project Before Adding Test Step

If you read the TeamCity blog post, the one I got my inspiration from, then you probably noticed it used the .NET Core Runner to compile the project.  You might have had to do this when the TeamCity blog post was first written but now using the Visual Studio Runner will compile .NET Core projects.

Before we can add the .NET Core unit test build step we need to install the TeamCity .NET CLI Plugin.  Do this by downloading the plugin zip file from here.

TeamCity .Net Plugin Download

Then install the plugin by clicking on Administration in the top right then Plugins List on the bottom left.

TeamCity Navigate To Plugins List

Then click Upload Plugin Zip link and choose the plugin zip file you just downloaded.

TeamCity Upload Plugin Zip

 

TeamCity Upload .Net Core Plugin

Once the upload is complete you should see something similar to the screen shot below.

TeamCity Upload Successful

The plugin is uploaded but before it’s active you need to reboot TeamCity.  In my case I just rebooted the server.

Once the reboot is complete you can check that the plugin installed correctly by going to an agent with Visual Studio 2017 installed.

TeamCity Navigate To Agent Parameters

Once on the agent navigate to the parameters page and you should see something similar to the below screen shot.

TeamCity Check .Net CLI Plugin Installed

If you don’t see the DotNetCli listed then you either forgot to reboot TeamCity, the plugin didn’t install correctly, or you don’t have .NET Core installed on you build agent.

Now that the plugin is installed we can go back to our project and add the unit test build step.  Add a new build step and in the runner type pick .NET CLI (dotnet).  Then in the command drop down pick test and finally enter the paths to your projects.  If you have several projects you can use wildcards.

TeamCity .Net CLI Build Step

If you don’t see all the options in the screen shot above them make sure to click Show Advanced Options.  In my case I also enabled code coverage at the bottom of the list.

TeamCity .Net CLI Build Step Enable Code Coverage

 

Now when we build the tests should get executed.  You can see the results of the tests in the build log or the tests tab of the build results.

TeamCity Test Results

As I said at the beginning I’m sure the NUnit Runner will be updated to handle .NET Core but use the above for now.

P.S. – R.I.P. Tom Petty.

Posted in Code Examples, Software Development, Today I Learned | Tagged , , , | Comments Off on Today I Learned How to Run NUnit Tests for a .NET Core Project in TeamCity