<commit_before>package main

const BaseTmplStr = `
{{ define "base" }}

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {{ template "title" . }}
    <link href="/assets/css/bootstrap.min.css" rel="stylesheet">
    <link href="/assets/css/skeddy.css" rel="stylesheet">

          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            Toggle navigation

          </button>
          Skeddy

    {{ template "content" . }}

Copyright © skeddy All Right Reserved 2016

{{ end }}
`

const ViewTmplStr = `
{{ define "title"}}<title>Skeddy - Entries</title>{{ end }}
{{ define "content" }}

Scheduler entries

Add

    {{ range $key, $value := . }}

          {{$value.Expression}}
          {{$value.Endpoint}}
          {{$value.Payload}}
          Edit
          Delete

    {{ end }}

{{ end }}
`

const EditTmplStr = `
{{ define "title"}}<title>Skeddy - Edit Entries</title>{{ end }}
{{ define "content" }}

Edit entries

<form enctype="multipart/form-data" name="edit-form" class="form-horizontal" action="/save/" method="post" >
  <input type="hidden" class="form-control" name="id" value="{{.ID}}">

    Cron Expression

      <input type="text" id="expression" class="form-control" placeholder="* * * * *" name="expression" value="{{.Expression}}" onfocusout="validateExpression()" required>

    Endpoint

      <input type="url" id="url" class="form-control" placeholder="Endpoint URL" name="endpoint" value="{{.Endpoint}}" onfocusout="validateURL()" required>

    Payload

      <input type="text" id="payload" class="form-control" placeholder="Payload" name="payload" value="{{.Payload}}" onfocusout="enableSubmission()">
      <input id="fileupload" type="file" title="add files" name="files" onchange="getFile()"/>

      <input type="submit" class="btn btn-default" id="submitBtn" disabled/>
      Cancel

</form>

{{ end }}
`

const AddTmplStr = `
{{ define "title"}}<title>Skeddy - Add Entries</title>{{ end }}
{{ define "content" }}

Add entries

<form enctype="multipart/form-data" class="form-horizontal" action="/add/" method="post">
  <input type="hidden" class="form-control" name="id" value="{{.ID}}">

    Cron Expression

      <input type="text" id="expression" class="form-control" placeholder="* * * * *" name="expression" value="{{.Expression}}" onfocusout="validateExpression()" required>

    Endpoint

      <input type="url" id="url" class="form-control" placeholder="Endpoint URL" name="endpoint" value="{{.Endpoint}}" onfocusout="validateURL()" required>

    Payload

      <input type="text" id="payload" class="form-control" placeholder="Payload" name="payload" value="{{.Payload}}" onfocusout="enableSubmission()">
      <input id="fileupload" type="file" title="add files" name="files" onchange="getFile()"/>

      <input type="submit" class="btn btn-default" id="submitBtn" disabled/>
      Cancel

</form>

{{ end }}
`
<commit_msg>Refactored UI<commit_after>package main

const BaseTmplStr = `
{{ define "base" }}

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {{ template "title" . }}
    <link href="/assets/css/bootstrap.min.css" rel="stylesheet">
    <link href="/assets/css/skeddy.css" rel="stylesheet">

          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            Toggle navigation

          </button>
          Skeddy

    {{ template "content" . }}

Copyright © skeddy All Right Reserved 2016

{{ end }}
`

const ViewTmplStr = `
{{ define "title"}}<title>Skeddy - Entries</title>{{ end }}
{{ define "content" }}

Scheduler entries

Add

    {{ range $key, $value := . }}

          {{$value.Expression}}
          {{$value.Endpoint}}
          {{$value.Payload}}
          Edit
          Delete

    {{ end }}

{{ end }}
`

const EditTmplStr = `
{{ define "title"}}<title>Skeddy - Edit Entries</title>{{ end }}
{{ define "content" }}

Edit entries

<form enctype="multipart/form-data" name="edit-form" class="form-horizontal" action="/save/" method="post" >
  <input type="hidden" class="form-control" name="id" value="{{.ID}}">

    Cron Expression

      <input type="text" id="expression" class="form-control" placeholder="* * * * *" name="expression" value="{{.Expression}}" onfocusout="validateExpression()" required>

    Endpoint

      <input type="url" id="url" class="form-control" placeholder="Endpoint URL" name="endpoint" value="{{.Endpoint}}" onfocusout="validateURL()" required>

    Payload

      <input type="text" id="payload" class="form-control" placeholder="Payload" name="payload" value="{{.Payload}}" onfocusout="enableSubmission()">

      <input id="fileupload" type="file" title="add files" name="files" onchange="getFile()"/>

      <input type="submit" class="btn btn-default" id="submitBtn" disabled/>
      Cancel

</form>

{{ end }}
`

const AddTmplStr = `
{{ define "title"}}<title>Skeddy - Add Entries</title>{{ end }}
{{ define "content" }}

Add entries

<form enctype="multipart/form-data" class="form-horizontal" action="/add/" method="post">
  <input type="hidden" class="form-control" name="id" value="{{.ID}}">

    Cron Expression

      <input type="text" id="expression" class="form-control" placeholder="* * * * *" name="expression" value="{{.Expression}}" onfocusout="validateExpression()" required>

    Endpoint

      <input type="url" id="url" class="form-control" placeholder="Endpoint URL" name="endpoint" value="{{.Endpoint}}" onfocusout="validateURL()" required>

    Payload

      <input type="text" id="payload" class="form-control" placeholder="Payload" name="payload" value="{{.Payload}}" onfocusout="enableSubmission()">
      <input id="fileupload" type="file" title="add files" name="files" onchange="getFile()"/>

      <input type="submit" class="btn btn-default" id="submitBtn" disabled/>
      Cancel

</form>

{{ end }}
`
<|endoftext|>


<commit_before>package tessen

var all_templates = map[string]string{
	"debug":      default_debug_template,
	"list":       default_list_template,
	"event_view": default_event_view_template,
	"help":       default_help_template,
}

//   issued:      [{{ dateFormat "2006-01-02T15:04" .check.issued }}](fg-blue)
const (
	default_debug_template      = "{{ . | toJson}}\n"
	default_list_template       = `[{{ .key | printf "%-12s"}}](fg-red)  [{{ if .fields.assignee }}{{ .fields.assignee.name | printf "%-10s" }}{{else}}{{"Unassigned"| printf "%-10s" }}{{end}} ](fg-blue) [{{ .fields.status.name | printf "%-12s"}}](fg-blue) [{{ dateFormat "2006-01-02" .fields.created }}](fg-blue)/[{{ dateFormat "2006-01-02T15:04" .fields.updated }}](fg-green)  {{ .fields.summary | printf "%-75s"}}`
	default_event_view_template = `
Client:
  name:         [{{ .client.name }}](fg-blue)
  instance_id:  [{{ .client.instance_id }}](fg-blue)
  fqdn:         [{{ .client.tags.FQDN }}](fg-blue)
  ecosystem:    [{{ .client.tags.Ecosystem }}](fg-blue)
  region:       [{{ .client.tags.Region }}](fg-blue)
  display_name: [{{ index . "client" "tags" "Display Name" }}](fg-blue)

Check:
   name:        [{{ .check.name }}](fg-blue)
   issued:      [{{ .check.issued }}](fg-blue)
   team:        [{{ .check.team }}](fg-blue)
   status:      {{ .check.status }}

   runbook:     [{{ .check.runbook }}](fg-blue)

   page:        [{{ .check.page }}](fg-blue)
   ticket:      [{{ .check.ticket }}](fg-blue)

Output:

   {{ indent 4 .check.output }}

`
	default_help_template = `
[Quick reference for tessen](fg-white)

[Actions:](fg-blue)

    <enter>      - select item
    h            - show help page

[Commands (a'la vim/tig):](fg-blue)

    :query {JQ boolean expression} - display filtered results
    :help                          - show help page
    :<up>                          - select previous command
    :quit or :q                    - quit

[Navigation:](fg-blue)

    up/k         - previous line
    down/j       - next line
    C-f/<space>  - next page
    C-b          - previous page
    }            - next paragraph/section/fast-move
    {            - previous paragraph/section/fast-move
    n            - next search match
    g            - go to top of page
    G            - go to bottom of page
    q            - go back / quit
    C-c/Q        - quit

[Notes:](fg-blue)

    Learning JQ is highly recommended, particularly boolean expressions:

        https://stedolan.github.io/jq/manual/

`
)
<commit_msg>improve event_view template<commit_after>package tessen

var all_templates = map[string]string{
	"debug":      default_debug_template,
	"list":       default_list_template,
	"event_view": default_event_view_template,
	"help":       default_help_template,
}

//   issued:      [{{ dateFormat "2006-01-02T15:04" .check.issued }}](fg-blue)
const (
	default_debug_template      = "{{ . | toJson}}\n"
	default_list_template       = `[{{ .key | printf "%-12s"}}](fg-red)  [{{ if .fields.assignee }}{{ .fields.assignee.name | printf "%-10s" }}{{else}}{{"Unassigned"| printf "%-10s" }}{{end}} ](fg-blue) [{{ .fields.status.name | printf "%-12s"}}](fg-blue) [{{ dateFormat "2006-01-02" .fields.created }}](fg-blue)/[{{ dateFormat "2006-01-02T15:04" .fields.updated }}](fg-green)  {{ .fields.summary | printf "%-75s"}}`
	default_event_view_template = `
Event:
  _id:          [{{ ._id }}](fg-blue)
  acknowledged: [{{ .acknowledged }}](fg-blue)
Client:
  name:         [{{ .client.name }}](fg-blue)
  instance_id:  [{{ .client.instance_id }}](fg-blue)
{{ if .client.tags }}
  fqdn:         [{{ .client.tags.FQDN }}](fg-blue)
  ecosystem:    [{{ .client.tags.Ecosystem }}](fg-blue)
  region:       [{{ .client.tags.Region }}](fg-blue)
  display_name: [{{ index . "client" "tags" "Display Name" }}](fg-blue)
{{ end }}

Check:
  name:        [{{ .check.name }}](fg-green)
  command:     [{{ .check.command }}](fg-green)
  issued:      [{{ .check.issued }}](fg-blue)
  team:        [{{ .check.team }}](fg-blue)
  project:     [{{ .check.project }}](fg-blue)
  status:      {{ .check.status }}

  runbook:     [{{ .check.runbook }}](fg-blue)

  page:        [{{ .check.page }}](fg-blue)
  ticket:      [{{ .check.ticket }}](fg-blue)

Output:

  {{ indent 2 .check.output }}

`
	default_help_template = `
[Quick reference for tessen](fg-white)

[Actions:](fg-blue)

    <enter>      - select item
    h            - show help page

[Commands (a'la vim/tig):](fg-blue)

    :query {JQ boolean expression} - display filtered results
    :help                          - show help page
    :<up>                          - select previous command
    :quit or :q                    - quit

[Navigation:](fg-blue)

    up/k         - previous line
    down/j       - next line
    C-f/<space>  - next page
    C-b          - previous page
    }            - next paragraph/section/fast-move
    {            - previous paragraph/section/fast-move
    n            - next search match
    g            - go to top of page
    G            - go to bottom of page
    q            - go back / quit
    C-c/Q        - quit

[Notes:](fg-blue)

    Learning JQ is highly recommended, particularly boolean expressions:

        https://stedolan.github.io/jq/manual/

`
)
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gcsproxy_test

