<commit_before>package gofakeit

import "fmt"

func ExampleMinecraftOre() {
	Seed(11)
	fmt.Println(MinecraftOre())
	// Output:
	// coal
}

func ExampleFaker_MinecraftOre() {
	f := New(11)
	fmt.Println(f.MinecraftOre())
	// Output:
	// coal
}

func ExampleMinecraftWood() {
	Seed(11)
	fmt.Println(MinecraftWood())
	// Output:
	// oak
}

func ExampleFaker_MinecraftWood() {
	f := New(11)
	fmt.Println(f.MinecraftWood())
	// Output:
	// oak
}

func ExampleMinecraftArmorTier() {
	Seed(11)
	fmt.Println(MinecraftArmorTier())
	// Output:
	// leather
}

func ExampleFaker_MinecraftArmorTier() {
	f := New(11)
	fmt.Println(f.MinecraftArmorTier())
	// Output:
	// leather
}

func ExampleMinecraftArmorPart() {
	Seed(11)
	fmt.Println(MinecraftArmorPart())
	// Output:
	// helmet
}

func ExampleFaker_MinecraftArmorPart() {
	f := New(11)
	fmt.Println(f.MinecraftArmorPart())
	// Output:
	// helmet
}

func ExampleMinecraftWeapon() {
	Seed(11)
	fmt.Println(MinecraftWeapon())
	// Output:
	// sword
}

func ExampleFaker_MinecraftWeapon() {
	f := New(11)
	fmt.Println(f.MinecraftWeapon())
	// Output:
	// sword
}

func ExampleMinecraftTool() {
	Seed(11)
	fmt.Println(MinecraftTool())
	// Output:
	// pickaxe
}

func ExampleFaker_MinecraftTool() {
	f := New(11)
	fmt.Println(f.MinecraftTool())
	// Output:
	// pickaxe
}

func ExampleMinecraftDye() {
	Seed(11)
	fmt.Println(MinecraftDye())
	// Output:
	// light gray
}

func ExampleFaker_MinecraftDye() {
	f := New(11)
	fmt.Println(f.MinecraftDye())
	// Output:
	// light gray
}

func ExampleMinecraftFood() {
	Seed(11)
	fmt.Println(MinecraftFood())
	// Output:
	// beetroot
}

func ExampleFaker_MinecraftFood() {
	f := New(11)
	fmt.Println(f.MinecraftFood())
	// Output:
	// beetroot
}

func ExampleMinecraftAnimal() {
	Seed(11)
	fmt.Println(MinecraftAnimal())
	// Output:
	// chicken
}

func ExampleFaker_MinecraftAnimal() {
	f := New(11)
	fmt.Println(f.MinecraftAnimal())
	// Output:
	// chicken
}

func ExampleMinecraftVillagerJob() {
	Seed(11)
	fmt.Println(MinecraftVillagerJob())
	// Output:
	// toolsmith
}

func ExampleFaker_MinecraftVillagerJob() {
	f := New(11)
	fmt.Println(f.MinecraftVillagerJob())
	// Output:
	// toolsmith
}

func ExampleMinecraftVillagerStation() {
	Seed(11)
	fmt.Println(MinecraftVillagerStation())
	// Output:
	// cauldron
}

func ExampleFaker_MinecraftVillagerStation() {
	f := New(11)
	fmt.Println(f.MinecraftVillagerStation())
	// Output:
	// cauldron
}

func ExampleMinecraftVillagerLevel() {
	Seed(11)
	fmt.Println(MinecraftVillagerLevel())
	// Output:
	// novice
}

func ExampleFaker_MinecraftVillagerLevel() {
	f := New(11)
	fmt.Println(f.MinecraftVillagerLevel())
	// Output:
	// novice
}

func ExampleMinecraftMobPassive() {
	Seed(11)
	fmt.Println(MinecraftMobPassive())
	// Output:
	// chicken
}

func ExampleFaker_MinecraftMobPassive() {
	f := New(11)
	fmt.Println(f.MinecraftMobPassive())
	// Output:
	// chicken
}

func ExampleMinecraftMobNeutral() {
	Seed(11)
	fmt.Println(MinecraftMobNeutral())
	// Output:
	// wolf
}

func ExampleFaker_MinecraftMobNeutral() {
	f := New(11)
	fmt.Println(f.MinecraftMobNeutral())
	// Output:
	// wolf
}

func ExampleMinecraftMobHostile() {
	Seed(11)
	fmt.Println(MinecraftMobHostile())
	// Output:
	// blaze
}

func ExampleFaker_MinecraftMobHostile() {
	f := New(11)
	fmt.Println(f.MinecraftMobHostile())
	// Output:
	// blaze
}

func ExampleMinecraftMobBoss() {
	Seed(11)
	fmt.Println(MinecraftMobBoss())
	// Output:
	// ender dragon
}

func ExampleFaker_MinecraftMobBoss() {
	f := New(11)
	fmt.Println(f.MinecraftMobBoss())
	// Output:
	// ender dragon
}

func ExampleMinecraftBiome() {
	Seed(11)
	fmt.Println(MinecraftBiome())
	// Output:
	// stone shore
}

func ExampleFaker_MinecraftBiome() {
	f := New(11)
	fmt.Println(f.MinecraftBiome())
	// Output:
	// stone shore
}

func ExampleMinecraftWeather() {
	Seed(11)
	fmt.Println(MinecraftWeather())
	// Output:
	// clear
}

func ExampleFaker_MinecraftWeather() {
	f := New(11)
	fmt.Println(f.MinecraftWeather())
	// Output:
	// clear
}
<commit_msg>minecraft - added benchmarks<commit_after>package gofakeit

import (
	"fmt"
	"testing"
)

func ExampleMinecraftOre() {
	Seed(11)
	fmt.Println(MinecraftOre())
	// Output:
	// coal
}

func ExampleFaker_MinecraftOre() {
	f := New(11)
	fmt.Println(f.MinecraftOre())
	// Output:
	// coal
}

func BenchmarkMinecraftOre(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftOre()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftOre()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftOre()
		}
	})
}

func ExampleMinecraftWood() {
	Seed(11)
	fmt.Println(MinecraftWood())
	// Output:
	// oak
}

func ExampleFaker_MinecraftWood() {
	f := New(11)
	fmt.Println(f.MinecraftWood())
	// Output:
	// oak
}

func BenchmarkMinecraftWood(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftWood()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftWood()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftWood()
		}
	})
}

func ExampleMinecraftArmorTier() {
	Seed(11)
	fmt.Println(MinecraftArmorTier())
	// Output:
	// leather
}

func ExampleFaker_MinecraftArmorTier() {
	f := New(11)
	fmt.Println(f.MinecraftArmorTier())
	// Output:
	// leather
}

func BenchmarkMinecraftArmorTier(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftArmorTier()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftArmorTier()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftArmorTier()
		}
	})
}

func ExampleMinecraftArmorPart() {
	Seed(11)
	fmt.Println(MinecraftArmorPart())
	// Output:
	// helmet
}

func ExampleFaker_MinecraftArmorPart() {
	f := New(11)
	fmt.Println(f.MinecraftArmorPart())
	// Output:
	// helmet
}

func BenchmarkMinecraftArmorPart(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftArmorPart()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftArmorPart()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftArmorPart()
		}
	})
}

func ExampleMinecraftWeapon() {
	Seed(11)
	fmt.Println(MinecraftWeapon())
	// Output:
	// sword
}

func ExampleFaker_MinecraftWeapon() {
	f := New(11)
	fmt.Println(f.MinecraftWeapon())
	// Output:
	// sword
}

func BenchmarkMinecraftWeapon(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftWeapon()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftWeapon()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftWeapon()
		}
	})
}

func ExampleMinecraftTool() {
	Seed(11)
	fmt.Println(MinecraftTool())
	// Output:
	// pickaxe
}

func ExampleFaker_MinecraftTool() {
	f := New(11)
	fmt.Println(f.MinecraftTool())
	// Output:
	// pickaxe
}

func BenchmarkMinecraftTool(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftTool()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftTool()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftTool()
		}
	})
}

func ExampleMinecraftDye() {
	Seed(11)
	fmt.Println(MinecraftDye())
	// Output:
	// light gray
}

func ExampleFaker_MinecraftDye() {
	f := New(11)
	fmt.Println(f.MinecraftDye())
	// Output:
	// light gray
}

func BenchmarkMinecraftDye(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftDye()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftDye()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftDye()
		}
	})
}

func ExampleMinecraftFood() {
	Seed(11)
	fmt.Println(MinecraftFood())
	// Output:
	// beetroot
}

func ExampleFaker_MinecraftFood() {
	f := New(11)
	fmt.Println(f.MinecraftFood())
	// Output:
	// beetroot
}

func BenchmarkMinecraftFood(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftFood()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftFood()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftFood()
		}
	})
}

func ExampleMinecraftAnimal() {
	Seed(11)
	fmt.Println(MinecraftAnimal())
	// Output:
	// chicken
}

func ExampleFaker_MinecraftAnimal() {
	f := New(11)
	fmt.Println(f.MinecraftAnimal())
	// Output:
	// chicken
}

func BenchmarkMinecraftAnimal(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftAnimal()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftAnimal()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftAnimal()
		}
	})
}

func ExampleMinecraftVillagerJob() {
	Seed(11)
	fmt.Println(MinecraftVillagerJob())
	// Output:
	// toolsmith
}

func ExampleFaker_MinecraftVillagerJob() {
	f := New(11)
	fmt.Println(f.MinecraftVillagerJob())
	// Output:
	// toolsmith
}

func BenchmarkMinecraftVillagerJob(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftVillagerJob()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftVillagerJob()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftVillagerJob()
		}
	})
}

func ExampleMinecraftVillagerStation() {
	Seed(11)
	fmt.Println(MinecraftVillagerStation())
	// Output:
	// cauldron
}

func ExampleFaker_MinecraftVillagerStation() {
	f := New(11)
	fmt.Println(f.MinecraftVillagerStation())
	// Output:
	// cauldron
}

func BenchmarkMinecraftVillagerStation(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftVillagerStation()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftVillagerStation()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftVillagerStation()
		}
	})
}

func ExampleMinecraftVillagerLevel() {
	Seed(11)
	fmt.Println(MinecraftVillagerLevel())
	// Output:
	// novice
}

func ExampleFaker_MinecraftVillagerLevel() {
	f := New(11)
	fmt.Println(f.MinecraftVillagerLevel())
	// Output:
	// novice
}

func BenchmarkMinecraftVillagerLevel(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftVillagerLevel()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftVillagerLevel()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftVillagerLevel()
		}
	})
}

func ExampleMinecraftMobPassive() {
	Seed(11)
	fmt.Println(MinecraftMobPassive())
	// Output:
	// chicken
}

func ExampleFaker_MinecraftMobPassive() {
	f := New(11)
	fmt.Println(f.MinecraftMobPassive())
	// Output:
	// chicken
}

func BenchmarkMinecraftMobPassive(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftMobPassive()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftMobPassive()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftMobPassive()
		}
	})
}

func ExampleMinecraftMobNeutral() {
	Seed(11)
	fmt.Println(MinecraftMobNeutral())
	// Output:
	// wolf
}

func ExampleFaker_MinecraftMobNeutral() {
	f := New(11)
	fmt.Println(f.MinecraftMobNeutral())
	// Output:
	// wolf
}

func BenchmarkMinecraftMobNeutral(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftMobNeutral()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftMobNeutral()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftMobNeutral()
		}
	})
}

func ExampleMinecraftMobHostile() {
	Seed(11)
	fmt.Println(MinecraftMobHostile())
	// Output:
	// blaze
}

func ExampleFaker_MinecraftMobHostile() {
	f := New(11)
	fmt.Println(f.MinecraftMobHostile())
	// Output:
	// blaze
}

func BenchmarkMinecraftMobHostile(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftMobHostile()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftMobHostile()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftMobHostile()
		}
	})
}

func ExampleMinecraftMobBoss() {
	Seed(11)
	fmt.Println(MinecraftMobBoss())
	// Output:
	// ender dragon
}

func ExampleFaker_MinecraftMobBoss() {
	f := New(11)
	fmt.Println(f.MinecraftMobBoss())
	// Output:
	// ender dragon
}

