Režim celé obrazovky ve VirtualBoxu

Při vytvoření virtuálního počítače ve VirtualBoxu a instalaci operačního systému do tohoto virtuálního počítače se může stát, že zobrazení celé obrazovky nebude zcela funkční (plocha operačního systému virtuálního počítače nebude přes celé okno).

virtual_box_guest_additions

Řešením je nainstalování přídavků pro hosta (guest additions).

Zařízení -> Instalovat přídavky pro hosta.

virtual_box_guest_additions02

Zobrazí se volba co se má dělat po vložení média. Potvrdit volbu „Otevřít v souborovém manageru“.

virtual_box_guest_additions03

Dvojklikem spustit autorun.sh.

virtual_box_guest_additions04

Potvrdit spuštění souboru.

virtual_box_guest_additions05

Zadat heslo.

virtual_box_guest_additions06

Po skončení instalace stisknout Enter a operační systém ve virtuálním počítači restartovat. Po restartu by se již měla plocha operačního systému přizpůsobovat velikosti okna.

virtual_box_guest_additions07

Zdroje:

Vložení měřícího kódu

Google Analytics používá pro měření návštěvnosti webu (a další statistiky) měřící kód, který je  třeba přidat do každé stránky, která má být sledována.

Kód pro vložení lze nalézt v části „Správce“.

google_analytics_merici_kod

Následně kliknout na „Údaje o měření“ -> „Měřicí kód“.

google_analytics_merici_kod02

Nejednodušším řešením je vložit kód do části head nebo footer, která je součástí (vkládá se do) každé stránky. Ve WordPressu stačí třeba editovat soubor (vložit kód do souboru) header.php nebo footer.php, které jsou umístěny v /www/wp-content/themes/nazev_tematu.

Symbolický link

Symbolický odkaz, anglicky symbolic link, symlink, softlink, tj. měkký odkaz označuje v informatice alternativní odkaz, který ukazuje na jiný soubor nebo adresář. Odkaz je realizován jako malý speciální soubor, který obsahuje absolutní nebo relativní cestu k cílovému souboru. Zdroj: cs.wikipedia.org/wiki/Symbolick%C3%BD_odkaz

Symbolický odkaz se vytváří pomocí příkazu ln s volbou -s.