import (
	"fmt"
	"io"
	"math"
	"testing"
	"time"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/gcsproxy"
	"github.com/googlecloudplatform/gcsfuse/lease"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	"github.com/jacobsa/gcloud/gcs/gcsutil"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

func TestIntegration(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

const fileLeaserLimit = 1 << 10

type IntegrationTest struct {
	ctx    context.Context
	bucket gcs.Bucket
	leaser lease.FileLeaser
	clock  timeutil.SimulatedClock

	mo *checkingMutableObject
}

var _ SetUpInterface = &IntegrationTest{}
var _ TearDownInterface = &IntegrationTest{}

func init() { RegisterTestSuite(&IntegrationTest{}) }

func (t *IntegrationTest) SetUp(ti *TestInfo) {
	t.ctx = ti.Ctx
	t.bucket = gcsfake.NewFakeBucket(&t.clock, "some_bucket")
	t.leaser = lease.NewFileLeaser("", fileLeaserLimit)

	// Set up a fixed, non-zero time.
	t.clock.SetTime(time.Date(2012, 8, 15, 22, 56, 0, 0, time.Local))
}

func (t *IntegrationTest) TearDown() {
	if t.mo != nil {
		t.mo.Destroy()
	}
}

func (t *IntegrationTest) create(o *gcs.Object) {
	// Ensure invariants are checked.
	t.mo = &checkingMutableObject{
		ctx: t.ctx,
		wrapped: gcsproxy.NewMutableObject(
			o,
			t.bucket,
			t.leaser,
			&t.clock),
	}
}

// Return the object generation, or -1 if non-existent. Panic on error.
func (t *IntegrationTest) objectGeneration(name string) (gen int64) {
	// Stat.
	req := &gcs.StatObjectRequest{Name: name}
	o, err := t.bucket.StatObject(t.ctx, req)

	if _, ok := err.(*gcs.NotFoundError); ok {
		gen = -1
		return
	}

	if err != nil {
		panic(err)
	}

	// Check the result.
	if o.Generation > math.MaxInt64 {
		panic(fmt.Sprintf("Out of range: %v", o.Generation))
	}

	gen = o.Generation
	return
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *IntegrationTest) ReadThenSync() {
	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Read the contents.
	buf := make([]byte, 1024)
	n, err := t.mo.ReadAt(buf, 0)

	AssertThat(err, AnyOf(io.EOF, nil))
	ExpectEq(len("taco"), n)
	ExpectEq("taco", string(buf[:n]))

	// Sync doesn't need to do anything.
	err = t.mo.Sync()
	ExpectEq(nil, err)

	ExpectEq(o.Generation, t.mo.SourceGeneration())
	ExpectEq(o.Generation, t.objectGeneration("foo"))
}

func (t *IntegrationTest) WriteThenSync() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) TruncateThenSync() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) Stat_Clean() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) Stat_Dirty() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) SmallerThanLeaserLimit() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) LargerThanLeaserLimit() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) BackingObjectHasBeenDeleted_BeforeReading() {
	// Create an object to obtain a record, then delete it.
	createTime := t.clock.Now()
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)
	t.clock.AdvanceTime(time.Second)

	err = t.bucket.DeleteObject(t.ctx, o.Name)
	AssertEq(nil, err)

	// Create a mutable object around it.
	t.create(o)

	// Synchronously-available things should work.
	ExpectEq(o.Name, t.mo.Name())
	ExpectEq(o.Generation, t.mo.SourceGeneration())

	sr, err := t.mo.Stat(true)
	AssertEq(nil, err)
	ExpectEq(o.Size, sr.Size)
	ExpectThat(sr.Mtime, timeutil.TimeEq(createTime))
	ExpectTrue(sr.Clobbered)

	// Sync doesn't need to do anything.
	err = t.mo.Sync()
	ExpectEq(nil, err)

	// Anything that needs to fault in the contents should fail.
	_, err = t.mo.ReadAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))

	err = t.mo.Truncate(10)
	ExpectThat(err, Error(HasSubstr("not found")))

	_, err = t.mo.WriteAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))
}

func (t *IntegrationTest) BackingObjectHasBeenDeleted_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) BackingObjectHasBeenOverwritten_BeforeReading() {
	// Create an object, then create the mutable object wrapper around it.
	createTime := t.clock.Now()
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)
	t.clock.AdvanceTime(time.Second)

	t.create(o)

	// Overwrite the GCS object.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, "foo", "burrito")
	AssertEq(nil, err)

	// Synchronously-available things should work.
	ExpectEq(o.Name, t.mo.Name())
	ExpectEq(o.Generation, t.mo.SourceGeneration())

	sr, err := t.mo.Stat(true)
	AssertEq(nil, err)
	ExpectEq(o.Size, sr.Size)
	ExpectThat(sr.Mtime, timeutil.TimeEq(createTime))
	ExpectTrue(sr.Clobbered)

	// Sync doesn't need to do anything.
	err = t.mo.Sync()
	ExpectEq(nil, err)

	// Anything that needs to fault in the contents should fail.
	_, err = t.mo.ReadAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))

	err = t.mo.Truncate(10)
	ExpectThat(err, Error(HasSubstr("not found")))

	_, err = t.mo.WriteAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))
}

func (t *IntegrationTest) BackingObjectHasBeenOverwritten_AfterReading() {
	AssertTrue(false, "TODO")
}
<commit_msg>IntegrationTest.WriteThenSync<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gcsproxy_test

import (
	"fmt"
	"io"
	"math"
	"testing"
	"time"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/gcsproxy"
	"github.com/googlecloudplatform/gcsfuse/lease"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	"github.com/jacobsa/gcloud/gcs/gcsutil"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

func TestIntegration(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

const fileLeaserLimit = 1 << 10

type IntegrationTest struct {
	ctx    context.Context
	bucket gcs.Bucket
	leaser lease.FileLeaser
	clock  timeutil.SimulatedClock

	mo *checkingMutableObject
}

var _ SetUpInterface = &IntegrationTest{}
var _ TearDownInterface = &IntegrationTest{}

func init() { RegisterTestSuite(&IntegrationTest{}) }

func (t *IntegrationTest) SetUp(ti *TestInfo) {
	t.ctx = ti.Ctx
	t.bucket = gcsfake.NewFakeBucket(&t.clock, "some_bucket")
	t.leaser = lease.NewFileLeaser("", fileLeaserLimit)

	// Set up a fixed, non-zero time.
	t.clock.SetTime(time.Date(2012, 8, 15, 22, 56, 0, 0, time.Local))
}

func (t *IntegrationTest) TearDown() {
	if t.mo != nil {
		t.mo.Destroy()
	}
}

func (t *IntegrationTest) create(o *gcs.Object) {
	// Ensure invariants are checked.
	t.mo = &checkingMutableObject{
		ctx: t.ctx,
		wrapped: gcsproxy.NewMutableObject(
			o,
			t.bucket,
			t.leaser,
			&t.clock),
	}
}

// Return the object generation, or -1 if non-existent. Panic on error.
func (t *IntegrationTest) objectGeneration(name string) (gen int64) {
	// Stat.
	req := &gcs.StatObjectRequest{Name: name}
	o, err := t.bucket.StatObject(t.ctx, req)

	if _, ok := err.(*gcs.NotFoundError); ok {
		gen = -1
		return
	}

	if err != nil {
		panic(err)
	}

	// Check the result.
	if o.Generation > math.MaxInt64 {
		panic(fmt.Sprintf("Out of range: %v", o.Generation))
	}

	gen = o.Generation
	return
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *IntegrationTest) ReadThenSync() {
	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Read the contents.
	buf := make([]byte, 1024)
	n, err := t.mo.ReadAt(buf, 0)

	AssertThat(err, AnyOf(io.EOF, nil))
	ExpectEq(len("taco"), n)
	ExpectEq("taco", string(buf[:n]))

	// Sync doesn't need to do anything.
	err = t.mo.Sync()
	ExpectEq(nil, err)

	ExpectEq(o.Generation, t.mo.SourceGeneration())
	ExpectEq(o.Generation, t.objectGeneration("foo"))
}

func (t *IntegrationTest) WriteThenSync() {
	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Overwrite the first byte.
	n, err := t.mo.WriteAt([]byte("p"), 0)

	AssertEq(nil, err)
	ExpectEq(1, n)

	// Sync should save out the new generation.
	err = t.mo.Sync()
	ExpectEq(nil, err)

	ExpectNe(o.Generation, t.mo.SourceGeneration())
	ExpectEq(t.objectGeneration("foo"), t.mo.SourceGeneration())

	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, "foo")
	AssertEq(nil, err)
	ExpectEq("paco", contents)
}

func (t *IntegrationTest) TruncateThenSync() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) Stat_Clean() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) Stat_Dirty() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) SmallerThanLeaserLimit() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) LargerThanLeaserLimit() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) BackingObjectHasBeenDeleted_BeforeReading() {
	// Create an object to obtain a record, then delete it.
	createTime := t.clock.Now()
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)
	t.clock.AdvanceTime(time.Second)

	err = t.bucket.DeleteObject(t.ctx, o.Name)
	AssertEq(nil, err)

	// Create a mutable object around it.
	t.create(o)

	// Synchronously-available things should work.
	ExpectEq(o.Name, t.mo.Name())
	ExpectEq(o.Generation, t.mo.SourceGeneration())

	sr, err := t.mo.Stat(true)
	AssertEq(nil, err)
	ExpectEq(o.Size, sr.Size)
	ExpectThat(sr.Mtime, timeutil.TimeEq(createTime))
	ExpectTrue(sr.Clobbered)

	// Sync doesn't need to do anything.
	err = t.mo.Sync()
	ExpectEq(nil, err)

	// Anything that needs to fault in the contents should fail.
	_, err = t.mo.ReadAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))

	err = t.mo.Truncate(10)
	ExpectThat(err, Error(HasSubstr("not found")))

	_, err = t.mo.WriteAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))
}

func (t *IntegrationTest) BackingObjectHasBeenDeleted_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *IntegrationTest) BackingObjectHasBeenOverwritten_BeforeReading() {
	// Create an object, then create the mutable object wrapper around it.
	createTime := t.clock.Now()
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)
	t.clock.AdvanceTime(time.Second)

	t.create(o)

	// Overwrite the GCS object.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, "foo", "burrito")
	AssertEq(nil, err)

	// Synchronously-available things should work.
	ExpectEq(o.Name, t.mo.Name())
	ExpectEq(o.Generation, t.mo.SourceGeneration())

	sr, err := t.mo.Stat(true)
	AssertEq(nil, err)
	ExpectEq(o.Size, sr.Size)
	ExpectThat(sr.Mtime, timeutil.TimeEq(createTime))
	ExpectTrue(sr.Clobbered)

	// Sync doesn't need to do anything.
	err = t.mo.Sync()
	ExpectEq(nil, err)

	// Anything that needs to fault in the contents should fail.
	_, err = t.mo.ReadAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))

	err = t.mo.Truncate(10)
	ExpectThat(err, Error(HasSubstr("not found")))

	_, err = t.mo.WriteAt([]byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))
}

