Tuesday, February 7, 2017

Go - TestMain

Every day learning new things about Go, trapped into an interesting one. Apparently, not only you could test your main method, you should follow some well-defined practices.

First of all, it shouldn't be
func TestMain(t *testing.T) {
...
}

as usually, but
func TestMain(m *testing.M) {
...
}
So, the typical structure for the main_test.go would be:

func TestMain(m *testing.M) {
  setup()
  main()
  // or
  // go func() {
  //  main()
  // }()
  code := m.Run()
  tearDown()
  os.Exit(code)
}

func TestA(t *testing.T) {
...
}

func TestZ(t *testing.T) {
...
}

func TestB(t *testing.T) {
...


Interesting fact - tests would run in the order they are declared in the file, not alphabetically, which is usually what you want. 

When to use pointers in Go

When in doubt - use pointer! A comprehensive reference on the topic.

Wednesday, February 1, 2017

Running Mongo 3.x on Travis CI

Unfortunately Mongo 3.x support is not supported by Travis CI OOTB. There are some workarounds to achieve this, the idea is to install mongo as a package. However all of them have some disadvantages.

My solution to that would be to use docker as a service and run mongo in container.

.travis.yml

language: go
services:
- docker
script:
- "./run.sh"

run.sh

language: go
services:
- docker
script:
- "./run.sh"

if [[ -z $(docker images | grep mongo | grep 3.4.1) ]]; then
  echo "Pulling mongo image."
  docker pull mongo:3.4.1
fi

if [[ -z $(docker ps | grep mongo | grep 3.4.1) ]]; then
  echo "Starting mongo container."
  MONGO_ID=$(docker run -p 27017:27017 -d mongo:3.4.1)
fi

### RUN YOUR CODE HERE (e.g. tests)

if [[ -n $MONGO_ID ]]; then
  echo "Killing mongo container."
  KILLED=$(docker kill $MONGO_ID)
fi

Thursday, March 12, 2015

VPN or Remote Desktop to work environment

It's a very common scenario when you need an access from home to your work machine. It's great if your IT department took care of this, however it's not always the case. Besides that sometimes, when you need the remote access urgently, the VPN is down. There are a plenty options how to workaround this. In my opinion the best and the easiest one is Hamachi by LogMeIn.
Originally I started using it to play Counter Strike with my friends but it turned out to be a life saver after we moved to another office with unstable VPN setup.

Tip: ArgumentException: Microsoft.SharePoint.SPFieldMap.GetColumnNumber

If you see this:
{System.ArgumentException: Value does not fall within the expected range.
at Microsoft.SharePoint.SPFieldMap.GetColumnNumber(String strFieldName, Boolean bThrow)
at Microsoft.SharePoint.SPListItemCollection.GetColumnNumber(String groupName, Boolean bThrowException)
at Microsoft.SharePoint.SPListItemCollection.GetRawValue(String fieldname, Int32 iIndex, Boolean bThrow)
at Microsoft.SharePoint.SPListItem.GetValue(SPField fld, Int32 columnNumber, Boolean bRaw, Boolean bThrowException)
at Microsoft.SharePoint.SPListItem.GetValue(String strName, Boolean bThrowException)
at Microsoft.SharePoint.SPListItem.get_Item(String fieldName)
probably you are facing with the list view lookup threshold (e.g. like described here).
Or simply the column is not included in the result set (SPQuery -> ViewFields) and you're trying to retrieve missing field value.

Thursday, October 23, 2014

Custom PowerShell Host - there is a better way

Recently I faced with an issue during reading/generating Excel files using OpenXML from PowerShell. Long story short, during unpacking Excel (which is essentially a CAB file) if allocated memory exceeds some limit (10 MB) it switches from memory stream to isolated storage. An exception is thrown when getting access to isolated storage since assembly's evidence could not be resolved from PowerShell. More information on this could be found here.

Stack trace:
at System.IO.IsolatedStorage.IsolatedStorage._GetAccountingInfo(Evidence evidence, Type evidenceType, IsolatedStorageScope fAssmDomApp, Object& oNormalized)
at System.IO.IsolatedStorage.IsolatedStorage.GetAccountingInfo(Evidence evidence, Type evidenceType, IsolatedStorageScope fAssmDomApp, String& typeName, String& instanceName)
at System.IO.IsolatedStorage.IsolatedStorage._InitStore(IsolatedStorageScope scope, Evidence domainEv, Type domainEvidenceType, Evidence assemEv, Type assemblyEvidenceType, Evidence appEv, Type appEvidenceType)
at System.IO.IsolatedStorage.IsolatedStorage.InitStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
at System.IO.IsolatedStorage.IsolatedStorageFile.GetStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
at MS.Internal.IO.Packaging.PackagingUtilities.GetDefaultIsolatedStorageFile()
at MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(Int32 retryCount, String& fileName)
at MS.Internal.IO.Packaging.SparseMemoryStream.EnsureIsolatedStoreStream()
at MS.Internal.IO.Packaging.SparseMemoryStream.SwitchModeIfNecessary()
at MS.Internal.IO.Packaging.DeflateEmulationTransform.Decompress(Stream source, Stream sink)
at MS.Internal.IO.Packaging.CompressEmulationStream..ctor(Stream baseStream, Stream tempStream, Int64 position, IDeflateTransform transformer)
at MS.Internal.IO.Packaging.CompressStream.ChangeMode(Mode newMode)
at MS.Internal.IO.Packaging.CompressStream.Seek(Int64 offset, SeekOrigin origin)
at MS.Internal.IO.Zip.ZipIOModeEnforcingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamReader.ReadBuffer(Char[] userBuffer, Int32 userOffset, Int32 desiredChars, Boolean& readToUserBuffer)
at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
at System.IO.TextReader.ReadBlock(Char[] buffer, Int32 index, Int32 count)
at OfficeOpenXml.ExcelWorksheet.GetWorkSheetXml(Stream stream, Int64 start, Int64 end, Encoding& encoding)
at OfficeOpenXml.ExcelWorksheet.CreateXml()
at OfficeOpenXml.ExcelWorksheet..ctor(XmlNamespaceManager ns, ExcelPackage excelPackage, String relID, Uri uriWorksheet, String sheetName, Int32 sheetID, Int32 positionID, eWorkSheetHidden hide)
at OfficeOpenXml.ExcelWorksheets..ctor(ExcelPackage pck, XmlNamespaceManager nsm, XmlNode topNode)
at OfficeOpenXml.ExcelWorkbook.get_Worksheets()
at OfficeOpenXml.ExcelWorkbook.GetDefinedNames()
at OfficeOpenXml.ExcelPackage.get_Workbook()

The solution to fix this is fairly simple - just run the excel specific code from regular application, e.g. Console. However in this case you'd lose all the flexibility of PowerShell and you'd need to recompile your code (on Production? ) every time you need to change anything.

Therefore it has been decided to run PowerShell code from application. There are enough examples on how to create custom PowerShell host similar to PowerShell ISE. However it's cumbersome to find how to create regular PS console from managed console application.

It turns out that it could be achieved by writing 2 lines of code:
static void Main(string[] args)
{
   var config = RunspaceConfiguration.Create();
   ConsoleShell.Start(config, "Awesome Powershell Host", string.Empty, args);
}
References to these assemblies are required:

  • System.Management.Automation
  • Microsoft.PowerShell.ConsoleHost

Thursday, October 11, 2012

How to make pretty URLs for files in Layouts folder

I know what you would feel after reading this post. It seems so easy. And actually it should be the first thing which comes to developer's mind. But nowadays we're so spoiled with different CMS that we forget about basic things.

So, the task is to make URLs prettier for files located in 14\Layouts folder.
Let's say we have a page which references /_layouts/your.project.name/scripts/thursday.js. Sometimes it might not look very good. Moreover if it's public site than you might not want to scream: "This is Sharepoint!!!!!".

Let's say you want URL to be something like /style/scripts/friday.js. How would you do that? You think about some kind of URL rewriting, aren't you? Maybe about writing some custom http module/handler? Anything else?

The solution is so obvious and easy, so shame to you pal.
What you need to do is:

  • Open IIS Manager
  • Right click on your site
  • Add Virtual Directory
  • Set alias, e.g. style
  • Set path to your folder in 14\Layouts hive



Then just type:
http://coolsite/style/scripts/yourcoolscript.js and go take a couple of beers. That's just it.

And don't forget: let's not make things complicated. We have our lovely women for that ;)