~$ ln -s /etc/rc.local 
~$ file rc.local 
rc.local: symbolic link to `/etc/rc.local' 

Výše uvedený příklad vytvoří symbolický odkaz na soubor /etc/rc.local. Příkaz file vypíše typ souboru. File mode bit na první pozici je l (malé písmeno l).

ln -s /etc/rc.local symLinkTo_rc.local

Tak jako v předchozím příkladu vytvoří symbolický link na soubor /etc/rc.local a pojmenuje jej symLinkTo_rc.local.

Velmi hezké vysvětlení symbolických odkazů jsem nalezl na této webové stránce a zde je budu citovat:

Symbolický link je něco jako zkratka, principem je velmi podobný odkazu v html souboru, ale funguje v rámci souborového systému. Je velmi vzdáleně podobný zástupci ve Windows, což je nedokonalá napodobenina symbolického linku. Zástupce ve Windows je obyčejný datový soubor, který některé programy speciálně interpretují a jiné nikoliv. Tj. podpora zástupců je záležitost jednotlivých aplikací. Symbolický link je záležitost podstatně nižší úrovně, je to součást souborového systému a jeho interpretaci má na starost jádro. Symbolický link je speciální soubor stejně jako je speciální soubor adresář.

Symbolický link si můžete představit jako normální soubor, jehož obsahem je adresa (cesta, path) na jiný soubor (i speciální, tedy adresář, rouru a podobně). Přesně to totiž symbolický link je. Akorát že to není normální soubor a ta cesta není uložena v datové oblasti (symbolický link nic takového nemá) takže ho třeba nemůžete otevřít v textovém editoru a podívat se na ni.

Symbolický link nemusí ukazovat jen na datové soubory. Může ukazovat na libovolný druh souboru, třeba na adresáře. Je užitežné (alespoň já to dělám a dělám to všem lidem, kterým instaluji a konfiguruji Linux) si ve svém domácím adresáři udělat adresář který obsahuje hromadu symbolických linků, které ukazující na často navštěvované adresáře rozmístěné po různých discích co máte v počítači jako zkratky, které umožňují rychlý přístup k nim. Do těchto frekventovaných adresářů se ze všech aplikací pak dostanete nanejvýš na dvě kliknutí, protože domácí adresář je v Linuxu výchozí bod, od kterého se pokračuje dál.

Když smažete soubor, na který ukazuje symbolický link, tak symbolický link poté ukazuje do nikam. Pokus o jeho otevření pro čtení nebo zápis se chová stejně jako pokus o otevření neexistujícího souboru. Správci souborů takové symbolické linky často výstražně zvýrazňují, třeba červenou barvou. Zdroj: usl.wraith.cz/usl.html

Time test

JUnit i TestNG umožňují pomocí parametru timeout anotace @Test nastavit podmínku testu tak, aby test, pokud má být úspěšný, proběhl do určité doby (definované v milisekundách). V případě, že test trvá déle, jeho běh je ukončen a test je označen jako neúspěšný (failure).

Metoda, která se bude testovat.

public void longMethod() {
	for (int i = 0; i < 1_000_000; i++) {
		System.out.println("myMethod");
	}
}

Test.

@Test(timeout=1000)
public void longMethodTest() {
	longMethod();
}

Kód je stený jak pro JUnit tak pro TestNG. Pro JUnit test se používá anotace org.junit.Test a pro TestNG org.testng.annotations.Test. Pokud bude výše uvedený test trvat déle jak 1000 milisekund, bude označen jako neúspěšný.

File mode bits

V Linuxu je vše soubor a tím pádem vše má nastaveno i oprávnění (permission). Oprávnění určuje kdo má právo číst (read), zapisovat (write) a spustit (execute) daný soubor. Výpis oprávnění souborů lze získat pomocí příkazu ls s volbou -l.

Ukázka:

drwxr-xr-x   6 root root     4096 říj 12 19:30 apt
drwxr-xr-x   2 root root     4096 srp  5 07:18 at-spi2
-rw-r--r--   1 root root     2177 dub  9  2014 bash.bashrc
-rw-r--r--   1 root root       45 bře 22  2014 bash_completion
drwxr-xr-x   2 root root     4096 říj 24 20:43 bash_completion.d
-rw-r--r--   1 root root      356 led  1  2012 bindresvport.blacklist
-rw-r--r--   1 root root      321 dub 16  2014 blkid.conf
lrwxrwxrwx   1 root root       15 zář  2 20:35 blkid.tab -> /dev/.blkid.tab

1 2-4 5-7 8-10
 typ souboru oprávnění uživatele oprávnění skupiny oprávnění ostatních uživatelů

Typ souboru

běžný soubor
d adresář
l link
s socket (slouží pro komunikaci mezi procesy)
p pojmenovaná roura (named pipe)
b blokové zařízení
c znakové zařízení

K určení typu souboru slouží příkaz file.

vitfo@vitfo-VirtualBox:~$ file Pictures/
Pictures/: directory 

vitfo@vitfo-VirtualBox:~$ file .profile 
.profile: ASCII text

Oprávnění

Oprávnění je určeno trojicí čísel. První znamená oprávnění pro čtení (r), druhé pro psaní (w) a třetí pro vykonání/spuštění (x). V případě, že dané oprávnění není, používá se -. Zde je ukázka souboru bez oprávnění ---------- (10 krát pomlčka). Pro změnu „file mode bits“ slouží příkaz chmod.

Zdroje:

Mockování s JMockit

JMockit umožňuje mockování. Mockování je nahrazení objektů za mock objekty. Mock objekty jsou objekty, které představují (napodobují) nahrazovaný objekt a simulují jeho funkcionalitu tak, jak programátor potřebuje. Mockování se používá při testech a mockují se objekty, na kterých testovaná třída závisí, ale nejsou součástí testu, nebo je programátor nemůže ovlivnit. Může se jednat o dotazy do databáze, na webové služby, ….

Programátor například potřebuje otestovat, jak se jeho objekt chová, když zavolá službu a ta mu vrátí false, nebo nějaký složitý objekt. Tato služba zatím třeba ani neexistuje, nebo je velmi složité napsat na ni dotaz tak, aby vrátil požadovaný výsledek (dotaz musí projít validací a musí se přetransformovat do dalšího objektu tak, aby nevyhazoval výjimky atd.).

V následujícím příkladu použiji pro mockování knihovnu JMockit. Vytvořím si svoji třídu MyService, která bude nabízet metodu getAuthorizedPerson, která autorizuje id a v případě, že dané id bude autorizované, vrátí na jeho základě objekt Person. Moje třída bude volat dvě další služby, které jako programátor nemohu ovlivnit a nejsou ani součástí mého testu.

Třída Person.

public class Person {

	private long id;
	private String name;
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Externí služba pro autorizaci.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class AuthorizationService {
	
	private Connection connection;

	public boolean isAuthorized(long id) throws SQLException {
		PreparedStatement ps = connection.prepareStatement("select * from t_person where id = ?");
		ps.setLong(1, id);
		ResultSet rs = ps.executeQuery();
		if (rs.next()) {
			return true;
		}
		return false;
	}
}

Třída pro dotazování do databáze.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class PersonDao {

	private Connection connection;
	
	public Person getPerson(long id) throws SQLException {
		PreparedStatement ps = connection.prepareStatement("select id, name from t_person where id = ?");
		ps.setLong(1, id);
		ResultSet rs = ps.executeQuery();
		if (rs.next()) {
			Person person = new Person();
			person.setId(rs.getLong("id"));
			person.setName(rs.getString("name"));
			return person;
		}
		return null;
	}
}

Třída, kterou potřebuji otestovat

import java.sql.SQLException;

public class MyService {
	
	public Person getAuthorizedPerson(long id) {
		
		// Find out if the person is authorized.
		AuthorizationService as = new AuthorizationService();
		boolean isAuthorized = false;
		try {
			isAuthorized = as.isAuthorized(id);
		} catch (SQLException e1) {
			throw new RuntimeException("Exception while authorizating");
		}
		
		// Get the person.
		if (isAuthorized) {
			PersonDao pd = new PersonDao();
			try {
				Person person;
				person = pd.getPerson(id);
				return person;
			} catch (SQLException e) {
				throw new RuntimeException("Exception while getting person");
			}
		} else {
			throw new RuntimeException("Person is not authorized");
		}
	}
}

Pro tento příklad je třeba přidat závislosti na JUnit a JMockit do projektu:

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.11</version>
</dependency>
<dependency>
	<groupId>org.jmockit</groupId>
	<artifactId>jmockit</artifactId>
	<version>1.20</version>
</dependency>

Můj test.

import static org.junit.Assert.*;

import java.sql.SQLException;

import mockit.Mock;
import mockit.MockUp;

import org.junit.Before;
import org.junit.Test;

public class MyServiceTest {

	private MyService myService;
	private AuthorizationService authorizationService;
	private PersonDao personDao;

	@Before
	public void prepare() {
		myService = new MyService();
		authorizationService = new AuthorizationService();
		personDao = new PersonDao();
	}

	@Test(expected = RuntimeException.class)
	public void getAuthorizedPersonFailTest() {

		// Mock AuthorizationService to return false.
		mockAuthorizationService(false);

		// Test MySevice#getAutohorizedPerson.
		myService.getAuthorizedPerson(1L);
	}

	@Test
	public void getAuthorizedPersonOKTest() {
		
		// Mock AuthorizationService and its isAuthorized method to return true.
		mockAuthorizationService(true);
		
		// Mock PersonDao#getPersonMethod to return specific Person object.
		mockGetPersonMethod();

		// Test MySevice#getAutohorizedPerson.
		Person p = myService.getAuthorizedPerson(1L);
		assertNotNull(p);
		assertTrue(p.getId() == 101L);
		assertTrue(p.getName().equals("František Koudelka"));
	}

	private void mockAuthorizationService(boolean isAuthorized) {
		new MockUp<AuthorizationService>() {
			@Mock
			public boolean isAuthorized(long id) throws SQLException {
				return isAuthorized;
			}
		};
	}

	private void mockGetPersonMethod() {
		new MockUp<PersonDao>() {
			@Mock
			public Person getPerson(long id) throws SQLException {
				Person p = new Person();
				p.setId(101L);
				p.setName("František Koudelka");
				return p;
			}
		};
	}
}

Vysvětlení:

new MockUp<PersonDao>() {
	@Mock
	public Person getPerson(long id) throws SQLException {
		Person p = new Person();
		p.setId(101L);
		p.setName("František Koudelka");
		return p;
	}
};

Vytvoří mock objekt PersonDao, jehož metoda getPerson vždy vrátí objekt Person s id 101 a name „František Koudelka“. Podobné je to pro AuthorizedService, jejíž metoda isAuthorized vrátí buď true nebo false dle toho, co zadáme jako parametr při volání mockAuthorizationService.

@Before
public void prepare() {
	myService = new MyService();
	authorizationService = new AuthorizationService();
	personDao = new PersonDao();
}

Tento kód se provede před každým testem (díky anotaci @Before). To znamená, že před každým testem se znovu inicializují tyto proměnné.

Zdroje:

Guava Optional.class

Null může znamenat mnoho věcí. Aby bylo jasnější, co vlastně má null představovat, a také proto, aby uživatel ošetřil stavy, kdy může dojít k NullPointerException je tady třída Optional z knihovny Guava. Tato třída je vhodná právě pro případy, kdy null má představovat prázdnou hodnotu.

Pokud proměnná obsahuje prázdnou hodnotu (například záznam nenalezen) použije se Optional.absent(). Pokud neprázdnou hodnotu pak je to Optional, který obsahuje referenci na danou hodnotu. Pokud by v tomto případě proměnná obsahovala null, znamenalo by to, že proměnná nebyla inicializována a byla by to chyba.

Tímto způsobem je přesně řečeno, kdy proměnná něco obsahuje a kdy ne. Dalším důvodem pro tuto třídu je přimět uživatele ke kontrole, a předejít případné NullPointerException.

Hodnotu (referenci na objekt) získlám z Optional voláním metody get(). Když už voláme get(), mělo by nás trknout, že hodnota může být absent a proto bychom měli nejdříve zavolat isPresent(). Pokud tato metoda vrátí true můžeme zavolat get() a s objektem dále pracovat. Určitou nevýhodou je neustálé volání get() metody.

Třída Person.

import com.google.common.base.Optional;

public class Person {
 
       private long id;
       private String name;
       private String surname;
       private Optional<String> nickname;
      
       public Person(long id, String name, String surname) {
             this.id = id;
             this.name = name;
             this.surname = surname;
             this.nickname = Optional.absent();
       }
       public Person(long id, String name, String surname, String nickname) {
             this.id = id;
             this.name = name;
             this.surname = surname;
             this.nickname = Optional.of(nickname);
       }
      
       public long getId() {
             return id;
       }
       public void setId(long id) {
             this.id = id;
       }
       public String getName() {
             return name;
       }
       public void setName(String name) {
             this.name = name;
       }
       public String getSurname() {
             return surname;
       }
       public void setSurname(String surname) {
             this.surname = surname;
       }
       public Optional<String> getNickname() {
             return nickname;
       }
       public void setNickname(Optional<String> nickname) {
             this.nickname = nickname;
       }
}

Třída Service s metodou, která vrací Optional.absent v případě, že daný objekt Person není v seznamu nalezen. V případě, že nalezen je, vrací Optional s referencí na nalezený objekt.

import java.util.List;

import com.google.common.base.Optional;

public class Service {

	public Optional<Person> findLongInList(List<Person> list, Long id) {
		for (Person person : list) {
			if (person.getId() == id) {
				return Optional.of(person);
			}
		}
		return Optional.absent();
	}
}

Třída App, ve které je ukázána práce s Optional.

import java.util.Arrays;
import java.util.List;

import com.google.common.base.Optional;
 
public class App {
       private static List<Person> persons = Arrays.asList(
                    new Person(1L, "František", "Koudelka"),
                    new Person(2L, "John", "Smith", "johny"),
                    new Person(3L, "James", "Bond"));
 
       public static void main(String[] args) {
             Service service = new Service();
             Optional<Person> personId2 = service.findLongInList(persons, 2L);
             Optional<Person> personId3 = service.findLongInList(persons, 3L);
             Optional<Person> personId4 = service.findLongInList(persons, 4L);
 
             // Pravujeme s objektem personId2
             // Zde většinu programátorů napadně kontrola na null.
             if (personId2.isPresent()) {
                    System.out.println("Jméno člověka s id 2: " + personId2.get().getName());
                    // Je ale jednoduché zapomenout na to, že getNickname může vrátit null. S Optional je to zřejmější.
                    if (personId2.get().getNickname().isPresent()) {
                           System.out.println("Jeho přezdívka je: " + personId2.get().getNickname().get());
                    }
             }
 
             // Pravujeme s objektem personId3
             if (personId3.isPresent()) {
                    System.out.println("Jméno člověka s id 3: " + personId3.get().getName());
                    if (personId3.get().getNickname().isPresent()) {
                           System.out.println("Jeho přezdívka je: " + personId3.get().getNickname().get());
                    }
             }
 
             // Pravujeme s objektem personId4
             if (personId4.isPresent()) {
                    System.out.println("Jméno člověka s id 4: " + personId4.get().getName());
                    if (personId4.get().getNickname().isPresent()) {
                           System.out.println("Jeho přezdívka je: " + personId4.get().getNickname().get());
                    }
             }
       }
}

Po spuštění dostaneme následující výsledek:

Jméno člověka s id 2: John
Jeho přezdívka je: johny
Jméno člověka s id 3: James

Zdroje:

Testování privátních metod

V některých případech obsahuje třída složité metody, které však používá pouze tato třída a je zbytečné měnit jejich viditelnost jen kvůli otestování. K otestování takových metod je nutné využít reflexi.

Třída, kterou budeme testovat. Tato třída obsahuje veřejnou metodu compute() a privátní metodu getLongFromString(). Obě tyto metody budeme chtít otestovat.

public class MyClass {
    
    public long compute(String num1, String num2) {
          return Math.abs(getLongFromString(num1) - getLongFromString(num2));
    }

    private long getLongFromString(String number) {
          return Long.parseLong(number);
    }
}

Třída, která slouží jako předek všech testovacích tříd. Tato třída obsahuje metodu getPrivateMethods, která na základě třídy, názvu metody a jejich parametrů dokáže vrátit a zpřístupnit danou metodu na daném objektu.

import java.lang.reflect.Method;

public class AbstractTest {
 
       protected Method getPrivateMethod(Class<?> clazz, String methodName, Class<?> ... parameterTypes) {
             try {
                    // get method vrací pouze public metody
                    // Method method = clazz.getMethod(methodName, parameterTypes);
                    // proto je potřeba volat getDeclaredMethod
                    Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
                    method.setAccessible(true);
                    return method;
             } catch (Exception e) {
                    throw new IllegalArgumentException("Cannot obtain method with name: " + methodName, e);
             }
       }
}

A nakonec třída s testy. Metodu getLongFromString testujeme dvakrát. Jednou pro případ, že zadáme správné parametry a podruhé testujeme, že vyhodí výjimku.

import static org.junit.Assert.assertTrue;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
import org.junit.BeforeClass;
import org.junit.Test;
 
public class MyClassTest extends AbstractTest {
       private static MyClass myClass;
      
       @BeforeClass
       public static void prepare() {
             myClass = new MyClass();
       }
 
       @Test
       public void computeOK() {
             String n1 = "120";
             String n2 = "330";
            
             long result = myClass.compute(n1, n2);
             assertTrue(result == 210);
       }
      
       @Test
       public void getLongFromStringOK() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
             String n = "30";
            
             Method testedMethod = getPrivateMethod(MyClass.class, "getLongFromString", String.class);
             long result = (Long) testedMethod.invoke(myClass, n);
            
             assertTrue(result == 30);
       }
      
       @Test(expected = InvocationTargetException.class)
       public void getLongFromStringThrowsException() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
             String s = "AB";
            
             Method testedMethod = getPrivateMethod(MyClass.class, "getLongFromString", String.class);
             testedMethod.invoke(myClass, s);
       }
      
}

Anotace @BeforeClass znamená, že daná metoda se volá jednou a to před voláním jakékoliv jiné metody ve třídě. Anotace @Test(expected = InvocationTargetException.class) definuje, jaký typ výjimky má být vyhozen. Metoda getLongFromString sice vyhodí NumberFormatException, ale ta pak způsobí InvocationTargetException. Z toho důvodu očekáváme při testu tuto výjimku.

Vytvoření řetězce z pole stringů

Níže uvedený kód předpokládá, že máme definováno následující pole: String[] arr = {"a", "b", "c", "d"}.

Použití StringBuilderu.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
       sb.append(arr[i]);
       if (i < arr.length - 1) {
              sb.append(", ");
       }
}
System.out.println(sb.toString());

Variace na předchozí způsob.

StringBuilder sbb = new StringBuilder();
for (int i = 0; i < arr.length; i++) { 
       if (i > 0) {
              sbb.append(", ");
       }
       sbb.append(arr[i]);
}
System.out.println(sbb.toString());

Použití StringUtils (vnitřně používá StringBuilder).

String result = StringUtils.join(arr, ", ");
System.out.println(result);

Do projektu je třeba přidat závislost.

<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-lang3</artifactId>
 <version>3.4</version>
</dependency>

A trochu divoký způsob pomocí třídy Arrays a regulárních výrazů.

String string = Arrays.toString(arr);
String regex = Pattern.quote("[") + "|" + Pattern.quote("]");
String string2 = string.replaceAll(regex, "");
System.out.println(string2);

Převede pole na řetězec (ten obsahuje [] a jednotlivé stringy oddělené čárkou). Následně provede odstranění hranatých závorek. Pattern.quote() provádí správně odescapování daného znaku či sekvence znaků.