func (t *IntegrationTest) BackingObjectHasBeenOverwritten_AfterReading() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>package datasize

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type ByteSize uint64

const (
	B  ByteSize = 1
	KB          = B << 10
	MB          = KB << 10
	GB          = MB << 10
	TB          = GB << 10
	PB          = TB << 10
	EB          = PB << 10

	fnUnmarshalText string = "UnmarshalText"
	maxUint64       uint64 = (1 << 64) - 1
	cutoff          uint64 = maxUint64 / 10
)

var ErrBits = errors.New("unit with capital unit prefix and lower case unit (b) - bits, not bytes ")

func (b ByteSize) Bytes() uint64 {
	return uint64(b)
}

func (b ByteSize) KBytes() float64 {
	v := b / KB
	r := b % KB
	return float64(v) + float64(r)/float64(KB)
}

func (b ByteSize) MBytes() float64 {
	v := b / MB
	r := b % MB
	return float64(v) + float64(r)/float64(MB)
}

func (b ByteSize) GBytes() float64 {
	v := b / GB
	r := b % GB
	return float64(v) + float64(r)/float64(GB)
}

func (b ByteSize) TBytes() float64 {
	v := b / TB
	r := b % TB
	return float64(v) + float64(r)/float64(TB)
}

func (b ByteSize) PBytes() float64 {
	v := b / PB
	r := b % PB
	return float64(v) + float64(r)/float64(PB)
}

func (b ByteSize) EBytes() float64 {
	v := b / EB
	r := b % EB
	return float64(v) + float64(r)/float64(EB)
}

func (b ByteSize) String() string {
	switch {
	case b == 0:
		return fmt.Sprint("0B")
	case b%EB == 0:
		return fmt.Sprintf("%dEB", b/EB)
	case b%PB == 0:
		return fmt.Sprintf("%dPB", b/PB)
	case b%TB == 0:
		return fmt.Sprintf("%dTB", b/TB)
	case b%GB == 0:
		return fmt.Sprintf("%dGB", b/GB)
	case b%MB == 0:
		return fmt.Sprintf("%dMB", b/MB)
	case b%KB == 0:
		return fmt.Sprintf("%dKB", b/KB)
	default:
		return fmt.Sprintf("%dB", b)
	}
}

func (b ByteSize) HR() string {
	return b.HumanReadable()
}

func (b ByteSize) HumanReadable() string {
	switch {
	case b > EB:
		return fmt.Sprintf("%f.1 EB", b.EBytes())
	case b > PB:
		return fmt.Sprintf("%f.1 PB", b.PBytes())
	case b > TB:
		return fmt.Sprintf("%f.1 TB", b.TBytes())
	case b > GB:
		return fmt.Sprintf("%f.1 GB", b.GBytes())
	case b > MB:
		return fmt.Sprintf("%f.1 MB", b.MBytes())
	case b > KB:
		return fmt.Sprintf("%f.1 KB", b.KBytes())
	default:
		return fmt.Sprintf("%d B", b)
	}
}

func (b ByteSize) MarshalText() ([]byte, error) {
	return []byte(b.String()), nil
}

func (b *ByteSize) UnmarshalText(t []byte) error {
	var val uint64
	var unit string

	// copy for error message
	t0 := t

	var c byte
	var i int

ParseLoop:
	for i < len(t) {
		c = t[i]
		switch {
		case '0' <= c && c <= '9':
			if val > cutoff {
				goto Overflow
			}

			c = c - '0'
			val *= 10

			if val > val+uint64(c) {
				// val+v overflows
				goto Overflow
			}
			val += uint64(c)
			i++

		default:
			if i == 0 {
				goto SyntaxError
			}
			break ParseLoop
		}
	}

	unit = strings.TrimSpace(string(t[i:]))
	switch unit {
	case "Kb", "Mb", "Gb", "Tb", "Pb", "Eb":
		goto BitsError
	}
	unit = strings.ToLower(unit)
	switch unit {
	case "", "b", "byte":
		// do nothing - already in bytes

	case "k", "kb", "kilo", "kilobyte", "kilobytes":
		if val > maxUint64/uint64(KB) {
			goto Overflow
		}
		val *= uint64(KB)

	case "m", "mb", "mega", "megabyte", "megabytes":
		if val > maxUint64/uint64(MB) {
			goto Overflow
		}
		val *= uint64(MB)

	case "g", "gb", "giga", "gigabyte", "gigabytes":
		if val > maxUint64/uint64(GB) {
			goto Overflow
		}
		val *= uint64(GB)

	case "t", "tb", "tera", "terabyte", "terabytes":
		if val > maxUint64/uint64(TB) {
			goto Overflow
		}
		val *= uint64(TB)

	case "p", "pb", "peta", "petabyte", "petabytes":
		if val > maxUint64/uint64(PB) {
			goto Overflow
		}
		val *= uint64(PB)

	case "E", "EB", "e", "eb", "eB":
		if val > maxUint64/uint64(EB) {
			goto Overflow
		}
		val *= uint64(EB)

	default:
		goto SyntaxError
	}

	*b = ByteSize(val)
	return nil

Overflow:
	*b = ByteSize(maxUint64)
	return &strconv.NumError{fnUnmarshalText, string(t0), strconv.ErrRange}

SyntaxError:
	*b = 0
	return &strconv.NumError{fnUnmarshalText, string(t0), strconv.ErrSyntax}

BitsError:
	*b = 0
	return &strconv.NumError{fnUnmarshalText, string(t0), ErrBits}
}
<commit_msg>Fix human readable ByteSize<commit_after>package datasize

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type ByteSize uint64

const (
	B  ByteSize = 1
	KB          = B << 10
	MB          = KB << 10
	GB          = MB << 10
	TB          = GB << 10
	PB          = TB << 10
	EB          = PB << 10

	fnUnmarshalText string = "UnmarshalText"
	maxUint64       uint64 = (1 << 64) - 1
	cutoff          uint64 = maxUint64 / 10
)

var ErrBits = errors.New("unit with capital unit prefix and lower case unit (b) - bits, not bytes ")

func (b ByteSize) Bytes() uint64 {
	return uint64(b)
}

func (b ByteSize) KBytes() float64 {
	v := b / KB
	r := b % KB
	return float64(v) + float64(r)/float64(KB)
}

func (b ByteSize) MBytes() float64 {
	v := b / MB
	r := b % MB
	return float64(v) + float64(r)/float64(MB)
}

func (b ByteSize) GBytes() float64 {
	v := b / GB
	r := b % GB
	return float64(v) + float64(r)/float64(GB)
}

func (b ByteSize) TBytes() float64 {
	v := b / TB
	r := b % TB
	return float64(v) + float64(r)/float64(TB)
}

func (b ByteSize) PBytes() float64 {
	v := b / PB
	r := b % PB
	return float64(v) + float64(r)/float64(PB)
}

func (b ByteSize) EBytes() float64 {
	v := b / EB
	r := b % EB
	return float64(v) + float64(r)/float64(EB)
}

func (b ByteSize) String() string {
	switch {
	case b == 0:
		return fmt.Sprint("0B")
	case b%EB == 0:
		return fmt.Sprintf("%dEB", b/EB)
	case b%PB == 0:
		return fmt.Sprintf("%dPB", b/PB)
	case b%TB == 0:
		return fmt.Sprintf("%dTB", b/TB)
	case b%GB == 0:
		return fmt.Sprintf("%dGB", b/GB)
	case b%MB == 0:
		return fmt.Sprintf("%dMB", b/MB)
	case b%KB == 0:
		return fmt.Sprintf("%dKB", b/KB)
	default:
		return fmt.Sprintf("%dB", b)
	}
}

func (b ByteSize) HR() string {
	return b.HumanReadable()
}

func (b ByteSize) HumanReadable() string {
	switch {
	case b > EB:
		return fmt.Sprintf("%.1f EB", b.EBytes())
	case b > PB:
		return fmt.Sprintf("%.1f PB", b.PBytes())
	case b > TB:
		return fmt.Sprintf("%.1f TB", b.TBytes())
	case b > GB:
		return fmt.Sprintf("%.1f GB", b.GBytes())
	case b > MB:
		return fmt.Sprintf("%.1f MB", b.MBytes())
	case b > KB:
		return fmt.Sprintf("%.1f KB", b.KBytes())
	default:
		return fmt.Sprintf("%d B", b)
	}
}

func (b ByteSize) MarshalText() ([]byte, error) {
	return []byte(b.String()), nil
}

func (b *ByteSize) UnmarshalText(t []byte) error {
	var val uint64
	var unit string

	// copy for error message
	t0 := t

	var c byte
	var i int

ParseLoop:
	for i < len(t) {
		c = t[i]
		switch {
		case '0' <= c && c <= '9':
			if val > cutoff {
				goto Overflow
			}

			c = c - '0'
			val *= 10

			if val > val+uint64(c) {
				// val+v overflows
				goto Overflow
			}
			val += uint64(c)
			i++

		default:
			if i == 0 {
				goto SyntaxError
			}
			break ParseLoop
		}
	}

	unit = strings.TrimSpace(string(t[i:]))
	switch unit {
	case "Kb", "Mb", "Gb", "Tb", "Pb", "Eb":
		goto BitsError
	}
	unit = strings.ToLower(unit)
	switch unit {
	case "", "b", "byte":
		// do nothing - already in bytes

	case "k", "kb", "kilo", "kilobyte", "kilobytes":
		if val > maxUint64/uint64(KB) {
			goto Overflow
		}
		val *= uint64(KB)

	case "m", "mb", "mega", "megabyte", "megabytes":
		if val > maxUint64/uint64(MB) {
			goto Overflow
		}
		val *= uint64(MB)

	case "g", "gb", "giga", "gigabyte", "gigabytes":
		if val > maxUint64/uint64(GB) {
			goto Overflow
		}
		val *= uint64(GB)

	case "t", "tb", "tera", "terabyte", "terabytes":
		if val > maxUint64/uint64(TB) {
			goto Overflow
		}
		val *= uint64(TB)

	case "p", "pb", "peta", "petabyte", "petabytes":
		if val > maxUint64/uint64(PB) {
			goto Overflow
		}
		val *= uint64(PB)

	case "E", "EB", "e", "eb", "eB":
		if val > maxUint64/uint64(EB) {
			goto Overflow
		}
		val *= uint64(EB)

	default:
		goto SyntaxError
	}

	*b = ByteSize(val)
	return nil

Overflow:
	*b = ByteSize(maxUint64)
	return &strconv.NumError{fnUnmarshalText, string(t0), strconv.ErrRange}

SyntaxError:
	*b = 0
	return &strconv.NumError{fnUnmarshalText, string(t0), strconv.ErrSyntax}

BitsError:
	*b = 0
	return &strconv.NumError{fnUnmarshalText, string(t0), ErrBits}
}
<|endoftext|>


<commit_before>package db

import (
	"container/list"
	"encoding/binary"
	"fmt"
	"strings"
	"time"

	"github.com/google/btree"
	query "github.com/gtfierro/hod/query"
	"github.com/syndtr/goleveldb/leveldb"
)