func BenchmarkMinecraftMobBoss(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftMobBoss()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftMobBoss()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftMobBoss()
		}
	})
}

func ExampleMinecraftBiome() {
	Seed(11)
	fmt.Println(MinecraftBiome())
	// Output:
	// stone shore
}

func ExampleFaker_MinecraftBiome() {
	f := New(11)
	fmt.Println(f.MinecraftBiome())
	// Output:
	// stone shore
}

func BenchmarkMinecraftBiome(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftBiome()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftBiome()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftBiome()
		}
	})
}

func ExampleMinecraftWeather() {
	Seed(11)
	fmt.Println(MinecraftWeather())
	// Output:
	// clear
}

func ExampleFaker_MinecraftWeather() {
	f := New(11)
	fmt.Println(f.MinecraftWeather())
	// Output:
	// clear
}

func BenchmarkMinecraftWeather(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			MinecraftWeather()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.MinecraftWeather()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.MinecraftWeather()
		}
	})
}
<|endoftext|>


<commit_before>package listen_test

import (
	"encoding/json"
	"errors"
	"syscall"

	. "github.com/cloudfoundry-incubator/nsync/listen"
	"github.com/cloudfoundry-incubator/nsync/listen/fakes"
	"github.com/cloudfoundry-incubator/receptor"
	"github.com/cloudfoundry-incubator/receptor/fake_receptor"
	"github.com/cloudfoundry-incubator/runtime-schema/cc_messages"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
	"github.com/cloudfoundry/dropsonde/metric_sender/fake"
	"github.com/cloudfoundry/dropsonde/metrics"
	"github.com/cloudfoundry/gunk/diegonats"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
)

const (
	stopIndexTopic       = "diego.stop.index"
	desireAppTopic       = "diego.desire.app"
	desireDockerAppTopic = "diego.docker.desire.app"
)

var _ = Describe("Listen", func() {
	var (
		builder            *fakes.FakeRecipeBuilder
		fakenats           *diegonats.FakeNATSClient
		desireAppRequest   cc_messages.DesireAppRequestFromCC
		logger             *lagertest.TestLogger
		fakeReceptorClient *fake_receptor.FakeClient

		process ifrit.Process

		metricSender *fake.FakeMetricSender
	)

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")

		fakenats = diegonats.NewFakeClient()

		builder = new(fakes.FakeRecipeBuilder)
		fakeReceptorClient = new(fake_receptor.FakeClient)

		runner := Listen{
			NATSClient:     fakenats,
			ReceptorClient: fakeReceptorClient,
			Logger:         logger,
			RecipeBuilder:  builder,
		}

		desireAppRequest = cc_messages.DesireAppRequestFromCC{
			ProcessGuid:  "some-guid",
			DropletUri:   "http://the-droplet.uri.com",
			Stack:        "some-stack",
			StartCommand: "the-start-command",
			Environment: cc_messages.Environment{
				{Name: "foo", Value: "bar"},
				{Name: "VCAP_APPLICATION", Value: "{\"application_name\":\"my-app\"}"},
			},
			MemoryMB:        128,
			DiskMB:          512,
			FileDescriptors: 32,
			NumInstances:    2,
			Routes:          []string{"route1", "route2"},
			LogGuid:         "some-log-guid",
		}

		metricSender = fake.NewFakeMetricSender()
		metrics.Initialize(metricSender)

		process = ifrit.Envoke(runner)
	})

	AfterEach(func() {
		process.Signal(syscall.SIGINT)
		Eventually(process.Wait()).Should(Receive())
	})

	Describe("when a desire app message is received", func() {
		JustBeforeEach(func() {
			messagePayload, err := json.Marshal(desireAppRequest)
			Ω(err).ShouldNot(HaveOccurred())

			fakenats.Publish(desireAppTopic, messagePayload)
		})

		newlyDesiredLRP := receptor.DesiredLRPCreateRequest{
			ProcessGuid: "new-process-guid",

			Instances: 1,
			Stack:     "stack-2",

			Action: &models.RunAction{
				Path: "ls",
			},
		}

		BeforeEach(func() {
			builder.BuildReturns(&newlyDesiredLRP, nil)
		})

		It("marks the LRP desired in the bbs", func() {
			Eventually(fakeReceptorClient.CreateDesiredLRPCallCount).Should(Equal(1))

			Ω(fakeReceptorClient.CreateDesiredLRPArgsForCall(0)).Should(Equal(newlyDesiredLRP))

			Ω(builder.BuildArgsForCall(0)).Should(Equal(&desireAppRequest))
		})

		It("increments the desired LRPs counter", func() {
			Eventually(func() uint64 {
				return metricSender.GetCounter("LRPsDesired")
			}).Should(Equal(uint64(1)))
		})

		Context("when the number of desired app instances is zero", func() {
			BeforeEach(func() {
				desireAppRequest.NumInstances = 0
			})

			It("deletes the desired LRP from BBS", func() {
				Eventually(fakeReceptorClient.DeleteDesiredLRPCallCount).Should(Equal(1))
				Ω(fakeReceptorClient.DeleteDesiredLRPArgsForCall(0)).Should(Equal("some-guid"))
			})
		})

		Describe("when building the recipe fails to build", func() {
			BeforeEach(func() {
				builder.BuildReturns(nil, errors.New("oh no!"))
			})

			It("logs an error", func() {
				Eventually(logger.TestSink.Buffer).Should(gbytes.Say("failed-to-build-recipe"))
				Eventually(logger.TestSink.Buffer).Should(gbytes.Say("oh no!"))
			})

			It("does not put a desired LRP into the BBS", func() {
				Consistently(fakeReceptorClient.DeleteDesiredLRPCallCount).Should(Equal(0))
			})
		})
	})

	Describe("when a message desiring a docker app is received", func() {

		JustBeforeEach(func() {
			desireAppRequest.DockerImageUrl = "https:///docker.com/docker"
			messagePayload, err := json.Marshal(desireAppRequest)
			Ω(err).ShouldNot(HaveOccurred())

			fakenats.Publish(desireDockerAppTopic, messagePayload)
		})

		newlyDesiredLRP := receptor.DesiredLRPCreateRequest{
			ProcessGuid: "new-process-guid",

			Instances:  1,
			Stack:      "stack-2",
			RootFSPath: "docker:///docker.com/docker",
			Action: &models.RunAction{
				Path: "ls",
			},
		}

		BeforeEach(func() {
			builder.BuildReturns(&newlyDesiredLRP, nil)
		})

		It("marks the LRP desired in the bbs", func() {
			Eventually(fakeReceptorClient.CreateDesiredLRPCallCount).Should(Equal(1))

			Ω(fakeReceptorClient.CreateDesiredLRPArgsForCall(0)).Should(Equal(newlyDesiredLRP))
			Ω(builder.BuildArgsForCall(0)).Should(Equal(&desireAppRequest))
		})
	})

	Describe("when an invalid desire app message is received", func() {
		BeforeEach(func() {
			fakenats.Publish(desireAppTopic, []byte(`
        {
          "some_random_key": "does not matter"
      `))
		})

		It("logs an error", func() {
			Eventually(logger.TestSink.Buffer).Should(gbytes.Say("parse-nats-message-failed"))
		})

		It("does not put a desired LRP into the BBS", func() {
			Consistently(fakeReceptorClient.DeleteDesiredLRPCallCount).Should(Equal(0))
		})
	})

	Describe("when a stop index message is received", func() {
		var killIndexRequest cc_messages.KillIndexRequestFromCC

		JustBeforeEach(func() {
			killIndexRequest = cc_messages.KillIndexRequestFromCC{
				ProcessGuid: "process-guid",
				Index:       1,
			}
			messagePayload, err := json.Marshal(killIndexRequest)
			Ω(err).ShouldNot(HaveOccurred())

			fakenats.Publish(stopIndexTopic, messagePayload)
		})

		It("makes stop requests for those instances", func() {
			Eventually(fakeReceptorClient.KillActualLRPsByProcessGuidAndIndexCallCount).Should(Equal(1))

			processGuid, stopIndex := fakeReceptorClient.KillActualLRPsByProcessGuidAndIndexArgsForCall(0)
			Ω(processGuid).Should(Equal(killIndexRequest.ProcessGuid))
			Ω(stopIndex).Should(Equal(killIndexRequest.Index))
		})
	})
})
<commit_msg>tweak language in tests<commit_after>package listen_test

import (
	"encoding/json"
	"errors"
	"syscall"

	. "github.com/cloudfoundry-incubator/nsync/listen"
	"github.com/cloudfoundry-incubator/nsync/listen/fakes"
	"github.com/cloudfoundry-incubator/receptor"
	"github.com/cloudfoundry-incubator/receptor/fake_receptor"
	"github.com/cloudfoundry-incubator/runtime-schema/cc_messages"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
	"github.com/cloudfoundry/dropsonde/metric_sender/fake"
	"github.com/cloudfoundry/dropsonde/metrics"
	"github.com/cloudfoundry/gunk/diegonats"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/tedsuo/ifrit"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
)

const (
	stopIndexTopic       = "diego.stop.index"
	desireAppTopic       = "diego.desire.app"
	desireDockerAppTopic = "diego.docker.desire.app"
)

var _ = Describe("Listen", func() {
	var (
		builder            *fakes.FakeRecipeBuilder
		fakenats           *diegonats.FakeNATSClient
		desireAppRequest   cc_messages.DesireAppRequestFromCC
		logger             *lagertest.TestLogger
		fakeReceptorClient *fake_receptor.FakeClient

		process ifrit.Process

		metricSender *fake.FakeMetricSender
	)

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")

		fakenats = diegonats.NewFakeClient()

		builder = new(fakes.FakeRecipeBuilder)
		fakeReceptorClient = new(fake_receptor.FakeClient)

		runner := Listen{
			NATSClient:     fakenats,
			ReceptorClient: fakeReceptorClient,
			Logger:         logger,
			RecipeBuilder:  builder,
		}

		desireAppRequest = cc_messages.DesireAppRequestFromCC{
			ProcessGuid:  "some-guid",
			DropletUri:   "http://the-droplet.uri.com",
			Stack:        "some-stack",
			StartCommand: "the-start-command",
			Environment: cc_messages.Environment{
				{Name: "foo", Value: "bar"},
				{Name: "VCAP_APPLICATION", Value: "{\"application_name\":\"my-app\"}"},
			},
			MemoryMB:        128,
			DiskMB:          512,
			FileDescriptors: 32,
			NumInstances:    2,
			Routes:          []string{"route1", "route2"},
			LogGuid:         "some-log-guid",
		}

		metricSender = fake.NewFakeMetricSender()
		metrics.Initialize(metricSender)

		process = ifrit.Envoke(runner)
	})

	AfterEach(func() {
		process.Signal(syscall.SIGINT)
		Eventually(process.Wait()).Should(Receive())
	})

	Describe("when a desire app message is received", func() {
		JustBeforeEach(func() {
			messagePayload, err := json.Marshal(desireAppRequest)
			Ω(err).ShouldNot(HaveOccurred())

			fakenats.Publish(desireAppTopic, messagePayload)
		})

		newlyDesiredLRP := receptor.DesiredLRPCreateRequest{
			ProcessGuid: "new-process-guid",

			Instances: 1,
			Stack:     "stack-2",

			Action: &models.RunAction{
				Path: "ls",
			},
		}

		BeforeEach(func() {
			builder.BuildReturns(&newlyDesiredLRP, nil)
		})

		It("marks the LRP desired in the bbs", func() {
			Eventually(fakeReceptorClient.CreateDesiredLRPCallCount).Should(Equal(1))

			Ω(fakeReceptorClient.CreateDesiredLRPArgsForCall(0)).Should(Equal(newlyDesiredLRP))

			Ω(builder.BuildArgsForCall(0)).Should(Equal(&desireAppRequest))
		})

		It("increments the desired LRPs counter", func() {
			Eventually(func() uint64 {
				return metricSender.GetCounter("LRPsDesired")
			}).Should(Equal(uint64(1)))
		})

		Context("when the number of desired app instances is zero", func() {
			BeforeEach(func() {
				desireAppRequest.NumInstances = 0
			})

			It("deletes the desired LRP", func() {
				Eventually(fakeReceptorClient.DeleteDesiredLRPCallCount).Should(Equal(1))
				Ω(fakeReceptorClient.DeleteDesiredLRPArgsForCall(0)).Should(Equal("some-guid"))
			})
		})

		Describe("when building the recipe fails to build", func() {
			BeforeEach(func() {
				builder.BuildReturns(nil, errors.New("oh no!"))
			})

			It("logs an error", func() {
				Eventually(logger.TestSink.Buffer).Should(gbytes.Say("failed-to-build-recipe"))
				Eventually(logger.TestSink.Buffer).Should(gbytes.Say("oh no!"))
			})

			It("does not desire the LRP", func() {
				Consistently(fakeReceptorClient.DeleteDesiredLRPCallCount).Should(Equal(0))
			})
		})
	})

	Describe("when a message desiring a docker app is received", func() {

		JustBeforeEach(func() {
			desireAppRequest.DockerImageUrl = "https:///docker.com/docker"
			messagePayload, err := json.Marshal(desireAppRequest)
			Ω(err).ShouldNot(HaveOccurred())

			fakenats.Publish(desireDockerAppTopic, messagePayload)
		})

		newlyDesiredLRP := receptor.DesiredLRPCreateRequest{
			ProcessGuid: "new-process-guid",

			Instances:  1,
			Stack:      "stack-2",
			RootFSPath: "docker:///docker.com/docker",
			Action: &models.RunAction{
				Path: "ls",
			},
		}

		BeforeEach(func() {
			builder.BuildReturns(&newlyDesiredLRP, nil)
		})

		It("desires the LRP", func() {
			Eventually(fakeReceptorClient.CreateDesiredLRPCallCount).Should(Equal(1))

			Ω(fakeReceptorClient.CreateDesiredLRPArgsForCall(0)).Should(Equal(newlyDesiredLRP))
			Ω(builder.BuildArgsForCall(0)).Should(Equal(&desireAppRequest))
		})
	})

	Describe("when an invalid desire app message is received", func() {
		BeforeEach(func() {
			fakenats.Publish(desireAppTopic, []byte(`
        {
          "some_random_key": "does not matter"
      `))
		})

		It("logs an error", func() {
			Eventually(logger.TestSink.Buffer).Should(gbytes.Say("parse-nats-message-failed"))
		})

		It("does not desire the LRP", func() {
			Consistently(fakeReceptorClient.DeleteDesiredLRPCallCount).Should(Equal(0))
		})
	})

	Describe("when a stop index message is received", func() {
		var killIndexRequest cc_messages.KillIndexRequestFromCC

		JustBeforeEach(func() {
			killIndexRequest = cc_messages.KillIndexRequestFromCC{
				ProcessGuid: "process-guid",
				Index:       1,
			}
			messagePayload, err := json.Marshal(killIndexRequest)
			Ω(err).ShouldNot(HaveOccurred())

			fakenats.Publish(stopIndexTopic, messagePayload)
		})

		It("makes stop requests for those instances", func() {
			Eventually(fakeReceptorClient.KillActualLRPsByProcessGuidAndIndexCallCount).Should(Equal(1))

			processGuid, stopIndex := fakeReceptorClient.KillActualLRPsByProcessGuidAndIndexArgsForCall(0)
			Ω(processGuid).Should(Equal(killIndexRequest.ProcessGuid))
			Ω(stopIndex).Should(Equal(killIndexRequest.Index))
		})
	})
})
<|endoftext|>


