docker-compose up at Ubuntu reboot


In a past post i wrote about the restart of RabbitMQ service: well it seems that this technique is no more requested, but it does not work if you define and run multi-container Docker applications with docker-compose: if you put commands as

cd /home/[user]/[folderwhereisdocker-compose.yml] 
docker-compose up -d

in /etc/rc.sysinit no way, it does not work: the container is not loaded.
In order to get working a docker-compose solution is requested to use the Unix crontab.
Launch crontab -e, the first time is requested which editor to use: the default is 1 (nano)
Then write a line in the crontab file opened in the editor as

@reboot (sleep 30s ; cd /home/[user]/[folderwhereisdocker-compose.yml] ; docker-compose up -d)&

@reboot is, obvious, a definition of Ubuntu booting time: something as the old good ms-dos autoexec.bat.

Advertisements
Categories: Docker, Ubuntu

Update Npm and Node 8 on Ubuntu 17.10

sudo apt-get purge --auto-remove nodejs
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

Categories: Node, Ubuntu

BlockChain Developer certification

Here the certificate.
As the previous certification, exam session mildly controlled but the material is valid.

Categories: BlockChain

NuGet debug


In my last post i wrote in last paragraph about debugging.
Some clarifications:
– it works only using a NuGet local source on the developer pc: the test project in practice must use a NuGet package source pointing to the folder where is the NuGet solution.
– at every change in the NuGet source must be increased the Assembly version (right clic on NuGet project->Properties->Application->clic on “Assembly Information” button.
– then you must update the NuGet package of the test project.

Categories: .NET, Vs2017

NuGet packaging

I’m working with a consulting firm where there are some commons dll used in the projects , developed from other team members.
Adding the references to a dll by hand in the References folder is ok, but if there is a new version and you try to delete the dll from the References this operation typically causes a Visual Studio crash: the best approach is to delete the reference, with the projects closed, into the .csproj file: then reopening the solution no problems to add the new version.
So after years of NuGet as a customer it was time to become an author.
So I created a dll: in this case, a localization support via XML files because the application was using translation tables from a SQL table and the SQL access was slowing down dramatically the customers.
In the same solution i added a standard MVC app for testing.
In order to make the host application working with this NuGet package are requested:
– a Localization folder with some initial sample XML files
– a new Controller, LocalesController, that essentially changes the value of a Cookie
– a change in Views\Web.Config
For the first two points , we must see something as

That is there is a completely new Localization folder, a new LocalesController in Controllers folder.
Without the new NuGet package we see

First thing, we need the NuGet executable, we can download it from here.
I’m using version 4.5.1.
Then you must generate a .nuspec file.
This can be generated by hand, but we can use the command

nuget spec

launched in the solution directory.
The .nuspec file is an xml structure, with the nodes that can be compiled by hand or using some default placeholders substituted form the values of the project properties, see this reference where is critical to understand the paragraph “Package folder structure”.
References about here, and here.
A Controller can be dynamically created but you know that is better if placed in the same namespace, and this can still be achieved via special placeholders, see also this.
I ended with this .nuspec file :

<?xml version="1.0"?>
<package >
    <metadata>
        <id>$id$</id>
        <version>$version$</version>
        <title>$title$</title>
        <authors></authors>
        <owners></owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>MVC project Localization via XML fields.</description>
        <releaseNotes>First version.</releaseNotes>
        <copyright>Copyright 2018</copyright>
        <tags>mvc http xml localization</tags>         
    </metadata>
    <files>
        <file src="..\Acme.MvcLocalization\Localization\**\*.*" target="" />
        <file src="content\any\any\Controllers\LocalesControllers.cs.pp" target="content\Controllers" />
        <file src="content\any\any\Views\web.config.transform" target="content\Views" />
    </files>    
</package>

The first “any” is a code language, the second the target framework (see references).
In this case some parts are taken form projects, others by hand; it works on a structure like this:

the blurred parts corresponds to the “Acme” in .nuspec (for privacy i don’t reveal the consulting firm true name)
There is a part (Localization folders with the contained xml files) that must be copied “as is” in the Localization folder of the hosting project, this is done with

<file src="..\Acme.MvcLocalization\Localization\**\*.*" target="" />

Then in the controllers there is a .cs file followed from a .pp, this instructs NuGet to evaluate the file, in this case our .pp contains

using Acme.MvcLocalization;
using System.Web.Mvc;

namespace $rootnamespace$.Controllers
{
    public class LocalesController : Controller
    {
        public ActionResult Index(string lang = "it_IT")
        {
            Response.Cookies["AcmeCacheLang"].Value = lang;
			// cookie above fundamental
            if (Request.UrlReferrer != null)
                Response.Redirect(Request.UrlReferrer.ToString());
             
			var message = Localization.Get("changedlng");
			return Content(message);
        }
    }
}

Note the $rootnamespace$ : when the package is installed it is evaluated to the root namespace of the host application.
Now we examine web.config.transform

<?xml version="1.0" encoding="utf-8"?>

<configuration>
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="Acme.MvcLocalization" />
        <add namespace="Acme.MvcLocalization.Helpers" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>
</configuration>

If we open the default Views/Web.Config of the Host application we can read

<?xml version="1.0" encoding="utf-8"?>

<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization" />
        <add namespace="System.Web.Routing" />
        <add namespace="WebApplication1" />
  </system.web.webPages.razor>

It is intuitive to understand that at run time the 2 new namespaces in the .transform will be added to the node with the same path:

<configuration><system.web.webPages.razor><host><pages><namespaces>

WebApplication1 is the name of the MVC host application that used for test.
Ok, now at a Command prompt in the NuGet project root (where there is the .nuspec file) we can generate the package

nuget pack Acme.MvcLocalization.csproj

So in the folder we have now a .nupkg files.
Obvious, every new release should be done after increasing the version in the project properties.
Now it time to test our new package.
First, while testing is not requested to publish it on the official NuGet repository but you can specify a folder on your pc a NuGet source: open the NuGet Package Manager and goto to Package Sources where to define a local path:

Done this, you can see available the new package:

Installing it , you can see that is created the new folder Localization with the xml files inside, in Controllers there is the LocalsController.cs with the changed namespace:

And in Views the web.config is changed:

The interesting fact is if you place a breakpoint in the NuGet project, it works:

Categories: .NET, Vs2015

Start menu not working in Windows 10


In Windows 10 1709 i encountered the nasty problem of the start button not working.
I was already thinking to reformat…but this article fortunately was helpful.
For me the solution is only at the first level (logout then login).

Categories: Windows 10

Testing with Selenium grid


Selenium Server is basically a way for remote-execute our tests in Visual Studio.
This is a .jar Java executable, so it is needed the Java runtime as first thing; then we can download the Standalone Server in this page.
The Selenium “grid” is a technology that allows us to take a test and run it on a number of different machines that are part of this “grid”, that is a network of physical, cloud , virtual (Hyper-V or VmWare) or also Docker instances running the same or different operative systems.
You can create for example a grid with 3 different instances: a physical Mac, a Ubuntu virtual machine, a Windows 10 virtual machine.
One of the instances in the grid must be the main Hub, the others are Nodes that must be connected to the Hub.
In every node of the grid must be installed Java, because the .jar executable of the Selenium Server must be run locally on all nodes with different runtime parameters.
In order to run the .jar the Java executable must be reached from the system path.
The code for a grid test is different from the one for a “normal” test.
For example we can create a ConsoleApplication with Visual Studio (here I’m using Visual Studio 2015 Community, but every version since 2013 should work without problems), add 2 NuGet packages:
– Selenium.Support
– Selenium.WebDriver
The first is the only one that we need for a normal test, WebDriver is requested in order to do grid testing.
Done this , in the Main of our Program.cs we can write

using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

 namespace WebDriverDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebDriver driver = new FirefoxDriver();
            driver.Url = "http://www.google.com";
            var searchBox = driver.FindElement(By.Id("lst-ib"));
            searchBox.SendKeys("Donald Trump");
        }
    }
}