// make a set of structs that capture what these queries want to do

// So, how do queries work?
// We have a list of filters, each of which has a subject, list of predicate things, and
// an object. Any of these might be variables, which we can distinguish by having a "?"
// in front of the value.
//
// First we "clean" these by making sure that they have their full
// namespaces rather than the prefix

type Item [4]byte

func (i Item) Less(than btree.Item) bool {
	t := than.(Item)
	return binary.LittleEndian.Uint32(i[:]) < binary.LittleEndian.Uint32(t[:])
}

func (db *DB) RunQuery(q query.Query) {
	// "clean" the query by expanding out the prefixes
	for idx, filter := range q.Where {
		if !strings.HasPrefix(filter.Subject.Value, "?") {
			if full, found := db.namespaces[filter.Subject.Namespace]; found {
				filter.Subject.Namespace = full
			}
			q.Where[idx] = filter
		}
		if !strings.HasPrefix(filter.Object.Value, "?") {
			if full, found := db.namespaces[filter.Object.Namespace]; found {
				filter.Object.Namespace = full
			}
			q.Where[idx] = filter
		}
		for idx2, pred := range filter.Path {
			if !strings.HasPrefix(pred.Predicate.Value, "?") {
				if full, found := db.namespaces[pred.Predicate.Namespace]; found {
					pred.Predicate.Namespace = full
				}
				filter.Path[idx2] = pred
			}
		}
		q.Where[idx] = filter
	}

	fmt.Println("-------------- start query plan -------------")
	planStart := time.Now()
	dg := db.formDependencyGraph(q)
	qp := db.formQueryPlan(dg)
	for _, op := range qp.operations {
		log.Debug("op", op)
	}
	log.Infof("Formed execution plan in %s", time.Since(planStart))
	fmt.Println("-------------- end query plan -------------")

	runStart := time.Now()
	rm := db.executeQueryPlan(qp)
	log.Infof("Ran query in %s", time.Since(runStart))

	runStart = time.Now()
	results := db.expandTuples(rm, qp.selectVars)
	log.Infof("Expanded tuples in %s", time.Since(runStart))
	if q.Select.Count {
		fmt.Println(len(results))
	} else {
		for _, r := range results {
			fmt.Println(r)
		}
	}
	return
}

// We need an execution plan for the list of filters contained in a query. How do we do this?
func (db *DB) formDependencyGraph(q query.Query) *dependencyGraph {
	dg := makeDependencyGraph(q)
	terms := make([]*queryTerm, len(q.Where))
	for i, f := range q.Where {
		terms[i] = dg.makeQueryTerm(f)
	}

	numUnresolved := func(qt *queryTerm) int {
		num := 0
		for _, v := range qt.variables {
			if !dg.variables[v] {
				num++
			}
		}
		return num
	}

	originalLength := len(terms)
	for len(terms) > 0 {
		// first find all the terms with 0 or 1 unresolved variable terms
		var added = []*queryTerm{}
		for _, term := range terms {
			if numUnresolved(term) < 2 {
				dg.addRootTerm(term)
				added = append(added, term)
			}
		}
		// remove the terms that we added to the root set
		terms = filterTermList(terms, added)
		added = []*queryTerm{}
		for _, term := range terms {
			if dg.addChild(term) {
				added = append(added, term)
			}
		}
		terms = filterTermList(terms, added)
		if len(terms) == originalLength {
			// we don't have any root elements. Need to consider 2-variable terms
			added = []*queryTerm{}
			for _, term := range terms {
				if numUnresolved(term) == 2 {
					dg.addRootTerm(term)
					added = append(added, term)
					break
				}
			}
			terms = filterTermList(terms, added)
		}
	}
	dg.dump()
	return dg
}

func (db *DB) executeQueryPlan(qp *queryPlan) *resultMap {
	rm := newResultMap()
	rm.varOrder = qp.varOrder
	var err error
	for _, op := range qp.operations {
		now := time.Now()
		rm, err = op.run(db, qp.varOrder, rm)
		fmt.Println(op, time.Since(now))
		if err != nil {
			log.Fatal(err)
		}
	}
	//for vname := range qp.varOrder.vars {
	//	fmt.Println(vname, rm.getVariableChain(vname))
	//	for re := range rm.iterVariable(vname) {
	//		fmt.Println(vname, re)
	//	}
	//}
	for vname, tree := range rm.vars {
		fmt.Println(vname, tree.Len())
	}
	return rm
}

// takes the inverse of every relationship. If no inverse exists, returns nil
func (db *DB) reversePathPattern(path []query.PathPattern) []query.PathPattern {
	var reverse = make([]query.PathPattern, len(path))
	for idx, pred := range path {
		if inverse, found := db.relationships[pred.Predicate]; found {
			pred.Predicate = inverse
			reverse[idx] = pred
		} else {
			return nil
		}
	}
	return reverse
}

// follow the pattern from the given object's InEdges, placing the results in the btree
func (db *DB) followPathFromObject(object *Entity, results *btree.BTree, searchstack *list.List, pattern query.PathPattern) {
	stack := list.New()
	stack.PushFront(object)

	predHash, err := db.GetHash(pattern.Predicate)
	if err != nil && err == leveldb.ErrNotFound {
		log.Infof("Adding unseen predicate %s", pattern.Predicate)
		var hashdest [4]byte
		if err := db.insertEntity(pattern.Predicate, hashdest[:]); err != nil {
			panic(fmt.Errorf("Could not insert entity %s (%v)", pattern.Predicate, err))
		}
	} else if err != nil {
		panic(fmt.Errorf("Not found: %v (%s)", pattern.Predicate, err))
	}

	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		switch pattern.Pattern {
		case query.PATTERN_SINGLE:
			// [found] indicates whether or not we have any edges with the given pattern
			edges, found := entity.InEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_ONE:
			log.Notice("PATH ?", pattern)
			// this does not require the pattern to exist, so we add ALL entities connected
			// by ALL edges
			for _, endpointHashList := range entity.InEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
				}
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_PLUS:
			log.Notice("PATH *", pattern)
			// we add ALL edges to the stack, but continue searching only on those that
			// have the required edge
			for edgeName, endpointHashList := range entity.InEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
					if edgeName == string(predHash[:]) {
						stack.PushBack(nextEntity)
					}
				}
			}
		case query.PATTERN_ONE_PLUS:
			edges, found := entity.InEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
				searchstack.PushBack(nextEntity)
				// also make sure to add this to the stack so we can search
				stack.PushBack(nextEntity)
			}
		}
	}
}

// follow the pattern from the given subject's OutEdges, placing the results in the btree
func (db *DB) followPathFromSubject(subject *Entity, results *btree.BTree, searchstack *list.List, pattern query.PathPattern) {
	stack := list.New()
	stack.PushFront(subject)

	predHash, err := db.GetHash(pattern.Predicate)
	if err != nil {
		panic(err)
	}

	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		switch pattern.Pattern {
		case query.PATTERN_SINGLE:
			// [found] indicates whether or not we have any edges with the given pattern
			edges, found := entity.OutEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_ONE:
			// this does not require the pattern to exist, so we add ALL entities connected
			// by ALL edges
			for _, endpointHashList := range entity.OutEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
				}
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_PLUS:
			// we add ALL edges to the stack, but continue searching only on those that
			// have the required edge
			for edgeName, endpointHashList := range entity.OutEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
					if edgeName == string(predHash[:]) {
						stack.PushBack(nextEntity)
					}
				}
			}
		case query.PATTERN_ONE_PLUS:
			edges, found := entity.OutEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
				searchstack.PushBack(nextEntity)
				// also make sure to add this to the stack so we can search
				stack.PushBack(nextEntity)
			}
		}
	}
}

func (db *DB) getSubjectFromPredObject(objectHash [4]byte, path []query.PathPattern) *btree.BTree {
	// first get the initial object entity from the db
	// then we're going to conduct a BFS search starting from this entity looking for all entities
	// that have the required path sequence. We place the results in a BTree to maintain uniqueness

	// So how does this traversal actually work?
	// At each 'step', we are looking at an entity and some offset into the path.

	// get the object, look in its "in" edges for the path pattern
	objEntity, err := db.GetEntityFromHash(objectHash)
	if err != nil {
		panic(err)
	}
	results := btree.New(2)

	stack := list.New()
	stack.PushFront(objEntity)

	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		for _, pat := range path {
			db.followPathFromObject(entity, results, stack, pat)
		}
	}

	return results
}

// Given object and predicate, get all subjects
func (db *DB) getObjectFromSubjectPred(subjectHash [4]byte, path []query.PathPattern) *btree.BTree {
	subEntity, err := db.GetEntityFromHash(subjectHash)
	if err != nil {
		panic(err)
	}

	results := btree.New(2)

	stack := list.New()
	stack.PushFront(subEntity)

	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		for _, pat := range path {
			db.followPathFromSubject(entity, results, stack, pat)
		}
	}

	return results
}

// Given a predicate, it returns pairs of (subject, object) that are connected by that relationship
func (db *DB) getSubjectObjectFromPred(path []query.PathPattern) (soPair [][][4]byte) {
	//pe, found := db.predIndex[pattern.Predicate]
	//if !found {
	//	panic(fmt.Sprintf("Cannot find predicate %s", pattern.Predicate))
	//}
	//for subject, objectMap := range pe.Subjects {
	//	for object := range objectMap {
	//		var sh, oh [4]byte
	//		copy(sh[:], subject)
	//		copy(oh[:], object)
	//		soPair = append(soPair, [][4]byte{sh, oh})
	//	}
	//}
	return soPair
}
<commit_msg>protect against loops in graph<commit_after>package db

import (
	"container/list"
	"encoding/binary"
	"fmt"
	"strings"
	"time"

	"github.com/google/btree"
	query "github.com/gtfierro/hod/query"
	"github.com/syndtr/goleveldb/leveldb"
)

// make a set of structs that capture what these queries want to do

// So, how do queries work?
// We have a list of filters, each of which has a subject, list of predicate things, and
// an object. Any of these might be variables, which we can distinguish by having a "?"
// in front of the value.
//
// First we "clean" these by making sure that they have their full
// namespaces rather than the prefix

type Item [4]byte

func (i Item) Less(than btree.Item) bool {
	t := than.(Item)
	return binary.LittleEndian.Uint32(i[:]) < binary.LittleEndian.Uint32(t[:])
}

