Minggu, 30 November 2008

Lakukan Test Terhadap Program Anda

Dapat dikatakan bahwa "melakukan test terhadap kode program" merupakan salah satu kebiasaan yang paling penting dalam melakukan pembuatan program. Dengan testing yang baik, kita akan mendapatkan keleluasaan dalam pembuatan program.

Kedengarannya seperti suatu kesimpulan yang aneh. Kemungkinan kita akan berfikir, bahwa testing merupakan halangan bagi keleluasaan pembuatan program. Tapi jika kita dapat melihat bahwa sebuah test yang baik terhadap method-method public di dalam sebuah class akan membuat kita bebas untuk merubah implementasi dari method public tersebut. Kita tidak perlu takut lagi bahwa perubahan yang dilakukan akan menyebabkan kita harus merubah atau lebih parah merusak keseluruhan program kita.

Selama kita dapat melewati Unit Test yang telah dibuat untuk method-method yang public, artinya method public kita memiliki parameter dan menghasilkan keluaran seperti yang diharapkan dalam test, kita dapat yakin bahwa keseluruhan program kita dapat tetap berjalan dengan lancar.

Memastikan bahwa keseluruhan program kita dapat berjalan dengan baik hanya merupakan tujuan pertama dari dilakukannya test. Beberapa hal lain yang kita bisa harapkan dengan adanya test secara menyeluruh terhadap program kita adalah:
  1. Testing memaksa kita membuat program yang dapat dengan mudah ditest. Ketika kita membuat sebuah method, kita akan selalu berfikir bagaimana kita akan melakukan test dengan menyeluruh terhadap method kita tersebut. Hal ini membawa kita untuk melakukan perubahan-perubahan di method dan tentunya keseluruhan program yang kita buat. Hasilnya adalah bagian-bagian program yang tidak saling terikat ('loose coupling'), fleksible dan lebih modular. Dengan begitu, perubahan terhadap program di kemudian hari dapat dilakukan dengan lebih mudah.
  2. Penulisan test mendorong kita untuk fokus dan mendefinisikan dengan jelas harapan kita terhadap bagaimana seharusnya program kita bekerja. Kita akan mendefinisikan dengan jelas, jika parameter A dimasukan, maka nilai B akan dihasilkan dan seterusnya. Setelah melihat harapan kita tentang keluaran dengan berbagai masukan, selanjutnya kita akan memikirkan mengenai kemungkinan-kemungkinan input yang akan diterima oleh program kita dan kemungkinan-kemungkinan keluarannya, yang mungkin berada di luar nilai sewajarnya. Dari situ kita akan harus mengambil keputusan mengenai bagaimana kita akan menanggulanginya. Hal ini mendorong kita untuk membuat program yang lebih fleksibel terhadap masukan dan menghindari kesalahan yang dapat menghentikan jalannya program secara keseluruhan.
  3. Dengan test case yang kita miliki, orang lain dapat melihat tujuan dibuatnya method yang kita test, berikut pula cara pemakaiannya. Dengan begitu, test dapat dijadikan sebagai dokumentasi yang jelas dari program yang kita bangun. Dan, pada point 1, karena kita akan cendrung membuat method kita mudah untuk ditest dan simple, maka tentunya akan memudahkan orang lain memahami mengenai keseluruhan program yang kita tulis.
Saya berharap dengan argumentasi di atas membuat penulisan Unit Test menjadi suatu hal yang menarik untuk dilakukan karena keuntungannya akan melebihi harapan awal anda. Selain itu, untuk mulai melakukan Unit testing di PHP bukanlah suatu hal yang sulit untuk dilakukan.

Selasa, 25 November 2008

Unit Testing di PHP (Bagian 2 Test Pertama)

Dalam tulisan sebelumnya, saya telah menjelaskan cara untuk melakukan instalasi PHPUnit. Berikutnya kita akan mulai membuat unit test menggunakan PHPUnit untuk aplikasi yang kita bangun. Sebelum kita mulai dengan test, mari kita buat dasar dari class yang akan kita test,

<?php

class Calculator {

public function add($a, $b) {
return 5;
}
}

Simpan ke dalam file dengan nama 'Calculator.php'. Kemudian, kita lanjutkan dengan membuat bentuk dasar dari test class kita. Sebuah test yang menggunakan PHPUnit memiliki bentuk dasar sebagai berikut:

<?php

require_once 'Calculator.php';
require_once 'PHPUnit/Framework.php';

class CalculatorTest extends PHPUnit_Framework_TestCase {

protected function setUp() {

}

protected function tearDown() {

}

public function testAdd() {

}
}