<commit_before>package mit

import (
	"testing"
	"time"
)

var testTerm = TermInfo{
	Code:              "2021FA",
	FirstDayOfClasses: time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC),
	LastDayOfClasses:  time.Date(2020, 12, 9, 0, 0, 0, 0, time.UTC),
	ExceptionDays:     map[string]time.Weekday{},
}

func termDate(year int, month time.Month, day int) *time.Time {
	result := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
	return &result
}

func compareWeekdays(a []time.Weekday, b []time.Weekday) bool {
	if len(a) != len(b) {
		return false
	}

	for i := 0; i < len(a); i++ {
		if a[i] != b[i] {
			return false
		}
	}

	return true
}

func testSingleTime(t *testing.T, input string, expectedScheduledMeeting *ScheduledMeeting, expectedStart *time.Time, expectedEnd *time.Time) {
	resultScheduledMeeting, resultStart, resultEnd, err := ParseScheduledMeeting(input, testTerm)
	if err != nil {
		t.Errorf("ParseScheduledMeeting('%s'): got error '%s'", input, err.Error())
		return
	}

	if !compareWeekdays(resultScheduledMeeting.Weekdays, expectedScheduledMeeting.Weekdays) {
		t.Errorf("ParseScheduledMeeting('%s'): ScheduledMeeting.Weekdays: got %#v, expected %#v", input, resultScheduledMeeting.Weekdays, expectedScheduledMeeting.Weekdays)
	}

	if resultScheduledMeeting.StartSeconds != expectedScheduledMeeting.StartSeconds {
		t.Errorf("ParseScheduledMeeting('%s'): ScheduledMeeting.StartSeconds: got %d, expected %d", input, resultScheduledMeeting.StartSeconds, expectedScheduledMeeting.StartSeconds)
	}

	if resultScheduledMeeting.EndSeconds != expectedScheduledMeeting.EndSeconds {
		t.Errorf("ParseScheduledMeeting('%s'): ScheduledMeeting.EndSeconds: got %d, expected %d", input, resultScheduledMeeting.EndSeconds, expectedScheduledMeeting.EndSeconds)
	}

	if (resultStart == nil && resultStart != expectedStart) || (resultStart != nil && *resultStart != *expectedStart) {
		t.Errorf("ParseScheduledMeeting('%s'): start date: got %s, expected %s", input, resultStart, expectedStart)
	}

	if (resultEnd == nil && resultEnd != expectedEnd) || (resultEnd != nil && *resultEnd != *expectedEnd) {
		t.Errorf("ParseScheduledMeeting('%s'): end date: got %s, expected %s", input, resultEnd, expectedEnd)
	}
}

const minuteSeconds = 60
const hourSeconds = 60 * minuteSeconds

func TestTimeParser(t *testing.T) {
	/*
	 * well-formed
	 */

	testSingleTime(t, "T3", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday},
		StartSeconds: 15 * hourSeconds,
		EndSeconds:   16 * hourSeconds,
	}, nil, nil)
	testSingleTime(t, "W3.30", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday},
		StartSeconds: (15 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (16 * hourSeconds) + (30 * minuteSeconds),
	}, nil, nil)
	testSingleTime(t, "R1.30-3.30", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Thursday},
		StartSeconds: (13 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (15 * hourSeconds) + (30 * minuteSeconds),
	}, nil, nil)
	testSingleTime(t, "S4", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Saturday},
		StartSeconds: 16 * hourSeconds,
		EndSeconds:   17 * hourSeconds,
	}, nil, nil)

	testSingleTime(t, "MTF11", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Tuesday, time.Friday},
		StartSeconds: 11 * hourSeconds,
		EndSeconds:   12 * hourSeconds,
	}, nil, nil)

	testSingleTime(t, "TR10.30-12 (BEGINS OCT 21)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday, time.Thursday},
		StartSeconds: (10 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   12 * hourSeconds,
	}, termDate(2020, time.October, 21), nil)

	testSingleTime(t, "RF11.30 (ENDS DEC 2)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Thursday, time.Friday},
		StartSeconds: (11 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (12 * hourSeconds) + (30 * minuteSeconds),
	}, nil, termDate(2020, time.December, 2))

	testSingleTime(t, "MT9 (MEETS 9/4 TO 10/6)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Tuesday},
		StartSeconds: 9 * hourSeconds,
		EndSeconds:   10 * hourSeconds,
	}, termDate(2020, time.September, 4), termDate(2020, time.October, 6))

	testSingleTime(t, "WF EVE (5-7)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday, time.Friday},
		StartSeconds: 17 * hourSeconds,
		EndSeconds:   19 * hourSeconds,
	}, nil, nil)
	testSingleTime(t, "TR EVE (4-6 PM)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday, time.Thursday},
		StartSeconds: 16 * hourSeconds,
		EndSeconds:   18 * hourSeconds,
	}, nil, nil)
	testSingleTime(t, "MW EVE (4.30-5.30 PM) (BEGINS NOV 2)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Wednesday},
		StartSeconds: (16 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (17 * hourSeconds) + (30 * minuteSeconds),
	}, termDate(2020, time.November, 2), nil)

	testSingleTime(t, "MW10 (LIMITED)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Wednesday},
		StartSeconds: 10 * hourSeconds,
		EndSeconds:   11 * hourSeconds,
	}, nil, nil)

	testSingleTime(t, "WR3.30-4.45 (LIMITED) (BEGINS OCT 14) (ENDS OCT 23)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday, time.Thursday},
		StartSeconds: (15 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (16 * hourSeconds) + (45 * minuteSeconds),
	}, termDate(2020, time.October, 14), termDate(2020, time.October, 23))

	testSingleTime(t, "WR EVE (3.30-4.45 PM) (LIMITED) (BEGINS OCT 14) (ENDS OCT 23)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday, time.Thursday},
		StartSeconds: (15 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (16 * hourSeconds) + (45 * minuteSeconds),
	}, termDate(2020, time.October, 14), termDate(2020, time.October, 23))

	/*
	 * not well-formed
	 */

	testSingleTime(t, "W 4:30", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday},
		StartSeconds: (16 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (17 * hourSeconds) + (30 * minuteSeconds),
	}, nil, nil)
	testSingleTime(t, "TR 10:30-12p", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday, time.Thursday},
		StartSeconds: (10 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   12 * hourSeconds,
	}, nil, nil)
}
<commit_msg>mit/parse_test: add test case for 'TH' as thursday<commit_after>package mit

import (
	"testing"
	"time"
)

var testTerm = TermInfo{
	Code:              "2021FA",
	FirstDayOfClasses: time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC),
	LastDayOfClasses:  time.Date(2020, 12, 9, 0, 0, 0, 0, time.UTC),
	ExceptionDays:     map[string]time.Weekday{},
}

func termDate(year int, month time.Month, day int) *time.Time {
	result := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
	return &result
}

func compareWeekdays(a []time.Weekday, b []time.Weekday) bool {
	if len(a) != len(b) {
		return false
	}

	for i := 0; i < len(a); i++ {
		if a[i] != b[i] {
			return false
		}
	}

	return true
}

func testSingleTime(t *testing.T, input string, expectedScheduledMeeting *ScheduledMeeting, expectedStart *time.Time, expectedEnd *time.Time) {
	resultScheduledMeeting, resultStart, resultEnd, err := ParseScheduledMeeting(input, testTerm)
	if err != nil {
		t.Errorf("ParseScheduledMeeting('%s'): got error '%s'", input, err.Error())
		return
	}

	if !compareWeekdays(resultScheduledMeeting.Weekdays, expectedScheduledMeeting.Weekdays) {
		t.Errorf("ParseScheduledMeeting('%s'): ScheduledMeeting.Weekdays: got %#v, expected %#v", input, resultScheduledMeeting.Weekdays, expectedScheduledMeeting.Weekdays)
	}

	if resultScheduledMeeting.StartSeconds != expectedScheduledMeeting.StartSeconds {
		t.Errorf("ParseScheduledMeeting('%s'): ScheduledMeeting.StartSeconds: got %d, expected %d", input, resultScheduledMeeting.StartSeconds, expectedScheduledMeeting.StartSeconds)
	}

	if resultScheduledMeeting.EndSeconds != expectedScheduledMeeting.EndSeconds {
		t.Errorf("ParseScheduledMeeting('%s'): ScheduledMeeting.EndSeconds: got %d, expected %d", input, resultScheduledMeeting.EndSeconds, expectedScheduledMeeting.EndSeconds)
	}

	if (resultStart == nil && resultStart != expectedStart) || (resultStart != nil && *resultStart != *expectedStart) {
		t.Errorf("ParseScheduledMeeting('%s'): start date: got %s, expected %s", input, resultStart, expectedStart)
	}

	if (resultEnd == nil && resultEnd != expectedEnd) || (resultEnd != nil && *resultEnd != *expectedEnd) {
		t.Errorf("ParseScheduledMeeting('%s'): end date: got %s, expected %s", input, resultEnd, expectedEnd)
	}
}

const minuteSeconds = 60
const hourSeconds = 60 * minuteSeconds