func (db *DB) RunQuery(q query.Query) {
	// "clean" the query by expanding out the prefixes
	for idx, filter := range q.Where {
		if !strings.HasPrefix(filter.Subject.Value, "?") {
			if full, found := db.namespaces[filter.Subject.Namespace]; found {
				filter.Subject.Namespace = full
			}
			q.Where[idx] = filter
		}
		if !strings.HasPrefix(filter.Object.Value, "?") {
			if full, found := db.namespaces[filter.Object.Namespace]; found {
				filter.Object.Namespace = full
			}
			q.Where[idx] = filter
		}
		for idx2, pred := range filter.Path {
			if !strings.HasPrefix(pred.Predicate.Value, "?") {
				if full, found := db.namespaces[pred.Predicate.Namespace]; found {
					pred.Predicate.Namespace = full
				}
				filter.Path[idx2] = pred
			}
		}
		q.Where[idx] = filter
	}

	fmt.Println("-------------- start query plan -------------")
	planStart := time.Now()
	dg := db.formDependencyGraph(q)
	qp := db.formQueryPlan(dg)
	for _, op := range qp.operations {
		log.Debug("op", op)
	}
	log.Infof("Formed execution plan in %s", time.Since(planStart))
	fmt.Println("-------------- end query plan -------------")

	runStart := time.Now()
	rm := db.executeQueryPlan(qp)
	log.Infof("Ran query in %s", time.Since(runStart))

	runStart = time.Now()
	results := db.expandTuples(rm, qp.selectVars)
	log.Infof("Expanded tuples in %s", time.Since(runStart))
	if q.Select.Count {
		fmt.Println(len(results))
	} else {
		for _, r := range results {
			fmt.Println(r)
		}
	}
	return
}

// We need an execution plan for the list of filters contained in a query. How do we do this?
func (db *DB) formDependencyGraph(q query.Query) *dependencyGraph {
	dg := makeDependencyGraph(q)
	terms := make([]*queryTerm, len(q.Where))
	for i, f := range q.Where {
		terms[i] = dg.makeQueryTerm(f)
	}

	numUnresolved := func(qt *queryTerm) int {
		num := 0
		for _, v := range qt.variables {
			if !dg.variables[v] {
				num++
			}
		}
		return num
	}

	originalLength := len(terms)
	for len(terms) > 0 {
		// first find all the terms with 0 or 1 unresolved variable terms
		var added = []*queryTerm{}
		for _, term := range terms {
			if numUnresolved(term) < 2 {
				dg.addRootTerm(term)
				added = append(added, term)
			}
		}
		// remove the terms that we added to the root set
		terms = filterTermList(terms, added)
		added = []*queryTerm{}
		for _, term := range terms {
			if dg.addChild(term) {
				added = append(added, term)
			}
		}
		terms = filterTermList(terms, added)
		if len(terms) == originalLength {
			// we don't have any root elements. Need to consider 2-variable terms
			added = []*queryTerm{}
			for _, term := range terms {
				if numUnresolved(term) == 2 {
					dg.addRootTerm(term)
					added = append(added, term)
					break
				}
			}
			terms = filterTermList(terms, added)
		}
	}
	dg.dump()
	return dg
}

func (db *DB) executeQueryPlan(qp *queryPlan) *resultMap {
	rm := newResultMap()
	rm.varOrder = qp.varOrder
	var err error
	for _, op := range qp.operations {
		now := time.Now()
		rm, err = op.run(db, qp.varOrder, rm)
		fmt.Println(op, time.Since(now))
		if err != nil {
			log.Fatal(err)
		}
	}
	//for vname := range qp.varOrder.vars {
	//	fmt.Println(vname, rm.getVariableChain(vname))
	//	for re := range rm.iterVariable(vname) {
	//		fmt.Println(vname, re)
	//	}
	//}
	for vname, tree := range rm.vars {
		fmt.Println(vname, tree.Len())
	}
	return rm
}

// takes the inverse of every relationship. If no inverse exists, returns nil
func (db *DB) reversePathPattern(path []query.PathPattern) []query.PathPattern {
	var reverse = make([]query.PathPattern, len(path))
	for idx, pred := range path {
		if inverse, found := db.relationships[pred.Predicate]; found {
			pred.Predicate = inverse
			reverse[idx] = pred
		} else {
			return nil
		}
	}
	return reverse
}

// follow the pattern from the given object's InEdges, placing the results in the btree
func (db *DB) followPathFromObject(object *Entity, results *btree.BTree, searchstack *list.List, pattern query.PathPattern) {
	stack := list.New()
	stack.PushFront(object)

	predHash, err := db.GetHash(pattern.Predicate)
	if err != nil && err == leveldb.ErrNotFound {
		log.Infof("Adding unseen predicate %s", pattern.Predicate)
		var hashdest [4]byte
		if err := db.insertEntity(pattern.Predicate, hashdest[:]); err != nil {
			panic(fmt.Errorf("Could not insert entity %s (%v)", pattern.Predicate, err))
		}
	} else if err != nil {
		panic(fmt.Errorf("Not found: %v (%s)", pattern.Predicate, err))
	}

	var traversed = btree.New(2)

	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		if traversed.Has(Item(entity.PK)) {
			continue
		}
		traversed.ReplaceOrInsert(Item(entity.PK))
		switch pattern.Pattern {
		case query.PATTERN_SINGLE:
			// [found] indicates whether or not we have any edges with the given pattern
			edges, found := entity.InEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_ONE:
			log.Notice("PATH ?", pattern)
			// this does not require the pattern to exist, so we add ALL entities connected
			// by ALL edges
			for _, endpointHashList := range entity.InEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
				}
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_PLUS:
			log.Notice("PATH *", pattern)
			// we add ALL edges to the stack, but continue searching only on those that
			// have the required edge
			for edgeName, endpointHashList := range entity.InEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
					if edgeName == string(predHash[:]) {
						stack.PushBack(nextEntity)
					}
				}
			}
		case query.PATTERN_ONE_PLUS:
			edges, found := entity.InEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
				searchstack.PushBack(nextEntity)
				// also make sure to add this to the stack so we can search
				stack.PushBack(nextEntity)
			}
		}
	}
}

// follow the pattern from the given subject's OutEdges, placing the results in the btree
func (db *DB) followPathFromSubject(subject *Entity, results *btree.BTree, searchstack *list.List, pattern query.PathPattern) {
	stack := list.New()
	stack.PushFront(subject)

	predHash, err := db.GetHash(pattern.Predicate)
	if err != nil {
		panic(err)
	}

	var traversed = btree.New(2)
	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		if traversed.Has(Item(entity.PK)) {
			continue
		}
		traversed.ReplaceOrInsert(Item(entity.PK))
		switch pattern.Pattern {
		case query.PATTERN_SINGLE:
			// [found] indicates whether or not we have any edges with the given pattern
			edges, found := entity.OutEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_ONE:
			// this does not require the pattern to exist, so we add ALL entities connected
			// by ALL edges
			for _, endpointHashList := range entity.OutEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
				}
			}
			// because this is one hop, we don't add any new entities to the stack
		case query.PATTERN_ZERO_PLUS:
			// we add ALL edges to the stack, but continue searching only on those that
			// have the required edge
			for edgeName, endpointHashList := range entity.OutEdges {
				for _, entityHash := range endpointHashList {
					nextEntity := db.MustGetEntityFromHash(entityHash)
					if !results.Has(Item(nextEntity.PK)) {
						searchstack.PushBack(nextEntity)
					}
					results.ReplaceOrInsert(Item(nextEntity.PK))
					if edgeName == string(predHash[:]) {
						stack.PushBack(nextEntity)
					}
				}
			}
		case query.PATTERN_ONE_PLUS:
			edges, found := entity.OutEdges[string(predHash[:])]
			// this requires the pattern to exist, so we skip if we have no edges of that name
			if !found {
				continue
			}
			// here, these entities are all connected by the required predicate
			for _, entityHash := range edges {
				nextEntity := db.MustGetEntityFromHash(entityHash)
				results.ReplaceOrInsert(Item(nextEntity.PK))
				searchstack.PushBack(nextEntity)
				// also make sure to add this to the stack so we can search
				stack.PushBack(nextEntity)
			}
		}
	}
}

func (db *DB) getSubjectFromPredObject(objectHash [4]byte, path []query.PathPattern) *btree.BTree {
	// first get the initial object entity from the db
	// then we're going to conduct a BFS search starting from this entity looking for all entities
	// that have the required path sequence. We place the results in a BTree to maintain uniqueness

	// So how does this traversal actually work?
	// At each 'step', we are looking at an entity and some offset into the path.

	// get the object, look in its "in" edges for the path pattern
	objEntity, err := db.GetEntityFromHash(objectHash)
	if err != nil {
		panic(err)
	}
	results := btree.New(2)

	stack := list.New()
	stack.PushFront(objEntity)

	var traversed = btree.New(2)
	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		if traversed.Has(Item(entity.PK)) {
			continue
		}
		traversed.ReplaceOrInsert(Item(entity.PK))
		for _, pat := range path {
			db.followPathFromObject(entity, results, stack, pat)
		}
	}

	return results
}

// Given object and predicate, get all subjects
func (db *DB) getObjectFromSubjectPred(subjectHash [4]byte, path []query.PathPattern) *btree.BTree {
	subEntity, err := db.GetEntityFromHash(subjectHash)
	if err != nil {
		panic(err)
	}

	results := btree.New(2)

	stack := list.New()
	stack.PushFront(subEntity)

	var traversed = btree.New(2)
	for stack.Len() > 0 {
		entity := stack.Remove(stack.Front()).(*Entity)
		if traversed.Has(Item(entity.PK)) {
			continue
		}
		traversed.ReplaceOrInsert(Item(entity.PK))
		for _, pat := range path {
			db.followPathFromSubject(entity, results, stack, pat)
		}
	}

	return results
}

// Given a predicate, it returns pairs of (subject, object) that are connected by that relationship
func (db *DB) getSubjectObjectFromPred(path []query.PathPattern) (soPair [][][4]byte) {
	//pe, found := db.predIndex[pattern.Predicate]
	//if !found {
	//	panic(fmt.Sprintf("Cannot find predicate %s", pattern.Predicate))
	//}
	//for subject, objectMap := range pe.Subjects {
	//	for object := range objectMap {
	//		var sh, oh [4]byte
	//		copy(sh[:], subject)
	//		copy(oh[:], object)
	//		soPair = append(soPair, [][4]byte{sh, oh})
	//	}
	//}
	return soPair
}
<|endoftext|>


<commit_before>// errchk $G -e $D/$F.go

// Copyright 2011 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.

package main

import "runtime"

func init() {
}

func main() {
	init()         // ERROR "undefined: init"
	runtime.init() // ERROR "unexported.*runtime\.init"
	var _ = init   // ERROR "undefined: init"
}
<commit_msg>test: match gccgo error messages for init.go<commit_after>// errchk $G -e $D/$F.go

// Copyright 2011 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.

package main

import "runtime"

func init() {
}

