<commit_before>package proxy

import (
	"bytes"
	. "launchpad.net/gocheck"
	"net/http"
	"net/url"
	"regexp"
	"time"
	"github.com/cloudfoundry/gorouter/route"
	"runtime"
)

type AccessLoggerSuite struct{}

var _ = Suite(&AccessLoggerSuite{})

func (s *AccessLoggerSuite) CreateAccessLogRecord() *AccessLogRecord {
	u, err := url.Parse("http://foo.bar:1234/quz?wat")
	if err != nil {
		panic(err)
	}

	req := &http.Request{
		Method:     "GET",
		URL:        u,
		Proto:      "HTTP/1.1",
		Header:     make(http.Header),
		Host:       "foo.bar",
		RemoteAddr: "1.2.3.4:5678",
	}

	req.Header.Set("Referer", "referer")
	req.Header.Set("User-Agent", "user-agent")

	res := &http.Response{
		StatusCode: http.StatusOK,
	}

	b := &route.Endpoint{
		ApplicationId: "my_awesome_id",
		Host:          "127.0.0.1",
		Port:          4567,
	}

	r := AccessLogRecord{
		Request:       req,
		Response:      res,
		RouteEndpoint: b,
		StartedAt:     time.Unix(10, 100000000),
		FirstByteAt:   time.Unix(10, 200000000),
		FinishedAt:    time.Unix(10, 300000000),
		BodyBytesSent: 42,
	}

	return &r
}

func (s *AccessLoggerSuite) TestAccessLogRecordEncode(c *C) {
	r := s.CreateAccessLogRecord()

	p := `` +
		regexp.QuoteMeta(`foo.bar `) +
		regexp.QuoteMeta(`- `) +
		`\[\d{2}/\d{2}/\d{4}:\d{2}:\d{2}:\d{2} [+-]\d{4}\] ` +
		regexp.QuoteMeta(`"GET /quz?wat HTTP/1.1" `) +
		regexp.QuoteMeta(`200 `) +
		regexp.QuoteMeta(`42 `) +
		regexp.QuoteMeta(`"referer" `) +
		regexp.QuoteMeta(`"user-agent" `) +
		regexp.QuoteMeta(`1.2.3.4:5678 `) +
		regexp.QuoteMeta(`response_time:0.200000000 `) +
		regexp.QuoteMeta(`app_id:my_awesome_id`)

	b := &bytes.Buffer{}
	_, err := r.WriteTo(b)
	c.Assert(err, IsNil)

	c.Check(b.String(), Matches, "^"+p+"\n")
}

type fakeFile struct {
	payload []byte
}

func (f *fakeFile) Write(data []byte) (int, error) {
	f.payload = data
	return 12, nil
}

type mockEmitter struct{
	emitted bool
	appId string
	message string
}

func (m *mockEmitter) Emit(appid, message string) {
	m.emitted = true
	m.appId = appid
	m.message = message
}