func TestTimeParser(t *testing.T) {
	/*
	 * well-formed
	 */

	testSingleTime(t, "T3", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday},
		StartSeconds: 15 * hourSeconds,
		EndSeconds:   16 * hourSeconds,
	}, nil, nil)
	testSingleTime(t, "W3.30", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday},
		StartSeconds: (15 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (16 * hourSeconds) + (30 * minuteSeconds),
	}, nil, nil)
	testSingleTime(t, "R1.30-3.30", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Thursday},
		StartSeconds: (13 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (15 * hourSeconds) + (30 * minuteSeconds),
	}, nil, nil)
	testSingleTime(t, "S4", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Saturday},
		StartSeconds: 16 * hourSeconds,
		EndSeconds:   17 * hourSeconds,
	}, nil, nil)

	testSingleTime(t, "MTF11", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Tuesday, time.Friday},
		StartSeconds: 11 * hourSeconds,
		EndSeconds:   12 * hourSeconds,
	}, nil, nil)

	testSingleTime(t, "TR10.30-12 (BEGINS OCT 21)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday, time.Thursday},
		StartSeconds: (10 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   12 * hourSeconds,
	}, termDate(2020, time.October, 21), nil)

	testSingleTime(t, "RF11.30 (ENDS DEC 2)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Thursday, time.Friday},
		StartSeconds: (11 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (12 * hourSeconds) + (30 * minuteSeconds),
	}, nil, termDate(2020, time.December, 2))

	testSingleTime(t, "MT9 (MEETS 9/4 TO 10/6)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Tuesday},
		StartSeconds: 9 * hourSeconds,
		EndSeconds:   10 * hourSeconds,
	}, termDate(2020, time.September, 4), termDate(2020, time.October, 6))

	testSingleTime(t, "WF EVE (5-7)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday, time.Friday},
		StartSeconds: 17 * hourSeconds,
		EndSeconds:   19 * hourSeconds,
	}, nil, nil)
	testSingleTime(t, "TR EVE (4-6 PM)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday, time.Thursday},
		StartSeconds: 16 * hourSeconds,
		EndSeconds:   18 * hourSeconds,
	}, nil, nil)
	testSingleTime(t, "MW EVE (4.30-5.30 PM) (BEGINS NOV 2)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Wednesday},
		StartSeconds: (16 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (17 * hourSeconds) + (30 * minuteSeconds),
	}, termDate(2020, time.November, 2), nil)

	testSingleTime(t, "MW10 (LIMITED)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Monday, time.Wednesday},
		StartSeconds: 10 * hourSeconds,
		EndSeconds:   11 * hourSeconds,
	}, nil, nil)

	testSingleTime(t, "WR3.30-4.45 (LIMITED) (BEGINS OCT 14) (ENDS OCT 23)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday, time.Thursday},
		StartSeconds: (15 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (16 * hourSeconds) + (45 * minuteSeconds),
	}, termDate(2020, time.October, 14), termDate(2020, time.October, 23))

	testSingleTime(t, "WR EVE (3.30-4.45 PM) (LIMITED) (BEGINS OCT 14) (ENDS OCT 23)", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday, time.Thursday},
		StartSeconds: (15 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (16 * hourSeconds) + (45 * minuteSeconds),
	}, termDate(2020, time.October, 14), termDate(2020, time.October, 23))

	/*
	 * not well-formed
	 */

	testSingleTime(t, "W 4:30", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Wednesday},
		StartSeconds: (16 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   (17 * hourSeconds) + (30 * minuteSeconds),
	}, nil, nil)
	testSingleTime(t, "TR 10:30-12p", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday, time.Thursday},
		StartSeconds: (10 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   12 * hourSeconds,
	}, nil, nil)
	testSingleTime(t, "TTH 10:30 - 12 PM", &ScheduledMeeting{
		Weekdays:     []time.Weekday{time.Tuesday, time.Thursday},
		StartSeconds: (10 * hourSeconds) + (30 * minuteSeconds),
		EndSeconds:   12 * hourSeconds,
	}, nil, nil)
}
<|endoftext|>


<commit_before>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker
// Copyright 2015 Guntas Grewal

package store

import (
	"fmt"
	"github.com/jinzhu/gorm"
	he "httpentity"
	"httpentity/util"
	"io"
	"strings"
)

var _ he.Entity = &Group{}
var _ he.NetEntity = &Group{}
var dirGroups he.Entity = newDirGroups()

// Model /////////////////////////////////////////////////////////////

type Group struct {
	Id        string
	Addresses []GroupAddress
}

func (o Group) schema(db *gorm.DB) {
	db.CreateTable(&o)
}

type GroupAddress struct {
	Id      int64
	GroupId string
	Medium  string
	Address string
}

func (o GroupAddress) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("group_id", "groups(id)", "RESTRICT", "RESTRICT")
	table.AddForeignKey("medium", "media(id)", "RESTRICT", "RESTRICT")
	table.AddUniqueIndex("uniqueness_idx", "medium", "address")
}

func GetGroupById(db *gorm.DB, id string) *Group {
	var o Group
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func GetUsersInGroup(db *gorm.DB, groupId string) *[]User {
	var users []User
	err := db.Joins("inner join user_addresses on user_addresses.user_id = users.id").Joins(
	"inner join subscriptions on subscriptions.address_id = user_addresses.id").Where(
	"subscriptions.group_id = ?", groupId).Find(&users)
	if err != nil {
		panic("could not get users in group")
	}
	return &users
}

func GetGroupByAddress(db *gorm.DB, address string) *Group {
	var o Group
	if result := db.Joins("inner join groups on group_addresses.group_id = groups.id").Where("group_addresses.address = ?", address).Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func getGroupAddressesByMediumAndGroupId(db *gorm.DB, medium string, groupId string) *GroupAddress {
	var o GroupAddress
	if result := db.Where("medium =? and group_id =?", medium, groupId).Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func getGroupAddressesByMedium(db *gorm.DB, medium string) *GroupAddress {
	var o GroupAddress
	if result := db.Where("medium =?", medium).Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func NewGroup(db *gorm.DB, name string) *Group {
	o := Group{Id: name}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func (o *Group) Subentity(name string, req he.Request) he.Entity {
	panic("TODO: API: (*Group).Subentity()")
}

func (o *Group) Methods() map[string]func(he.Request) he.Response {
	return map[string]func(he.Request) he.Response{
		"GET": func(req he.Request) he.Response {
			return he.StatusOK(o)
	},
		"PUT": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			users := GetUsersInGroup(db,  o.Id)
			flag := false
			for _, user := range *users {
				if sess.UserId == user.Id {
					flag = true
					break
				}
			}
			if !flag {
                                return he.StatusForbidden(heutil.NetString("Unauthorized user"))
                        }

			var new_group Group
			err := safeDecodeJSON(req.Entity, &new_group)
			if err != nil {
				return err.Response()
			}
			if o.Id != new_group.Id {
				return he.StatusConflict(heutil.NetString("Cannot change group id"))
			}
			*o = new_group
			//o.Save(db)
			return he.StatusOK(o)
		},
		"PATCH": func(req he.Request) he.Response {
			panic("TODO: API: (*Group).Methods()[\"PATCH\"]")
		},
		"DELETE": func(req he.Request) he.Response {
			panic("TODO: API: (*Group).Methods()[\"DELETE\"]")
		},
	}
}

// View //////////////////////////////////////////////////////////////

func (o *Group) Encoders() map[string]func(io.Writer) error {
	return defaultEncoders(o)
}

// Directory ("Controller") //////////////////////////////////////////

type t_dirGroups struct {
	methods map[string]func(he.Request) he.Response
}

func newDirGroups() t_dirGroups {
	r := t_dirGroups{}
	r.methods = map[string]func(he.Request) he.Response{
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			badbody := he.StatusUnsupportedMediaType(heutil.NetString(fmt.Sprintf("submitted body not what expected")))
			hash, ok := req.Entity.(map[string]interface{}); if !ok { return badbody }
			groupname, ok := hash["groupname"].(string)    ; if !ok { return badbody }

			groupname = strings.ToLower(groupname)

			group := NewGroup(db, groupname)
			if group == nil {
				return he.StatusConflict(heutil.NetString("a group with that name already exists"))
			} else {
				return he.StatusCreated(r, groupname, req)
			}
		},
	}
	return r
}

func (d t_dirGroups) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_dirGroups) Subentity(name string, req he.Request) he.Entity {
	db := req.Things["db"].(*gorm.DB)
	return GetGroupById(db, name)
}
<commit_msg>getGroupAddressesByMedium and getGroupAddressesByMediumAndGroupId now return an array of pointers instead of one element.<commit_after>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker
// Copyright 2015 Guntas Grewal

package store

import (
	"fmt"
	"github.com/jinzhu/gorm"
	he "httpentity"
	"httpentity/util"
	"io"
	"strings"
)

var _ he.Entity = &Group{}
var _ he.NetEntity = &Group{}
var dirGroups he.Entity = newDirGroups()

// Model /////////////////////////////////////////////////////////////

type Group struct {
	Id        string
	Addresses []GroupAddress
}

func (o Group) schema(db *gorm.DB) {
	db.CreateTable(&o)
}

type GroupAddress struct {
	Id      int64
	GroupId string
	Medium  string
	Address string
}

func (o GroupAddress) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("group_id", "groups(id)", "RESTRICT", "RESTRICT")
	table.AddForeignKey("medium", "media(id)", "RESTRICT", "RESTRICT")
	table.AddUniqueIndex("uniqueness_idx", "medium", "address")
}

func GetGroupById(db *gorm.DB, id string) *Group {
	var o Group
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func GetUsersInGroup(db *gorm.DB, groupId string) *[]User {
	var users []User
	err := db.Joins("inner join user_addresses on user_addresses.user_id = users.id").Joins(
	"inner join subscriptions on subscriptions.address_id = user_addresses.id").Where(
	"subscriptions.group_id = ?", groupId).Find(&users)
	if err != nil {
		panic("could not get users in group")
	}
	return &users
}

func GetGroupByAddress(db *gorm.DB, address string) *Group {
	var o Group
	if result := db.Joins("inner join groups on group_addresses.group_id = groups.id").Where("group_addresses.address = ?", address).Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func getGroupAddressesByMediumAndGroupId(db *gorm.DB, medium string, groupId string) *[]GroupAddress {
	var o GroupAddress
	if result := db.Where("medium =? and group_id =?", medium, groupId).Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func getGroupAddressesByMedium(db *gorm.DB, medium string) *[]GroupAddress {
	var o GroupAddress
	if result := db.Where("medium =?", medium).Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func NewGroup(db *gorm.DB, name string) *Group {
	o := Group{Id: name}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func (o *Group) Subentity(name string, req he.Request) he.Entity {
	panic("TODO: API: (*Group).Subentity()")
}

func (o *Group) Methods() map[string]func(he.Request) he.Response {
	return map[string]func(he.Request) he.Response{
		"GET": func(req he.Request) he.Response {
			return he.StatusOK(o)
	},
		"PUT": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			users := GetUsersInGroup(db,  o.Id)
			flag := false
			for _, user := range *users {
				if sess.UserId == user.Id {
					flag = true
					break
				}
			}
			if !flag {
                                return he.StatusForbidden(heutil.NetString("Unauthorized user"))
                        }

			var new_group Group
			err := safeDecodeJSON(req.Entity, &new_group)
			if err != nil {
				return err.Response()
			}
			if o.Id != new_group.Id {
				return he.StatusConflict(heutil.NetString("Cannot change group id"))
			}
			*o = new_group
			//o.Save(db)
			return he.StatusOK(o)
		},
		"PATCH": func(req he.Request) he.Response {
			panic("TODO: API: (*Group).Methods()[\"PATCH\"]")
		},
		"DELETE": func(req he.Request) he.Response {
			panic("TODO: API: (*Group).Methods()[\"DELETE\"]")
		},
	}
}

// View //////////////////////////////////////////////////////////////

func (o *Group) Encoders() map[string]func(io.Writer) error {
	return defaultEncoders(o)
}

// Directory ("Controller") //////////////////////////////////////////

type t_dirGroups struct {
	methods map[string]func(he.Request) he.Response
}

func newDirGroups() t_dirGroups {
	r := t_dirGroups{}
	r.methods = map[string]func(he.Request) he.Response{
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			badbody := he.StatusUnsupportedMediaType(heutil.NetString(fmt.Sprintf("submitted body not what expected")))
			hash, ok := req.Entity.(map[string]interface{}); if !ok { return badbody }
			groupname, ok := hash["groupname"].(string)    ; if !ok { return badbody }

			groupname = strings.ToLower(groupname)

			group := NewGroup(db, groupname)
			if group == nil {
				return he.StatusConflict(heutil.NetString("a group with that name already exists"))
			} else {
				return he.StatusCreated(r, groupname, req)
			}
		},
	}
	return r
}

func (d t_dirGroups) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_dirGroups) Subentity(name string, req he.Request) he.Entity {
	db := req.Things["db"].(*gorm.DB)
	return GetGroupById(db, name)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"text/tabwriter"

	"github.com/codegangsta/cli"
	"github.com/damonkelley/hostsup/hostsfile"
)

var Commands = []cli.Command{
	{
		Name:   "add",
		Usage:  "Add a hosts entry",
		Action: cmdAddEntry,
	},
	{
		Name:   "rm",
		Usage:  "Remove a hosts entry",
		Action: cmdRemoveEntry,
	},
	{
		Name:   "ls",
		Usage:  "List hosts entries",
		Action: cmdListEntry,
	},
	{
		Name:   "clean",
		Usage:  "Remove all hosts entries added by hostsup",
		Action: cmdClean,
	},
}

const HOSTSFILE string = "/etc/hosts"

func cmdAddEntry(c *cli.Context) {
	hostname := c.Args().Get(1)
	ip := c.Args().First()

	h, err := hostsfile.NewHostsfile(HOSTSFILE)
	handleHostsfileError(err)

	host := hostsfile.NewHost(ip, hostname)
	h.AddEntry(host)
}

func cmdRemoveEntry(c *cli.Context) {
	hostname := c.Args().First()

	h, err := hostsfile.NewHostsfile(HOSTSFILE)
	handleHostsfileError(err)

	entry := h.FindEntry(hostname)

	if entry == nil {
		log.Fatalf("Unable to find a hosts entry with a hostname %s", hostname)
	}

	h.RemoveEntry(entry)
}

func cmdListEntry(c *cli.Context) {
	h, _ := hostsfile.NewHostsfile(HOSTSFILE, true)
	entries := h.ListEntries()

	w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
	fmt.Fprintln(w, "HOSTNAME\tIP")

	for _, entry := range entries {
		fmt.Fprintf(w, "%s\t%s\n", entry.Hostname, entry.IP)
	}

	w.Flush()
}

func cmdClean(c *cli.Context) {
	h, err := hostsfile.NewHostsfile(HOSTSFILE)
	handleHostsfileError(err)

	entries := h.Clean()

	for _, entry := range entries {
		log.Infof("Removed %s\t%s", entry.Hostname, entry.IP)
	}

	log.Info("Hosts file has been cleaned.")
}

func handleHostsfileError(err error) {
	if os.IsNotExist(err) {
		log.Fatalf("The file %s does not exists on your system.", HOSTSFILE)
	}

	if os.IsPermission(err) {
		log.Fatal("You do not have permission to edit this file. Try reissueing the command with sudo.")
	}
}
<commit_msg>Log errors returned by AddEntry and RemoveEntry.<commit_after>package main

import (
	"fmt"
	"os"
	"text/tabwriter"

	"github.com/codegangsta/cli"
	"github.com/damonkelley/hostsup/hostsfile"
)

var Commands = []cli.Command{
	{
		Name:   "add",
		Usage:  "Add a hosts entry",
		Action: cmdAddEntry,
	},
	{
		Name:   "rm",
		Usage:  "Remove a hosts entry",
		Action: cmdRemoveEntry,
	},
	{
		Name:   "ls",
		Usage:  "List hosts entries",
		Action: cmdListEntry,
	},
	{
		Name:   "clean",
		Usage:  "Remove all hosts entries added by hostsup",
		Action: cmdClean,
	},
}

const HOSTSFILE string = "/etc/hosts"

func cmdAddEntry(c *cli.Context) {
	hostname := c.Args().Get(1)
	ip := c.Args().First()

	h, err := hostsfile.NewHostsfile(HOSTSFILE)
	handleHostsfileError(err)

	host := hostsfile.NewHost(ip, hostname)
	err = h.AddEntry(host)

	if err != nil {
		log.Fatal(err)
	}
}

func cmdRemoveEntry(c *cli.Context) {
	hostname := c.Args().First()

	h, err := hostsfile.NewHostsfile(HOSTSFILE)
	handleHostsfileError(err)

	entry := h.FindEntry(hostname)

	if entry == nil {
		log.Infof("Unable to find a hosts entry with a hostname %s", hostname)
		os.Exit(0)
	}

	err = h.RemoveEntry(entry)

	if err != nil {
		log.Fatal(err)
	}
}

func cmdListEntry(c *cli.Context) {
	h, _ := hostsfile.NewHostsfile(HOSTSFILE, true)
	entries := h.ListEntries()

	w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
	fmt.Fprintln(w, "HOSTNAME\tIP")

	for _, entry := range entries {
		fmt.Fprintf(w, "%s\t%s\n", entry.Hostname, entry.IP)
	}

	w.Flush()
}

func cmdClean(c *cli.Context) {
	h, err := hostsfile.NewHostsfile(HOSTSFILE)
	handleHostsfileError(err)

	entries := h.Clean()

	for _, entry := range entries {
		log.Infof("Removed %s\t%s", entry.Hostname, entry.IP)
	}

	log.Info("Hosts file has been cleaned.")
}

func handleHostsfileError(err error) {
	if os.IsNotExist(err) {
		log.Fatalf("The file %s does not exists on your system.", HOSTSFILE)
	}

	if os.IsPermission(err) {
		log.Fatal("You do not have permission to edit this file. Try reissueing the command with sudo.")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/byrnedo/capitan/logger"
	. "github.com/byrnedo/capitan/logger"
	"github.com/codeskyblue/go-sh"
	"github.com/mgutz/str"
	"io/ioutil"
	"os"
	"sort"
	"strings"
	"sync"
"math/rand"
)

const UniqueLabelName = "capitanRunCmd"

var colorList = []string{
	"white",
	"red",
	"green",
	"yellow",
	"blue",
	"magenta",
	"cyan",
}

var nextColorIndex = rand.Intn(len(colorList) - 1)

func getImageId(imageName string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "image", "--format", "{{.Id}}", imageName).Output()
	if err != nil {
		return ""
	}
	imageId := strings.Trim(string(out), " \n")
	return imageId
}

func getContainerIPAddress(name string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "container", "--format", "{{.NetworkSettings.IPAddress}}", name).Output()
	if err != nil {
		return ""
	}
	ip := strings.Trim(string(out), " \n")
	return ip

}

func getContainerUniqueLabel(name string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "container", "--format", "{{.Config.Labels."+UniqueLabelName+"}}", name).Output()
	if err != nil {
		return ""
	}
	label := strings.Trim(string(out), " \n")
	return label

}

func getContainerImageId(name string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "container", "--format", "{{.Image}}", name).Output()
	if err != nil {
		return ""
	}
	imageId := strings.Trim(string(out), " \n")
	return imageId

}

