Ramblings of a software tester…developer…tester…

Ramblings of a tester who is a programmer who is a tester who is a developer…

Sieve of Eratosthenes in Go

I’m pretty proud of this one as well.

package sieve
 
//Sieve Uses the Sieve of Eratosthenes to calculate primes to a certain limit
func Sieve(limit int) []int {
	var listOfPrimes []int
	markers := make([]bool, limit)
 
	for i := 2; i < limit; i++ {
		if !markers[i] {
			for j := i + i; j < limit; j += i {
				markers[j] = true
			}
			listOfPrimes = append(listOfPrimes, i)
		}
	}
 
	return listOfPrimes
}

Quick Tip for Debugging Headless Locally

If you are installing something with Packer and you have Headless enabled(and you are lazy and don’t want to switch it off), it gets difficult, to see output.

Especially on a windows install the Answer File / Unattended install can be like => Waiting for SSH… for about an hour or two! If you are doing this locally fret not. Just start VirtualBox, and watch the Preview section which will display the current state even if it’s a headless install!

It’s a small windows, but your can click on Show which will open the VM in a proper view.

Screenshot from 2015-07-22 15:22:35

Enjoy,
Gergely.

Converting numbers into string representations

I quiet like this one. My first go program snippet without any peaking or googling. I’m proud, though it could be improved with a bit of struct magic and such and such. And it only counts ’till 1000…

package main
 
import "fmt"
 
var words = map[int]string{1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven",
	8: "eight", 9: "nine", 10: "ten", 11: "eleven", 12: "twelve", 13: "thirteen", 14: "fourteen", 15: "fifteen",
	16: "sixteen", 17: "seventeen", 18: "eighteen", 19: "nineteen", 20: "twenty", 30: "thirty", 40: "forty",
	50: "fifty", 60: "sixty", 70: "seventy", 80: "eighty", 90: "ninety"}
 
// CountLetters count the letters in a long string number representation
func CountLetters(limit int) {
	myLongNumberString := ""
	for i := 1; i <= limit; i++ {
		addLettersToMyString(&myLongNumberString, i)
	}
	// fmt.Println("1-9 written with letters is: ", len(myLongNumberString))
	fmt.Println("The string is:", myLongNumberString)
	fmt.Println("Lenght of string is:", len(myLongNumberString))
}
 
func addLettersToMyString(myString *string, num int) {
	if num < 20 {
		*myString += words[num]
	}
 
	if num >= 20 && num < 100 {
		*myString += countMiddle(num)
	}
 
	if num >= 100 && num < 1000 {
		hundred, tenth := countHundred(num)
		if tenth == 0 {
			*myString += hundred
		} else if tenth >= 11 && tenth < 20 {
			*myString += hundred + "and" + words[tenth]
		} else {
			*myString += hundred + "and" + countMiddle(tenth)
		}
 
	}
 
	if num == 1000 {
		*myString += "onethousand"
	}
}
 
func countMiddle(num int) string {
	minues := num % 10
	num -= minues
	return words[num] + words[minues]
}
 
func countHundred(num int) (string, int) {
	minues := num % 100
	num -= minues
	return (words[(num/100)] + "hundred"), minues
}

Bitwise & Operator

The first, and only time so far, that I got to use the bitwise & operator. I enjoyed doing so!!

And of course from now on, I’ll be looking for more opportunities to (ab)use it.

package secret
 
import "sort"
 
const REVERSE = 16
 
func Handshake(code int) []string {
    // binary_rep := convertDecimalToBinary(code)
    if code < 0 { return nil }
    secret_map := map[int]string {
        1: "wink",
        2: "double blink",
        4: "close your eyes",
        8: "jump",
    }
 
    var keys []int
    for k := range secret_map {
        keys = append(keys, k)
    }
    // To make sure iteration is always in the same order.
    sort.Ints(keys)
 
    code_array := make([]string, 0)
    for _, key := range keys {
        if code & key == key {
            code_array = append(code_array, secret_map[key])
        }
    }
 
    if code & REVERSE == REVERSE {
        code_array = reverse_array(code_array)
    }
 
    return code_array
}
 