But if you launch this code, you get an error:

This happens because with Selenium is requested a driver for each browser that we intend to use for testing.
For Firefox is requested a Gecko driver that you can download from here.
For Windows systems we download an exe that must be placed in the same directory where we will plan to run the .jar of the Selenium Server, and in every case in a folder in the system path: i use a copy in c:\windows of the exe and another in the folder where is the .jar, but is my questionable practice.
And for the other browsers? For Chrome you can find the ChromeDriver here (the current latest version 2.35 here for Windows, Mac, Linux); the WebDriver for Edge from here; you can see the available downloads in the official Selenium downloads (http://docs.seleniumhq.org/download ).

After placed the exe, launching this code it is opened a command window:

And then is opened the browser, which opens the Google site and in the search textbox is written from the C# code our search term:

We used the Firefox driver and so, obvious, Firefox must be installed on the local machine.
There are drivers for Internet Explorer, Edge, Chrome…, also Opera.
If for example you are testing using Opera, Opera must be installed on the pc where you are launching the test, you must download the WebDriver for Opera, it is requested

using OpenQA.Selenium.Opera;

In the C# code and you must use OperaDriver() instead of FirefoxDriver().
If we want to use a remote browser for testing in a grid, it is needed to define the Hub that typically is the pc where you are developing.
On this pc (could be a virtual machine) in the folder where is placed the Selenium .jar file we must launch this .jar defining the pc as the hub.
Needless to say, every pc/vm/docker instance in the grid must be in the same network, it must be possible to ping the Nodes from the Hub.

For example I’m working with a vm which has the address 172.18.105.118, so I launched

java -jar selenium-server-standalone-3.8.1.jar -role hub -host 172.18.105.118

I specified the role as “hub”, and the -host parameter because i noticed that in a Hyper-V vm without specifying the -host parameter the server is waiting with another address 172* but cannot be reached from another vm.
The .jar is writing in the console some log, the last 2 rows are the most interesting:

16:46:27.227 INFO - Nodes should register to http://172.18.105.118:4444/grid/register/
16:46:27.227 INFO - Selenium Grid hub is up and running

We can read that we are advised how to connect a node to our hub, and it is used the port 4444.
It is also used 5555, so in my Windows 10 Hyper-V instance i configured the firewall in order to permit everything on these 2 port numbers, as Inbound and Outbound rules:

We would for example to make a test on a remote (another Hyper-V instance on the same host, in my case) Ubuntu 17.10 instance.

The browser with which you would make a test must be installed on the remote system, so if you want to make a Firefox test on a remote Ubuntu instance on this instance must be installed Firefox.
And must be installed the relative WebDriver in this remote instance; so in our case (test with Firefox) we must open on the remote Ubuntu a browser and go to https://github.com/mozilla/geckodriver , here click on “Clone or download” green button.
At this point we have downloaded a .tar.gz file (at the time of this post geckodriver-v0.19.1-linux64.tar.gz) in the Downloads folder, then we can made available on Ubuntu the driver with these commands:

tar -xvf geckodriver*

that extracts a file named geckodriver, then

chmod +x geckodriver
sudo mv geckodriver /usr/local/bin

Note that in my case the Ubuntu instance has IP 172.18.105.114 (in Windows we use ipconfig, in Ubuntu ifconfig to see which is the local ip).

Done this , in a Unix shell i launched

java -jar selenium-server-standalone-3.8.1.jar -role node -hub http://172.18.105.118:4444/grid/register/ -host 172.18.105.114

Note:

– the role now is “node” , not “hub”
– i used the http address given from the hub server for the connection to the hub (-hub http://172.18.105.118:4444/grid/register/)
– as for the hub, even for the node i specified in -host the local IP.
Launched this , in the hub which is running we can see a message as

16:46:30.997 INFO – Registered a node http://172.18.105.114:5555

On the pc/vm which is acting as hub, pointing a browser to http://localhost:4444/grid/console we can see something as


You can see that we got one remote proxy here.

Every browser icon has a tooltip, for example we can see

In this case the protocol is Selenium.Platform , WIN10.

Browser name is chrome.

And then the max instances is 5 (it supports up to five concurrent tests).
All is ready, we can do our first grid test.

First, the code must be changed only in the part of the connection, we have now:

using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using System;

 namespace WebDriverDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //IWebDriver driver = new FirefoxDriver();
            IWebDriver driver = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"),
                new DesiredCapabilities("firefox", "", new Platform(PlatformType.Linux)));
            driver.Url = "http://www.google.com";
            var searchBox = driver.FindElement(By.Id("lst-ib"));
            searchBox.SendKeys("Donald Trump");
        }
    }
}