func main() {
	init()         // ERROR "undefined.*init"
	runtime.init() // ERROR "unexported.*runtime\.init"
	var _ = init   // ERROR "undefined.*init"
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

package dashboard

// This file handles identities of people.

import (
	"sort"
)

var (
	emailToPerson  = make(map[string]string) // email => person
	preferredEmail = make(map[string]string) // person => email
	personList     []string
)

func init() {
	// People we assume have golang.org and google.com accounts,
	// and prefer to use their golang.org address for code review.
	gophers := [...]string{
		"adg",
		"agl",
		"bradfitz",
		"campoy",
		"dsymonds",
		"gri",
		"iant",
		"nigeltao",
		"r",
		"rsc",
		"sameer",
	}
	for _, p := range gophers {
		personList = append(personList, p)
		emailToPerson[p+"@golang.org"] = p
		emailToPerson[p+"@google.com"] = p
		preferredEmail[p] = p + "@golang.org"
	}
	// Other people.
	others := map[string]string{
		"adonovan": "adonovan@google.com",
		"brainman": "alex.brainman@gmail.com",
		"ality":    "ality@pbrane.org",
		"dfc":      "dave@cheney.net",
		"dvyukov":  "dvyukov@google.com",
		"gustavo":  "gustavo@niemeyer.net",
		"jsing":    "jsing@google.com",
		"mikioh":   "mikioh.mikioh@gmail.com",
		"minux":    "minux.ma@gmail.com",
		"rminnich": "rminnich@gmail.com",
	}
	for p, e := range others {
		personList = append(personList, p)
		emailToPerson[e] = p
		preferredEmail[p] = e
	}

	sort.Strings(personList)
}
<commit_msg>misc/dashboard/codereview: add Rémy to the list of assignees<commit_after>// Copyright 2012 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.

package dashboard

// This file handles identities of people.

import (
	"sort"
)

var (
	emailToPerson  = make(map[string]string) // email => person
	preferredEmail = make(map[string]string) // person => email
	personList     []string
)

func init() {
	// People we assume have golang.org and google.com accounts,
	// and prefer to use their golang.org address for code review.
	gophers := [...]string{
		"adg",
		"agl",
		"bradfitz",
		"campoy",
		"dsymonds",
		"gri",
		"iant",
		"nigeltao",
		"r",
		"rsc",
		"sameer",
	}
	for _, p := range gophers {
		personList = append(personList, p)
		emailToPerson[p+"@golang.org"] = p
		emailToPerson[p+"@google.com"] = p
		preferredEmail[p] = p + "@golang.org"
	}
	// Other people.
	others := map[string]string{
		"adonovan": "adonovan@google.com",
		"brainman": "alex.brainman@gmail.com",
		"ality":    "ality@pbrane.org",
		"dfc":      "dave@cheney.net",
		"dvyukov":  "dvyukov@google.com",
		"gustavo":  "gustavo@niemeyer.net",
		"jsing":    "jsing@google.com",
		"mikio":    "mikioh.mikioh@gmail.com",
		"minux":    "minux.ma@gmail.com",
		"remy":     "remyoudompheng@gmail.com",
		"rminnich": "rminnich@gmail.com",
	}
	for p, e := range others {
		personList = append(personList, p)
		emailToPerson[e] = p
		preferredEmail[p] = e
	}

	sort.Strings(personList)
}
<|endoftext|>


<commit_before>package dns

// Everything is assumed in the ClassINET class. If
// you need other classes you are on your own.

// Add SetEDNS0
// IsEDNS0  function

// Create a reply packet from a request message.
func (dns *Msg) SetReply(request *Msg) {
	dns.MsgHdr.Id = request.MsgHdr.Id
	dns.MsgHdr.Authoritative = true
	dns.MsgHdr.Response = true
	dns.MsgHdr.Opcode = OpcodeQuery
	dns.MsgHdr.Rcode = RcodeSuccess
	dns.Question = make([]Question, 1)
	dns.Question[0] = request.Question[0]
}

// Create a question packet.
func (dns *Msg) SetQuestion(z string, t uint16) {
	dns.MsgHdr.Id = Id()
	dns.MsgHdr.RecursionDesired = true
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, t, ClassINET}
}

// Create a notify packet.
func (dns *Msg) SetNotify(z string) {
	dns.MsgHdr.Opcode = OpcodeNotify
	dns.MsgHdr.Authoritative = true
	dns.MsgHdr.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeSOA, ClassINET}
}

// Create an error packet.
func (dns *Msg) SetRcode(request *Msg, rcode int) {
        dns.MsgHdr.Rcode = rcode
        dns.MsgHdr.Opcode = OpcodeQuery
        dns.MsgHdr.Response = true
        dns.MsgHdr.Authoritative = false
        dns.MsgHdr.Id = request.MsgHdr.Id
        dns.Question = make([]Question, 1)
        dns.Question[0] = request.Question[0]
}

// Create a packet with FormError set.
func (dns *Msg) SetRcodeFormatError(request *Msg) {
        dns.MsgHdr.Rcode = RcodeFormatError
        dns.MsgHdr.Opcode = OpcodeQuery
        dns.MsgHdr.Response = true
        dns.MsgHdr.Authoritative = false
        dns.MsgHdr.Id = request.MsgHdr.Id
}

// SetUpdate makes the message a dynamic update packet. It
// sets the ZONE section to: z, TypeSOA, classINET.
func (dns *Msg) SetUpdate(z string) {
        dns.MsgHdr.Id = Id()
        dns.MsgHdr.Opcode = OpcodeUpdate
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeSOA, ClassINET}
}

// SetIxfr creates dns msg suitable for requesting an ixfr.
func (dns *Msg) SetIxfr(z string, serial uint32) {
	dns.MsgHdr.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Ns = make([]RR, 1)
	s := new(RR_SOA)
	s.Hdr = RR_Header{z, TypeSOA, ClassINET, DefaultTTL, 0}
	s.Serial = serial

	dns.Question[0] = Question{z, TypeIXFR, ClassINET}
	dns.Ns[0] = s
}

// SetAxfr creates dns msg suitable for requesting an ixfr.
func (dns *Msg) SetAxfr(z string) {
	dns.MsgHdr.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeAXFR, ClassINET}
}

// SetTsig appends a TSIG RR to the message.
// This is only a skeleton Tsig RR that added as the last RR in the
// additional section. The caller should then call TsigGenerate,
// to generate the complete TSIG from the secret.
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64) {
	t := new(RR_TSIG)
	t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
	t.Algorithm = algo
	t.Fudge = 300
	t.TimeSigned = timesigned
	dns.Extra = append(dns.Extra, t)
}

// IsRcode checks if the header of the packet has rcode set.
func (dns *Msg) IsRcode(rcode int) (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
        ok = dns.MsgHdr.Rcode == rcode
        return
}

// IsQuestion returns true if the the packet is a question.
func (dns *Msg) IsQuestion() (ok bool) {
        if len(dns.Question) == 0 {
                return false
        }
        ok = dns.MsgHdr.Response == false
        return
}

// IsRcodeFormatError checks if the message has the FormErr set.
func (dns *Msg) IsRcodeFormatError() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
        ok = dns.MsgHdr.Rcode == RcodeFormatError
        return
}

// IsUpdate checks if the message is a dynamic update packet.
func (dns *Msg) IsUpdate() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeUpdate
	ok = ok && dns.Question[0].Qtype == TypeSOA
	return
}

// IsNotify checks if the message is a valid notify packet.
func (dns *Msg) IsNotify() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeNotify
	ok = ok && dns.Question[0].Qclass == ClassINET
	ok = ok && dns.Question[0].Qtype == TypeSOA
	return
}

// IsAxfr checks if the message is a valid axfr request packet.
func (dns *Msg) IsAxfr() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeQuery
	ok = ok && dns.Question[0].Qclass == ClassINET
	ok = ok && dns.Question[0].Qtype == TypeAXFR
	return
}

// IsIXfr checks if the message is a valid ixfr request packet.
func (dns *Msg) IsIxfr() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeQuery
	ok = ok && dns.Question[0].Qclass == ClassINET
	ok = ok && dns.Question[0].Qtype == TypeIXFR
	return
}

// IsTsig checks if the message has a TSIG record as the last record
// in the additional section.
func (dns *Msg) IsTsig() (ok bool) {
	if len(dns.Extra) > 0 {
		return dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG
	}
	return
}

// IsDomainName checks if s is a valid domainname.
func IsDomainName(s string) bool { // copied from net package.
	// See RFC 1035, RFC 3696.
	if len(s) == 0 {
		return false
	}
	if len(s) > 255 {
		return false
	}
	if s[len(s)-1] != '.' { // simplify checking loop: make name end in dot
		s += "."
	}

	last := byte('.')
	ok := false // ok once we've seen a letter
	partlen := 0
	for i := 0; i < len(s); i++ {
		c := s[i]
		switch {
		default:
			return false
		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '*':
			ok = true
			partlen++
		case '0' <= c && c <= '9':
			// fine
			partlen++
		case c == '-':
			// byte before dash cannot be dot
			if last == '.' {
				return false
			}
			partlen++
		case c == '.':
			// byte before dot cannot be dot, dash
			if last == '.' || last == '-' {
				return false
			}
			if partlen > 63 || partlen == 0 {
				return false
			}
			partlen = 0
		}
		last = c
	}

	return ok
}

// Return the number of labels in a domain name.
// Need to add these kind of function in a structured way. TODO(mg)
func Labels(a string) (c uint8) {
	// walk the string and count the dots
	// except when it is escaped
	esc := false
	for _, v := range a {
		switch v {
		case '.':
			if esc {
				esc = !esc
				continue
			}
			c++
		case '\\':
			esc = true
		}
	}
	return
}
<commit_msg>SetEdns0 helper function<commit_after>package dns

// Everything is assumed in the ClassINET class. If
// you need other classes you are on your own.

// Add SetEDNS0
// IsEDNS0  function

// SetReply creates a reply packet from a request message.
func (dns *Msg) SetReply(request *Msg) {
	dns.MsgHdr.Id = request.MsgHdr.Id
	dns.MsgHdr.Authoritative = true
	dns.MsgHdr.Response = true
	dns.MsgHdr.Opcode = OpcodeQuery
	dns.MsgHdr.Rcode = RcodeSuccess
	dns.Question = make([]Question, 1)
	dns.Question[0] = request.Question[0]
}

// Create a question packet.
func (dns *Msg) SetQuestion(z string, t uint16) {
	dns.MsgHdr.Id = Id()
	dns.MsgHdr.RecursionDesired = true
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, t, ClassINET}
}

// Create a notify packet.
func (dns *Msg) SetNotify(z string) {
	dns.MsgHdr.Opcode = OpcodeNotify
	dns.MsgHdr.Authoritative = true
	dns.MsgHdr.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeSOA, ClassINET}
}

// Create an error packet.
func (dns *Msg) SetRcode(request *Msg, rcode int) {
        dns.MsgHdr.Rcode = rcode
        dns.MsgHdr.Opcode = OpcodeQuery
        dns.MsgHdr.Response = true
        dns.MsgHdr.Authoritative = false
        dns.MsgHdr.Id = request.MsgHdr.Id
        dns.Question = make([]Question, 1)
        dns.Question[0] = request.Question[0]
}

// Create a packet with FormError set.
func (dns *Msg) SetRcodeFormatError(request *Msg) {
        dns.MsgHdr.Rcode = RcodeFormatError
        dns.MsgHdr.Opcode = OpcodeQuery
        dns.MsgHdr.Response = true
        dns.MsgHdr.Authoritative = false
        dns.MsgHdr.Id = request.MsgHdr.Id
}

// SetUpdate makes the message a dynamic update packet. It
// sets the ZONE section to: z, TypeSOA, classINET.
func (dns *Msg) SetUpdate(z string) {
        dns.MsgHdr.Id = Id()
        dns.MsgHdr.Opcode = OpcodeUpdate
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeSOA, ClassINET}
}