func reverse_array (array_to_reverse []string) []string {
    for i, j := 0, len(array_to_reverse) -1 ; i < j; i, j = i + 1, j - 1 {
        array_to_reverse[i], array_to_reverse[j] = array_to_reverse[j], array_to_reverse[i]
    }
    return array_to_reverse
}

Packer 0.8.1.

Previously I wrote that the scripts I’m writing, are failing because Packer hangs.

Apparently, this was a known issue. And apparently, I was using an older version, 0.7.5. After I updated everything is working wonderfully!!!

And for my thanks, here is an updated PowerShell script for provisioning my dotnet stuff.

$source = "http://download.microsoft.com/download/1/6/7/167F0D79-9317-48AE-AEDB-17120579F8E2/NDP451-KB2858728-x86-x64-AllOS-ENU.exe"
$destination = "C:\Windows\Temp\dotnet.exe"
Write-Host 'Starting to download dotnet file.'
try {
  (New-Object System.Net.WebClient).DownloadFile($source, $destination)
} catch [Exception] {
  Write-Host "Exception during download. Probable cause could be that the directory or the file didn't exist."
  Write-Host '$_.Exception is' $_.Exception
}
Write-Host 'Download done. Checking if file exists.'
if (!(Test-Path $destination)) {
  Write-Host 'Downloading dotnet Failed!'
} else {
  Write-Host 'Download successful.'
}
 
Write-Host 'Starting install process.'
try {
  Start-Process -FilePath $source -ArgumentList "/q /norestart" -Wait -PassThru
} catch [Exception] {
  Write-Host 'Exception during install process.'
  Write-Host '$_.Exception is' $_.Exception
}
 
Write-Host 'All done. Goodbye.'

Thanks for reading!
Gergely.

Powershell can also be nice -Or Installing Java silently and waiting

Hello folks.

Today, I would like to show you a small script. It installs Java JDK, both version, x86 and 64 bit, silently, and wait for that process to finish.

The wait is necessary because /s on a java install has the nasty habit of running in the background. If you are using a .bat file, you shouldn’t, than you would use something like: start /w jdk-setup.exe /s. This gets it done, but is ugly. Also, if you are using Packer and PowerShell provisioning, you might want to set up some environment variables as well for the next script. And you want that property to be available and you don’t want to mess it up with setting a path into a file and then re-setting your path on the begin of your other script. Or pass it around with Packer. No. Use a proper PowerShell script. Learn it. It’s not that hard. Be a professional. Don’t hack something together for the next person to suffer at.

Here is how I did it. Hope it helps somebody out.

$JDK_VER="7u75"
$JDK_FULL_VER="7u75-b13"
$JDK_PATH="1.7.0_75"
$source86 = "http://download.oracle.com/otn-pub/java/jdk/$JDK_FULL_VER/jdk-$JDK_VER-windows-i586.exe"
$source64 = "http://download.oracle.com/otn-pub/java/jdk/$JDK_FULL_VER/jdk-$JDK_VER-windows-x64.exe"
$destination86 = "C:\vagrant\$JDK_VER-x86.exe"
$destination64 = "C:\vagrant\$JDK_VER-x64.exe"
$client = new-object System.Net.WebClient
$cookie = "oraclelicense=accept-securebackup-cookie"
$client.Headers.Add([System.Net.HttpRequestHeader]::Cookie, $cookie)
 
Write-Host 'Checking if Java is already installed'
if ((Test-Path "c:\Program Files (x86)\Java") -Or (Test-Path "c:\Program Files\Java")) {
    Write-Host 'No need to Install Java'
    Exit
}
 
Write-Host 'Downloading x86 to $destination86'
 
$client.downloadFile($source86, $destination86)
if (!(Test-Path $destination86)) {
    Write-Host "Downloading $destination86 failed"
    Exit
}
Write-Host 'Downloading x64 to $destination64'
 