Tentunya kita mengikutsertakan file 'Calculator.php' karena kita akan membuat unit test untuk class tersebut. Anda dapat mengubah bagian tersebut sesuai dengan class yang ingin anda buatkan testnya.

Beberapa hal yang perlu dijelaskan adalah, test class harus melakukan extends terhadap PHPUnit_Framework_TestCase. Selain itu, masing-masing test method yang akan dijalankan, HARUS memiliki nama yang dimulai dengan kata 'test' dan bersifat public. Pada contoh di atas, method 'testAdd' merupakan salah satu method yang akan melakukan test. Tinggal dua method lagi yang belum dijelaskan, yaitu 'setUp' dan 'tearDown'.

Method dengan nama 'setUp' dan 'tearDown' merupakan method yang akan dijalankan setiap kali test method kita dijalankan. 'setUp' dijalankan sebelum masing-masing test method dan 'tearDown' dijalankan setelah masing-masing test method. Jadi, jika kita memiliki dua buah test method, misalnya 'testMethodSatu' dan 'testMethodDua', maka urutan dijalakannya method-method adalah:

  • setUp

  • testMethodSatu

  • tearDown

  • setUp

  • testMethodDua

  • tearDown


  • 'setUp' dapat digunakan untuk melakukan inisialisasi yang diperlukan sebelum sebuah test dijalankan, misalnya mempersiapkan data, membuat object yang dibutuhkan atau koneksi ke database. 'tearDown' dapat digunakan untuk melakukan pembersihan terhadap hasil proses test, misalnya menghapus file yang dibuat dalam test, menghapus data yang dimasukkan ke dalam database dan lain sebagainya. Dengan cara ini kita dapat memastikan method test selalu dijalankan dengan kondisi lingkungan yang tetap.

    Mari kita mulai membuat unit test kita. Saya hanya menampilkan potongan dari file 'CalculatorTest.php' di bawah ini:

    class CalculatorTest extends PHPUnit_Framework_TestCase {

    private $calculator;

    protected function setUp() {
    /* Kita membuat object calculator karena selalu dibutuhkan
    * dalam setiap test kita.
    */
    $this->calculator = new Calculator();
    }

    protected function tearDown() {

    }

    public function testAdd() {
    /* Pastikan hasil method add di calculator sesuai */
    $this->assertEquals(5, $this->calculator->add(2, 3));
    }
    }


    Di method setUp kita mempersiapkan sebuah object dari Calculator karena akan selalu dipergunakan dalam setiap test kita. Kemudian dalam method 'testAdd' kita melakukan pemanggilan terhadap $this->assertEquals . Method ini merupakan method yang disediakan oleh PHPUnit yang melakukan pengetasan apakah parameter pertama, sama dengan parameter kedua. Dalam contoh di atas, apakah 5 sama dengan hasil dari $this->calculator->add(2, 3). PHPUnit menyediakan beberapa fungsi 'assert' yang dapat digunakan untuk keperluan unit test yang berbeda.

    Saya mencoba untuk membuat test terlebih dahulu sebelum melakukan implementasi ke dalam class Calculator sendiri. Setelah test selesai dibuat, implementasi di dalam class dapat dibuat untuk melewati test yang ada. Pada saat ini jika kita menjalankan test, tentunya akan gagal. Coba lakukan perintah berikut:

    phpunit CalculatorTest

    Akan terjadi error karena kita belum memiliki method add di class Calculator. Mari kita lanjutkan dengan membuat method add. Kita membuat method hanya untuk melewati test yang telah dibuat.

    class Calculator {

    public function add($a, $b) {
    return 5;
    }
    }

    jika kita menjalankan phpunit kembali seperti perintah sebelumnya, test kita akan berhasil sekarang. Tetapi method add kita belum selesai. Tambahkan assertion lagi ke dalam unit test untuk memastikannya.

    public function testAdd() {
    /* Pastikan hasil method add di calculator sesuai */
    $this->assertEquals(5, $this->calculator->add(2, 3));

    /* Coba dengan nilai berbeda */
    $this->assertEquals(23, $this->calculator->add(15, 8));
    }

    Jika test dijalankan maka akan gagal kembali dengan pesan:

    'Failed asserting that <integer:5> matches expected value <integer:23>'
    /blog/CalculatorTest.php:20

    Hasil tersebut mengatakan bahwa, pada baris nomor 20 (di program saya nomor 20, lihat hasil dari test anda) terjadi perbedaan nilai, dimana yang diharapkan adalah 23 dan nilai hasil adalah 5. Hal tersebut terjadi karena method add kita selalu mengembalikan nilai 5. Mari kita ubah method tersebut:

    class Calculator {

    public function add($a, $b) {
    return $a + $b;
    }
    }

    Jalankan kembali test untuk melihat hasilnya.

    Coba tambahkan test dengan angka yang berbeda lagi, dan coba lihat hasilnya. Jika sudah berhasil, kita dapat membuat unit test dengan memasukkan nilai yang bukan angka sebagai parameter. Coba masukkan string, null ataupun array. Bagaimana hasilnya? Apakah terjadi error? Apakah hasilnya seperti yang kita inginkan?

    Ternyata membuat unit test menggunakan PHPUnit tidak sesulit yang saya bayangkan sebelumnya. Pada tulisan berikutnya saya akan menerangkan mengenai cara untuk melakukan unit test untuk memastikan bahwa sebuah error telah terjadi.

    Senin, 24 November 2008

    Unit Testing di PHP (Bagian 1 Instalasi)

    Sejalan dengan berkembangnya Object Oriented di PHP, penggunaan Testing Framework menjadi hal yang semakin banyak dibicarakan. Selain itu, PHP juga telah berkembang dari sekedar menambahkan efek dinamis di sebuah website kecil, menjadi bahasa pemrogramman aplikasi besar yang perlu memperhatikan ketepatan jalannya sebuah logika aplikasi. Dengan melakukan test yang menyeluruh, kita dapat memastikan ketepatan dari aplikasi yang kita bangun, seperti yang dijelaskan pada blog mengenai keuntungan melakukan test. Melihat hal tersebut, kita sebagai pembangun aplikasi di PHP harus sesegera mungkin mempelajari Testing Framework yang dapat membantu dalam pembangunan aplikasi.

    Salah satu testing framework yang sering digunakan untuk melakukan Unit Testing di PHP adalah PHPunit. PHPunit merupakan bagian dari xUnit Testing Framework yang memudahkan penulisan testing dan menganalisa hasil dari test yang dilakukan. Instalasi PHPunit sendiri sangat mudah karena menggunakan bantuan PEAR installer dalam menjalankannya. Berikut cara instalasi PHPunit menggunakan PEAR installer.

    Pertama-tama kita perlu mendaftarkan PEAR channel yang digunakan untuk mendistribusi PHPunit. Hal ini dilakukan dengan memberikan perintah:

    pear channel-discover pear.phpunit.de

    Setelah hal tersebut dijalankan, instalasi dapat dilakukan dengan:

    pear install phpunit/PHPUnit


    Setelah instalasi selesi, kita dapat menemukan file source PHPUnit di tempat kita meletakkan PEAR package. Hal ini tergantung distribusi PHP anda. Ada baiknya kita menambahkan directory tempat phpunit ke dalam PATH sehingga kita bisa memanggil program tersebut dari mana saja. Untuk memastikan instalasi berhasil, coba jalankan perintah berikut:

    phpunit --version

    akan keluar versi dari phpunit yang terinstall di tempat anda. Sekarang, kita tinggal membuat Unit Test yang sesuai dengan aplikasi yang kita bangun dan memanggil phpunit untuk menjalankannya. Bagaimana cara membuat unit test pertama anda, dengan menggunakan PHPUnit, akan dijelaskan pada tulisan berikutnya.

    Jumat, 21 November 2008

    Stress Test Aplikasi Web dengan Apache ab2

    Salah satu tugas dari pembangun aplikasi adalah melakukan test terhadap aplikasi yang dibangunnya. Salah satu test yang perlu untuk dilakukan adalah Stress Test. Stress test aplikasi web bertujuan untuk melihat apakah aplikasi yang telah dibangun di atas sebuah web server dapat berjalan dengan stabil dengan beban yang diberikan. Dalam tersebut kita memberikan beban yang berbeda-beda kepada aplikasi dan melihat respon dari aplikasi web tersebut.

    Untuk melakukan stress test aplikasi web tersedia berbagai macam tools. Salah satu yang menarik adalah Apache Ab (ab2 di Opensuse). Tools tersebut disediakan langsung oleh apache web server sebagai bagian dari system toolsnya. Penggunaannya sangat mudah dan tidak memerlukan banyak setting. Di Opensuse tools tersebut bisa didapatkan dengan menginstall paket apache2-utils. Untuk menggunakannya lakukan perintah berikut:

    # ab -kc 10 -t 30 http://localhost/
    Perintah di atas akan melakukan sepuluh koneksi secara bersamaan ke web server anda dan melakukan request secara terus menerus selama 30 detik. Hasil yang dilaporkan pun cukup menarik dan bisa diexport ke gnuplot format ataupun csv. Berikut contoh hasil dari perintah di atas:

    This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright 2006 The Apache Software Foundation, http://www.apache.org/

    Benchmarking localhost (be patient)
    Completed 5000 requests
    Completed 10000 requests
    Completed 15000 requests
    Completed 20000 requests
    Completed 25000 requests
    Completed 30000 requests
    Completed 35000 requests
    Completed 40000 requests
    Completed 45000 requests
    Finished 50000 requests


    Server Software: Apache/2.2.4
    Server Hostname: localhost
    Server Port: 80

    Document Path: /
    Document Length: 163 bytes

    Concurrency Level: 10
    Time taken for tests: 8.804394 seconds
    Complete requests: 50000
    Failed requests: 0
    Write errors: 0
    Keep-Alive requests: 49509
    Total transferred: 22530617 bytes
    HTML transferred: 8150978 bytes
    Requests per second: 5678.98 [#/sec] (mean)
    Time per request: 1.761 [ms] (mean)
    Time per request: 0.176 [ms] (mean, across all concurrent requests)
    Transfer rate: 2498.98 [Kbytes/sec] received

    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 0.0 0 4
    Processing: 0 1 4.2 1 282
    Waiting: 0 1 4.2 1 282
    Total: 0 1 4.2 1 282

    Percentage of the requests served within a certain time (ms)
    50% 1
    66% 1
    75% 1
    80% 1
    90% 2
    95% 2
    98% 4
    99% 5
    100% 282 (longest request)


    Untuk melihat performance dari aplikasi web kita, ganti nilai -kc (concurrent connetion) dengan angka yang terus bertambah (hingga 50 sebagai contoh) dan tingkatkan batas waktu (-t) sehingga test dapat dilakukan dalam jangka waktu yang cukup untuk diukur. Kemudian, bandingkan hasil antara jumlah conccurent connection yang berbeda-beda tersebut. Selamat mencoba

    Static Keyword di PHP5

    Dengan mendefinisikan sebuah property ataupun method menggunakan kata-kata static, kita dapat mengakses property atau method tersebut tanpa melakukan inisiasi terhadap class yang mendefinisikannya. Dari dokumentasi mengenai static keyword di PHP5, ada beberapa hal yang perlu diperhatikan:
    1. Deklarasi kata static harus setelah deklarasi dari visibility, contoh

    public static $data;

    BUKAN

    static public $data;

    Jika tidak ada deklarasi visibility, maka property atau method tersebut akan dianggap public.

    2. Karena static method dapat dipanggil tanpa melakukan instansiasi dari object, maka penggunaan kata '$this' tidak berlaku untuk method yang menggunakan deklarasi static.

    3. Static property tidak dapat diakses menggunaan operator tanda panah (->), tetapi static method dapat diakses dengan operator tanda panah.

    Sekarang kita melihat contoh dari property dan method yang bersifat static:

    class MyClass {

    public static $data = 5;
    public $id;

    public function setData($data) {
    self::$data = $data;
    }

    public function getData() {
    return self::$data;
    }

    public function setId($id) {
    $this->id = $id;
    }

    public function getID() {
    return $this->id;
    }

    public static function staticGetData() {
    return self::$data;
    }
    }


    Dengan class di atas, kode-kode di bawah ini dapat dilakukan:

    echo MyClass::$data; // Mengeluarkan angka 5, tidak perlu melakukan intansiasi class
    echo MyClass::staticGetData() // Mengeluarkan angka 5, tidak perlu melakukan intansiasi class

    $x = new MyClass();
    $x->setId(3);

    echo $x->getId(); // Mengeluarkan angka 3, harus melakukan instansiasi sebelum dipanggil
    echo $x->getData(); // Mengeluarkan angka 5, harus melakukan instansiasi sebelum dipanggil


    Nah, sekarang beberapa contoh yang menarik untuk meningkatkan pemahaman terhadap pengaruh static deklarasi terhadap property di class:

    $x = new MyClass();
    $x->setId(3);
    $x->setData(12);

    // Print out nilai di X
    echo 'Nilai id di $x: ' . $x->getId() . ' -- nilai data di $x: ' . $x->getData() . '<br/>';

    $y = new MyClass();
    $y->setId(8);
    $y->setData(30);

    // Print out nilai di Y
    echo 'Nilai id di $y: ' . $y->getId() . ' -- nilai data di $y: ' . $y->getData() . '<br/>';

    // Sekarang kita coba lagi dengan nilai di X
    echo 'Nilai id di $x: ' . $x->getId() . ' -- nilai data di $x: ' . $x->getData() . '<br/>';


    Perhatikan baik-baik nilai yang dihasilkan, terutama nilai X di pemanggilan kedua dibandingkan dengan nilai Y. Dengan deklarasi static, property $data di X dan di Y merupakan dua hal yang sama. Perubahan di satu tempat akan merubah hal yang lain. Lalu, apa bagusnya hal tersebut?

    Beberapa hal yang dapat dilakukan dengan deklarasi static:
    1. Melakukan Singleton Pattern dimana sepanjang proses hanya terdapat satu instance dari class yang kita inginkan.

    2. Menggantikan $_GLOBAL variable. Karena kita bisa mengakses property static tersebut dari mana saja, kita bisa menggunakannya untuk menggantikan $_GLOBAL variable. Kelebihannya adalah kita mempunyai namespace karena property didefinisikan di dalam class. Artinya, kita bisa memiliki dua buah property static yang bernama $data di dua class yang berbeda dan tidak perlu khawatir saling bertabrakan. Contoh:

    class NumberOne {
    public static $data = 3;
    }

    class NumberTwo {
    public static $data = 'test';
    }

    echo "Value number one: " . NumberOne::$data;
    echo "Value number two: " . NumberTwo::$data;


    Semoga dapat menambah pengetahuan.

    Kamis, 20 November 2008

    Netbeans 6.5 akhirnya diluncurkan

    Setelah sempat tertunda beberapa kali Netbeans 6.5 akhirnya diluncurkan juga. Beberapa hal baru yang ada di netbeans 6.5 adalah support terhadap PHP, peningkatan editing JavaScript dan Ajax serta peningkatan support terhadap Hibernate dan Java Persistence API. Selain itu Netbeans 6.5 juga menawarkan integrasi yang lebih baik ke GlassFish v3 dan MySQL.

    Persaingan di IDE makin seru aja dan yang diuntungkan adalah developer yang semakin punya pilihan terhadap IDE nya. hmm.. atau malah makin dibingungkan dengan pilihan yang ada :)

    Rabu, 19 November 2008

    Front Controller Pattern

    Mengapa kita membutuhkan pattern ini?

    Ketika sebuah aplikasi menangani permintaan service melalui titik masuk yang berbeda-beda, akan sangan sulit tentunya untuk menghindari duplikasi yang terjadi dalam programmnya. Sebagai contoh, ketika kita membutuhkan autentikasi terhadap user, maka proses autentikasi tersebut harus kita pastikan terjadi di berbagai titik masuk dari aplikasi kita. Jika ada titik masuk yang terlupa, tidak dilakukan autentikasi, aplikasi kita dapat diakses tanpa ada autentikasi. Masalahnya akan lebih besar lagi ketika kita harus melakukan perubahan terhadap proses autentikasi tersebut. Perubahan yang dibutuhkan, mau tidak mau, harus dilakukan di setiap titik yang membutuhkan autentikasi itu sendiri. Dengan cara ini, akan terdapat kemungkinan dimana beberapa bagian dari program kita terlupakan untuk diupdate. Tentunya kita dapat membuat library atau fungsi yang digunakan bersama-sama untuk menangani proses autentikasi tersebut, tetapi kita tetap harus memanggil fungsi tersebut dari beberapa titik masuk aplikasi kita.

    Permasalahan besar juga terjadi ketika kita harus menangani aplikasi yang memiliki alur penampilan (View) yang berbeda-beda. Untuk sistem yang kompleks, tampilan yang dikirimkan ke pengguna mungkin dibentuk oleh beberapa bagian yang berbeda, tergantung pada hasil berbagai proses di dalam aplikasi. Belum lagi jika bagian-bagian dari tampilan tersebut dapat digunakan dengan cara yang berbeda-beda. Ketika kita memiliki titik masuk yang banyak ke dalam aplikasi, mememecahkan proses penampilan tersebut menjadi pekerjaan yang tidak mudah untuk dilakukan.

    Untuk mengatasi permasalahan-permasalahan di atas, kita dapat menggunakan pattern yang disebut sebagai Front Controller Pattern. Pattern ini menyediakan satu titik masuk bagi keseluruhan aplikasi kita. Kemudian, Front Controller akan melakukan pemrosesan untuk menentukan siapa yang harus bertanggung jawab terhadap permintaan yang terjadi. Dengan cara ini, kita dapat menambahkan fungsi-fungsi seperti autentikasi, inisialisasi, penentuan bahasa atau theme di satu tempat dan mendapatkan hasilnya di seluruh bagian dari aplikasi kita.

    Implementasi

    Di sini kita akan membahas mengenai Front Controller Pattern dengan PHP. Yang kita butuhkan adalah sebuah class yang akan menerima request dari client dan kemudian berdasarkan request tersebut menentukan hal apa atau siapa yang bertanggung jawab untuk melakukan proses selanjutnya. Contoh dari controller tersebut dapat dilihat di potongan class di bawah.


    class FrontController {
    private $applicationHelper;

    private function __construct() {}

    static function run() {
    $instance = new self();
    $instance->init();
    $instance->handleRequest();
    }

    function init() {
    $applicationHelper = ApplicationHelper::getInstance();
    $applicationHelper->init();
    }

    function handleRequest() {
    $request = new Request();
    $router = new Router();
    $cmd = $router->resolve($request);

    $cmd->execute( $request );
    }
    }


    Ternyata tidak terlalu sulit menerapkan Front Controller Pattern di PHP. Tentunya akan lebih terasa manfaatnya jika kita menambahkan beberapa helper class yang akan membantu dalam tugas-tugas seperti autentikasi dll. Untuk menggunakan class di atas, di awal aplikasi (misal: index.php) kita dapat melakukan pemanggilan:

    require_once 'FrontController.php';
    FrontController::run();


    Mulai sekarang, semua request ke aplikasi kita akan ditangani oleh FrontController dan diteruskan ke pihak-pihak yang berwenang :) . Detail dari beberapa bagian di FrontController tersebut akan saya bahas di tulisan berikutnya.

    Senin, 17 November 2008

    Opensource CMS

    Lagi melakukan research mengenai open source Content Management System (CMS). Cukup kaget juga melihat kenyataan bahwa terdapat lebih dari 70 CMS open source saat ini. Mungkin data itu masih belum mencakup semua CMS open source yang ada pada saat ini, tetapi angka tersebut sangat banyak menurut saya.

    Hal yang menarik perhatian saya adalah kebanyakan CMS open source yang menggunakan domain .org lebih memiliki tampilan yang menarik dan isi yang lebih fokus kepada komunitas dibandingkan dengan yang menggunakan domain .com. Walaupun, ada juga CMS yang menggunakan domain .org yang tidak terlihat fokus. Selain itu, jika dibandingkan dengan CMS yang ada beberapa tahun lalu (5 tahun mungkin) CMS open source yang ada saat ini banyak yang telah memperhatikan desain tampilan dari aplikasinya serta dokumentasi yang jauh lebih lengkap.

    Kesimpulan lain adalah pemain-pemain lama di CMS open source bukan saja dapat bertahan hidup tetapi malah telah jauh berkembang, baik dari sisi fitur maupun konsep pengembangannya. Ada juga pemain lama yang terlihat kurang berkembang dibandingkan yang lainnya. Di lain sisi, pemain-pemain yang relatif lebih baru banyak bermunculan dan telah siap dengan fitur-fitur yang dapat diadu dengan pemain lama.

    Proses instalasi juga mengalami perbaikan yang sangat terasa. Saya mencoba melakukan instalasi beberapa aplikasi CMS tersebut dan semuanya berjalan dengan mudah. Hanya butuh beberapa menit untuk melakukan instalasi aplikasinya. Untuk setting masing-masing aplikasi setelah instalasi selesai tentunya akan sangat bergantung pada fitur apa yang kita inginkan. Masing-masing CMS menggunakan strategi setting yang berbeda, tetapi keseluruhan belum banyak perubahan yang terjadi dari konsep cara melakukan setting.

    Secara garis besar, salut untuk perkembangan CMS open source dan komunitasnya yang menyediakan aplikasi bermutu. Semoga dari Indonesia akan terlahir juga aplikasi sejenis yang dapat bersaing.

    Minggu, 16 November 2008

    Instalasi subversion repository di Linux (Opensuse)

    Mengenai subversion
    Subversion merupakan sebuah tools open source yang digunakan sebagai tempat penyimpanan source code dalam pembangunan aplikasi. Tools tersebut dibutuhkan terutama jika pembangunan dilakukan oleh tim yang memungkinkan terjadinya perubahan terhadap file secara bersamaan oleh anggota tim. Tetapi, jika anda melakukan pembangunan aplikasi sendirian pun, anda masih dapat pula mengambil manfaat dari penggunaan subversion dimana semua source code anda dapat terkumpul di satu tempat dan terdapat history perubahan dari aplikasi yang dibuat.

    Salah satu hal yang menarik dari subversion adalah fitur yang memungkinkan melihat source code melalui web front end. Untuk itu dibutuhkan sebuah web server yang akan melayani pengaksesan subversion melalui protokol http tersubut. Integrasi antara subversion dengan web server Apache akan dibahas dalam blog ini sebagai bagian dari setting subversion.

    Selain subversion, tools serupa yang dapat digunakan untuk dijadikan sebagai tempat penyimpanan source code adalah CVS. Di dalam blog ini saya tidak akan melakukan perbandingan antara subversion dan CVS.


    Instalasi
    Instalasi dari subversion sendiri bukanlah hal yang sulit, terutama karena telah tersedia paket-paket dari distributor linux untuk subversion. Paket di bawah ini merupakan paket dari subversion sendiri:
    1. subversion -- Subversion client
    2. subversion-server -- Paket subversion server

    Kemudian untuk integrasi dengan apache dibutuhkan paket-paket di bawah ini
    1. apache2
    2. apache2-prefork
    3. libapr1
    4. libapr-util1
    5. neon

    untuk instalasi di suse menggunakan rpm package dapat dilakukan (sebagai root) :
    # rpm -ivh RPM_PACKAGE_FILE
    perintah tersebut akan menginstall package yang dimaksud dan melakukan pengecekan terhadap package lain yang dibutuhkan. Jika terdapat paket-paket yang dibutuhkan, cari package tersebut dan install.

    Lokasi Repository dan User Password
    Directory untuk subversion repository dapat diletakkan di mana saja dalam file system. Dalam contoh ini saya akan menggunakan /opt/svn sebagai tempat penyimpanan
    # mkdir -p /opt/svn/repos
    # mkdir /opt/svn/user_access
    # touch /opt/svn/user_access/svn_passwdfile
    # chown root:www /opt/svn/user_access/svn_passwdfile
    # chmod 640 /opt/svn/user_access/svn_passwdfile
    Perhatikan di langkah ke empat, kita menggunakan root:www yang artinya file tersebut merupakan milik dari root dan group www, yang merupakan group dari user yang menjalankan server apache. Sesuaikan
    Pada langkah ketiga di atas, kita membuat sebuah file yang akan digunakan untuk menampung data user dan password dari pengguna subversion yang boleh melakukan perubahan terhadap source code. Kita dapat pula membedakan hak akses user berdasarkan project. Untuk itu, kita harus membuat file yang berbeda untuk project yang berbeda. Misalnya kita memiliki project dengan name cool_project, kita dapat membuat file sebagai berikut:
    # touch /opt/svn/user_access/cool_project_svn_passwdfile
    # chown root:www /opt/svn/user_access/cool_project_svn_passwdfile
    # chmod 640 /opt/svn/user_access/cool_project_svn_passwdfile
    Demikian seterusnya untuk project yang berbeda. Dengan cara ini kita dapat membatasi user-user terhadap project yang boleh mereka ubah. Untuk menambah user gunakan perintah yang dimiliki oleh apache, yaitu
    # htpasswd2 /opt/svn/user_access/svn_passwdfile YOUR_USER_NAME
    masukkan password yang diinginkan dua kali.

    Integrasi Apache Subversion
    Integrasi apache dan subversion membutuhkan aktivasi dari module di apache, yaitu:
    1. dav
    2. dav_svn

    Untuk itu, lakukan perintah berikut sebagai root:'
    # a2enmod dav
    # a2enmod dav_svn
    Atau, tambahkan langsung module dav dan dav_svn di file /etc/sysconfig/apache2 pada bagian APACHE_MODULES. Setelah module ditambahkan edit file /etc/apache2/conf.d/subversion.conf untuk menunjukkan pada apache letak dari repository kita.
    # vi /etc/apache2/conf.d/subversion.conf
    masukkan baris-baris di bawah ini:
       <ifModule mod_dav_svn.c>
    # Set up single repository directory 'kdrepos'
    # This has open read access, but limited write (commit) access
    <Location /repos>
    DAV svn
    SVNParentPath /opt/svn/repos
    # Allow the 'repos' index page to list all the repositories it contains
    SVNListParentPath On
    # Limit write permission to list of valid users.
    <LimitExcept GET PROPFIND OPTIONS REPORT>
    # Require SSL connection for password protection.
    # SSLRequireSSL
    AuthType Basic
    # Message to give to the committer
    AuthName "Write access requires a password"
    # File listing users with write (commit) access
    AuthUserFile /opt/svn/user_access/svn_passwdfile
    Require valid-user
    </LimitExcept>
    </Location>
    </ifModule>
    Jika kita ingin menggunakan file password yang berbeda untuk project yang berbeda, maka kita perlu membuat tag yang berbeda untuk masing-masing. Misal, tambahkan bagian berikut di bawah tag di konfigurasi di atas.
       <Location /repos/coolproject>
    DAV svn
    SVNParentPath /opt/svn/repos/coolproject
    SVNListParentPath On
    <LimitExcept GET PROPFIND OPTIONS REPORT >
    AuthType Basic
    AuthName "Write access requires a password"
    AuthUserFile /opt/svn/user_access/cool_project_svn_passwdfile
    Require valid-user
    </LimitExcept>
    </Location>
    Setelah setting ini selesai, anda dapat melakukan restart apache, untuk mengaktifkan konfigurasi
    # /etc/init.d/apache2 restart
    Project Repository
    Jika tidak terdapat permasalahan ketika kita melakukan restart apache, maka kita dapat melanjutkan dengan mempersiapkan subversion repository untuk project kita. Proses ini harus dilakukan untuk masing-masing project yang ingin kita tambahkan:
    # svnadmin create /opt/svn/repos/myproject
    # chown -R wwwrun:www /opt/svn/repos/myproject/{dav,db,locks}
    Dua perintah di atas pertama membuat struktur directory untuk project dengan nama myproject. Kemudian kita memberikan hak akses kepada apache untuk melakukan penulisan ke directory dav, db dan locks di bawah directory project kita. Sekali lagi perlu diperhatikan user dan group yang menjalankan apache sendiri, dan sesuaikan dengan setting anda.

    Setelah langkah di atas, kita dapat melakukan import dari source code yang sudah kita miliki ke subversion repository. Tetapi, merupakan langkah yang baik untuk membagi directory project kita ke dalam beberapa directory lagi, untuk digunakan kemudian. Lakukan perintah berikut menggunakan svn client (Tidak harus sebagai root) :
    > svn mkdir http://localhost/repos/myproject/trunk
    > svn mkdir http://localhost/repos/myproject/branches
    > svn mkdir http://localhost/repos/myproject/tags
    Pada dasarnya langkah di atas meminta svn client melakukan pembuatan directory di bawah directory project yang sudah dibuat sebelumnya. Perhatikan penggunaan akses http ketika kita membuat directory. Ini menunjukkan integrasi apache dengan subversion kita telah berjalan.

    Directory yang kita buat ada tiga buah, trunk, branches dan tags. Mengapa kita membutuhkan directory sebanyak itu untuk project kita. Merupakan kebiasaan yang baik untuk mempersiapkan kemungkinan pengembangan ke depan sebagai berikut:

  • trunk: Digunakan untuk menyimpan kode-kode hasil pembangunan terbaru yang saat ini sedang berjalan. Semua update secara normal dilakukan di directory trunk.
  • branches: Digunakan untuk menyimpan pencabangan terhadap pembangunan. Sebagai contoh, jika kita membangun sebuah CMS dan kemudian hari diputuskan akan dimungkinkan terdapat dua buah CMS, atau ada sebagian developer yang ingin mengembangkan dengan cara yang berbeda, maka branches dapat digunakan untuk hal tersebut. Pada pelaksanaannya perlu dibuat directory lagi di bawah branches untuk mengakomodir pencabangan yang ada dari aplikasi yang dibuat.
  • tags: Dapat digunakan untuk menyimpan kode dari hari-hari yang berbeda. Kita dapat membuat sebuah cron job yang setiap malam melakukan pengambilan source code terbaru dari directory trunk dan menyimpannya di bawah tags dengan tanggal sebagai nama directory penyimpanannya. Dengan begitu kita memiliki tags untuk masing-masing tanggal. Hal ini dimaksudkan untuk mempermudah jika kita menginginkan untuk kembali ke salah satu tanggal.

  • Setelah itu, kita dapat mulai memasukkan source code yang sudah kita miliki pada saat ini:
    > svn import /path/to/myproject/dir http://localhost/repos/myproject/trunk
    Perhatikan bahwa kita melakukan import source code kita ke dalam directory trunk. Ganti /path/to/myproject/dir dengan directory tempat anda menyimpan project anda. Jika berhasil, kita perlu mencoba untuk melakukan checkout dari project yang baru saja kita masukkan:
    > svn co http://localhost/repos/myproject/trunk theproject
    Dengan perintah di atas akan terbentuk directory theproject yang berisi source code yang sebelumnya telah kita import. Sekarang, kita dapat mulai melakukan perbaikan terhadap sistem yang di bangun di directory theproject tersebut.

    Jangan lupa, setelah anda selesai mengedit sebuah file, lakukan perintah 'commit' sehingga perubahan akan terkirim kembali ke repository.
    > svn commit theproject
    Untuk melakukan 'commit' terhadap keseluruhan project, atau untuk melakukan commit pada satu file perintah dapat diubah menjadi
    > svn commit theproject/myfile.php
    Penutup
    Pada tulisan ini telah dibahas mengenai cara untuk melakukan instalasi subversion repository dan integrasinya dengan Apache di linux terutama untuk Opensuse. Prinsip yang sama dapat digunakan di distribusi linux yang lain, tetapi beberapa setting perlu disesuaikan.