// SetIxfr creates dns msg suitable for requesting an ixfr.
func (dns *Msg) SetIxfr(z string, serial uint32) {
	dns.MsgHdr.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Ns = make([]RR, 1)
	s := new(RR_SOA)
	s.Hdr = RR_Header{z, TypeSOA, ClassINET, DefaultTTL, 0}
	s.Serial = serial

	dns.Question[0] = Question{z, TypeIXFR, ClassINET}
	dns.Ns[0] = s
}

// SetAxfr creates dns msg suitable for requesting an ixfr.
func (dns *Msg) SetAxfr(z string) {
	dns.MsgHdr.Id = Id()
	dns.Question = make([]Question, 1)
	dns.Question[0] = Question{z, TypeAXFR, ClassINET}
}

// SetTsig appends a TSIG RR to the message.
// This is only a skeleton Tsig RR that added as the last RR in the
// additional section. The caller should then call TsigGenerate,
// to generate the complete TSIG from the secret.
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64) {
	t := new(RR_TSIG)
	t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
	t.Algorithm = algo
	t.Fudge = 300
	t.TimeSigned = timesigned
	dns.Extra = append(dns.Extra, t)
}

// IsRcode checks if the header of the packet has rcode set.
func (dns *Msg) IsRcode(rcode int) (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
        ok = dns.MsgHdr.Rcode == rcode
        return
}

// IsQuestion returns true if the the packet is a question.
func (dns *Msg) IsQuestion() (ok bool) {
        if len(dns.Question) == 0 {
                return false
        }
        ok = dns.MsgHdr.Response == false
        return
}

// IsRcodeFormatError checks if the message has the FormErr set.
func (dns *Msg) IsRcodeFormatError() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
        ok = dns.MsgHdr.Rcode == RcodeFormatError
        return
}

// IsUpdate checks if the message is a dynamic update packet.
func (dns *Msg) IsUpdate() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeUpdate
	ok = ok && dns.Question[0].Qtype == TypeSOA
	return
}

// IsNotify checks if the message is a valid notify packet.
func (dns *Msg) IsNotify() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeNotify
	ok = ok && dns.Question[0].Qclass == ClassINET
	ok = ok && dns.Question[0].Qtype == TypeSOA
	return
}

// IsAxfr checks if the message is a valid axfr request packet.
func (dns *Msg) IsAxfr() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeQuery
	ok = ok && dns.Question[0].Qclass == ClassINET
	ok = ok && dns.Question[0].Qtype == TypeAXFR
	return
}

// IsIXfr checks if the message is a valid ixfr request packet.
func (dns *Msg) IsIxfr() (ok bool) {
	if len(dns.Question) == 0 {
		return false
	}
	ok = dns.MsgHdr.Opcode == OpcodeQuery
	ok = ok && dns.Question[0].Qclass == ClassINET
	ok = ok && dns.Question[0].Qtype == TypeIXFR
	return
}

// IsTsig checks if the message has a TSIG record as the last record
// in the additional section.
func (dns *Msg) IsTsig() (ok bool) {
	if len(dns.Extra) > 0 {
		return dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG
	}
	return
}

// IsDomainName checks if s is a valid domainname.
func IsDomainName(s string) bool { // copied from net package.
	// See RFC 1035, RFC 3696.
	if len(s) == 0 {
		return false
	}
	if len(s) > 255 {
		return false
	}
	if s[len(s)-1] != '.' { // simplify checking loop: make name end in dot
		s += "."
	}

	last := byte('.')
	ok := false // ok once we've seen a letter
	partlen := 0
	for i := 0; i < len(s); i++ {
		c := s[i]
		switch {
		default:
			return false
		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '*':
			ok = true
			partlen++
		case '0' <= c && c <= '9':
			// fine
			partlen++
		case c == '-':
			// byte before dash cannot be dot
			if last == '.' {
				return false
			}
			partlen++
		case c == '.':
			// byte before dot cannot be dot, dash
			if last == '.' || last == '-' {
				return false
			}
			if partlen > 63 || partlen == 0 {
				return false
			}
			partlen = 0
		}
		last = c
	}

	return ok
}

// Return the number of labels in a domain name.
// Need to add these kind of function in a structured way. TODO(mg)
func Labels(a string) (c uint8) {
	// walk the string and count the dots
	// except when it is escaped
	esc := false
	for _, v := range a {
		switch v {
		case '.':
			if esc {
				esc = !esc
				continue
			}
			c++
		case '\\':
			esc = true
		}
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/1lann/beacon/handler"
	"log"
)

type state int

var currentState state

// var lastSet time.Time

const (
	stateInitializing = iota
	stateStopped
	stateIdle
	stateIdling
	stateStarted
	stateStarting
	stateUnavailable
)

func (s state) String() string {
	switch s {
	case stateInitializing:
		return "Intializing"
	case stateStopped:
		return "Stopped"
	case stateIdle:
		return "Idle"
	case stateIdling:
		return "Idling"
	case stateStarted:
		return "Started"
	case stateStarting:
		return "Starting"
	}

	return "Unknown"
}

var connectMessage string

func setState(s state) {
	// if time.Now().Sub(lastSet) < time.Duration(time.Second*2) {
	// 	log.Println("Set state cancelled due to being too fast")
	// }

	// lastSet := time.Now()

	if s != stateStarted && currentState == stateStarted {
		stopForwarder()
		go startBeacon()
	}

	switch s {
	case stateInitializing:
		connectMessage = "Sorry, the server is not ready take requests yet! " +
			"Wait and try again later."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Initializing..."
		handler.CurrentStatus.ShowConnection = false
	case stateStopped:
		connectMessage = "Sorry, the server is down. Try again later."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Down"
		handler.CurrentStatus.ShowConnection = false
	case stateIdling:
		connectMessage = "The server is currently idling. " +
			"You may restart it when it is idle.\n" +
			"Try again in a minute."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Idling..."
		handler.CurrentStatus.ShowConnection = false
	case stateIdle:
		handler.OnConnect = onConnectIdle
		handler.CurrentStatus.Message = "Status: Idle"
		handler.CurrentStatus.ShowConnection = true
	case stateStarting:
		connectMessage = "The server is still starting. Try again in a minute."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Starting..."
		handler.CurrentStatus.ShowConnection = false
	case stateUnavailable:
		connectMessage = "The server is unavailable due to an error. " +
			"Contact the server owner for help."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Unavailable"
		handler.CurrentStatus.ShowConnection = false
	case stateStarted:
		if currentState != stateStarted {
			stopBeacon()
			go startForwarder()
		}
	}

	currentState = s
}

func onConnectMessage(player *handler.Player) string {
	return connectMessage
}

func onConnectIdle(player *handler.Player) string {
	log.Println(player.Username + " has started the server.")
	go restoreServer()
	return "The server is now starting. Come back in 2 minutes."
}
<commit_msg>Add colorful status messages<commit_after>package main

import (
	"github.com/1lann/beacon/chat"
	"github.com/1lann/beacon/handler"
	"log"
)

type state int

var currentState state

// var lastSet time.Time

const (
	stateInitializing = iota
	stateStopped
	stateIdle
	stateIdling
	stateStarted
	stateStarting
	stateUnavailable
)

const prefixText = chat.Aqua + "[Beacon] " + chat.White
const headerText = chat.Aqua + "-- [Beacon] --\n" + chat.White

func (s state) String() string {
	switch s {
	case stateInitializing:
		return "Intializing"
	case stateStopped:
		return "Stopped"
	case stateIdle:
		return "Idle"
	case stateIdling:
		return "Idling"
	case stateStarted:
		return "Started"
	case stateStarting:
		return "Starting"
	}

	return "Unknown"
}

var connectMessage string

func setState(s state) {
	// if time.Now().Sub(lastSet) < time.Duration(time.Second*2) {
	// 	log.Println("Set state cancelled due to being too fast")
	// }

	// lastSet := time.Now()

	if s != stateStarted && currentState == stateStarted {
		stopForwarder()
		go startBeacon()
	}

	switch s {
	case stateInitializing:
		connectMessage = headerText +
			"Sorry, the server is not ready take requests yet! " +
			"Wait and try again later."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = prefixText +
			chat.Yellow + "Initializing..."
		handler.CurrentStatus.ShowConnection = false
	case stateStopped:
		connectMessage = headerText +
			"Sorry, the server is intentionally down.\n" +
			"Contact the server owner for more information."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = prefixText +
			chat.Red + "Intentionally down"
		handler.CurrentStatus.ShowConnection = false
	case stateIdling:
		connectMessage = headerText +
			"Sorry, the server is currently shutting down. " +
			"You may start it again when it is completely turned off.\n" +
			"Try connecting again in a few minutes."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = prefixText + chat.Yellow +
			"Shutting down..."
		handler.CurrentStatus.ShowConnection = false
	case stateIdle:
		handler.OnConnect = onConnectIdle
		handler.CurrentStatus.Message = "Off"
		handler.CurrentStatus.ShowConnection = true
	case stateStarting:
		connectMessage = headerText +
			"Sorry, the server is still starting up. " +
			"Try again in a minute."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = prefixText + chat.LightGreen +
			"Starting up..."
		handler.CurrentStatus.ShowConnection = false
	case stateUnavailable:
		connectMessage = headerText +
			"The server is unavailable due to an error. " +
			"Contact the server owner for help."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = prefixText + chat.Red + "Unavailable"
		handler.CurrentStatus.ShowConnection = false
	case stateStarted:
		if currentState != stateStarted {
			stopBeacon()
			go startForwarder()
		}
	}

	currentState = s
}

func onConnectMessage(player *handler.Player) string {
	return connectMessage
}

func onConnectIdle(player *handler.Player) string {
	log.Println(player.Username + " has started the server.")
	go restoreServer()
	return headerText + "The server is now starting. Come back in 2 minutes."
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/1lann/beacon/handler"
	"log"
)

type state int

var currentState state

// var lastSet time.Time

const (
	stateInitializing = iota
	stateStopped
	stateIdle
	stateIdling
	stateStarted
	stateStarting
	stateUnavailable
)

func (s state) String() string {
	switch s {
	case stateInitializing:
		return "Intializing"
	case stateStopped:
		return "Stopped"
	case stateIdle:
		return "Idle"
	case stateIdling:
		return "Idling"
	case stateStarted:
		return "Started"
	case stateStarting:
		return "Starting"
	}

	return "Unknown"
}

var connectMessage string

func setState(s state) {
	// if time.Now().Sub(lastSet) < time.Duration(time.Second*2) {
	// 	log.Println("Set state cancelled due to being too fast")
	// }

	// lastSet := time.Now()

	if s != stateStarted && currentState == stateStarted {
		stopForwarder()
		go startBeacon()
	}

	switch s {
	case stateInitializing:
		connectMessage = "Sorry, the server is not ready take requests yet! " +
			"Wait and try again later."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Initializing..."
		handler.CurrentStatus.ShowConnection = false
	case stateStopped:
		connectMessage = "Sorry, the server is down. Try again later."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Down"
		handler.CurrentStatus.ShowConnection = false
	case stateIdling:
		connectMessage = "The server is currently idling. " +
			"You may restart it when it is idle.\n" +
			"Try again in a minute."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Idling..."
		handler.CurrentStatus.ShowConnection = false
	case stateIdle:
		handler.OnConnect = onConnectIdle
		handler.CurrentStatus.Message = "Status: Idle"
		handler.CurrentStatus.ShowConnection = true
	case stateStarting:
		connectMessage = "The server is still starting. Try again in a minute."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Starting..."
		handler.CurrentStatus.ShowConnection = false
	case stateUnavailable:
		connectMessage = "The server is unavailable due to an error. " +
			"Contact the server owner for help."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Unavailable"
		handler.CurrentStatus.ShowConnection = false
	case stateStarted:
		if currentState != stateStarted {
			stopBeacon()
			go startForwarder()
		}
	}

	currentState = s
}

func onConnectMessage(player *handler.Player) string {
	return connectMessage
}

func onConnectIdle(player *handler.Player) string {
	log.Println(player.Username + " has started the server.")
	go restoreServer()
	return "The server is now starting. Come back in 2 minutes."
}
<commit_msg>Add delay in switching<commit_after>package main

import (
	"github.com/1lann/beacon/handler"
	"log"
	"time"
)

type state int

var currentState state

// var lastSet time.Time

const (
	stateInitializing = iota
	stateStopped
	stateIdle
	stateIdling
	stateStarted
	stateStarting
	stateUnavailable
)

func (s state) String() string {
	switch s {
	case stateInitializing:
		return "Intializing"
	case stateStopped:
		return "Stopped"
	case stateIdle:
		return "Idle"
	case stateIdling:
		return "Idling"
	case stateStarted:
		return "Started"
	case stateStarting:
		return "Starting"
	}

	return "Unknown"
}

var connectMessage string

func setState(s state) {
	// if time.Now().Sub(lastSet) < time.Duration(time.Second*2) {
	// 	log.Println("Set state cancelled due to being too fast")
	// }

	// lastSet := time.Now()

	if s != stateStarted && currentState == stateStarted {
		stopForwarder()
		time.Sleep(time.Second)
		go startBeacon()
	}

	switch s {
	case stateInitializing:
		connectMessage = "Sorry, the server is not ready take requests yet! " +
			"Wait and try again later."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Initializing..."
		handler.CurrentStatus.ShowConnection = false
	case stateStopped:
		connectMessage = "Sorry, the server is down. Try again later."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Down"
		handler.CurrentStatus.ShowConnection = false
	case stateIdling:
		connectMessage = "The server is currently idling. " +
			"You may restart it when it is idle.\n" +
			"Try again in a minute."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Idling..."
		handler.CurrentStatus.ShowConnection = false
	case stateIdle:
		handler.OnConnect = onConnectIdle
		handler.CurrentStatus.Message = "Status: Idle"
		handler.CurrentStatus.ShowConnection = true
	case stateStarting:
		connectMessage = "The server is still starting. Try again in a minute."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Starting..."
		handler.CurrentStatus.ShowConnection = false
	case stateUnavailable:
		connectMessage = "The server is unavailable due to an error. " +
			"Contact the server owner for help."
		handler.OnConnect = onConnectMessage
		handler.CurrentStatus.Message = "Status: Unavailable"
		handler.CurrentStatus.ShowConnection = false
	case stateStarted:
		if currentState != stateStarted {
			stopBeacon()
			time.Sleep(time.Second)
			go startForwarder()
		}
	}

	currentState = s
}

func onConnectMessage(player *handler.Player) string {
	return connectMessage
}

func onConnectIdle(player *handler.Player) string {
	log.Println(player.Username + " has started the server.")
	go restoreServer()
	return "The server is now starting. Come back in 2 minutes."
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	consul "github.com/hashicorp/consul/api"
)

type discoveryRecord struct {
	name            string
	tag             string
	discoveredHosts []string
}

func NewDiscovery(client *consul.Client, name string, tag string) *discoveryRecord {
	rec := &discoveryRecord{
		name:            name,
		tag:             tag,
		discoveredHosts: []string{},
	}

	discover(client, rec)

	return rec
}

func discover(client *consul.Client, r *discoveryRecord) {
	services, _, err := client.Catalog().Service(r.name, r.tag, nil)
	if err != nil {
		log.Warnf("Couldn't get %s services from consul: %v", r.name, err)
	}

	var hosts []string
	for _, svc := range services {
		host := svc.Address
		port := svc.ServicePort
		location := fmt.Sprintf("%s:%d", host, port)
		hosts = append(hosts, location)
	}
	r.discoveredHosts = hosts
	log.Debugf("Discovered %s service hosts: %v", r.name, r.discoveredHosts)
}
<commit_msg>use node instead of address in discovery<commit_after>package main

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	consul "github.com/hashicorp/consul/api"
)