func exists(name string) bool {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--format", "{{.State.Running}}", name).Output()
	if err != nil {
		return false
	}
	if strings.Trim(string(out), " \n") == "<no value>" {
		return false
	}
	return true

}

func isRunning(name string) bool {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--format", "{{.State.Running}}", name).Output()
	if err != nil {
		return false
	}
	if strings.Trim(string(out), " \n") == "true" {
		return true
	}
	return false
}

func runCmd(args ...interface{}) ([]byte, error) {
	ses := sh.NewSession()

	if logger.GetLevel() == DebugLevel {
		ses.ShowCMD = true
	}

	out, err := ses.Command("docker", args...).Output()
	Debug.Println(string(out))
	if err != nil {
		return out, err
	}
	return out, nil
}

func DockerBuild(settings *ProjectSettings, dryRun bool) error {
	sort.Sort(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		if len(set.Build) == 0 {
			continue
		}
		Info.Println("Building " + set.Name)
		if !dryRun {
			if err := runHook("before.build", &set); err != nil {
				return err
			}
			if _, err := runCmd("build", "--tag", set.Name, set.Build); err != nil {
				return err
			}
			if err := runHook("after.build", &set); err != nil {
				return err
			}
		}

	}
	return nil
}

func DockerUp(settings *ProjectSettings, dryRun bool) error {
	sort.Sort(settings.ContainerSettingsList)

	for _, set := range settings.ContainerSettingsList {

		if !exists(set.Name) {
			if err := runContainer(&set, dryRun); err != nil {
				return err
			}
			continue
		}

		if set.Image != "" {
			conImage := getContainerImageId(set.Name)
			localImage := getImageId(set.Image)
			if conImage != "" && localImage != "" && conImage != localImage {
				// remove and restart
				Info.Println("Removing (different image available):", set.Name)
				if !dryRun {
					if _, err := runCmd("rm", "-f", set.Name); err != nil {
						return err
					}
				}

				if err := runContainer(&set, dryRun); err != nil {
					return err
				}
				continue
			}
			uniqueLabel := fmt.Sprintf("%s", getRunArguments(&set))
			if getContainerUniqueLabel(set.Name) != uniqueLabel {
				// remove and restart
				Info.Println("Removing (run arguments changed):", set.Name)
				if !dryRun {
					if _, err := runCmd("rm", "-f", set.Name); err != nil {
						return err
					}
				}

				if err := runContainer(&set, dryRun); err != nil {
					return err
				}
				continue
			}
		}

		if isRunning(set.Name) {
			Info.Println("Already running:", set.Name)
		} else {
			Info.Println("Starting " + set.Name)
			if err := runHook("before.start", &set); err != nil {
				return err
			}
			if !dryRun {
				if _, err := runCmd("start", set.Name); err != nil {
					return err
				}
			}
			if err := runHook("after.start", &set); err != nil {
				return err
			}
		}
		continue

	}
	return nil
}

func runContainer(set *ContainerSettings, dryRun bool) error {

	Info.Println("Running " + set.Name)
	if dryRun {
		return nil
	}
	if err := runHook("before.run", set); err != nil {
		return err
	}

	cmd := getRunArguments(set)
	uniqueLabel := UniqueLabelName + "=" + fmt.Sprintf("%s", cmd)
	if _, err := runCmd(append([]interface{}{"run", "-d", "-t", "--label", uniqueLabel}, cmd...)...); err != nil {
		return err
	}

	if err := runHook("after.run", set); err != nil {
		return err
	}

	return nil
}

func getRunArguments(set *ContainerSettings) []interface{} {
	imageName := set.Name
	if len(set.Image) > 0 {
		imageName = set.Image
	}

	var linkArgs = make([]interface{}, 0, len(set.Links)*2)
	for _, link := range set.Links {
		linkStr := link.Container
		if link.Alias != "" {
			linkStr += ":" + link.Alias
		}
		linkArgs = append(linkArgs, "--link", linkStr)
	}

	cmd := append([]interface{}{"--name", set.Name}, toInterfaceSlice(set.Args)...)
	cmd = append(cmd, linkArgs...)
	cmd = append(cmd, imageName)
	cmd = append(cmd, toInterfaceSlice(set.Command)...)
	return cmd
}