Note that we don’t need anymore

using OpenQA.Selenium.Firefox;

but is requested

using OpenQA.Selenium.Remote;

and we connect to the hub at localhost:4444/wd/hub , piloting a remote Firefox on Unix (DesiredCapabilities).

We have a remote Linux (Ubuntu) proxy with FireFox, so launching this code we can see on the remote Ubuntu instance:

The browser is opened, automatically goes to Google, the search term is inserted in the Google textbox.
We scratched only the surface, Selenium is an argument on which there are entire books: but for starters this article could be useful.

Categories: .NET, Selenium, Testing, Ubuntu, Vs2015

Install only some parts of Office 2016 and 2013


From 2013 version Microsoft Office has the nasty default of install everything, while in the past it was possible to choose what to install.
Sometimes in a test virtual machine the space is limited, and i needed to use only Word and Outlook.
Fortunately there are 2 Office Deployment tools:
Office 2013 Deployment Tool
https://www.microsoft.com/en-us/download/details.aspx?id=36778
Office 2016 Deployment Tool
https://www.microsoft.com/en-us/download/details.aspx?id=49117
With the above links it is downloaded an exe file, which extracts 2 files setup.exe and configuration.xml in a folder of your choice.
In order to install only Word and Outlook 2016 i configured the xml file as:

<Configuration>
<Add SourcePath="C:\Work\Office\" OfficeClientEdition="32" >
<Product ID="ProPlusRetail">
<Language ID="en-us" />
<ExcludeApp ID="Access" />
<ExcludeApp ID="Excel" />
<ExcludeApp ID="Groove" />
<ExcludeApp ID="InfoPath" />
<ExcludeApp ID="Lync" />
<ExcludeApp ID="OneNote" />
<ExcludeApp ID="PowerPoint" />
<ExcludeApp ID="Project" />
<ExcludeApp ID="Publisher" />
<ExcludeApp ID="SharePointDesigner" />
<ExcludeApp ID="Visio" />
</Product>
</Add>

Then i launched, in the folder where are placed the 2 files setup.exe and configuration.xml:

setup /configure configuration.xml

In this case i used the license key from my Action Pack, i tried to use “O365ProPlusRetail” as Product ID but my Office 365 working serial was not recognized: could be that the 365 serial from the Action Pack is not valid in this context for some reason.
I discovered also this Configuration XML Editor:
http://officedev.github.io/Office-IT-Pro-Deployment-Scripts/XmlEditor.html

But my simple xml has worked.

Categories: Office, Office365

Electric NEVS based on SAAB 9.3


So my SAAB 9.3 is still alive and kicking ?

Categories: Saab