type discoveryRecord struct {
	name            string
	tag             string
	discoveredHosts []string
}

func NewDiscovery(client *consul.Client, name string, tag string) *discoveryRecord {
	rec := &discoveryRecord{
		name:            name,
		tag:             tag,
		discoveredHosts: []string{},
	}

	discover(client, rec)

	return rec
}

func discover(client *consul.Client, r *discoveryRecord) {
	services, _, err := client.Catalog().Service(r.name, r.tag, nil)
	if err != nil {
		log.Warnf("Couldn't get %s services from consul: %v", r.name, err)
	}

	var hosts []string
	for _, svc := range services {
		host := svc.Node
		port := svc.ServicePort
		location := fmt.Sprintf("%s:%d", host, port)
		hosts = append(hosts, location)
	}
	r.discoveredHosts = hosts
	log.Debugf("Discovered %s service hosts: %v", r.name, r.discoveredHosts)
}
<|endoftext|>


<commit_before>package test

import (
	"bytes"
)

func Fuzz(data []byte) int {
	if len(data) == 2 {
		if data[0] == '!' || data[0] == '#' {
			panic("bingo 0")
		}
		if data[0] == '0' || data[0] == '9' {
			for {
				c := make(chan bool)
				close(c)
			}
		}
		if data[0] == 'a' || data[0] == 'z' {
			data := make([]byte, 128<<30-1)
			_ = data
		}
	}
	if len(data) == 15 && bytes.HasPrefix(data, []byte("0123456789")) {
		x := int(data[10]) + int(data[11]) << 8 + int(data[12]) << 16 + int(data[13]) << 24
		if x == 0 || x == -1 {
			panic("bingo 1")
		}
		if x == 255 || x == 256 {
			for {
				c := make(chan bool)
				close(c)
			}
		}
		if x == 1<<16-1 || x == 1<<16 {
			data := make([]byte, 128<<30-1)
			_ = data
		}
	}
	return 0
}
<commit_msg>work in progress<commit_after>package test

import (
	"bytes"
)

func Fuzz(data []byte) int {
	if len(data) == 2 {
		if data[0] == '!' || data[0] == '#' {
			panic("bingo 0")
		}
		if data[0] == '0' || data[0] == '9' {
			for {
				c := make(chan bool)
				close(c)
			}
		}
		if data[0] == 'a' || data[0] == 'z' {
			data := make([]byte, 128<<30-1)
			_ = data
		}
		if data[0] == 'b' {
			// new coverage
		}
		if data[0] == 'c' {
			// new coverage
		}
	}
	if len(data) == 15 && bytes.HasPrefix(data, []byte("0123456789")) {
		x := int(data[10]) + int(data[11]) << 8 + int(data[12]) << 16 + int(data[13]) << 24
		if x == 0 || x == -1 {
			panic("bingo 1")
		}
		if x == 255 || x == 256 {
			for {
				c := make(chan bool)
				close(c)
			}
		}
		if x == 1<<16-1 || x == 1<<16 {
			data := make([]byte, 128<<30-1)
			_ = data
		}
		if x == '1' {
			// new coverage
		}
		if x == '2' {
			// new coverage
		}
	}
	return 0
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"time"

	"github.com/mattheath/goprotobuf/proto"

	pb "github.com/mattheath/phosphor/proto"
)

const (
	MAX_PACKET_SIZE = 1500 - 8 - 20 // 8-byte UDP header, 20-byte IP header
)

func main() {

	// Make example trace frame
	t := &pb.TraceFrame{
		TraceId:   proto.String("aasldjaskjdlsakjdkasjdklasjdlasjdkljdas"),
		SpanId:    proto.String("8yf8sdg76sg897b98fbuys8b9s6rvs6ducghkfhi27tuw"),
		ParentId:  proto.String("97as8d7s9a7a7dv32hrkqehfkuh23hq8d7h4g7iygs7ih"),
		Type:      pb.FrameType_OUT,
		Timestamp: proto.String(time.Now().UnixNano()),
		Duration:  proto.Int64(1231312),
		Hostname:  proto.String("somehostname"),
		From:      proto.String("some.api"),
		To:        proto.String("some.service"),
		Payload:   proto.String(`{"boop":123}`),
	}

	// Marshal to bytes

	b, err := proto.Marshal(t)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Encoded: %s\n", string(b))
	fmt.Printf("Encoded bytes: %v\n", b)

	// Send via UDP!

	// Get a conn
	c, err := net.DialTimeout("udp", "localhost:7760", time.Second)
	if err != nil {
		panic(err)
	}

	// Write into the connection
	var i int

	for j := 0; j < 20; j++ {
		for i = 0; i < 500; i++ {
			_, err := c.Write([]byte(b))
			if err != nil {
				panic(err)
			}
		}
		time.Sleep(500 * time.Millisecond)
	}

	fmt.Println("Sent", i, "messages")

	// fmt.Println("Sent %v bytes", n)
}
<commit_msg>Update test runner with new proto<commit_after>package main

import (
	"fmt"
	"net"
	"time"

	"github.com/mattheath/goprotobuf/proto"

	pb "github.com/mattheath/phosphor/proto"
)

const (
	MAX_PACKET_SIZE = 1500 - 8 - 20 // 8-byte UDP header, 20-byte IP header
)

func main() {

	// Make example trace frame
	t := &pb.TraceFrame{
		TraceId:     proto.String("aasldjaskjdlsakjdkasjdklasjdlasjdkljdas"),
		SpanId:      proto.String("8yf8sdg76sg897b98fbuys8b9s6rvs6ducghkfhi27tuw"),
		ParentId:    proto.String("97as8d7s9a7a7dv32hrkqehfkuh23hq8d7h4g7iygs7ih"),
		Type:        pb.FrameType_OUT.Enum(),
		Timestamp:   proto.Int64(time.Now().UnixNano()),
		Duration:    proto.Int64(1231312),
		Hostname:    proto.String("somehostname"),
		Origin:      proto.String("some.api"),
		Destination: proto.String("some.service"),
		Payload:     proto.String(`{"boop":123}`),
	}

	// Marshal to bytes

	b, err := proto.Marshal(t)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Encoded: %s\n", string(b))
	fmt.Printf("Encoded bytes: %v\n", b)

	// Send via UDP!

	// Get a conn
	c, err := net.DialTimeout("udp", "localhost:7760", time.Second)
	if err != nil {
		panic(err)
	}

	// Write into the connection
	var i int

	for j := 0; j < 20; j++ {
		for i = 0; i < 500; i++ {
			_, err := c.Write([]byte(b))
			if err != nil {
				panic(err)
			}
		}
		time.Sleep(500 * time.Millisecond)
	}

	fmt.Println("Sent", i, "messages")

	// fmt.Println("Sent %v bytes", n)
}
<|endoftext|>