$client.downloadFile($source64, $destination64)
if (!(Test-Path $destination64)) {
    Write-Host "Downloading $destination64 failed"
    Exit
}
 
 
try {
    Write-Host 'Installing JDK-x64'
    $proc1 = Start-Process -FilePath "$destination64" -ArgumentList "/s REBOOT=ReallySuppress" -Wait -PassThru
    $proc1.waitForExit()
    Write-Host 'Installation Done.'
 
    Write-Host 'Installing JDK-x86'
    $proc2 = Start-Process -FilePath "$destination86" -ArgumentList "/s REBOOT=ReallySuppress" -Wait -PassThru
    $proc2.waitForExit()
    Write-Host 'Installtion Done.'
} catch [exception] {
    write-host '$_ is' $_
    write-host '$_.GetType().FullName is' $_.GetType().FullName
    write-host '$_.Exception is' $_.Exception
    write-host '$_.Exception.GetType().FullName is' $_.Exception.GetType().FullName
    write-host '$_.Exception.Message is' $_.Exception.Message
}
 
if ((Test-Path "c:\Program Files (x86)\Java") -Or (Test-Path "c:\Program Files\Java")) {
    Write-Host 'Java installed successfully.'
}
Write-Host 'Setting up Path variables.'
[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "c:\Program Files (x86)\Java\jdk$JDK_PATH", "Machine")
[System.Environment]::SetEnvironmentVariable("PATH", $Env:Path + ";c:\Program Files (x86)\Java\jdk$JDK_PATH\bin", "Machine")
Write-Host 'Done. Goodbye.'

Now, there is room for improvement here. Like checking exit code, doing something extra after a failed exit. Throwing an exception, and so on and so forth. But this is a much needed improvement from calling a BAT file.

And you would use this in a Packer JSON file like this..

{
      "type": "powershell",
      "scripts": [
        "./scripts/jdk_inst.ps1"
      ]
}

Easy. And at the end, the System.Environment actually writes out into the registry permanently so no need to pass it around in a file or something ugly like that.

Hope this helps somebody.
Thanks for reading.
Gergely.

Setting up a new Laptop with Puppet

Hello folks.

So, some of you know puppet, some of you don’t. Puppet is a configuration management system. It’s quite awesome. I like working with it. One of the benefits of puppet is, that I never, ever, EVER have to setup a new laptop from scratch, EVER again.

I’m writing a puppet manifest file which sets up my new laptop to my liking. I will improve it as I go along. Here is version 1.0.

# include apt
 
class base::basics {
        $packages = ['git', 'subversion', 'mc', 'vim', 'maven', 'gradle']
 
        exec { "update":
                command => "/usr/bin/apt-get update",
        }
 
        package { $packages:
                ensure => installed,
                require => Exec["update"],
        }
 
}
 
class base::skype {
        exec { "add-arc":
                command => "/usr/bin/dpkg --add-architecture i386",
        }
 
        exec { "add-repo-skype":
                command => "/usr/bin/add-apt-repository \"deb http://archive.canonical.com/ \$(lsb_release -sc) partner\"",
                require => Exec['add-arc'],
        }
 
        exec { "update-and-install":
                command => "/usr/bin/apt-get update && /usr/bin/apt-get install skype",
                require => Exec['add-repo-skype'],
        }
}
 
class base::java8 {
        # Automatically does an update afterwards
        # apt::ppa { 'ppa:webupd8team/java': }
        exec { "add-repo-java":
                command => "/usr/bin/add-apt-repository -y \"ppa:webupd8team/java\" && /usr/bin/apt-get update"
        }
 
        exec { "set-accept":
                command => "/bin/echo /usr/bin/debconf shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections && /bin/echo /usr/bin/debconf shared/accepted-oracle-license-v1-1 seen true | sudo /usr/bin/debconf-set-selections",
                require => Exec['add-repo-java'],
        }
 
        exec { "install":
                command => "/usr/bin/apt-get install -y oracle-java8-installer",
                require => Exec['set-accept'],
        }
 
        exec { "setup_home":
                command => "/bin/echo \"export JDK18_HOME=/usr/lib/jvm/java-8-oracle/\" >> /etc/environment",
                require => Exec['install'],
        }
}
 
include base::basics
include base::skype
include base::java8

I’ll improve upon it as I go, and you can check it out later from my git repo. I removed the parts which required extra libraries for now, as I want it to run without the need of getting extra stuff installed. I might automate that part as well later on.

EDIT: https://github.com/Skarlso/puppet/blob/master/manifests/base_setup.pp

Have fun.
Gergely.