Beispiel #1
0
func TestHttpGunWithHttp(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
	defer cancel()

	result := make(chan *aggregate.Sample)
	requests := make(chan *http.Request)

	ts := httptest.NewServer(
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprintln(w, "Hello, client")
			go func() {
				requests <- r
			}()
		}))
	defer ts.Close()

	gun := &HttpGun{
		target:  ts.Listener.Addr().String(),
		ssl:     false,
		results: result,
	}
	promise := utils.Promise(func() error {
		defer close(result)
		return gun.Shoot(ctx, &ammo.Http{
			Host:   "example.org",
			Method: "GET",
			Uri:    "/path",
			Headers: map[string]string{
				"Accept":          "*/*",
				"Accept-Encoding": "gzip, deflate",
				"Host":            "example.org",
				"User-Agent":      "Pandora/0.0.1",
			},
		})
	})
	results := aggregate.Drain(ctx, result)
	require.Len(t, results, 1)
	assert.Equal(t, "REQUEST", results[0].Tag)
	assert.Equal(t, 200, results[0].ProtoCode)

	select {
	case r := <-requests:
		assert.Equal(t, "GET", r.Method)
		assert.Equal(t, "example.org", r.Host)
		assert.Equal(t, "/path", r.URL.Path)
		assert.Equal(t, "Pandora/0.0.1", r.Header.Get("User-Agent"))
	case <-ctx.Done():
		t.Fatal(ctx.Err())
	}

	// TODO: test scenaries with errors

	select {
	case err := <-promise:
		require.NoError(t, err)
	case <-ctx.Done():
		t.Fatal(ctx.Err())
	}
}
Beispiel #2
0
func TestSpdyGun(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
	defer cancel()

	result := make(chan aggregate.Sample)

	gun := &SpdyGun{
		target:     "localhost:3000",
		pingPeriod: time.Second * 5,
	}
	promise := utils.Promise(func() error {
		defer close(result)
		return gun.Shoot(ctx, &ammo.Http{
			Host:   "example.org",
			Method: "GET",
			Uri:    "/path",
			Headers: map[string]string{
				"Accept":          "*/*",
				"Accept-Encoding": "gzip, deflate",
				"Host":            "example.org",
				"User-Agent":      "Pandora/0.0.1",
			},
		}, result)
	})

	results := aggregate.Drain(ctx, result)
	require.Len(t, results, 2)
	{
		// first result is connect
		rPhout, casted := (results[0]).(aggregate.PhantomCompatible)
		require.True(t, casted, "Should be phantom compatible")
		phoutSample := rPhout.PhoutSample()
		assert.Equal(t, "CONNECT", phoutSample.Tag)
		assert.Equal(t, 200, phoutSample.ProtoCode)
	}
	{
		// second result is request
		rPhout, casted := (results[1]).(aggregate.PhantomCompatible)
		require.True(t, casted, "Should be phantom compatible")
		phoutSample := rPhout.PhoutSample()
		spew.Dump(phoutSample)
		assert.Equal(t, "REQUEST", phoutSample.Tag)
		assert.Equal(t, 200, phoutSample.ProtoCode)
	}

	// TODO: test scenaries with errors
	// TODO: test ping logic

	select {
	case err := <-promise:
		require.NoError(t, err)
	case <-ctx.Done():
		t.Fatal(ctx.Err())
	}

}
Beispiel #3
0
func Run() {
	fmt.Printf("Pandora v0.1.1\n")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of Pandora: pandora [<config_filename>]\n"+
			"<config_filename> is './load.json' by default\n")
		flag.PrintDefaults()
	}
	example := flag.Bool("example", false, "print example config to STDOUT and exit")
	flag.Parse()

	if *example {
		fmt.Printf(exampleConfig)
		return
	}

	configFileName := "./load.json"
	if len(flag.Args()) > 0 {
		configFileName = flag.Args()[0]
	}
	log.Printf("Reading config from '%s'...\n", configFileName)
	jsonDoc, err := ioutil.ReadFile(configFileName)
	if err != nil {
		log.Printf("Could not read config from file: %s", err)
		return
	}
	cfg, err := config.NewGlobalFromJSON(jsonDoc)
	if err != nil {
		log.Printf("Could not unmarshal config from json: %s", err)
		return
	}

	pandora := engine.New(cfg)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	promise := utils.Promise(func() error { return pandora.Serve(ctx) })

	select {
	case <-utils.NotifyInterrupt():
		log.Print("Interrupting by signal, trying to stop")
		cancel()
		select {
		case err = <-promise:
		case <-time.After(time.Second * 5):
			err = fmt.Errorf("timeout exceeded")
		}
	case err = <-promise:
	}
	if err != nil {
		log.Fatal(err)
	}
}
Beispiel #4
0
func TestSpdyGun(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
	defer cancel()

	result := make(chan *aggregate.Sample)

	gun := &SpdyGun{
		target:  "localhost:3000",
		results: result,
	}
	promise := utils.Promise(func() error {
		defer gun.Close()
		defer close(result)
		return gun.Shoot(ctx, &ammo.Http{
			Host:   "example.org",
			Method: "GET",
			Uri:    "/path",
			Headers: map[string]string{
				"Accept":          "*/*",
				"Accept-Encoding": "gzip, deflate",
				"Host":            "example.org",
				"User-Agent":      "Pandora/0.0.1",
			},
		})
	})

	results := aggregate.Drain(ctx, result)
	require.Len(t, results, 2)
	{
		// first result is connect

		assert.Equal(t, "CONNECT", results[0].Tag)
		assert.Equal(t, 200, results[0].ProtoCode)
	}
	{
		// second result is request

		assert.Equal(t, "REQUEST", results[1].Tag)
		assert.Equal(t, 200, results[1].ProtoCode)
	}

	// TODO: test scenaries with errors

	select {
	case err := <-promise:
		require.NoError(t, err)
	case <-ctx.Done():
		t.Fatal(ctx.Err())
	}

}
Beispiel #5
0
func TestSpdyConnectPing(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
	defer cancel()

	result := make(chan *aggregate.Sample)

	gun := &SpdyGun{
		target:  "localhost:3000",
		results: result,
	}
	promise := utils.Promise(func() error {
		defer gun.Close()
		defer close(result)
		if err := gun.Connect(); err != nil {
			return err
		}
		gun.Ping()
		return nil
	})

	results := aggregate.Drain(ctx, result)
	require.Len(t, results, 2)
	{
		// first result is connect

		assert.Equal(t, "CONNECT", results[0].Tag)
		assert.Equal(t, 200, results[0].ProtoCode)
	}
	{
		// second result is PING

		assert.Equal(t, "PING", results[1].Tag)
		assert.Equal(t, 200, results[1].ProtoCode)
	}
	select {
	case err := <-promise:
		require.NoError(t, err)
	case <-ctx.Done():
		t.Fatal(ctx.Err())
	}

}
Beispiel #6
0
func Run() {
	fmt.Printf("Pandora v%s\n", Version)
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of Pandora: pandora [<config_filename>]\n"+
			"<config_filename> is './load.json' by default\n")
		flag.PrintDefaults()
	}
	example := flag.Bool("example", false, "print example config to STDOUT and exit")
	cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
	memprofile := flag.String("memprofile", "", "write memory profile to this file")
	expvarHttp := flag.Bool("expvar", false, "start HTTP server with monitoring variables")
	flag.Parse()

	if *example {
		fmt.Printf(exampleConfig)
		return
	}

	if *expvarHttp {
		go http.ListenAndServe(":1234", nil)
	}

	configFileName := "./load.json"
	if len(flag.Args()) > 0 {
		configFileName = flag.Args()[0]
	}
	log.Printf("Reading config from '%s'...\n", configFileName)
	jsonDoc, err := ioutil.ReadFile(configFileName)
	if err != nil {
		log.Printf("Could not read config from file: %s", err)
		return
	}
	cfg, err := config.NewGlobalFromJSON(jsonDoc)
	if err != nil {
		log.Printf("Could not unmarshal config from json: %s", err)
		return
	}

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	if *memprofile != "" {
		defer func() {
			f, err := os.Create(*memprofile)
			if err != nil {
				log.Fatal(err)
			}
			pprof.WriteHeapProfile(f)
			f.Close()
		}()
	}
	pandora := engine.New(cfg)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	promise := utils.Promise(func() error { return pandora.Serve(ctx) })

	select {
	case <-utils.NotifyInterrupt():
		log.Print("Interrupting by signal, trying to stop")
		cancel()
		select {
		case err = <-promise:
		case <-time.After(time.Second * 5):
			err = fmt.Errorf("timeout exceeded")
		}
	case err = <-promise:
	}
	if err != nil {
		log.Fatal(err)
	}
}