Goならわかるシステムプログラミング:第3章(練習問題)

Q3.1 ファイルのコピー

package main

import (
    "io"
    "os"
)

func main() {
    file, err := os.Open("old.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    newFile, err := os.Create("new.txt")
    if err != nil {
        panic(err)
    }
    defer newFile.Close()
    io.Copy(newFile, file)
}

テスト

package main

import (
    "bytes"
    "io/ioutil"
    "os"
    "testing"
)

func exists(filename string)bool {
    _, err := os.Stat(filename)
    return err == nil
}

func TestMainSuccess(t *testing.T){
    if exists("new.txt") {
        os.Remove("new.txt")
    }

    main()
    oldFile, err := os.Open("old.txt")
    if err != nil {
        t.Fatalf("failed to open old file: %#v", err)
    }
    newFile, err := os.Open("new.txt")
    if err != nil {
        t.Fatalf("failed to open new file: %#v", err)
    }
    oldBuffer, err := ioutil.ReadAll(oldFile)
    if err != nil {
        t.Fatalf("failed to read content: %#v", err)
    }
    newBuffer, err := ioutil.ReadAll(newFile)
    if err != nil {
        t.Fatalf("failed to read content: %#v", err)
    }
    if bytes.Compare(oldBuffer, newBuffer) != 0 {
        t.Fatalf("each contents of files are different.")
    }

    os.Remove("new.txt")
}

テストはもうちょっとスッキリかける気がする。

Q3.2 テスト用の適切なサイズのファイルを生成

package main

import (
    "crypto/rand"
    "io"
    "os"
)

func main() {
    file, err := os.Create("samplefile")
    if err != nil {
        panic(err)
    }
    defer file.Close()
    r := io.LimitedReader{R: rand.Reader, N: 1024}
    io.Copy(file, &r)
}

io.Copyを使わないように」と問題には書いてあったが、LimitReaderを使って読み出しているので問題ない?

テスト

package main

import (
    "os"
    "testing"
)

func TestMainSuccess(t *testing.T) {
    main()
    info, err := os.Stat("samplefile")
    if err != nil {
        t.Fatalf("could not open file.")
    }
    if info.Size() != 1024 {
        t.Fatal("size was not 1024 byte.")
    }
    defer os.Remove("samplefile")
}

ファイルサイズはos.Stat()で取れる。