func DockerStart(settings *ProjectSettings, dryRun bool) error {
	sort.Sort(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		if isRunning(set.Name) {
			Info.Println(set.Name, "already running")
			continue
		}
		Info.Println("Starting " + set.Name)
		if !dryRun {
			if err := runHook("before.start", &set); err != nil {
				return err
			}
			if _, err := runCmd("start", set.Name); err != nil {
				return err
			}
			if err := runHook("after.start", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerRestart(settings *ProjectSettings, secBeforeKill int, dryRun bool) error {
	sort.Reverse(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		Info.Println("Restarting " + set.Name)
		if !dryRun {
			if err := runHook("before.restart", &set); err != nil {
				return err
			}
			if _, err := runCmd("restart", "--time", fmt.Sprintf("%d", secBeforeKill), set.Name); err != nil {
				return err
			}
			if err := runHook("after.restart", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerIp(settings *ProjectSettings) error {
	sort.Sort(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		ip := getContainerIPAddress(set.Name)
		Info.Printf("%s: %s", set.Name, ip)
	}
	return nil
}

func nextColor() string {
	defer func(){
		nextColorIndex ++
		if nextColorIndex >= len(colorList) {
			nextColorIndex = 0
		}
	}()
	return colorList[nextColorIndex]
}

func DockerLogs(settings *ProjectSettings) error {
	sort.Sort(settings.ContainerSettingsList)
	var wg sync.WaitGroup
	for _, set := range settings.ContainerSettingsList {

		color := nextColor()
		ses := sh.NewSession()
		ses.Command("docker", "logs", "--tail", "1", "-f", set.Name)

		ses.Stdout = NewContainerLogWriter(os.Stdout, set.Name, color)
		ses.Stderr = NewContainerLogWriter(os.Stderr, set.Name, color)

		if err := ses.Start(); err != nil {
			Error.Println("Error getting log for " + set.Name + ": " + err.Error())
			continue
		}
		wg.Add(1)

		go func() {
			ses.Wait()
			wg.Done()
		}()

	}
	wg.Wait()

	return nil
}

func DockerPs(settings *ProjectSettings) error {
	sort.Sort(settings.ContainerSettingsList)
	nameFilter := make([]string, 0)
	for _, set := range settings.ContainerSettingsList {
		nameFilter = append(nameFilter, "-f", "name="+set.Name)
	}
	var (
		err error
		out []byte
	)
	if out, err = runCmd("ps", "-a", nameFilter); err != nil {
		return err
	}
	Info.Print(string(out))
	return nil
}

func DockerKill(settings *ProjectSettings, signal string, dryRun bool) error {
	sort.Reverse(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		if !isRunning(set.Name) {
			Info.Println(set.Name, "already dead")
			continue
		}
		Info.Println("Killing " + set.Name)
		if !dryRun {
			if err := runHook("before.kill", &set); err != nil {
				return err
			}
			if _, err := runCmd("kill", "--signal", signal, set.Name); err != nil {
				return err
			}
			if err := runHook("after.kill", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerStop(settings *ProjectSettings, secBeforeKill int, dryRun bool) error {
	sort.Reverse(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		if !isRunning(set.Name) {
			Info.Println(set.Name, "already dead")
			continue
		}
		Info.Println("Stopping " + set.Name)
		if !dryRun {
			if err := runHook("before.stop", &set); err != nil {
				return err
			}
			if _, err := runCmd("stop", "--time", fmt.Sprintf("%d", secBeforeKill), set.Name); err != nil {
				return err
			}
			if err := runHook("after.stop", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerRm(settings *ProjectSettings, force bool, dryRun bool) error {
	sort.Reverse(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		var forceStr = "--force=false"
		if force {
			forceStr = "--force=true"
		}

		Info.Println("Removing " + set.Name)
		if !dryRun && exists(set.Name) {
			if err := runHook("before.rm", &set); err != nil {
				return err
			}
			if _, err := runCmd("rm", forceStr, set.Name); err != nil {
				return err
			}
			if err := runHook("after.rm", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func runHook(hookName string, settings *ContainerSettings) error {
	var (
		hookScript string
		found      bool
		ses        *sh.Session
		argVs      []string
	)
	if hookScript, found = settings.Hooks[hookName]; !found {
		return nil
	}

	Info.Print("Executing hook: " + hookName + "\n")

	ses = sh.NewSession()
	ses.SetEnv("CAPITAN_CONTAINER_NAME", settings.Name)
	ses.SetEnv("CAPITAN_HOOK_NAME", hookName)

	argVs = str.ToArgv(hookScript)
	if len(argVs) > 1 {
		ses.Command(argVs[0], toInterfaceSlice(argVs[1:])...)
	} else {
		ses.Command(argVs[0])
	}
	ses.Stdout = os.Stdout
	ses.Stderr = os.Stderr
	return ses.Run()
}

func toStringSlice(data []interface{}) (out []string) {
	out = make([]string, len(data))
	for i, item := range data {
		out[i] = fmt.Sprintf("%s", item)
	}
	return
}

func toInterfaceSlice(data []string) (out []interface{}) {
	out = make([]interface{}, len(data))
	for i, item := range data {
		out[i] = item
	}
	return
}
<commit_msg>Fixed reverse sorting<commit_after>package main

import (
	"fmt"
	"github.com/byrnedo/capitan/logger"
	. "github.com/byrnedo/capitan/logger"
	"github.com/codeskyblue/go-sh"
	"github.com/mgutz/str"
	"io/ioutil"
	"os"
	"sort"
	"strings"
	"sync"
"math/rand"
)

const UniqueLabelName = "capitanRunCmd"

var colorList = []string{
	"white",
	"red",
	"green",
	"yellow",
	"blue",
	"magenta",
	"cyan",
}

var nextColorIndex = rand.Intn(len(colorList) - 1)

func getImageId(imageName string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "image", "--format", "{{.Id}}", imageName).Output()
	if err != nil {
		return ""
	}
	imageId := strings.Trim(string(out), " \n")
	return imageId
}

func getContainerIPAddress(name string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "container", "--format", "{{.NetworkSettings.IPAddress}}", name).Output()
	if err != nil {
		return ""
	}
	ip := strings.Trim(string(out), " \n")
	return ip

}

func getContainerUniqueLabel(name string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "container", "--format", "{{.Config.Labels."+UniqueLabelName+"}}", name).Output()
	if err != nil {
		return ""
	}
	label := strings.Trim(string(out), " \n")
	return label

}

func getContainerImageId(name string) string {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--type", "container", "--format", "{{.Image}}", name).Output()
	if err != nil {
		return ""
	}
	imageId := strings.Trim(string(out), " \n")
	return imageId

}

func exists(name string) bool {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--format", "{{.State.Running}}", name).Output()
	if err != nil {
		return false
	}
	if strings.Trim(string(out), " \n") == "<no value>" {
		return false
	}
	return true

}

func isRunning(name string) bool {
	ses := sh.NewSession()
	ses.Stderr = ioutil.Discard
	out, err := ses.Command("docker", "inspect", "--format", "{{.State.Running}}", name).Output()
	if err != nil {
		return false
	}
	if strings.Trim(string(out), " \n") == "true" {
		return true
	}
	return false
}

func runCmd(args ...interface{}) ([]byte, error) {
	ses := sh.NewSession()

	if logger.GetLevel() == DebugLevel {
		ses.ShowCMD = true
	}

	out, err := ses.Command("docker", args...).Output()
	Debug.Println(string(out))
	if err != nil {
		return out, err
	}
	return out, nil
}

func DockerBuild(settings *ProjectSettings, dryRun bool) error {
	sort.Sort(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		if len(set.Build) == 0 {
			continue
		}
		Info.Println("Building " + set.Name)
		if !dryRun {
			if err := runHook("before.build", &set); err != nil {
				return err
			}
			if _, err := runCmd("build", "--tag", set.Name, set.Build); err != nil {
				return err
			}
			if err := runHook("after.build", &set); err != nil {
				return err
			}
		}

	}
	return nil
}

func DockerUp(settings *ProjectSettings, dryRun bool) error {
	sort.Sort(settings.ContainerSettingsList)

	for _, set := range settings.ContainerSettingsList {

		if !exists(set.Name) {
			if err := runContainer(&set, dryRun); err != nil {
				return err
			}
			continue
		}

		if set.Image != "" {
			conImage := getContainerImageId(set.Name)
			localImage := getImageId(set.Image)
			if conImage != "" && localImage != "" && conImage != localImage {
				// remove and restart
				Info.Println("Removing (different image available):", set.Name)
				if !dryRun {
					if _, err := runCmd("rm", "-f", set.Name); err != nil {
						return err
					}
				}

				if err := runContainer(&set, dryRun); err != nil {
					return err
				}
				continue
			}
			uniqueLabel := fmt.Sprintf("%s", getRunArguments(&set))
			if getContainerUniqueLabel(set.Name) != uniqueLabel {
				// remove and restart
				Info.Println("Removing (run arguments changed):", set.Name)
				if !dryRun {
					if _, err := runCmd("rm", "-f", set.Name); err != nil {
						return err
					}
				}

				if err := runContainer(&set, dryRun); err != nil {
					return err
				}
				continue
			}
		}

		if isRunning(set.Name) {
			Info.Println("Already running:", set.Name)
		} else {
			Info.Println("Starting " + set.Name)
			if err := runHook("before.start", &set); err != nil {
				return err
			}
			if !dryRun {
				if _, err := runCmd("start", set.Name); err != nil {
					return err
				}
			}
			if err := runHook("after.start", &set); err != nil {
				return err
			}
		}
		continue

	}
	return nil
}

func runContainer(set *ContainerSettings, dryRun bool) error {

	Info.Println("Running " + set.Name)
	if dryRun {
		return nil
	}
	if err := runHook("before.run", set); err != nil {
		return err
	}

	cmd := getRunArguments(set)
	uniqueLabel := UniqueLabelName + "=" + fmt.Sprintf("%s", cmd)
	if _, err := runCmd(append([]interface{}{"run", "-d", "-t", "--label", uniqueLabel}, cmd...)...); err != nil {
		return err
	}

	if err := runHook("after.run", set); err != nil {
		return err
	}

	return nil
}

func getRunArguments(set *ContainerSettings) []interface{} {
	imageName := set.Name
	if len(set.Image) > 0 {
		imageName = set.Image
	}

	var linkArgs = make([]interface{}, 0, len(set.Links)*2)
	for _, link := range set.Links {
		linkStr := link.Container
		if link.Alias != "" {
			linkStr += ":" + link.Alias
		}
		linkArgs = append(linkArgs, "--link", linkStr)
	}

	cmd := append([]interface{}{"--name", set.Name}, toInterfaceSlice(set.Args)...)
	cmd = append(cmd, linkArgs...)
	cmd = append(cmd, imageName)
	cmd = append(cmd, toInterfaceSlice(set.Command)...)
	return cmd
}

func DockerStart(settings *ProjectSettings, dryRun bool) error {
	sort.Sort(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		if isRunning(set.Name) {
			Info.Println(set.Name, "already running")
			continue
		}
		Info.Println("Starting " + set.Name)
		if !dryRun {
			if err := runHook("before.start", &set); err != nil {
				return err
			}
			if _, err := runCmd("start", set.Name); err != nil {
				return err
			}
			if err := runHook("after.start", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerRestart(settings *ProjectSettings, secBeforeKill int, dryRun bool) error {
	sort.Sort(sort.Reverse(settings.ContainerSettingsList))
	for _, set := range settings.ContainerSettingsList {
		Info.Println("Restarting " + set.Name)
		if !dryRun {
			if err := runHook("before.restart", &set); err != nil {
				return err
			}
			if _, err := runCmd("restart", "--time", fmt.Sprintf("%d", secBeforeKill), set.Name); err != nil {
				return err
			}
			if err := runHook("after.restart", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerIp(settings *ProjectSettings) error {
	sort.Sort(settings.ContainerSettingsList)
	for _, set := range settings.ContainerSettingsList {
		ip := getContainerIPAddress(set.Name)
		Info.Printf("%s: %s", set.Name, ip)
	}
	return nil
}

func nextColor() string {
	defer func(){
		nextColorIndex ++
		if nextColorIndex >= len(colorList) {
			nextColorIndex = 0
		}
	}()
	return colorList[nextColorIndex]
}

func DockerLogs(settings *ProjectSettings) error {
	sort.Sort(settings.ContainerSettingsList)
	var wg sync.WaitGroup
	for _, set := range settings.ContainerSettingsList {

		color := nextColor()
		ses := sh.NewSession()
		ses.Command("docker", "logs", "--tail", "1", "-f", set.Name)

		ses.Stdout = NewContainerLogWriter(os.Stdout, set.Name, color)
		ses.Stderr = NewContainerLogWriter(os.Stderr, set.Name, color)

		if err := ses.Start(); err != nil {
			Error.Println("Error getting log for " + set.Name + ": " + err.Error())
			continue
		}
		wg.Add(1)

		go func() {
			ses.Wait()
			wg.Done()
		}()

	}
	wg.Wait()

	return nil
}

func DockerPs(settings *ProjectSettings) error {
	sort.Sort(settings.ContainerSettingsList)
	nameFilter := make([]string, 0)
	for _, set := range settings.ContainerSettingsList {
		nameFilter = append(nameFilter, "-f", "name="+set.Name)
	}
	var (
		err error
		out []byte
	)
	if out, err = runCmd("ps", "-a", nameFilter); err != nil {
		return err
	}
	Info.Print(string(out))
	return nil
}

func DockerKill(settings *ProjectSettings, signal string, dryRun bool) error {
	sort.Sort(sort.Reverse(settings.ContainerSettingsList))
	for _, set := range settings.ContainerSettingsList {
		if !isRunning(set.Name) {
			Info.Println(set.Name, "already dead")
			continue
		}
		Info.Println("Killing " + set.Name)
		if !dryRun {
			if err := runHook("before.kill", &set); err != nil {
				return err
			}
			if _, err := runCmd("kill", "--signal", signal, set.Name); err != nil {
				return err
			}
			if err := runHook("after.kill", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerStop(settings *ProjectSettings, secBeforeKill int, dryRun bool) error {
	sort.Sort(sort.Reverse(settings.ContainerSettingsList))
	for _, set := range settings.ContainerSettingsList {
		if !isRunning(set.Name) {
			Info.Println(set.Name, "already dead")
			continue
		}
		Info.Println("Stopping " + set.Name)
		if !dryRun {
			if err := runHook("before.stop", &set); err != nil {
				return err
			}
			if _, err := runCmd("stop", "--time", fmt.Sprintf("%d", secBeforeKill), set.Name); err != nil {
				return err
			}
			if err := runHook("after.stop", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func DockerRm(settings *ProjectSettings, force bool, dryRun bool) error {
	sort.Sort(sort.Reverse(settings.ContainerSettingsList))
	for _, set := range settings.ContainerSettingsList {
		var forceStr = "--force=false"
		if force {
			forceStr = "--force=true"
		}

		Info.Println("Removing " + set.Name)
		if !dryRun && exists(set.Name) {
			if err := runHook("before.rm", &set); err != nil {
				return err
			}
			if _, err := runCmd("rm", forceStr, set.Name); err != nil {
				return err
			}
			if err := runHook("after.rm", &set); err != nil {
				return err
			}
		}
	}
	return nil
}

func runHook(hookName string, settings *ContainerSettings) error {
	var (
		hookScript string
		found      bool
		ses        *sh.Session
		argVs      []string
	)
	if hookScript, found = settings.Hooks[hookName]; !found {
		return nil
	}

	Info.Print("Executing hook: " + hookName + "\n")

	ses = sh.NewSession()
	ses.SetEnv("CAPITAN_CONTAINER_NAME", settings.Name)
	ses.SetEnv("CAPITAN_HOOK_NAME", hookName)

	argVs = str.ToArgv(hookScript)
	if len(argVs) > 1 {
		ses.Command(argVs[0], toInterfaceSlice(argVs[1:])...)
	} else {
		ses.Command(argVs[0])
	}
	ses.Stdout = os.Stdout
	ses.Stderr = os.Stderr
	return ses.Run()
}

func toStringSlice(data []interface{}) (out []string) {
	out = make([]string, len(data))
	for i, item := range data {
		out[i] = fmt.Sprintf("%s", item)
	}
	return
}

func toInterfaceSlice(data []string) (out []interface{}) {
	out = make([]interface{}, len(data))
	for i, item := range data {
		out[i] = item
	}
	return
}
<|endoftext|>


<commit_before>package zettajail

import "fmt"
import "io/ioutil"
import "log"
import "net"
import "net/url"
import "os"
import "path"
import "path/filepath"
import "strings"
import "time"

import "github.com/augustoroman/multierror"

import "github.com/3ofcoins/zettajail/cli"

func ParseJails(args []string) ([]Jail, error) {
	if len(args) == 0 {
		return Host.Jails(), nil // FIXME: Jails() should return an error
	}
	jails := make([]Jail, 0, len(args))
	var errs multierror.Accumulator
	for _, jailName := range args {
		if jail, err := GetJail(jailName); err != nil {
			errs.Push(err)
		} else {
			jails = append(jails, jail)
		}
	}
	return jails, errs.Error()
}

func ForEachJail(jailNames []string, fn func(Jail) error) error {
	jails, err := ParseJails(jailNames)
	if err != nil {
		return err
	}
	var errs multierror.Accumulator
	for _, jail := range jails {
		errs.Push(fn(jail))
	}
	return errs.Error()

}

const jailRcConf = `sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
cron_enable="NO"
devd_enable="NO"
syslogd_enable="NO"
`

var fl struct {
	User               string
	Snapshot           string
	Install            string
	ModForce, ModStart bool
}

func cmdCtlJail(command string, args []string) error {
	var op string
	switch command {
	case "start":
		op = "-c"
	case "stop":
		op = "-r"
	case "restart":
		op = "-rc"
	case "modify":
		switch {
		case fl.ModForce && fl.ModStart:
			op = "-cmr"
		case fl.ModForce:
			op = "-rm"
		case fl.ModStart:
			op = "-cm"
		default:
			op = "-m"
		}
	}
	return ForEachJail(args, func(jail Jail) error {
		// FIXME: feedback
		return jail.RunJail(op)
	})
}

func cmdInfo(_ string, args []string) error {
	if len(args) == 0 {
		log.Println("Root ZFS dataset:", ZFSRoot)
		if !Host.Exists() {
			log.Println("Root ZFS dataset does not exist. Please run `zjail init`.")
			return nil
		}
		log.Println("File system root:", Host.Mountpoint)
		iface, err := net.InterfaceByName(Host.Properties["zettajail:jail:interface"])
		if err != nil {
			return err
		}
		addrs, err := iface.Addrs()
		if err != nil {
			return err
		}
		log.Printf("Interface: %v (%v)\n", iface.Name, addrs[0])
		return nil
	}
	return ForEachJail(args, func(jail Jail) error {
		if err := jail.Status(); err != nil {
			return err
		}
		if jail.Origin != "" {
			origin := jail.Origin
			if strings.HasPrefix(origin, Host.Name+"/") {
				origin = origin[len(Host.Name)+1:]
			}
			log.Println("Origin:", origin)
		}
		log.Println("Snapshots:", jail.Snapshots())
		return jail.WriteConfigTo(os.Stdout)
	})
}

func printTree(allJails []Jail, snap Dataset, indent string) {
	origin := ""
	if snap != ZeroDataset {
		origin = snap.Name
	}

	jails := []Jail{}
	for _, jail := range allJails {
		if jail.Origin == origin {
			jails = append(jails, jail)
		}
	}

	for i, jail := range jails {
		halfdent := "┃"
		item := "┠"
		if i == len(jails)-1 {
			halfdent = " "
			item = "┖"
		}
		fmt.Printf("%s%s%s\n", indent, item, jail)

		snaps := jail.Snapshots()
		for i, snap := range snaps {
			halfdent2 := "│"
			item := "├"
			if i == len(snaps)-1 {
				halfdent2 = " "
				item = "└"
			}
			fmt.Printf("%s%s%s%s\n", indent, halfdent, item, snap)
			printTree(allJails, snap, indent+halfdent+halfdent2)
		}
	}
}

func cmdTree(_ string, _ []string) error {
	printTree(Host.Jails(), ZeroDataset, "")
	return nil
}

func cmdStatus(_ string, args []string) error {
	return ForEachJail(args, func(jail Jail) error {
		return jail.Status()
	})
}

func cmdConsole(_ string, args []string) error {
	if len(args) == 0 {
		return cli.ErrUsage
	}
	jail, err := GetJail(args[0])
	if err != nil {
		return err
	}
	if !jail.IsActive() {
		return fmt.Errorf("%s is not started", args[0])
	}
	args = args[1:]

	if len(args) == 0 {
		args = []string{"login", "-f", fl.User}
		fl.User = ""
	}
	if fl.User == "root" {
		fl.User = ""
	}
	return jail.RunJexec(fl.User, args)
}

func cmdSet(_ string, args []string) error {
	// FIXME: modify if running, -f for force-modify
	if len(args) < 2 {
		return cli.ErrUsage
	}
	jail, err := GetJail(args[0])
	if err != nil {
		return err
	}
	return jail.SetProperties(ParseProperties(args[1:]))
}

func cmdInit(_ string, args []string) error {
	return Host.Init(ParseProperties(args))
}

func cmdSnapshot(_ string, args []string) error {
	return ForEachJail(args, func(jail Jail) error {
		// FIXME: feedback
		_, err := jail.Snapshot(fl.Snapshot, false)
		return err
	})
}

func cmdCreate(_ string, args []string) error {
	jail, err := CreateJail(args[0], ParseProperties(args[1:]))
	if err != nil {
		return err
	}
	if fl.Install == "" {
		return nil
	}

	// Maybe just use fetch(1)'s copy/link behaviour here?
	switch fi, err := os.Stat(fl.Install); {
	case err == nil && fi.IsDir():
		fl.Install = filepath.Join(fl.Install, "base.txz")
		if _, err = os.Stat(fl.Install); err != nil {
			return err
		}
	case err == nil:
		// Pass. It is a file, so we assume it's base.txz
	case os.IsNotExist(err):
		if url, err := url.Parse(fl.Install); err != nil {
			return err
		} else {
			// FIXME: fetch MANIFEST, check checksum
			if path.Ext(url.Path) != "txz" {
				// Directory URL
				url.Path = path.Join(url.Path, "base.txz")
			}
			distdir := jail.Mountpoint + ".dist"
			if err := os.MkdirAll(distdir, 0755); err != nil {
				return err
			}
			distfile := filepath.Join(distdir, path.Base(url.Path))

			log.Println("Downloading", url)
			if err := RunCommand("fetch", "-o", distfile, "-m", "-l", url.String()); err != nil {
				return err
			}
			fl.Install = distfile
		}
		// Check if it's an URL, fetch if yes, bomb if not
	default:
		// Weird error we can't handle
		return err
	}

	log.Println("Unpacking", fl.Install)
	if err := RunCommand("tar", "-C", jail.Mountpoint, "-xpf", fl.Install); err != nil {
		return err
	}

	log.Println("Configuring", jail.Mountpoint)
	if err := ioutil.WriteFile(filepath.Join(jail.Mountpoint, "/etc/rc.conf"), []byte(jailRcConf), 0644); err != nil {
		return err
	}

	if bb, err := ioutil.ReadFile("/etc/resolv.conf"); err != nil {
		return err
	} else {
		if err := ioutil.WriteFile(filepath.Join(jail.Mountpoint, "/etc/resolv.conf"), bb, 0644); err != nil {
			return err
		}
	}

	rf, err := os.Open("/dev/random")
	if err != nil {
		return err
	}
	defer rf.Close()
	entropy := make([]byte, 4096)
	if _, err := rf.Read(entropy); err != nil {
		return err
	}
	return ioutil.WriteFile(filepath.Join(jail.Mountpoint, "/entropy"), entropy, 0600)
}

func cmdClone(_ string, args []string) error {
	_, err := CloneJail(args[0], args[1], ParseProperties(args[2:]))
	return err
}

var Cli = cli.NewCli("")

func init() {
	// Global flags
	Cli.StringVar(&ZFSRoot, "root", ZFSRoot, "Root ZFS filesystem")

	// Commands
	Cli.AddCommand("clone", "SNAPSHOT JAIL [PROPERTY...] -- create new jail from existing snapshot", cmdClone)
	Cli.AddCommand("console", "[-u=USER] JAIL [COMMAND...] -- execute COMMAND or login shell in JAIL", cmdConsole)
	Cli.AddCommand("create", "[-install=DIST] JAIL [PROPERTY...] -- create new jail", cmdCreate)
	Cli.AddCommand("info", "[JAIL...] -- show global info or jail details", cmdInfo)
	Cli.AddCommand("init", "[PROPERTY...] -- initialize or modify host (NFY)", cmdInit)
	Cli.AddCommand("modify", "[-rc] [JAIL...] -- modify some or all jails", cmdCtlJail)
	Cli.AddCommand("restart", "[JAIL...] -- restart some or all jails", cmdCtlJail)
	Cli.AddCommand("set", "JAIL PROPERTY... -- set or modify jail properties", cmdSet)
	Cli.AddCommand("snapshot", "[-s=SNAP] [JAIL...] -- snapshot some or all jails", cmdSnapshot)
	Cli.AddCommand("start", "[JAIL...] -- start (create) some or all jails", cmdCtlJail)
	Cli.AddCommand("status", "[JAIL...] -- show jail status", cmdStatus)
	Cli.AddCommand("stop", "[JAIL...] -- stop (remove) some or all jails", cmdCtlJail)
	Cli.AddCommand("tree", "-- show family tree of jails", cmdTree)

	Cli.Commands["console"].StringVar(&fl.User, "u", "root", "User to run command as")
	Cli.Commands["create"].StringVar(&fl.Install, "install", "", "Install base system from DIST (e.g. ftp://ftp2.freebsd.org/pub/FreeBSD/releases/amd64/amd64/10.1-RELEASE/, /path/to/base.txz)")
	Cli.Commands["modify"].BoolVar(&fl.ModForce, "r", false, "Restart jail if necessary")
	Cli.Commands["modify"].BoolVar(&fl.ModStart, "c", false, "Start (create) jail if not started")
	Cli.Commands["snapshot"].StringVar(&fl.Snapshot, "s", time.Now().UTC().Format("20060102T150405Z"), "Snapshot name")
}
<commit_msg>zjl ps<commit_after>package zettajail

import "fmt"
import "io/ioutil"
import "log"
import "net"
import "net/url"
import "os"
import "path"
import "path/filepath"
import "strconv"
import "strings"
import "time"

import "github.com/augustoroman/multierror"

import "github.com/3ofcoins/zettajail/cli"

func ParseJails(args []string) ([]Jail, error) {
	if len(args) == 0 {
		return Host.Jails(), nil // FIXME: Jails() should return an error
	}
	jails := make([]Jail, 0, len(args))
	var errs multierror.Accumulator
	for _, jailName := range args {
		if jail, err := GetJail(jailName); err != nil {
			errs.Push(err)
		} else {
			jails = append(jails, jail)
		}
	}
	return jails, errs.Error()
}

func ForEachJail(jailNames []string, fn func(Jail) error) error {
	jails, err := ParseJails(jailNames)
	if err != nil {
		return err
	}
	var errs multierror.Accumulator
	for _, jail := range jails {
		errs.Push(fn(jail))
	}
	return errs.Error()

}

const jailRcConf = `sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
cron_enable="NO"
devd_enable="NO"
syslogd_enable="NO"
`

var fl struct {
	User               string
	Snapshot           string
	Install            string
	ModForce, ModStart bool
}

func cmdCtlJail(command string, args []string) error {
	var op string
	switch command {
	case "start":
		op = "-c"
	case "stop":
		op = "-r"
	case "restart":
		op = "-rc"
	case "modify":
		switch {
		case fl.ModForce && fl.ModStart:
			op = "-cmr"
		case fl.ModForce:
			op = "-rm"
		case fl.ModStart:
			op = "-cm"
		default:
			op = "-m"
		}
	}
	return ForEachJail(args, func(jail Jail) error {
		// FIXME: feedback
		return jail.RunJail(op)
	})
}

func cmdInfo(_ string, args []string) error {
	if len(args) == 0 {
		log.Println("Root ZFS dataset:", ZFSRoot)
		if !Host.Exists() {
			log.Println("Root ZFS dataset does not exist. Please run `zjail init`.")
			return nil
		}
		log.Println("File system root:", Host.Mountpoint)
		iface, err := net.InterfaceByName(Host.Properties["zettajail:jail:interface"])
		if err != nil {
			return err
		}
		addrs, err := iface.Addrs()
		if err != nil {
			return err
		}
		log.Printf("Interface: %v (%v)\n", iface.Name, addrs[0])
		return nil
	}
	return ForEachJail(args, func(jail Jail) error {
		if err := jail.Status(); err != nil {
			return err
		}
		if jail.Origin != "" {
			origin := jail.Origin
			if strings.HasPrefix(origin, Host.Name+"/") {
				origin = origin[len(Host.Name)+1:]
			}
			log.Println("Origin:", origin)
		}
		log.Println("Snapshots:", jail.Snapshots())
		return jail.WriteConfigTo(os.Stdout)
	})
}

func printTree(allJails []Jail, snap Dataset, indent string) {
	origin := ""
	if snap != ZeroDataset {
		origin = snap.Name
	}

	jails := []Jail{}
	for _, jail := range allJails {
		if jail.Origin == origin {
			jails = append(jails, jail)
		}
	}

	for i, jail := range jails {
		halfdent := "┃"
		item := "┠"
		if i == len(jails)-1 {
			halfdent = " "
			item = "┖"
		}
		fmt.Printf("%s%s%s\n", indent, item, jail)

		snaps := jail.Snapshots()
		for i, snap := range snaps {
			halfdent2 := "│"
			item := "├"
			if i == len(snaps)-1 {
				halfdent2 = " "
				item = "└"
			}
			fmt.Printf("%s%s%s%s\n", indent, halfdent, item, snap)
			printTree(allJails, snap, indent+halfdent+halfdent2)
		}
	}
}

func cmdTree(_ string, _ []string) error {
	printTree(Host.Jails(), ZeroDataset, "")
	return nil
}

func cmdStatus(_ string, args []string) error {
	return ForEachJail(args, func(jail Jail) error {
		return jail.Status()
	})
}

func cmdPs(_ string, args []string) error {
	jail, err := GetJail(args[0])
	if err != nil {
		return err
	}
	jid := jail.Jid()
	if jid == 0 {
		return fmt.Errorf("%s is not running", jail)
	}
	psArgs := []string{"-J", strconv.Itoa(jid)}
	psArgs = append(psArgs, args[1:]...)
	return RunCommand("ps", psArgs...)
}

func cmdConsole(_ string, args []string) error {
	if len(args) == 0 {
		return cli.ErrUsage
	}
	jail, err := GetJail(args[0])
	if err != nil {
		return err
	}
	if !jail.IsActive() {
		return fmt.Errorf("%s is not started", args[0])
	}
	args = args[1:]

	if len(args) == 0 {
		args = []string{"login", "-f", fl.User}
		fl.User = ""
	}
	if fl.User == "root" {
		fl.User = ""
	}
	return jail.RunJexec(fl.User, args)
}

func cmdSet(_ string, args []string) error {
	// FIXME: modify if running, -f for force-modify
	if len(args) < 2 {
		return cli.ErrUsage
	}
	jail, err := GetJail(args[0])
	if err != nil {
		return err
	}
	return jail.SetProperties(ParseProperties(args[1:]))
}

func cmdInit(_ string, args []string) error {
	return Host.Init(ParseProperties(args))
}

func cmdSnapshot(_ string, args []string) error {
	return ForEachJail(args, func(jail Jail) error {
		// FIXME: feedback
		_, err := jail.Snapshot(fl.Snapshot, false)
		return err
	})
}

func cmdCreate(_ string, args []string) error {
	jail, err := CreateJail(args[0], ParseProperties(args[1:]))
	if err != nil {
		return err
	}
	if fl.Install == "" {
		return nil
	}

	// Maybe just use fetch(1)'s copy/link behaviour here?
	switch fi, err := os.Stat(fl.Install); {
	case err == nil && fi.IsDir():
		fl.Install = filepath.Join(fl.Install, "base.txz")
		if _, err = os.Stat(fl.Install); err != nil {
			return err
		}
	case err == nil:
		// Pass. It is a file, so we assume it's base.txz
	case os.IsNotExist(err):
		if url, err := url.Parse(fl.Install); err != nil {
			return err
		} else {
			// FIXME: fetch MANIFEST, check checksum
			if path.Ext(url.Path) != "txz" {
				// Directory URL
				url.Path = path.Join(url.Path, "base.txz")
			}
			distdir := jail.Mountpoint + ".dist"
			if err := os.MkdirAll(distdir, 0755); err != nil {
				return err
			}
			distfile := filepath.Join(distdir, path.Base(url.Path))

			log.Println("Downloading", url)
			if err := RunCommand("fetch", "-o", distfile, "-m", "-l", url.String()); err != nil {
				return err
			}
			fl.Install = distfile
		}
		// Check if it's an URL, fetch if yes, bomb if not
	default:
		// Weird error we can't handle
		return err
	}

	log.Println("Unpacking", fl.Install)
	if err := RunCommand("tar", "-C", jail.Mountpoint, "-xpf", fl.Install); err != nil {
		return err
	}

	log.Println("Configuring", jail.Mountpoint)
	if err := ioutil.WriteFile(filepath.Join(jail.Mountpoint, "/etc/rc.conf"), []byte(jailRcConf), 0644); err != nil {
		return err
	}

	if bb, err := ioutil.ReadFile("/etc/resolv.conf"); err != nil {
		return err
	} else {
		if err := ioutil.WriteFile(filepath.Join(jail.Mountpoint, "/etc/resolv.conf"), bb, 0644); err != nil {
			return err
		}
	}

	rf, err := os.Open("/dev/random")
	if err != nil {
		return err
	}
	defer rf.Close()
	entropy := make([]byte, 4096)
	if _, err := rf.Read(entropy); err != nil {
		return err
	}
	return ioutil.WriteFile(filepath.Join(jail.Mountpoint, "/entropy"), entropy, 0600)
}

func cmdClone(_ string, args []string) error {
	_, err := CloneJail(args[0], args[1], ParseProperties(args[2:]))
	return err
}

var Cli = cli.NewCli("")

func init() {
	// Global flags
	Cli.StringVar(&ZFSRoot, "root", ZFSRoot, "Root ZFS filesystem")

	// Commands
	Cli.AddCommand("clone", "SNAPSHOT JAIL [PROPERTY...] -- create new jail from existing snapshot", cmdClone)
	Cli.AddCommand("console", "[-u=USER] JAIL [COMMAND...] -- execute COMMAND or login shell in JAIL", cmdConsole)
	Cli.AddCommand("create", "[-install=DIST] JAIL [PROPERTY...] -- create new jail", cmdCreate)
	Cli.AddCommand("info", "[JAIL...] -- show global info or jail details", cmdInfo)
	Cli.AddCommand("init", "[PROPERTY...] -- initialize or modify host (NFY)", cmdInit)
	Cli.AddCommand("modify", "[-rc] [JAIL...] -- modify some or all jails", cmdCtlJail)
	Cli.AddCommand("ps", "JAIL [ps options...] -- show list of jail's processes", cmdPs)
	Cli.AddCommand("restart", "[JAIL...] -- restart some or all jails", cmdCtlJail)
	Cli.AddCommand("set", "JAIL PROPERTY... -- set or modify jail properties", cmdSet)
	Cli.AddCommand("snapshot", "[-s=SNAP] [JAIL...] -- snapshot some or all jails", cmdSnapshot)
	Cli.AddCommand("start", "[JAIL...] -- start (create) some or all jails", cmdCtlJail)
	Cli.AddCommand("status", "[JAIL...] -- show jail status", cmdStatus)
	Cli.AddCommand("stop", "[JAIL...] -- stop (remove) some or all jails", cmdCtlJail)
	Cli.AddCommand("tree", "-- show family tree of jails", cmdTree)

	Cli.Commands["console"].StringVar(&fl.User, "u", "root", "User to run command as")
	Cli.Commands["create"].StringVar(&fl.Install, "install", "", "Install base system from DIST (e.g. ftp://ftp2.freebsd.org/pub/FreeBSD/releases/amd64/amd64/10.1-RELEASE/, /path/to/base.txz)")
	Cli.Commands["modify"].BoolVar(&fl.ModForce, "r", false, "Restart jail if necessary")
	Cli.Commands["modify"].BoolVar(&fl.ModStart, "c", false, "Start (create) jail if not started")
	Cli.Commands["snapshot"].StringVar(&fl.Snapshot, "s", time.Now().UTC().Format("20060102T150405Z"), "Snapshot name")
}
<|endoftext|>


<commit_before>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !amd64,!arm,!386

package rc4

// XORKeyStream sets dst to the result of XORing src with the key stream.
// Dst and src may be the same slice but otherwise should not overlap.
func (c *Cipher) XORKeyStream(dst, src []byte) {
	i, j := c.i, c.j
	for k, v := range src {
		i += 1
		j += c.s[i]
		c.s[i], c.s[j] = c.s[j], c.s[i]
		dst[k] = v ^ c.s[c.s[i]+c.s[j]]
	}
	c.i, c.j = i, j
}
<commit_msg>crypto/rc4: fix type errors in pure Go implementation<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !amd64,!arm,!386

package rc4

// XORKeyStream sets dst to the result of XORing src with the key stream.
// Dst and src may be the same slice but otherwise should not overlap.
func (c *Cipher) XORKeyStream(dst, src []byte) {
	i, j := c.i, c.j
	for k, v := range src {
		i += 1
		j += uint8(c.s[i])
		c.s[i], c.s[j] = c.s[j], c.s[i]
		dst[k] = v ^ uint8(c.s[uint8(c.s[i]+c.s[j])])
	}
	c.i, c.j = i, j
}
<|endoftext|>