func (s *AccessLoggerSuite) TestEmittingOfLogRecords(c *C) {
	accessLogger := NewAccessLogger(nil, "localhost:9843")
	testEmitter := &mockEmitter{emitted: false}
	accessLogger.e = testEmitter

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(testEmitter.emitted, Equals, true)
	c.Check(testEmitter.appId, Equals, "my_awesome_id")
	c.Check(testEmitter.message, Equals, "foo.bar - [31/12/1969:17:00:10 -0700] \"GET /quz?wat HTTP/1.1\" 200 42 \"referer\" \"user-agent\" 1.2.3.4:5678 response_time:0.200000000 app_id:my_awesome_id\n")
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestWritingOfLogRecordsToTheFile(c *C) {
	var fakeFile = new(fakeFile)

	accessLogger := NewAccessLogger(fakeFile, "localhost:9843")

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(string(fakeFile.payload), Equals, "foo.bar - [31/12/1969:17:00:10 -0700] \"GET /quz?wat HTTP/1.1\" 200 42 \"referer\" \"user-agent\" 1.2.3.4:5678 response_time:0.200000000 app_id:my_awesome_id\n")
	accessLogger.Stop()<commit_msg>Fixing a timezone related test failure<commit_after>package proxy

import (
	"bytes"
	. "launchpad.net/gocheck"
	"net/http"
	"net/url"
	"regexp"
	"time"
	"github.com/cloudfoundry/gorouter/route"
	"runtime"
)

type AccessLoggerSuite struct{}

var _ = Suite(&AccessLoggerSuite{})

var logMessageRegex = `` +
	regexp.QuoteMeta(`foo.bar `) +
	regexp.QuoteMeta(`- `) +
	`\[\d{2}/\d{2}/\d{4}:\d{2}:\d{2}:\d{2} [+-]\d{4}\] ` +
	regexp.QuoteMeta(`"GET /quz?wat HTTP/1.1" `) +
	regexp.QuoteMeta(`200 `) +
	regexp.QuoteMeta(`42 `) +
	regexp.QuoteMeta(`"referer" `) +
	regexp.QuoteMeta(`"user-agent" `) +
	regexp.QuoteMeta(`1.2.3.4:5678 `) +
	regexp.QuoteMeta(`response_time:0.200000000 `) +
	regexp.QuoteMeta(`app_id:my_awesome_id`)

func (s *AccessLoggerSuite) CreateAccessLogRecord() *AccessLogRecord {
	u, err := url.Parse("http://foo.bar:1234/quz?wat")
	if err != nil {
		panic(err)
	}

	req := &http.Request{
		Method:     "GET",
		URL:        u,
		Proto:      "HTTP/1.1",
		Header:     make(http.Header),
		Host:       "foo.bar",
		RemoteAddr: "1.2.3.4:5678",
	}

	req.Header.Set("Referer", "referer")
	req.Header.Set("User-Agent", "user-agent")

	res := &http.Response{
		StatusCode: http.StatusOK,
	}

	b := &route.Endpoint{
		ApplicationId: "my_awesome_id",
		Host:          "127.0.0.1",
		Port:          4567,
	}

	r := AccessLogRecord{
		Request:       req,
		Response:      res,
		RouteEndpoint: b,
		StartedAt:     time.Unix(10, 100000000),
		FirstByteAt:   time.Unix(10, 200000000),
		FinishedAt:    time.Unix(10, 300000000),
		BodyBytesSent: 42,
	}

	return &r
}

func (s *AccessLoggerSuite) TestAccessLogRecordEncode(c *C) {
	r := s.CreateAccessLogRecord()

	b := &bytes.Buffer{}
	_, err := r.WriteTo(b)
	c.Assert(err, IsNil)

	c.Check(b.String(), Matches, "^"+logMessageRegex+"\n")
}

type fakeFile struct {
	payload []byte
}

func (f *fakeFile) Write(data []byte) (int, error) {
	f.payload = data
	return 12, nil
}

type mockEmitter struct{
	emitted bool
	appId string
	message string
}

func (m *mockEmitter) Emit(appid, message string) {
	m.emitted = true
	m.appId = appid
	m.message = message
}

func (s *AccessLoggerSuite) TestEmittingOfLogRecords(c *C) {
	accessLogger := NewAccessLogger(nil, "localhost:9843")
	testEmitter := &mockEmitter{emitted: false}
	accessLogger.e = testEmitter

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(testEmitter.emitted, Equals, true)
	c.Check(testEmitter.appId, Equals, "my_awesome_id")
	c.Check(testEmitter.message, Matches, "^"+logMessageRegex+"\n")
	accessLogger.Stop()
}

func (s *AccessLoggerSuite) TestWritingOfLogRecordsToTheFile(c *C) {
	var fakeFile = new(fakeFile)

	accessLogger := NewAccessLogger(fakeFile, "localhost:9843")

	accessLogger.Log(*s.CreateAccessLogRecord())
	go accessLogger.Run()
	runtime.Gosched()

	c.Check(string(fakeFile.payload), Matches, "^"+logMessageRegex+"\n")
	accessLogger.Stop()
{'fraction_non_alphanumeric': 0.17475247524752474, 'fraction_numerical': 0.047524752475247525, 'mean_word_length': 4.12341504649197, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 8, 'substrings_counts': 10, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3921729', 'n_tokens_mistral': 2679, 'n_tokens_neox': 2426, 'n_words': 417}