Merge branch 'feature/df' into 'master'

Feature/df

See merge request !8
This commit is contained in:
Fredric Silberberg 2014-10-14 16:51:21 -04:00
commit 3b8552d758
4 changed files with 138 additions and 0 deletions

53
df/main.go Normal file
View File

@ -0,0 +1,53 @@
package main
import (
"flag"
"fmt"
"jsh"
"strings"
)
// Converts raw output of "ps" into a slice of Filesystem objects
func DfOutputToFilesystems(out string) *[]jsh.Filesystem {
filesystems := []jsh.Filesystem{}
lines := strings.Split(out, "\n")
header, fses := lines[0], lines[1:]
numFields := len(strings.Fields(header))
for _, fs := range fses {
allFields := jsh.FieldsN(fs, numFields)
if len(allFields) != 0 {
fields := append(allFields[0:4], allFields[5])
p, err := jsh.NewFilesystem(fields)
if err == nil {
filesystems = append(filesystems, *p)
}
}
}
return &filesystems
}
func runJsonMode() {
dfOut := string(*jsh.FallbackWithArgs("df", []string{"-B1"}))
filesystemsPtr := DfOutputToFilesystems(dfOut)
frame := jsh.JshFrame{*filesystemsPtr, []string{}}
queue := make(chan *jsh.JshFrame)
done := make(chan bool)
go jsh.OutputFrames(queue, done)
queue <- &frame
close(queue)
<-done
}
func main() {
// Parse for JSON flag.
jsonModePtr := flag.Bool("json", false, "a bool")
flag.Parse()
if !*jsonModePtr {
fmt.Printf("%s", jsh.Fallback("df"))
} else {
runJsonMode()
}
}

22
df/main_test.go Normal file
View File

@ -0,0 +1,22 @@
package main
import (
"jsh"
"reflect"
"testing"
)
func TestPsOutputToProcesses(t *testing.T) {
psOutput := `USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 26204 4916 ? Ss 00:39 0:00 /sbin/init
root 2 0.0 0.0 0 0 ? S 00:39 0:00 [kthreadd]`
processes := PsOutputToProcesses(psOutput)
expected := []jsh.Process{jsh.Process{"root", "1", "0.0", "0.1", "26204",
"4916", "?", "Ss", "00:39", "0:00", "/sbin/init"},
jsh.Process{"root", "2", "0.0", "0.0", "0", "0", "?", "S", "00:39",
"0:00", "[kthreadd]"}}
actual := *processes
if !reflect.DeepEqual(expected, actual) {
t.Errorf("Processes not parsed correctly.\n%s != %s", expected, actual)
}
}

35
filesystem.go Normal file
View File

@ -0,0 +1,35 @@
/* File for Filesystem-related structs and methods */
package jsh
import (
"errors"
"strconv"
)
// Filesystem is a struct for marshalling into JSON output for the df utility.
type Filesystem struct {
Name string
Size int
Used int
Available int
MountPoint string
}
// NewFilesystem
func NewFilesystem(args []string) (procPtr *Filesystem, err error) {
err = nil
// 11 = number of fields in the Filesystem struct
if len(args) != 5 {
procPtr = &Filesystem{}
err = errors.New("Unexpected number of columns")
} else {
// TODO: add error checking
size, _ := strconv.Atoi(args[1])
used, _ := strconv.Atoi(args[2])
available, _ := strconv.Atoi(args[2])
procPtr = &Filesystem{
args[0], size, used, available, args[4]}
}
return
}

28
filesystem_test.go Normal file
View File

@ -0,0 +1,28 @@
package jsh
import "testing"
func TestNewFilesystem(t *testing.T) {
tooManyArgs := []string{"1", "2", "3", "4"}
_, err := NewFilesystem(tooManyArgs)
if err == nil {
t.Errorf("Passing 4 strings should raise an error")
}
tooFewArgs := []string{"1", "2", "3", "4", "5", "6"}
_, err = NewFilesystem(tooFewArgs)
if err == nil {
t.Errorf("Passing 6 strings should raise an error")
}
justRightArgs := []string{"1", "2", "3", "4", "5"}
proc, err := NewFilesystem(justRightArgs)
if err != nil {
t.Errorf("Passing 5 strings should not raise an error")
}
expected := Filesystem{"1", "2", "3", "4", "5"}
actual := *proc
if expected != actual {
t.Errorf("Filesystem was incorrectly generated:\n%s != %s", expected, actual)
}
}