Wednesday, August 26, 2015

Recursive search for folder with Powershell

Recently I needed to solve a fairly trivial task - recursively find folder by name using Powershell. As a result, I’ve wrote function:

 

function FindFolder($rootDir, $dirToFind)

{

  if ((Get-ChildItem $rootDir $dirToFind).count -eq 1)

  {

    return $rootDir

  }

 

  $directories = Get-ChildItem $rootDir | ?{ $_.PSIsContainer } | sort LastWriteTime -Descending

 

  foreach($directory in $directories)

  {

    $dirName = $rootDir + $directory.Name + "\"

    if ((Get-ChildItem $dirName $dirToFind).count -eq 1)

    {

      return $dirName + $dirToFind

    }

    if ((Get-ChildItem $dirName).count -gt 0)

    {

      $ret = FindFolder $dirName $dirToFind

      if ($ret -ne "")

      {

        return $ret

      }

    }

  }

 

  return ""

}

 

 

Arguments for function are root directory where it will start searching and name of the folder. Function returns the full path to the first found folder - that's exactly what I needed. If you want to get all possible folders, you can edit the script, and for example, echo each found folder and then parse the result. Just keep in mind that I’m sorting results inside function by the last write time because I need to find newest of all possible folders with this name (sort LastWriteTime -Descending).

 

Tuesday, August 11, 2015

How to timeout tests in gtest

If you want to limit the time to run the test, you can use the following macro:

#include <future>
#define TEST_TIMEOUT_BEGIN   std::promise<bool> promisedFinished; \
                              auto futureResult = promisedFinished.get_future(); \
                              std::thread([](std::promise<bool>& finished) {
 
#define TEST_TIMEOUT_FAIL_END(X)  finished.set_value(true); \
                                   }, std::ref(promisedFinished)).detach(); \
                                   EXPECT_TRUE(futureResult.wait_for(std::chrono::milliseconds(X)) != std::future_status::timeout);
 
#define TEST_TIMEOUT_SUCCESS_END(X)  finished.set_value(true); \
                                      }, std::ref(promisedFinished)).detach(); \
                                      EXPECT_FALSE(futureResult.wait_for(std::chrono::milliseconds(X)) != std::future_status::timeout);

 

Example:

 

TEST(some_unit, LongCalculationTimeout)
{
  TEST_TIMEOUT_BEGIN
    EXPECT_EQ(10, long_calculation_function());
  TEST_TIMEOUT_FAIL_END(1000)
}

Test will not pass and will be aborted, If execution of long_calculation_function() takes more time than 1000 ms.

In rare cases, we want to test that the function will take at least some time. In that case you can use TEST_TIMEOUT_SUCCESS_END instead of TEST_TIMEOUT_FAIL_END. Test will run for a specified time and if the code is still running after this time, test will pass and program starts next test.

Wednesday, August 5, 2015

How to use native C++ code in Azure Cloud Service/C# application

Sometimes it becomes necessary to use native C ++ code in C# application or in the Azure Cloud Service. We will not dwell on the reasons why this should be done and how you can avoid it - sometimes it does not depend on the developer.

Unfortunately, you can’t link native code in C # project directly. But you can wrap your code in CLR project and then link wrapped project to your original application.

This way we have three parts:

1)      Project A written in native C++

2)      Wrapper for native project

3)      Azure Cloud Service (or C# application) where you would like to use code from project A.

To illustrate whole process, we will create a sample project that will have some native C++ code, and then I will show, how to use this code in Azure Cloud Service/C# Application.

You will find all source here: https://github.com/SkyRunn3r/NativeCodeWrapping

Let’s call our project NativeProjectA. The project have one class “sample_class”. This class has one method “write_to_file”– to write given string to the given file:

sample_class.h

#pragma once

#include <string>

 

class sample_class

{

public:

  void write_to_file(const std::string &filename, const std::string &message);

};

 

sample_class.cpp

#include <fstream>

#include "sample_class.h"

 

void sample_class::write_to_file(const std::string & filename, const std::string & message)

{

  std::ofstream o(filename);

  o << message << std::endl;

}

 

Native project modification

Let’s assume that you want to use “write_to_file” function in your Azure Cloud Service/C# application. Create header and source file to export this function:

sample_class_api.h

#pragma once

#define DLLEXP   __declspec( dllexport )

#include <string>

 

DLLEXP void write_to_file(const std::string &filename, const std::string &message);

 

sample_class_api.cpp

#include "sample_class.h"

#include "sample_class_api.h"

 

void write_to_file(const std::string &filename, const std::string &message)

{

  sample_class sample;

  sample.write_to_file(filename, message);

}

Build project as a static lib, Release configuration. Perhaps, for this kind of build you would like to create a new configuration. I created new configuration and called it Release-Lib. Go to project properties (I’m using Microsoft Visual Studio), then General -> Configuration Type, choose “Static Library (.lib)”. Then go to С/C++ -> Code Generation and set Runtime library as “Multi-threaded DLL (/MD)” (of course, all dependencies must be built the same way). Don’t forget to set platform as x64 if you plan to run your code in Cloud.

Wrapper-project

To make code compatible with C# code, it should be put in CLR (Common Language Runtime) project. In this project we will create class sample_class_wrapper, in which we will call imported from native code function. MarshalString function will help us to convert string arguments to std::string for native code.

Add to Azure Cloud App/C# Application solution (Add->Existing project) NativeProjectA. If you don’t want to mess your solution with extra projects, just make sure that wrapper project links necessary .lib files and include necessary headers file from native project. But for the first time I would recommend to add all 3 projects (native, wrapper, C# project) in the same solution and separate them after you will have a successful build.

Add new CLR-project (Add -> New Project, Visual C++ -> Windows -> CLR, CLR Empty Project) NativeProjectAWrapper. Then right-click on the newly created project and choose Add -> Reference. Open Projects -> Solution, then choose NativeProjectA (or specify Library Path and a list of input libraries if you decided not to include the native project in the solution).

Create wrapper-class:

sample_class_wrapper.h

#include <string>

 

namespace sample_class {

  public ref class sample_class_wrapper

  {

  public:

    sample_class_wrapper() {

    };

 

    void write_to_file_wrapper(System::String^ filename, System::String^ message);

    std::string marshal_string(System::String^ input);

  };

}

 

sample_class_wrapper.cpp

#include "sample_class_wrapper.h"

#include <sample_class_api.h>

 

 

namespace sample_class {

  void sample_class_wrapper::write_to_file_wrapper(System::String ^ filename, System::String ^ message)

  {

    write_to_file(marshal_string(filename), marshal_string(message));

  }

 

  std::string sample_class_wrapper::marshal_string(System::String^ s)

  {

    using namespace System::Runtime::InteropServices;

    const char* chars =

      (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();

    std::string os = chars;

    Marshal::FreeHGlobal(System::IntPtr((void*)chars));

    return os;

  }

}

 

Build project as .dll with Release configuration. Go to project properties, then for General -> Configuration Type set “Dynamic Library (.dll)”. Then go to С/C++ -> Code Generation and make sure that Runtime library set to “Multi-threaded DLL (/MD)”. Platform must be the same as in the native project.

Linking wrapper to Azure Cloud Service/C# application

We want to use native code in WorkerRole1 in our project AzureCloudSampleService.

Right-click on Reference for WorkerRole1 and then choose Add Reference. Choose Projects -> Solution, then click in checkbox for NativeProjectAWrapper.

Open Configuration Manager. Make sure all “Build” checkboxes are checked for NativeProjectA and NativeProjectAWrapper, and you have chosen the proper configuration (Release-Lib for NativeProjectA and Release for NativeProjectAWrapper. Set x64 as platform for WorkerRole1 configuration, but cloud service and solution platform must remain “Any CPU”.

Now let’s use some native code. In WorkerRole1 add “using sample_class”:

...

using Microsoft.WindowsAzure.ServiceRuntime;

using Microsoft.WindowsAzure.Storage;

using sample_class; //add code here

 

namespace WorkerRole1

{

...

}

Create instance of sample_class_wrapper and call for the desired function. I added native code to write to file to RunAsync function. I get temp file name and write “Hello Cloud” to this file.

Here is how my RunAsync function looks like:

private async Task RunAsync(CancellationToken cancellationToken)

{

    // TODO: Replace the following with your own logic.

    while (!cancellationToken.IsCancellationRequested)

    {

        sample_class_wrapper sample_class_object = new sample_class_wrapper();

        string testString = "Hello Cloud!";

        string filepath = System.IO.Path.GetTempFileName();

        sample_class_object.write_to_file_wrapper(filepath, testString);

        Trace.TraceInformation("Wrote message to file " + filepath);

        await Task.Delay(5000);

    }

}

After execution program starts to write to log:

In File Explorer we can see:

One of this tmp files:

It works!

You can find all sources for this project here: https://github.com/SkyRunn3r/NativeCodeWrapping