<commit_before>package thuder

import (
	"regexp"
	"runtime"
	"strings"
	"testing"
)

func TestGenerateUniqueHostname(t *testing.T) {
	u, err := GenerateUniqueHostname()
	if err != nil {
		t.Fatal(err)
	}
	var macpart string
	if runtime.GOOS == "windows" {
		r := regexp.MustCompile("_[0-9A-F]{4}-[0-9A-F]{4}$")
		if !r.MatchString(u) {
			t.Fatal(u, "is not of expected formate")
		}
		s := strings.Split(u, "_")
		macpart = s[len(s)-2]
	}
	t.Log(macpart)
	t.Log(u)
}
<commit_msg>more debug message in test<commit_after>package thuder

import (
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strings"
	"testing"
)

func TestGenerateUniqueHostname(t *testing.T) {
	cmd := exec.Command("lsblk", "-O")
	cmd.Stdout = os.Stdout
	cmd.Run()

	u, err := GenerateUniqueHostname()
	if err != nil {
		t.Fatal(err)
	}
	var macpart string
	if runtime.GOOS == "windows" {
		r := regexp.MustCompile("_[0-9A-F]{4}-[0-9A-F]{4}$")
		if !r.MatchString(u) {
			t.Fatal(u, "is not of expected formate")
		}
		s := strings.Split(u, "_")
		macpart = s[len(s)-2]
	}
	t.Log(macpart)
	t.Log(u)
}
<|endoftext|>


<commit_before>package config_test

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"testing"

	"github.com/fly/config"
)

type testConfig struct {
	Example []string `yaml:"example"`
}

type burritoConfig struct {
	Location string `yaml:"location"`
	Burritos bool   `yaml:"burritos"`
}

// TODO: come up with a way to test homedir without hardcoding travis
const (
	correctEnvVar string = "TESTORG_TESTSYSTEM_CONFIG_URI"
	systemBaseDir string = "/etc/"
	systemDir     string = "/etc/testorg/testsystem/"
	systemPath    string = "/etc/testorg/testsystem/config.yaml"
	userBaseDir   string = "/home/travis/.config/"
	userDir       string = "/home/travis/"
	userPath      string = "/home/travis/.config/testorg/testsystem/config.yaml"
	organization  string = "testorg"
	system        string = "testsystem"
)

const (
	dirMode  os.FileMode = 0755
	fileMode os.FileMode = 0644
)

var cfgNS = config.Namespace{
	Organization: organization,
	System:       system,
}

// In this example our organization is named "podhub", and our project
// namespace is "canary".
//
// In this example we have a file located at /Users/jchen/.config/podhub/canary/config.yaml,
// with the following contents:
//  example:
//    - "a"
//    - "b"
//    - "c"
func ExampleNamespace() {
	var err error
	var cfg testConfig
	var path string

	path = cfgNS.Path()
	fmt.Println("Path to config " + path)

	err = cfgNS.Load(&cfg)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println("Contents of cfg " + fmt.Sprint(cfg))
}

func TestExpandUser(t *testing.T) {
	var path string
	correctPath := userPath

	path = config.ExpandUser("~/.config/fly/config/config.yaml")

	if path != correctPath {
		t.Error("Expected ", correctPath, ", got ", path)
	}

	path = config.ExpandUser("$HOME/.config/fly/config/config.yaml")

	if path != correctPath {
		t.Error("Expected ", correctPath, ", got ", path)
	}
}

func TestLoad(t *testing.T) {
	correctDir := systemDir
	correctPath := systemPath
	var correctCfgText = `location: Señor Sisig
burritos: true`
	var correctCfg = burritoConfig{
		Location: "Señor Sisig",
		Burritos: true,
	}
	var err error
	var cfg burritoConfig

	// Setup
	os.RemoveAll(userPath)
	os.MkdirAll(correctDir, dirMode)
	err = ioutil.WriteFile(correctPath, []byte(correctCfgText), fileMode)
	if err != nil {
		t.Error("Got an error writing ", correctPath, ", got an error: ", err)
	}

	// Test
	err = config.Load(correctPath, &cfg)
	if err != nil {
		t.Error("Got an error: ", err, ", expecting nil")
	}

	if cfg != correctCfg {
		t.Error("Expecting ", correctCfg, ", got ", cfg)
	}

	err = config.Load(correctPath, cfg)
	if err.Error() != "config: not a pointer" {
		t.Error("Expecting error: config: not a pointer, instead got", err)
	}

	err = config.Load("rumpelstilzjchen", &cfg)
	if err == nil {
		t.Error("Expected read error, got nil")
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}
}

func TestUserBase(t *testing.T) {
	if config.UserBase != userBaseDir {
		t.Error("Expecting ", userBaseDir, ", got ", config.UserBase)
	}
}

func TestSystemBase(t *testing.T) {
	if config.SystemBase != systemBaseDir {
		t.Error("Expecting ", systemBaseDir, ", got ", config.SystemBase)
	}
}

func TestNamespacePath(t *testing.T) {
	var err error
	var path string

	correctDir := systemDir
	correctPath := systemPath

	// Setup
	os.RemoveAll(userPath)
	os.MkdirAll(correctDir, dirMode)
	_, err = os.Create(correctPath)
	if err != nil {
		t.Error("Unable to create file ", correctPath, ", got an error: ", err)
	}

	// Test
	path = cfgNS.Path()
	if path != correctPath {
		t.Error("Expecting ", correctPath, ", got ", path)
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}

	// test homedir
	// Setup
	correctDir = userDir
	correctPath = userPath
	os.RemoveAll(systemDir)
	os.MkdirAll(correctDir, dirMode)
	_, err = os.Create(correctPath)
	if err != nil {
		t.Error("Unable to create file ", correctPath, ", got an error: ", err)
	}

	// Test
	path = cfgNS.Path()
	if path != correctPath {
		t.Error("Expecting ", correctPath, ", got ", path)
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}
}

func TestNamespaceEnvVar(t *testing.T) {
	if cfgNS.EnvVar() != envVar {
		t.Error("Expecting ", envVar, ", got ", cfgNS.EnvVar())
	}
}

func TestNamespaceLoad(t *testing.T) {
	correctDir := systemDir
	correctPath := systemPath

	correctCfgText := `location: Señor Sisig
burritos: true`
	correctCfg := configExample{
		Location: "Señor Sisig",
		Burritos: true,
	}
	var err error
	var cfg configExample

	// Setup
	os.RemoveAll(userPath)
	os.MkdirAll(correctDir, dirMode)
	err = ioutil.WriteFile(correctPath, []byte(correctCfgText), fileMode)
	if err != nil {
		t.Error("Got an error writing ", correctPath, ", got an error: ", err)
	}

	// Test
	err = cfgNS.Load(&cfg)
	if err != nil {
		t.Error("Got an error: ", err, ", expecting nil")
	}

	if cfg != correctCfg {
		t.Error("Expecting ", correctCfg, ", got ", cfg)
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}
}
<commit_msg>fix more errors<commit_after>package config_test

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"testing"

	"github.com/fly/config"
)

type testConfig struct {
	Example []string `yaml:"example"`
}

type burritoConfig struct {
	Location string `yaml:"location"`
	Burritos bool   `yaml:"burritos"`
}

// TODO: come up with a way to test homedir without hardcoding travis
const (
	correctEnvVar string = "TESTORG_TESTSYSTEM_CONFIG_URI"
	systemBaseDir string = "/etc/"
	systemDir     string = "/etc/testorg/testsystem/"
	systemPath    string = "/etc/testorg/testsystem/config.yaml"
	userBaseDir   string = "/home/travis/.config/"
	userDir       string = "/home/travis/"
	userPath      string = "/home/travis/.config/testorg/testsystem/config.yaml"
	organization  string = "testorg"
	system        string = "testsystem"
)

const (
	dirMode  os.FileMode = 0755
	fileMode os.FileMode = 0644
)

var cfgNS = config.Namespace{
	Organization: organization,
	System:       system,
}

// In this example our organization is named "testorganization", and our project
// namespace is "testsystem".
//
// In this example we have a file located at
// /Users/jchen/.config/testorganization/testsystem/config.yaml with the
// following contents:
//  example:
//    - "a"
//    - "b"
//    - "c"
func ExampleNamespace() {
	var err error
	var cfg testConfig
	var path string

	path = cfgNS.Path()
	fmt.Println("Path to config " + path)

	err = cfgNS.Load(&cfg)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println("Contents of cfg " + fmt.Sprint(cfg))
}

func TestExpandUser(t *testing.T) {
	var path string
	correctPath := userPath

	path = config.ExpandUser("~/.config/fly/config/config.yaml")

	if path != correctPath {
		t.Error("Expected ", correctPath, ", got ", path)
	}

	path = config.ExpandUser("$HOME/.config/fly/config/config.yaml")

	if path != correctPath {
		t.Error("Expected ", correctPath, ", got ", path)
	}
}

func TestLoad(t *testing.T) {
	correctDir := systemDir
	correctPath := systemPath
	var correctCfgText = `location: Señor Sisig
burritos: true`
	var correctCfg = burritoConfig{
		Location: "Señor Sisig",
		Burritos: true,
	}
	var err error
	var cfg burritoConfig

	// Setup
	os.RemoveAll(userPath)
	os.MkdirAll(correctDir, dirMode)
	err = ioutil.WriteFile(correctPath, []byte(correctCfgText), fileMode)
	if err != nil {
		t.Error("Got an error writing ", correctPath, ", got an error: ", err)
	}

	// Test
	err = config.Load(correctPath, &cfg)
	if err != nil {
		t.Error("Got an error: ", err, ", expecting nil")
	}

	if cfg != correctCfg {
		t.Error("Expecting ", correctCfg, ", got ", cfg)
	}

	err = config.Load(correctPath, cfg)
	if err.Error() != "config: not a pointer" {
		t.Error("Expecting error: config: not a pointer, instead got", err)
	}

	err = config.Load("rumpelstilzjchen", &cfg)
	if err == nil {
		t.Error("Expected read error, got nil")
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}
}

func TestUserBase(t *testing.T) {
	if config.UserBase != userBaseDir {
		t.Error("Expecting ", userBaseDir, ", got ", config.UserBase)
	}
}

func TestSystemBase(t *testing.T) {
	if config.SystemBase != systemBaseDir {
		t.Error("Expecting ", systemBaseDir, ", got ", config.SystemBase)
	}
}

func TestNamespacePath(t *testing.T) {
	var err error
	var path string

	correctDir := systemDir
	correctPath := systemPath

	// Setup
	os.RemoveAll(userPath)
	os.MkdirAll(correctDir, dirMode)
	_, err = os.Create(correctPath)
	if err != nil {
		t.Error("Unable to create file ", correctPath, ", got an error: ", err)
	}

	// Test
	path = cfgNS.Path()
	if path != correctPath {
		t.Error("Expecting ", correctPath, ", got ", path)
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}

	// test homedir
	// Setup
	correctDir = userDir
	correctPath = userPath
	os.RemoveAll(systemDir)
	os.MkdirAll(correctDir, dirMode)
	_, err = os.Create(correctPath)
	if err != nil {
		t.Error("Unable to create file ", correctPath, ", got an error: ", err)
	}

	// Test
	path = cfgNS.Path()
	if path != correctPath {
		t.Error("Expecting ", correctPath, ", got ", path)
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}
}

func TestNamespaceEnvVar(t *testing.T) {
	if cfgNS.EnvVar() != correctEnvVar {
		t.Error("Expecting ", correctEnvVar, ", got ", cfgNS.EnvVar())
	}
}

func TestNamespaceLoad(t *testing.T) {
	correctDir := systemDir
	correctPath := systemPath

	correctCfgText := `location: Señor Sisig
burritos: true`
	correctCfg := burritoConfig{
		Location: "Señor Sisig",
		Burritos: true,
	}
	var err error
	var cfg burritoConfig

	// Setup
	os.RemoveAll(userPath)
	os.MkdirAll(correctDir, dirMode)
	err = ioutil.WriteFile(correctPath, []byte(correctCfgText), fileMode)
	if err != nil {
		t.Error("Got an error writing ", correctPath, ", got an error: ", err)
	}

	// Test
	err = cfgNS.Load(&cfg)
	if err != nil {
		t.Error("Got an error: ", err, ", expecting nil")
	}

	if cfg != correctCfg {
		t.Error("Expecting ", correctCfg, ", got ", cfg)
	}

	// Teardown
	err = os.RemoveAll(correctPath)
	if err != nil {
		t.Error("Unable to remove file ", correctPath,
			" in teardown, got an error: ", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
	"testing"
)

func TestConfig(t *testing.T) {
	c := Config{
		[]Prober{{"http", "http://localhost:4040", 5}},
		[]Notificator{{"pushover", "userdestination", ""},
			{"smtp", "user@example.com", "from@example.com"}},
	}
	b, err := json.MarshalIndent(c, "", "  ")
	if err != nil {
		t.Fatal(err)
	}
	fmt.Println("got")
	fmt.Println(string(b))
	// t.Logf("Got: %v", string(b))
	dec := json.NewDecoder(bytes.NewReader(b))
	var c2 Config
	if err := dec.Decode(&c2); err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(c, c2) {
		t.Fatalf("Config parsing wanted %v, got %v", c, c2)
	}
}

func TestConcreteConfig(t *testing.T) {
	c := Config{
		[]Prober{{"http", "http://localhost:4040", 5}},
		[]Notificator{{"pushover", "userdestination", "fooopushoverkey"}},
	}
	fmt.Printf("Escalator: %+v", c.newEscalator())
	fmt.Printf("Escalator Noti: %+v", c.newEscalator().Notifiers)
}

func TestSMTPAuthParse(t *testing.T) {
	tests := []struct {
		input      string
		user       string
		serverport string
	}{{"nictuku", "nictuku", ""},
		{"nictuku@server", "nictuku", "server"},
		{"nictuku@server:port", "nictuku", "server:port"},
		{"nictuku:password", "nictuku", ""},
		{"nictuku:password@server", "nictuku", "server"},
		{"nictuku:password@server:port", "nictuku", "server:port"},
	}
	for _, test := range tests {
		user, serverport := parseSMTPAuth(test.input)
		if user != test.user {
			t.Errorf("parseSMTPAuth(%v), user = %v; wanted %v", test.input, user, test.user)
		}
		if serverport != test.serverport {
			t.Errorf("parseSMTPAuth(%v), serverport = %v; wanted %v", test.input, serverport, test.serverport)
		}
	}
}
<commit_msg>Remove test cruft<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"reflect"
	"testing"
)

func TestConfig(t *testing.T) {
	c := Config{
		[]Prober{{"http", "http://localhost:4040", 5}},
		[]Notificator{{"pushover", "userdestination", ""},
			{"smtp", "user@example.com", "from@example.com"}},
	}
	b, err := json.MarshalIndent(c, "", "  ")
	if err != nil {
		t.Fatal(err)
	}
	// fmt.Println("TestConfig got")
	// fmt.Println(string(b))
	dec := json.NewDecoder(bytes.NewReader(b))
	var c2 Config
	if err := dec.Decode(&c2); err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(c, c2) {
		t.Fatalf("Config parsing wanted %v, got %v", c, c2)
	}
}

func TestSMTPAuthParse(t *testing.T) {
	tests := []struct {
		input      string
		user       string
		serverport string
	}{{"nictuku", "nictuku", ""},
		{"nictuku@server", "nictuku", "server"},
		{"nictuku@server:port", "nictuku", "server:port"},
		{"nictuku:password", "nictuku", ""},
		{"nictuku:password@server", "nictuku", "server"},
		{"nictuku:password@server:port", "nictuku", "server:port"},
	}
	for _, test := range tests {
		user, serverport := parseSMTPAuth(test.input)
		if user != test.user {
			t.Errorf("parseSMTPAuth(%v), user = %v; wanted %v", test.input, user, test.user)
		}
		if serverport != test.serverport {
			t.Errorf("parseSMTPAuth(%v), serverport = %v; wanted %v", test.input, serverport, test.serverport)
		}
	}
}
<|endoftext|>


<commit_before>package atlas

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"os"
	"path"
	"testing"
)

func TestCheckName(t *testing.T) {
	os.Setenv("HOME", "/home/foo")

	// Check tag usage
	file := "mytag"
	res := checkName(file)
	realPath := path.Join(os.Getenv("HOME"), fmt.Sprintf(".%s", file), "config.toml")
	assert.EqualValues(t, realPath, res, "should be equal")

	// Check fullname usage
	file = "/nonexistent/foobar.toml"
	res = checkName(file)
	assert.EqualValues(t, file, res, "should be equal")

	// Check bad usage
	file = "/toto.yaml"
	res = checkName(file)
	assert.EqualValues(t, "", res, "should be equal")

	file = "/toto.toml"
	res = checkName(file)
	assert.EqualValues(t, file, res, "should be equal")

	file = "toto.yaml"
	res = checkName(file)
	assert.EqualValues(t, "/home/foo/.toto.yaml/config.toml", res, "should be equal")

	// Check plain file
	file = "foo.toml"
	res = checkName(file)
	assert.EqualValues(t, file, res, "should be equal")
}

func TestLoadConfig(t *testing.T) {
	file := "newconfig.toml"
	conf, err := LoadConfig(file)
	assert.NoError(t, err, "no file is no error")

	file = "/config.yaml"
	conf, err = LoadConfig(file)
	assert.Error(t, err, "error")
	assert.EqualValues(t, &Config{}, conf, "empty")

	file = "perms.toml"
	_, err = LoadConfig(file)
	assert.Error(t, err, "no error")

	file = "invalid.toml"
	_, err = LoadConfig(file)
	assert.Error(t, err, "no error")

	file = "./config.toml"
	conf, err = LoadConfig(file)
	assert.NoError(t, err, "no error")

	file = "config.toml"
	conf, err = LoadConfig(file)
	assert.NoError(t, err, "no error")

	defaultProbe := 666
	assert.EqualValues(t, defaultProbe, conf.DefaultProbe, "should be equal")

	key := "<INSERT-API-KEY>"
	assert.EqualValues(t, key, conf.APIKey, "should be equal")

	poolSize := 10
	assert.EqualValues(t, poolSize, conf.PoolSize, "should be equal")
}
<commit_msg>Adjust paths for tests.<commit_after>package atlas

import (
	"github.com/stretchr/testify/assert"
	"path"
	"testing"
)

func TestCheckName(t *testing.T) {
	basedir = "/home/foo"

	// Check tag usage
	file := "mytag"
	res := checkName(file)
	realPath := path.Join(basedir, file, "config.toml")
	assert.EqualValues(t, realPath, res, "should be equal")

	// Check fullname usage
	file = "/nonexistent/foobar.toml"
	res = checkName(file)
	assert.EqualValues(t, file, res, "should be equal")

	// Check bad usage
	file = "/toto.yaml"
	res = checkName(file)
	assert.EqualValues(t, "", res, "should be equal")

	file = "/toto.toml"
	res = checkName(file)
	assert.EqualValues(t, file, res, "should be equal")

	file = "toto.yaml"
	res = checkName(file)
	assert.EqualValues(t, "/home/foo/toto.yaml/config.toml", res, "should be equal")

	// Check plain file
	file = "foo.toml"
	res = checkName(file)
	assert.EqualValues(t, file, res, "should be equal")
}

func TestLoadConfig(t *testing.T) {
	file := "newconfig.toml"
	conf, err := LoadConfig(file)
	assert.NoError(t, err, "no file is no error")

	file = "/config.yaml"
	conf, err = LoadConfig(file)
	assert.Error(t, err, "error")
	assert.EqualValues(t, &Config{}, conf, "empty")

	file = "test/perms.toml"
	_, err = LoadConfig(file)
	assert.Error(t, err, "error")

	file = "test/invalid.toml"
	_, err = LoadConfig(file)
	assert.Error(t, err, "error")

	file = "test/config.toml"
	conf, err = LoadConfig(file)
	assert.NoError(t, err, "no error")

	defaultProbe := 666
	assert.EqualValues(t, defaultProbe, conf.DefaultProbe, "should be equal")

	key := "<INSERT-API-KEY>"
	assert.EqualValues(t, key, conf.APIKey, "should be equal")

	poolSize := 10
	assert.EqualValues(t, poolSize, conf.PoolSize, "should be equal")
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 nmutil

import (
	"encoding/hex"
	"fmt"
	"os"
	"time"
)

var PacketTraceDir string
var traceFile *os.File

// @return                      true if the file can be used;
//                              false otherwise.
func ensureTraceFileOpen() bool {
	if traceFile != nil {
		return true
	}
	if PacketTraceDir == "" {
		return false
	}

	now := time.Now()
	secs := now.Unix()

	filename := fmt.Sprintf("%s/%d", PacketTraceDir, secs)

	var err error
	traceFile, err = os.Create(filename)
	if err != nil {
		return false
	}

	return true
}

func LogIncoming(bytes []byte) {
	if !ensureTraceFileOpen() {
		return
	}

	fmt.Fprintf(traceFile, "Incoming:\n%s\n", hex.Dump(bytes))
}

func LogOutgoing(bytes []byte) {
	if !ensureTraceFileOpen() {
		return
	}

	fmt.Fprintf(traceFile, "Outgoing:\n%s\n", hex.Dump(bytes))
}

func LogMessage(msg string) {

}
<commit_msg>newtmgr - allow message to be logged to trace log.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 nmutil

import (
	"encoding/hex"
	"fmt"
	"os"
	"time"
)

var PacketTraceDir string
var traceFile *os.File

// @return                      true if the file can be used;
//                              false otherwise.
func ensureTraceFileOpen() bool {
	if traceFile != nil {
		return true
	}
	if PacketTraceDir == "" {
		return false
	}

	now := time.Now()
	secs := now.Unix()

	filename := fmt.Sprintf("%s/%d", PacketTraceDir, secs)

	var err error
	traceFile, err = os.Create(filename)
	if err != nil {
		return false
	}

	return true
}

func LogIncoming(bytes []byte) {
	if !ensureTraceFileOpen() {
		return
	}

	fmt.Fprintf(traceFile, "Incoming:\n%s\n", hex.Dump(bytes))
}

func LogOutgoing(bytes []byte) {
	if !ensureTraceFileOpen() {
		return
	}

	fmt.Fprintf(traceFile, "Outgoing:\n%s\n", hex.Dump(bytes))
}

func LogMessage(msg string) {
	fmt.Fprintf(traceFile, "Message: %s\n", msg)
}
<|endoftext|>


<commit_before>package tchannel_test

import (
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	. "github.com/uber/tchannel-go"
	"github.com/uber/tchannel-go/raw"
	"github.com/uber/tchannel-go/testutils"
)

func assertRelaysReleased(t testing.TB, ch *Channel) {
	for _, peerState := range ch.IntrospectState(nil).RootPeers {
		var connStates []ConnectionRuntimeState
		connStates = append(connStates, peerState.InboundConnections...)
		connStates = append(connStates, peerState.OutboundConnections...)
		for _, connState := range connStates {
			n := connState.Relayer.NumItems
			assert.Equal(t, 0, n, "Found %v left-over items in relayer for %v.", n, connState.LocalHostPort)
		}
	}
}

func withRelayedEcho(t testing.TB, f func(relay, server *Channel, client *SubChannel)) {
	relay, err := NewChannel("relay", &ChannelOptions{
		RelayHosts: NewSimpleRelayHosts(map[string][]string{}),
	})
	require.NoError(t, err, "Failed to create a relay channel.")
	defer assertRelaysReleased(t, relay)
	defer relay.Close()
	require.NoError(t, relay.ListenAndServe("127.0.0.1:0"), "Relay failed to listen.")

	server := testutils.NewServer(t, testutils.NewOpts().SetServiceName("test"))
	defer server.Close()
	server.Register(raw.Wrap(newTestHandler(t)), "echo")
	relay.RelayHosts().(*SimpleRelayHosts).Add("test", server.PeerInfo().HostPort)

	client := testutils.NewClient(t, nil)
	defer client.Close()
	client.Peers().Add(relay.PeerInfo().HostPort)
	sc := client.GetSubChannel("test")

	f(relay, server, sc)
}

func TestRelay(t *testing.T) {
	withRelayedEcho(t, func(_, _ *Channel, sc *SubChannel) {
		tests := []struct {
			header string
			body   string
		}{
			{"fake-header", "fake-body"},                        // fits in one frame
			{"fake-header", strings.Repeat("fake-body", 10000)}, // requires continuation
		}
		for _, tt := range tests {
			ctx, cancel := NewContext(time.Second)
			defer cancel()

			arg2, arg3, _, err := raw.CallSC(ctx, sc, "echo", []byte(tt.header), []byte(tt.body))
			require.NoError(t, err, "Relayed call failed.")
			assert.Equal(t, tt.header, string(arg2), "Header was mangled during relay.")
			assert.Equal(t, tt.body, string(arg3), "Body was mangled during relay.")
		}
	})
}

// TODO: Fix races and leaks, then enable.
func DisabledTestRelayHandlesCrashedPeers(t *testing.T) {
	withRelayedEcho(t, func(_, server *Channel, sc *SubChannel) {
		ctx, cancel := NewContext(time.Second)
		defer cancel()

		_, _, _, err := raw.CallSC(ctx, sc, "echo", []byte("fake-header"), []byte("fake-body"))
		require.NoError(t, err, "Relayed call failed.")

		// Simulate a server crash.
		server.Close()
		require.NotPanics(t, func() {
			raw.CallSC(ctx, sc, "echo", []byte("fake-header"), []byte("fake-body"))
		})
	})
}
<commit_msg>Add test for closing connection<commit_after>package tchannel_test

import (
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	. "github.com/uber/tchannel-go"
	"github.com/uber/tchannel-go/raw"
	"github.com/uber/tchannel-go/testutils"
	"github.com/uber/tchannel-go/testutils/goroutines"
)

func assertRelaysReleased(t testing.TB, ch *Channel) {
	for _, peerState := range ch.IntrospectState(nil).RootPeers {
		var connStates []ConnectionRuntimeState
		connStates = append(connStates, peerState.InboundConnections...)
		connStates = append(connStates, peerState.OutboundConnections...)
		for _, connState := range connStates {
			n := connState.Relayer.NumItems
			assert.Equal(t, 0, n, "Found %v left-over items in relayer for %v.", n, connState.LocalHostPort)
		}
	}
}

func withRelayedEcho(t testing.TB, f func(relay, server, client *Channel)) {
	relay, err := NewChannel("relay", &ChannelOptions{
		RelayHosts: NewSimpleRelayHosts(map[string][]string{}),
	})
	require.NoError(t, err, "Failed to create a relay channel.")
	defer assertRelaysReleased(t, relay)
	defer relay.Close()
	require.NoError(t, relay.ListenAndServe("127.0.0.1:0"), "Relay failed to listen.")

	server := testutils.NewServer(t, testutils.NewOpts().SetServiceName("test"))
	defer server.Close()
	server.Register(raw.Wrap(newTestHandler(t)), "echo")
	relay.RelayHosts().(*SimpleRelayHosts).Add("test", server.PeerInfo().HostPort)

	client := testutils.NewServer(t, nil)
	defer client.Close()
	client.Peers().Add(relay.PeerInfo().HostPort)

	f(relay, server, client)
}

func TestRelay(t *testing.T) {
	withRelayedEcho(t, func(_, _, client *Channel) {
		tests := []struct {
			header string
			body   string
		}{
			{"fake-header", "fake-body"},                        // fits in one frame
			{"fake-header", strings.Repeat("fake-body", 10000)}, // requires continuation
		}
		sc := client.GetSubChannel("test")
		for _, tt := range tests {
			ctx, cancel := NewContext(time.Second)
			defer cancel()

			arg2, arg3, _, err := raw.CallSC(ctx, sc, "echo", []byte(tt.header), []byte(tt.body))
			require.NoError(t, err, "Relayed call failed.")
			assert.Equal(t, tt.header, string(arg2), "Header was mangled during relay.")
			assert.Equal(t, tt.body, string(arg3), "Body was mangled during relay.")
		}
	})
}

func DisabledTestRelayHandlesCrashedPeers(t *testing.T) {
	withRelayedEcho(t, func(_, server, client *Channel) {
		ctx, cancel := NewContext(time.Second)
		defer cancel()

		sc := client.GetSubChannel("test")
		_, _, _, err := raw.CallSC(ctx, sc, "echo", []byte("fake-header"), []byte("fake-body"))
		require.NoError(t, err, "Relayed call failed.")

		// Simulate a server crash.
		server.Close()
		require.NotPanics(t, func() {
			raw.CallSC(ctx, sc, "echo", []byte("fake-header"), []byte("fake-body"))
		})
	})
}

func TestRelayConnectionCloseDrainsRelayItems(t *testing.T) {
	withRelayedEcho(t, func(relay, server, client *Channel) {
		ctx, cancel := NewContext(time.Second)
		defer cancel()

		clientHP := client.PeerInfo().HostPort
		testutils.RegisterEcho(server, func() {
			// Handler should close the connection to the relay.
			conn, err := relay.Peers().GetOrAdd(clientHP).GetConnection(ctx)
			require.NoError(t, err, "TODO")
			conn.Close()
		})

		_, _, _, err := raw.CallSC(ctx, client.GetSubChannel("test"), "echo", []byte("fake-header"), []byte("fake-body"))
		require.NoError(t, err, "Relayed call failed.")
	})

	goroutines.VerifyNoLeaks(t, nil)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSNetworkAclRule_basic(t *testing.T) {
	var networkAcl ec2.NetworkAcl

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSNetworkAclRuleDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSNetworkAclRuleBasicConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSNetworkAclRuleExists("aws_network_acl_rule.bar", &networkAcl),
				),
			},
		},
	})
}

func testAccCheckAWSNetworkAclRuleDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ec2conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_network_acl_rule" {
			continue
		}

		rule_number := rs.Primary.Attributes["rule_number"].(int)
		egress := rs.Primary.Attributes["egress"].(bool)

		req := &ec2.DescribeNetworkAclsInput{
			NetworkAclIds: []*string{aws.String(rs.Primary.ID)},
		}
		resp, err := conn.DescribeNetworkAcls(req)
		if err == nil {
			if len(resp.NetworkAcls) > 0 && *resp.NetworkAcls[0].NetworkAclId == rs.Primary.ID {
				networkAcl := resp.NetworkAcls[0]
				if networkAcl.Entries != nil {
					for _, i := range networkAcl.Entries {
						if *i.RuleNumber == int64(rule_number) && *i.Egress == egress {
							return fmt.Errorf("Network ACL Rule (%s) still exists.", rs.Primary.ID)
						}
					}
				}
			}
		}

		ec2err, ok := err.(awserr.Error)
		if !ok {
			return err
		}
		// Confirm error code is what we want
		if ec2err.Code() != "InvalidNetworkAclEntry.NotFound" {
			return err
		}
	}

	return nil
}

func testAccCheckAWSNetworkAclRuleExists(n string, networkAcl *ec2.NetworkAcl) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Security Group is set")
		}

		return nil
	}

	return nil
}

const testAccAWSNetworkAclRuleBasicConfig = `
provider "aws" {
  region = "us-east-1"
}
resource "aws_vpc" "foo" {
	cidr_block = "10.3.0.0/16"
}
resource "aws_network_acl" "bar" {
	vpc_id = "${aws_vpc.foo.id}"
}
resource "aws_network_acl_rule" "bar" {
	network_acl_id = "${aws_network_acl.bar.id}"
	rule_number = 200
	egress = false
	protocol = "tcp"
	rule_action = "allow"
	cidr_block = "0.0.0.0/0"
	from_port = 22
	to_port = 22
}
`
<commit_msg>Adds an acceptance test for the AWS Network ACL Rules<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSNetworkAclRule_basic(t *testing.T) {
	var networkAcl ec2.NetworkAcl

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSNetworkAclRuleDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSNetworkAclRuleBasicConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSNetworkAclRuleExists("aws_network_acl_rule.bar", &networkAcl),
				),
			},
		},
	})
}

func testAccCheckAWSNetworkAclRuleDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ec2conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_network_acl_rule" {
			continue
		}

		req := &ec2.DescribeNetworkAclsInput{
			NetworkAclIds: []*string{aws.String(rs.Primary.ID)},
		}
		resp, err := conn.DescribeNetworkAcls(req)
		if err == nil {
			if len(resp.NetworkAcls) > 0 && *resp.NetworkAcls[0].NetworkAclId == rs.Primary.ID {
				networkAcl := resp.NetworkAcls[0]
				if networkAcl.Entries != nil {
					return fmt.Errorf("Network ACL Entries still exist")
				}
			}
		}

		ec2err, ok := err.(awserr.Error)
		if !ok {
			return err
		}
		if ec2err.Code() != "InvalidNetworkAclEntry.NotFound" {
			return err
		}
	}

	return nil
}

func testAccCheckAWSNetworkAclRuleExists(n string, networkAcl *ec2.NetworkAcl) resource.TestCheckFunc {
	conn := testAccProvider.Meta().(*AWSClient).ec2conn

	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No Network ACL Id is set")
		}

		req := &ec2.DescribeNetworkAclsInput{
			NetworkAclIds: []*string{aws.String(rs.Primary.ID)},
		}
		resp, err := conn.DescribeNetworkAcls(req)
		if err == nil {
			if len(resp.NetworkAcls) > 0 && *resp.NetworkAcls[0].NetworkAclId == rs.Primary.ID {
				networkAcl := resp.NetworkAcls[0]
				if networkAcl.Entries == nil {
					return fmt.Errorf("No Network ACL Entries exist")
				}
			}
		}

		ec2err, ok := err.(awserr.Error)
		if !ok {
			return err
		}
		if ec2err.Code() != "InvalidNetworkAclEntry.NotFound" {
			return err
		}

		return nil
	}

	return nil
}

const testAccAWSNetworkAclRuleBasicConfig = `
provider "aws" {
  region = "us-east-1"
}
resource "aws_vpc" "foo" {
	cidr_block = "10.3.0.0/16"
}
resource "aws_network_acl" "bar" {
	vpc_id = "${aws_vpc.foo.id}"
}
resource "aws_network_acl_rule" "bar" {
	network_acl_id = "${aws_network_acl.bar.id}"
	rule_number = 200
	egress = false
	protocol = "tcp"
	rule_action = "allow"
	cidr_block = "0.0.0.0/0"
	from_port = 22
	to_port = 22
}
`
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/s3"
)

func TestAccAWSS3BucketObject_source(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-source")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	// first write some data to the tempfile just so it's not 0 bytes.
	err = ioutil.WriteFile(tmpFile.Name(), []byte("{anything will do }"), 0644)
	if err != nil {
		t.Fatal(err)
	}
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfigSource(rInt, tmpFile.Name()),
				Check:  testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
			},
		},
	})
}

func TestAccAWSS3BucketObject_content(t *testing.T) {
	rInt := acctest.RandInt()
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				PreConfig: func() {},
				Config:    testAccAWSS3BucketObjectConfigContent(rInt),
				Check:     testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
			},
		},
	})
}

func TestAccAWSS3BucketObject_withContentCharacteristics(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-content-characteristics")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	// first write some data to the tempfile just so it's not 0 bytes.
	err = ioutil.WriteFile(tmpFile.Name(), []byte("{anything will do }"), 0644)
	if err != nil {
		t.Fatal(err)
	}

	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig_withContentCharacteristics(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
					resource.TestCheckResourceAttr(
						"aws_s3_bucket_object.object", "content_type", "binary/octet-stream"),
				),
			},
		},
	})
}

func TestAccAWSS3BucketObject_updates(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-updates")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	err = ioutil.WriteFile(tmpFile.Name(), []byte("initial object state"), 0644)
	if err != nil {
		t.Fatal(err)
	}
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig_updates(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "647d1d58e1011c743ec67d5e8af87b53"),
				),
			},
			resource.TestStep{
				PreConfig: func() {
					err = ioutil.WriteFile(tmpFile.Name(), []byte("modified object"), 0644)
					if err != nil {
						t.Fatal(err)
					}
				},
				Config: testAccAWSS3BucketObjectConfig_updates(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "1c7fd13df1515c2a13ad9eb068931f09"),
				),
			},
		},
	})
}

func TestAccAWSS3BucketObject_updatesWithVersioning(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-updates-w-versions")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	err = ioutil.WriteFile(tmpFile.Name(), []byte("initial versioned object state"), 0644)
	if err != nil {
		t.Fatal(err)
	}

	var originalObj, modifiedObj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig_updatesWithVersioning(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &originalObj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "cee4407fa91906284e2a5e5e03e86b1b"),
				),
			},
			resource.TestStep{
				PreConfig: func() {
					err = ioutil.WriteFile(tmpFile.Name(), []byte("modified versioned object"), 0644)
					if err != nil {
						t.Fatal(err)
					}
				},
				Config: testAccAWSS3BucketObjectConfig_updatesWithVersioning(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &modifiedObj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "00b8c73b1b50e7cc932362c7225b8e29"),
					testAccCheckAWSS3BucketObjectVersionIdDiffers(&originalObj, &modifiedObj),
				),
			},
		},
	})
}

func testAccCheckAWSS3BucketObjectVersionIdDiffers(first, second *s3.GetObjectOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if first.VersionId == nil {
			return fmt.Errorf("Expected first object to have VersionId: %s", first)
		}
		if second.VersionId == nil {
			return fmt.Errorf("Expected second object to have VersionId: %s", second)
		}

		if *first.VersionId == *second.VersionId {
			return fmt.Errorf("Expected Version IDs to differ, but they are equal (%s)", *first.VersionId)
		}

		return nil
	}
}

func testAccCheckAWSS3BucketObjectDestroy(s *terraform.State) error {
	s3conn := testAccProvider.Meta().(*AWSClient).s3conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_s3_bucket_object" {
			continue
		}

		_, err := s3conn.HeadObject(
			&s3.HeadObjectInput{
				Bucket:  aws.String(rs.Primary.Attributes["bucket"]),
				Key:     aws.String(rs.Primary.Attributes["key"]),
				IfMatch: aws.String(rs.Primary.Attributes["etag"]),
			})
		if err == nil {
			return fmt.Errorf("AWS S3 Object still exists: %s", rs.Primary.ID)
		}
	}
	return nil
}

func testAccCheckAWSS3BucketObjectExists(n string, obj *s3.GetObjectOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not Found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No S3 Bucket Object ID is set")
		}

		s3conn := testAccProvider.Meta().(*AWSClient).s3conn
		out, err := s3conn.GetObject(
			&s3.GetObjectInput{
				Bucket:  aws.String(rs.Primary.Attributes["bucket"]),
				Key:     aws.String(rs.Primary.Attributes["key"]),
				IfMatch: aws.String(rs.Primary.Attributes["etag"]),
			})
		if err != nil {
			return fmt.Errorf("S3Bucket Object error: %s", err)
		}

		*obj = *out

		return nil
	}
}

func TestAccAWSS3BucketObject_kms(t *testing.T) {
	rInt := acctest.RandInt()
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				PreConfig: func() {},
				Config:    testAccAWSS3BucketObjectConfig_withKMSId(rInt),
				Check:     testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
			},
		},
	})
}

func testAccAWSS3BucketObjectConfigSource(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket" {
    bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket.bucket}"
	key = "test-key"
	source = "%s"
	content_type = "binary/octet-stream"
}
`, randInt, source)
}

func testAccAWSS3BucketObjectConfig_withContentCharacteristics(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket_2" {
	bucket = "tf-object-test-bucket-%d"
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_2.bucket}"
	key = "test-key"
	source = "%s"
	content_language = "en"
	content_type = "binary/octet-stream"
}
`, randInt, source)
}

func testAccAWSS3BucketObjectConfigContent(randInt int) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket" {
        bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
        bucket = "${aws_s3_bucket.object_bucket.bucket}"
        key = "test-key"
        content = "some_bucket_content"
}
`, randInt)
}

func testAccAWSS3BucketObjectConfig_updates(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket_3" {
	bucket = "tf-object-test-bucket-%d"
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_3.bucket}"
	key = "updateable-key"
	source = "%s"
	etag = "${md5(file("%s"))}"
}
`, randInt, source, source)
}

func testAccAWSS3BucketObjectConfig_updatesWithVersioning(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket_3" {
	bucket = "tf-object-test-bucket-%d"
	versioning {
		enabled = true
	}
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_3.bucket}"
	key = "updateable-key"
	source = "%s"
	etag = "${md5(file("%s"))}"
}
`, randInt, source, source)
}

func testAccAWSS3BucketObjectConfig_withKMSId(randInt int) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "kms_key_1" {
}

resource "aws_s3_bucket" "object_bucket_2" {
	bucket = "tf-object-test-bucket-%d"
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_2.bucket}"
	key = "test-key"
	content = "stuff"
	kms_key_id = "${aws_kms_key.kms_key_1.key_id}"
}
`, randInt)
}
<commit_msg>provider/aws: Use KMS ARN in S3 Bucket test<commit_after>package aws

import (
	"fmt"
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/s3"
)

func TestAccAWSS3BucketObject_source(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-source")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	// first write some data to the tempfile just so it's not 0 bytes.
	err = ioutil.WriteFile(tmpFile.Name(), []byte("{anything will do }"), 0644)
	if err != nil {
		t.Fatal(err)
	}
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfigSource(rInt, tmpFile.Name()),
				Check:  testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
			},
		},
	})
}

func TestAccAWSS3BucketObject_content(t *testing.T) {
	rInt := acctest.RandInt()
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				PreConfig: func() {},
				Config:    testAccAWSS3BucketObjectConfigContent(rInt),
				Check:     testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
			},
		},
	})
}

func TestAccAWSS3BucketObject_withContentCharacteristics(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-content-characteristics")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	// first write some data to the tempfile just so it's not 0 bytes.
	err = ioutil.WriteFile(tmpFile.Name(), []byte("{anything will do }"), 0644)
	if err != nil {
		t.Fatal(err)
	}

	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig_withContentCharacteristics(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
					resource.TestCheckResourceAttr(
						"aws_s3_bucket_object.object", "content_type", "binary/octet-stream"),
				),
			},
		},
	})
}

func TestAccAWSS3BucketObject_updates(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-updates")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	err = ioutil.WriteFile(tmpFile.Name(), []byte("initial object state"), 0644)
	if err != nil {
		t.Fatal(err)
	}
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig_updates(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "647d1d58e1011c743ec67d5e8af87b53"),
				),
			},
			resource.TestStep{
				PreConfig: func() {
					err = ioutil.WriteFile(tmpFile.Name(), []byte("modified object"), 0644)
					if err != nil {
						t.Fatal(err)
					}
				},
				Config: testAccAWSS3BucketObjectConfig_updates(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "1c7fd13df1515c2a13ad9eb068931f09"),
				),
			},
		},
	})
}

func TestAccAWSS3BucketObject_updatesWithVersioning(t *testing.T) {
	tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-updates-w-versions")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpFile.Name())

	rInt := acctest.RandInt()
	err = ioutil.WriteFile(tmpFile.Name(), []byte("initial versioned object state"), 0644)
	if err != nil {
		t.Fatal(err)
	}

	var originalObj, modifiedObj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketObjectConfig_updatesWithVersioning(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &originalObj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "cee4407fa91906284e2a5e5e03e86b1b"),
				),
			},
			resource.TestStep{
				PreConfig: func() {
					err = ioutil.WriteFile(tmpFile.Name(), []byte("modified versioned object"), 0644)
					if err != nil {
						t.Fatal(err)
					}
				},
				Config: testAccAWSS3BucketObjectConfig_updatesWithVersioning(rInt, tmpFile.Name()),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &modifiedObj),
					resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "00b8c73b1b50e7cc932362c7225b8e29"),
					testAccCheckAWSS3BucketObjectVersionIdDiffers(&originalObj, &modifiedObj),
				),
			},
		},
	})
}

func testAccCheckAWSS3BucketObjectVersionIdDiffers(first, second *s3.GetObjectOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		if first.VersionId == nil {
			return fmt.Errorf("Expected first object to have VersionId: %s", first)
		}
		if second.VersionId == nil {
			return fmt.Errorf("Expected second object to have VersionId: %s", second)
		}

		if *first.VersionId == *second.VersionId {
			return fmt.Errorf("Expected Version IDs to differ, but they are equal (%s)", *first.VersionId)
		}

		return nil
	}
}

func testAccCheckAWSS3BucketObjectDestroy(s *terraform.State) error {
	s3conn := testAccProvider.Meta().(*AWSClient).s3conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_s3_bucket_object" {
			continue
		}

		_, err := s3conn.HeadObject(
			&s3.HeadObjectInput{
				Bucket:  aws.String(rs.Primary.Attributes["bucket"]),
				Key:     aws.String(rs.Primary.Attributes["key"]),
				IfMatch: aws.String(rs.Primary.Attributes["etag"]),
			})
		if err == nil {
			return fmt.Errorf("AWS S3 Object still exists: %s", rs.Primary.ID)
		}
	}
	return nil
}

func testAccCheckAWSS3BucketObjectExists(n string, obj *s3.GetObjectOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not Found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No S3 Bucket Object ID is set")
		}

		s3conn := testAccProvider.Meta().(*AWSClient).s3conn
		out, err := s3conn.GetObject(
			&s3.GetObjectInput{
				Bucket:  aws.String(rs.Primary.Attributes["bucket"]),
				Key:     aws.String(rs.Primary.Attributes["key"]),
				IfMatch: aws.String(rs.Primary.Attributes["etag"]),
			})
		if err != nil {
			return fmt.Errorf("S3Bucket Object error: %s", err)
		}

		*obj = *out

		return nil
	}
}

func TestAccAWSS3BucketObject_kms(t *testing.T) {
	rInt := acctest.RandInt()
	var obj s3.GetObjectOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				PreConfig: func() {},
				Config:    testAccAWSS3BucketObjectConfig_withKMSId(rInt),
				Check:     testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
			},
		},
	})
}

func testAccAWSS3BucketObjectConfigSource(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket" {
    bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket.bucket}"
	key = "test-key"
	source = "%s"
	content_type = "binary/octet-stream"
}
`, randInt, source)
}

func testAccAWSS3BucketObjectConfig_withContentCharacteristics(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket_2" {
	bucket = "tf-object-test-bucket-%d"
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_2.bucket}"
	key = "test-key"
	source = "%s"
	content_language = "en"
	content_type = "binary/octet-stream"
}
`, randInt, source)
}

func testAccAWSS3BucketObjectConfigContent(randInt int) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket" {
        bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
        bucket = "${aws_s3_bucket.object_bucket.bucket}"
        key = "test-key"
        content = "some_bucket_content"
}
`, randInt)
}

func testAccAWSS3BucketObjectConfig_updates(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket_3" {
	bucket = "tf-object-test-bucket-%d"
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_3.bucket}"
	key = "updateable-key"
	source = "%s"
	etag = "${md5(file("%s"))}"
}
`, randInt, source, source)
}

func testAccAWSS3BucketObjectConfig_updatesWithVersioning(randInt int, source string) string {
	return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket_3" {
	bucket = "tf-object-test-bucket-%d"
	versioning {
		enabled = true
	}
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_3.bucket}"
	key = "updateable-key"
	source = "%s"
	etag = "${md5(file("%s"))}"
}
`, randInt, source, source)
}

func testAccAWSS3BucketObjectConfig_withKMSId(randInt int) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "kms_key_1" {
}

resource "aws_s3_bucket" "object_bucket_2" {
	bucket = "tf-object-test-bucket-%d"
}

resource "aws_s3_bucket_object" "object" {
	bucket = "${aws_s3_bucket.object_bucket_2.bucket}"
	key = "test-key"
	content = "stuff"
	kms_key_id = "${aws_kms_key.kms_key_1.arn}"
}
`, randInt)
}
<|endoftext|>


<commit_before>package client

import (
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/Sia/types"
)

// MinerHeaderGet uses the /miner/header endpoint to get a header for work.
func (c *Client) MinerHeaderGet() (target types.Target, bh types.BlockHeader, err error) {
	targetAndHeader, err := c.getRawResponse("/miner/header")
	if err != nil {
		return types.Target{}, types.BlockHeader{}, err
	}
	err = encoding.UnmarshalAll(targetAndHeader, &target, &bh)
	return
}

// MinerHeaderPost uses the /miner/header endpoint to submit a solved block
// header that was previously received from the same endpoint
func (c *Client) MinerHeaderPost(bh types.BlockHeader) (err error) {
	err = c.post("/miner/header", string(encoding.Marshal(bh)), nil)
	return
}
<commit_msg>add client wrapper for /miner/start<commit_after>package client

import (
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/Sia/types"
)

// MinerHeaderGet uses the /miner/header endpoint to get a header for work.
func (c *Client) MinerHeaderGet() (target types.Target, bh types.BlockHeader, err error) {
	targetAndHeader, err := c.getRawResponse("/miner/header")
	if err != nil {
		return types.Target{}, types.BlockHeader{}, err
	}
	err = encoding.UnmarshalAll(targetAndHeader, &target, &bh)
	return
}

// MinerHeaderPost uses the /miner/header endpoint to submit a solved block
// header that was previously received from the same endpoint
func (c *Client) MinerHeaderPost(bh types.BlockHeader) (err error) {
	err = c.post("/miner/header", string(encoding.Marshal(bh)), nil)
	return
}

// MinerStartGet uses the /miner/start endpoint to start the cpu miner.
func (c *Client) MinerStartGet() (err error) {
	err = c.get("/miner/start", nil)
	return
}
<|endoftext|>


<commit_before>// Copyright 2013 Chris McGee <sirnewton_01@yahoo.ca>. 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 (
	_ "code.google.com/p/go.tools/cmd/oracle"
	"encoding/json"
	"flag"
	"fmt"
	"go/build"
	"log"
	"net/http"
	"net/http/cgi"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
)

var (
	goroot  = ""
	srcDirs = []string{}
	godev   = flag.Bool("godev", false, "Set the command into GoDev CGI mode")
)

func init() {
	flag.Parse()

	goroot = runtime.GOROOT() + string(os.PathSeparator)

	dirs := build.Default.SrcDirs()

	for i := len(dirs) - 1; i >= 0; i-- {
		srcDir := dirs[i]

		if !strings.HasPrefix(srcDir, goroot) {
			srcDirs = append(srcDirs, srcDir)
		}
	}
}

const (
	SEV_ERR  = "Error"
	SEV_WARN = "Warning"
	SEV_INFO = "Info"
	SEV_CNCL = "Cancel"
	SEV_OK   = "Ok"
)

// Orion Status object
type Status struct {
	// One of SEV_ERR, SEV_WARN, SEV_INFO, SEV_CNCL, SEV_OK
	Severity        string
	HttpCode        uint
	Message         string
	DetailedMessage string
}

// Helper function to write an Orion-compatible error message with an optional error object
func ShowError(writer http.ResponseWriter, httpCode uint, message string, err error) {
	writer.Header().Add("Content-Type", "application/json")
	writer.WriteHeader(int(httpCode))
	errStr := ""
	if err != nil {
		errStr = err.Error()
	}
	status := Status{SEV_ERR, httpCode, message, errStr}
	bytes, err := json.Marshal(status)
	if err != nil {
		panic(err)
	}
	_, err = writer.Write(bytes)
	if err != nil {
		log.Printf("ERROR: %v\n", err)
	}
}

// Helper function to write an Orion-compatible JSON object
func ShowJson(writer http.ResponseWriter, httpCode uint, obj interface{}) {
	writer.Header().Add("Content-Type", "application/json")
	writer.WriteHeader(int(httpCode))

	bytes, err := json.Marshal(obj)
	if err != nil {
		panic(err)
	}
	_, err = writer.Write(bytes)
	if err != nil {
		log.Printf("ERROR %v\n", err)
	}
}

type ImplementsResult struct {
	Implements Implements `json:"implements"`
}

type Implements struct {
	FromPtr []ImplementsType `json:"fromptr,omitempty"`
	To      []ImplementsType `json:"to,omitempty"`
}

type ImplementsType struct {
	Name       string `json:"name"`
	Pos        string `json:"pos"`
	LogicalPos string `json:"logicalPos"`
	Kind       string `json:"kind"`
}

type ReferrersResult struct {
	Referrers Referrers `json:"referrers"`
}

type Referrers struct {
	LogicalRefs []string `json:"logicalRefs"`
	Refs        []string `json:"refs"`
}

type CallersResult struct {
	Callers []Caller `json:"callers"`
}

type Caller struct {
	Desc       string `json:"desc"`
	Pos        string `json:"pos"`
	LogicalPos string `json:"logicalPos"`
}

type PeersResult struct {
	Peers Peers `json:"peers"`
}

type Peers struct {
	LogicalAllocs   []string `json:"logicalAllocs"`
	Allocs          []string `json:"allocs"`
	LogicalReceives []string `json:"logicalReceives"`
	Receives        []string `json:"receives"`
	LogicalSends    []string `json:"logicalSends"`
	Sends           []string `json:"sends"`
}

func getLogicalPos(localPos string) (logicalPos string) {
	for _, path := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
		match := path
		if match[len(match)-1] != filepath.Separator {
			match = match + string(filepath.Separator)
		}

		if strings.HasPrefix(localPos, match) {
			logicalPos = localPos[len(match)-1:]

			if path == filepath.Join(goroot, "/src/pkg") {
				logicalPos = "/GOROOT" + logicalPos
			}

			// Replace any Windows back-slashes into forward slashes
			logicalPos = strings.Replace(logicalPos, "\\", "/", -1)
		}
	}

	if logicalPos == "" {
		logicalPos = localPos
	}

	return logicalPos
}

func main() {
	if *godev == false {
		fmt.Printf("This is a CGI program mean to be plugged into the godev IDE\n")
		return
	}

	req, err := cgi.Request()

	if err != nil {
		fmt.Printf("Error trying to set up the CGI request", err.Error())
		return
	}

	writer := &cgiWriter{file: os.Stdout, wroteHeader: false, header: make(http.Header)}

	if !oracleHandler(writer, req, req.URL.Path, strings.Split(req.URL.Path, "/")[2:]) {
		ShowError(writer, 400, "Request not handled", nil)
	}
}

type cgiWriter struct {
	file        *os.File
	header      http.Header
	wroteHeader bool
}

func (writer *cgiWriter) WriteHeader(status int) {
	if !writer.wroteHeader {
		statusStr := strconv.FormatInt(int64(status), 10)
		writer.file.Write([]byte("Status: " + statusStr + "\r\n"))
		writer.header.Write(writer.file)

		// Final blank line separates the headers from the content
		writer.file.Write([]byte("\r\n"))
	} else {
		fmt.Errorf("Multiple write header calls")
	}
	writer.wroteHeader = true
}

func (writer *cgiWriter) Header() http.Header {
	return writer.header
}

func (writer *cgiWriter) Write(bytes []byte) (n int, err error) {
	if !writer.wroteHeader {
		writer.WriteHeader(http.StatusOK)
	}

	return writer.file.Write(bytes)
}

func oracleHandler(writer http.ResponseWriter, req *http.Request, path string, pathSegs []string) bool {
	switch {
	case req.Method == "GET" && pathSegs[2] == "implements":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "implements", scope)
		output, err := cmd.Output()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		implements := &ImplementsResult{}
		json.Unmarshal(output, implements)

		for idx, _ := range implements.Implements.FromPtr {
			path := getLogicalPos(implements.Implements.FromPtr[idx].Pos)
			implements.Implements.FromPtr[idx].LogicalPos = path
		}

		for idx, _ := range implements.Implements.To {
			path := getLogicalPos(implements.Implements.To[idx].Pos)
			implements.Implements.To[idx].LogicalPos = path
		}

		ShowJson(writer, 200, implements)
		return true
	case req.Method == "GET" && pathSegs[2] == "referrers":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "referrers", scope)
		output, err := cmd.StdoutPipe()
		if err != nil {
			ShowError(writer, 500, "Error opening pipe", err)
			return true
		}
		defer output.Close()
		err = cmd.Start()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		decoder := json.NewDecoder(output)
		referrers := &ReferrersResult{}
		decoder.Decode(referrers)

		cmd.Wait()

		for idx, _ := range referrers.Referrers.Refs {
			path := getLogicalPos(referrers.Referrers.Refs[idx])
			referrers.Referrers.LogicalRefs = append(referrers.Referrers.LogicalRefs, path)
		}

		ShowJson(writer, 200, referrers)
		return true
	case req.Method == "GET" && pathSegs[2] == "callers":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "callers", scope)
		output, err := cmd.StdoutPipe()
		if err != nil {
			ShowError(writer, 500, "Error opening pipe", err)
			return true
		}
		defer output.Close()
		err = cmd.Start()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		decoder := json.NewDecoder(output)
		callers := &CallersResult{}
		decoder.Decode(callers)

		cmd.Wait()

		for idx, _ := range callers.Callers {
			callers.Callers[idx].LogicalPos = getLogicalPos(callers.Callers[idx].Pos)
		}

		ShowJson(writer, 200, callers)
		return true
	case req.Method == "GET" && pathSegs[2] == "peers":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "peers", scope)
		output, err := cmd.StdoutPipe()
		if err != nil {
			ShowError(writer, 500, "Error opening pipe", err)
			return true
		}
		defer output.Close()
		err = cmd.Start()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		decoder := json.NewDecoder(output)
		peers := &PeersResult{}
		decoder.Decode(peers)

		cmd.Wait()

		for idx, _ := range peers.Peers.Allocs {
			path := getLogicalPos(peers.Peers.Allocs[idx])
			peers.Peers.LogicalAllocs = append(peers.Peers.LogicalAllocs, path)
		}

		for idx, _ := range peers.Peers.Sends {
			path := getLogicalPos(peers.Peers.Sends[idx])
			peers.Peers.LogicalSends = append(peers.Peers.LogicalSends, path)
		}

		for idx, _ := range peers.Peers.Receives {
			path := getLogicalPos(peers.Peers.Receives[idx])
			peers.Peers.LogicalReceives = append(peers.Peers.LogicalReceives, path)
		}

		ShowJson(writer, 200, peers)
		return true
	}

	return false
}
<commit_msg>Fix the oracle import.<commit_after>// Copyright 2013 Chris McGee <sirnewton_01@yahoo.ca>. 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 (
	"encoding/json"
	"flag"
	"fmt"
	"go/build"
	"log"
	"net/http"
	"net/http/cgi"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
)

var (
	goroot  = ""
	srcDirs = []string{}
	godev   = flag.Bool("godev", false, "Set the command into GoDev CGI mode")
)

func init() {
	flag.Parse()

	goroot = runtime.GOROOT() + string(os.PathSeparator)

	dirs := build.Default.SrcDirs()

	for i := len(dirs) - 1; i >= 0; i-- {
		srcDir := dirs[i]

		if !strings.HasPrefix(srcDir, goroot) {
			srcDirs = append(srcDirs, srcDir)
		}
	}
}

const (
	SEV_ERR  = "Error"
	SEV_WARN = "Warning"
	SEV_INFO = "Info"
	SEV_CNCL = "Cancel"
	SEV_OK   = "Ok"
)

// Orion Status object
type Status struct {
	// One of SEV_ERR, SEV_WARN, SEV_INFO, SEV_CNCL, SEV_OK
	Severity        string
	HttpCode        uint
	Message         string
	DetailedMessage string
}

// Helper function to write an Orion-compatible error message with an optional error object
func ShowError(writer http.ResponseWriter, httpCode uint, message string, err error) {
	writer.Header().Add("Content-Type", "application/json")
	writer.WriteHeader(int(httpCode))
	errStr := ""
	if err != nil {
		errStr = err.Error()
	}
	status := Status{SEV_ERR, httpCode, message, errStr}
	bytes, err := json.Marshal(status)
	if err != nil {
		panic(err)
	}
	_, err = writer.Write(bytes)
	if err != nil {
		log.Printf("ERROR: %v\n", err)
	}
}

// Helper function to write an Orion-compatible JSON object
func ShowJson(writer http.ResponseWriter, httpCode uint, obj interface{}) {
	writer.Header().Add("Content-Type", "application/json")
	writer.WriteHeader(int(httpCode))

	bytes, err := json.Marshal(obj)
	if err != nil {
		panic(err)
	}
	_, err = writer.Write(bytes)
	if err != nil {
		log.Printf("ERROR %v\n", err)
	}
}

type ImplementsResult struct {
	Implements Implements `json:"implements"`
}

type Implements struct {
	FromPtr []ImplementsType `json:"fromptr,omitempty"`
	To      []ImplementsType `json:"to,omitempty"`
}

type ImplementsType struct {
	Name       string `json:"name"`
	Pos        string `json:"pos"`
	LogicalPos string `json:"logicalPos"`
	Kind       string `json:"kind"`
}

type ReferrersResult struct {
	Referrers Referrers `json:"referrers"`
}

type Referrers struct {
	LogicalRefs []string `json:"logicalRefs"`
	Refs        []string `json:"refs"`
}

type CallersResult struct {
	Callers []Caller `json:"callers"`
}

type Caller struct {
	Desc       string `json:"desc"`
	Pos        string `json:"pos"`
	LogicalPos string `json:"logicalPos"`
}

type PeersResult struct {
	Peers Peers `json:"peers"`
}

type Peers struct {
	LogicalAllocs   []string `json:"logicalAllocs"`
	Allocs          []string `json:"allocs"`
	LogicalReceives []string `json:"logicalReceives"`
	Receives        []string `json:"receives"`
	LogicalSends    []string `json:"logicalSends"`
	Sends           []string `json:"sends"`
}

func getLogicalPos(localPos string) (logicalPos string) {
	for _, path := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
		match := path
		if match[len(match)-1] != filepath.Separator {
			match = match + string(filepath.Separator)
		}

		if strings.HasPrefix(localPos, match) {
			logicalPos = localPos[len(match)-1:]

			if path == filepath.Join(goroot, "/src/pkg") {
				logicalPos = "/GOROOT" + logicalPos
			}

			// Replace any Windows back-slashes into forward slashes
			logicalPos = strings.Replace(logicalPos, "\\", "/", -1)
		}
	}

	if logicalPos == "" {
		logicalPos = localPos
	}

	return logicalPos
}

func main() {
	if *godev == false {
		fmt.Printf("This is a CGI program mean to be plugged into the godev IDE\n")
		return
	}

	req, err := cgi.Request()

	if err != nil {
		fmt.Printf("Error trying to set up the CGI request", err.Error())
		return
	}

	writer := &cgiWriter{file: os.Stdout, wroteHeader: false, header: make(http.Header)}

	if !oracleHandler(writer, req, req.URL.Path, strings.Split(req.URL.Path, "/")[2:]) {
		ShowError(writer, 400, "Request not handled", nil)
	}
}

type cgiWriter struct {
	file        *os.File
	header      http.Header
	wroteHeader bool
}

func (writer *cgiWriter) WriteHeader(status int) {
	if !writer.wroteHeader {
		statusStr := strconv.FormatInt(int64(status), 10)
		writer.file.Write([]byte("Status: " + statusStr + "\r\n"))
		writer.header.Write(writer.file)

		// Final blank line separates the headers from the content
		writer.file.Write([]byte("\r\n"))
	} else {
		fmt.Errorf("Multiple write header calls")
	}
	writer.wroteHeader = true
}

func (writer *cgiWriter) Header() http.Header {
	return writer.header
}

func (writer *cgiWriter) Write(bytes []byte) (n int, err error) {
	if !writer.wroteHeader {
		writer.WriteHeader(http.StatusOK)
	}

	return writer.file.Write(bytes)
}

func oracleHandler(writer http.ResponseWriter, req *http.Request, path string, pathSegs []string) bool {
	switch {
	case req.Method == "GET" && pathSegs[2] == "implements":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "implements", scope)
		output, err := cmd.Output()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		implements := &ImplementsResult{}
		json.Unmarshal(output, implements)

		for idx, _ := range implements.Implements.FromPtr {
			path := getLogicalPos(implements.Implements.FromPtr[idx].Pos)
			implements.Implements.FromPtr[idx].LogicalPos = path
		}

		for idx, _ := range implements.Implements.To {
			path := getLogicalPos(implements.Implements.To[idx].Pos)
			implements.Implements.To[idx].LogicalPos = path
		}

		ShowJson(writer, 200, implements)
		return true
	case req.Method == "GET" && pathSegs[2] == "referrers":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "referrers", scope)
		output, err := cmd.StdoutPipe()
		if err != nil {
			ShowError(writer, 500, "Error opening pipe", err)
			return true
		}
		defer output.Close()
		err = cmd.Start()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		decoder := json.NewDecoder(output)
		referrers := &ReferrersResult{}
		decoder.Decode(referrers)

		cmd.Wait()

		for idx, _ := range referrers.Referrers.Refs {
			path := getLogicalPos(referrers.Referrers.Refs[idx])
			referrers.Referrers.LogicalRefs = append(referrers.Referrers.LogicalRefs, path)
		}

		ShowJson(writer, 200, referrers)
		return true
	case req.Method == "GET" && pathSegs[2] == "callers":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "callers", scope)
		output, err := cmd.StdoutPipe()
		if err != nil {
			ShowError(writer, 500, "Error opening pipe", err)
			return true
		}
		defer output.Close()
		err = cmd.Start()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		decoder := json.NewDecoder(output)
		callers := &CallersResult{}
		decoder.Decode(callers)

		cmd.Wait()

		for idx, _ := range callers.Callers {
			callers.Callers[idx].LogicalPos = getLogicalPos(callers.Callers[idx].Pos)
		}

		ShowJson(writer, 200, callers)
		return true
	case req.Method == "GET" && pathSegs[2] == "peers":
		localFilePath := ""
		pathToMatch := "/" + strings.Join(pathSegs[4:], "/")
		pathToMatch = strings.Replace(pathToMatch, "/GOROOT/", "/", 1)

		for _, srcDir := range append(srcDirs, filepath.Join(goroot, "/src/pkg")) {
			path := filepath.Join(srcDir, pathToMatch)

			_, err := os.Stat(path)

			if err == nil {
				localFilePath = path
				break
			}
		}

		pos := req.URL.Query().Get("pos")
		pos = localFilePath + ":#" + pos

		scope := req.URL.Query().Get("scope")

		cmd := exec.Command("oracle", "-format=json", "-pos="+pos, "peers", scope)
		output, err := cmd.StdoutPipe()
		if err != nil {
			ShowError(writer, 500, "Error opening pipe", err)
			return true
		}
		defer output.Close()
		err = cmd.Start()

		if err != nil {
			if strings.Contains(strings.ToLower(err.Error()), "not found") {
				// Executable was not found, inform the user
				ShowError(writer, 500, "Oracle tool failed or is not installed.", err)
				return true
			}

			// Tool returns no results basically
			writer.WriteHeader(204)
			return true
		}

		decoder := json.NewDecoder(output)
		peers := &PeersResult{}
		decoder.Decode(peers)

		cmd.Wait()

		for idx, _ := range peers.Peers.Allocs {
			path := getLogicalPos(peers.Peers.Allocs[idx])
			peers.Peers.LogicalAllocs = append(peers.Peers.LogicalAllocs, path)
		}

		for idx, _ := range peers.Peers.Sends {
			path := getLogicalPos(peers.Peers.Sends[idx])
			peers.Peers.LogicalSends = append(peers.Peers.LogicalSends, path)
		}

		for idx, _ := range peers.Peers.Receives {
			path := getLogicalPos(peers.Peers.Receives[idx])
			peers.Peers.LogicalReceives = append(peers.Peers.LogicalReceives, path)
		}

		ShowJson(writer, 200, peers)
		return true
	}

	return false
}
<|endoftext|>


<commit_before>package GOsu

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
)

// Game Types which can be accessed via GOsu.<GAMETYPE>.
const (
	OSU   = "0"
	TAIKO = "1"
	CTB   = "2"
	MANIA = "3"
)

// Beatmap Identifier Types for use with GetBeatmaps.
const (
	BEATMAPSET = "s"
	BEATMAPID  = "b"
	USERID     = "u"
)

// Osu Mods which are accessed by the GetMod function.
// iota moves the 'binary 1' to the left.
// e.g. NoFail = 1, Easy = 10 in binary which is 2.
// NoVideo = 100 in binary which is 4.
// This is done in order for any combination of mods to be enabled at once.
const (
	None   = 0
	NoFail = 1 << (iota - 1)
	Easy
	NoVideo
	Hidden
	HardRock
	SuddenDeath
	DoubleTime
	Relax
	HalfTime
	Nightcore
	Flashlight
	Autoplay
	SpunOut
	Relax2
	Perfect
	Key4
	Key5
	Key6
	Key7
	Key8
	FadeIn
	Random
	LastMod
)

var (
	API_URL           string = "https://osu.ppy.sh/api/"
	API_RECENT_PLAYS  string = "get_user_recent"
	API_GET_BEATMAPS  string = "get_beatmaps"
	API_GET_USER      string = "get_user"
	API_GET_SCORES    string = "get_scores"
	API_GET_USER_BEST string = "get_user_best"
	API_GET_MATCH     string = "get_match"
)

type Database struct {
	API_KEY string
}

type Beatmap struct {
	Beatmapset_ID     string
	Beatmap_ID        string
	Approved          string
	Approved_Date     string
	Last_Update       string
	Total_Length      string
	Hit_Length        string
	Version           string
	Artist            string
	Title             string
	Creator           string
	Bpm               string
	Source            string
	Difficulty_Rating string
	Diff_Size         string
	Diff_Overall      string
	Diff_Approach     string
	Diff_Drain        string
	Mode              string
}

type Song struct {
	Beatmap_ID   string
	Score        string
	MaxCombo     string
	Count50      string
	Count100     string
	Count300     string
	CountMiss    string
	CountKatu    string
	CountGeki    string
	Perfect      string
	Enabled_Mods string
	User_ID      string
	Date         string
	Rank         string
}

type User struct {
	User_ID       string
	Username      string
	Count300      string
	Count100      string
	Count50       string
	PlayCount     string
	Ranked_Score  string
	Total_Score   string
	PP_Rank       string
	Level         string
	PP_Raw        string
	Accuracy      string
	Count_Rank_SS string
	Count_Rank_S  string
	Count_Rank_A  string
	Country       string
	Country_Rank  string
	Events        []Event
}

type Event struct {
	Display_HTML  string
	Beatmap_ID    string
	Beatmapset_ID string
	Date          string
	EpicFactor    string
}

type Score struct {
	Score        string
	Username     string
	MaxCombo     string
	Count50      string
	Count100     string
	Count300     string
	CountMiss    string
	CountKatu    string
	CountGeki    string
	Perfect      string
	Enabled_Mods string
	User_ID      string
	Date         string
	Rank         string
	PP           string
}

type PPSong struct {
	Beatmap_ID   string
	Score        string
	MaxCombo     string
	Count50      string
	Count100     string
	Count300     string
	CountMiss    string
	CountKatu    string
	CountGeki    string
	Perfect      string
	Enabled_Mods string
	User_ID      string
	Date         string
	Rank         string
	PP           string
}

type Game struct {
	Match MPMatch
	Games []MPGame
}

type MPMatch struct {
	Match_ID   string
	Name       string
	Start_Time string
	End_Time   string
}

type MPGame struct {
	Game_ID      string
	Start_Time   string
	End_Time     string
	Beatmap_ID   string
	Play_Mode    string
	Match_Type   string
	Scoring_Type string
	Team_Type    string
	Mods         string
	Scores       []MPScore
}

type MPScore struct {
	Slot      string
	Team      string
	User_ID   string
	Score     string
	MaxCombo  string
	Rank      string
	Count50   string
	Count100  string
	Count300  string
	CountMiss string
	CountGeki string
	CountKatu string
	Perfect   string
	Pass      string
}

func (d *Database) SetAPIKey(API_KEY string) error {
	var err error
	if len(API_KEY) <= 1 {
		err = errors.New("API Key: invalid/non-existant API key.")
		return err
	} else {
		d.API_KEY = API_KEY
	}

	return err
}

func (d Database) BuildRecentURL(USER_ID string, GAME_TYPE string) string {
	return API_URL + API_RECENT_PLAYS + "?k=" + d.API_KEY + "&u=" + USER_ID + "&m=" + GAME_TYPE + "&limit=50"
}

func (d Database) BuildBeatmapURL(ID string, TYPE string) string {
	return API_URL + API_GET_BEATMAPS + "?k=" + d.API_KEY + "&" + TYPE + "=" + ID
}

func (d Database) BuildUserURL(USER_ID string, GAME_TYPE string, DAYS string) string {
	return API_URL + API_GET_USER + "?k=" + d.API_KEY + "&u=" + USER_ID + "&m=" + GAME_TYPE + "&event_days=" + DAYS
}

func (d Database) BuildUserBestURL(USER_ID string, GAME_TYPE string) string {
	return API_URL + API_GET_USER_BEST + "?k=" + d.API_KEY + "&u=" + USER_ID + "&m=" + GAME_TYPE
}

func (d Database) BuildScoreURL(BEATMAP_ID string, USER_ID string, GAME_TYPE string) string {
	return API_URL + API_GET_SCORES + "?k=" + d.API_KEY + "&b=" + BEATMAP_ID + "&m=" + GAME_TYPE + "&u=" + USER_ID
}

func (d Database) BuildMatchURL(MATCH_ID string) string {
	return API_URL + API_GET_MATCH + "?k=" + d.API_KEY + "&mp=" + MATCH_ID
}

func RetrieveHTML(URL string) ([]byte, error) {
	res, err := http.Get(URL)

	if err != nil {
		return nil, errors.New("HTTP: Could not open a connection to the Osu! API server.")
	}

	defer res.Body.Close()

	html, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return nil, errors.New("HTML: Could not read the HTML page grabbed.")
	}

	return html, err
}

func (d Database) GetUser(USER_ID string, GAME_TYPE string, DAYS string) ([]User, error) {
	var user []User
	url := d.BuildUserURL(USER_ID, GAME_TYPE, DAYS)
	html, err := RetrieveHTML(url)

	if err != nil {
		return user, err
	}

	err = json.Unmarshal(html, &user)

	if err != nil {
		return user, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return user, err
}

func (d Database) GetBeatmaps(ID string, BM_TYPE string) ([]Beatmap, error) {
	var beatmaps []Beatmap
	url := d.BuildBeatmapURL(ID, BM_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &beatmaps)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return beatmaps, err
}

func (d Database) GetRecentPlays(USER_ID string, GAME_TYPE string) ([]Song, error) {
	var songs []Song
	url := d.BuildRecentURL(USER_ID, GAME_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &songs)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return songs, err
}

func (d Database) GetScores(BEATMAP_ID string, USER_ID string, GAME_TYPE string) ([]Score, error) {
	var scores []Score
	url := d.BuildScoreURL(BEATMAP_ID, USER_ID, GAME_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &scores)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return scores, err
}

func (d Database) GetUserBest(USER_ID string, GAME_TYPE string) ([]PPSong, error) {
	var songs []PPSong
	url := d.BuildUserBestURL(USER_ID, GAME_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &songs)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return songs, err
}

func (d Database) GetMatch(MATCH_ID string) (Game, error) {
	var game Game
	url := d.BuildMatchURL(MATCH_ID)
	html, err := RetrieveHTML(url)

	if err != nil {
		return game, err
	}

	err = json.Unmarshal(html, &game)

	if err != nil {
		return game, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return game, err
}

// ONLY A TEMPORARY FUNCTION.
// Use this function if you are behind a proxy/corporate network and want to work off a local file.
// It will serve as a local HTML file for you to test the website.
func GetLocalPlays(path string) ([]Song, error) {
	var songs []Song

	html, err := ioutil.ReadFile(path)

	if err != nil {
		return nil, errors.New("HTML: Could not read the local HTML page properly.")
	}

	err = json.Unmarshal(html, &songs)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the local HTML page, most likely due to not being in the right format.")
	}

	return songs, err
}

func GetMods(mods int) []string {
	var resultantMods []string

	if mods == 0 {
		resultantMods = append(resultantMods, "None")
		return resultantMods
	}

	AddMod(&resultantMods, &mods, LastMod, "Last Mod")
	AddMod(&resultantMods, &mods, Random, "Random")
	AddMod(&resultantMods, &mods, FadeIn, "Fade In")
	AddMod(&resultantMods, &mods, Key8, "Key 8")
	AddMod(&resultantMods, &mods, Key7, "Key 7")
	AddMod(&resultantMods, &mods, Key6, "Key 6")
	AddMod(&resultantMods, &mods, Key5, "Key 5")
	AddMod(&resultantMods, &mods, Key4, "Key 4")
	AddMod(&resultantMods, &mods, Perfect, "Perfect")
	AddMod(&resultantMods, &mods, Relax2, "Relax 2")
	AddMod(&resultantMods, &mods, SpunOut, "Spun Out")
	AddMod(&resultantMods, &mods, Autoplay, "Autoplay")
	AddMod(&resultantMods, &mods, Flashlight, "Flashlight")
	AddMod(&resultantMods, &mods, Nightcore, "Nightcore")
	AddMod(&resultantMods, &mods, HalfTime, "Half Time")
	AddMod(&resultantMods, &mods, Relax, "Relax")
	AddMod(&resultantMods, &mods, DoubleTime, "Double Time")
	AddMod(&resultantMods, &mods, SuddenDeath, "Sudden Death")
	AddMod(&resultantMods, &mods, HardRock, "Hard Rock")
	AddMod(&resultantMods, &mods, Hidden, "Hidden")
	AddMod(&resultantMods, &mods, NoVideo, "No Video")
	AddMod(&resultantMods, &mods, Easy, "Easy")
	AddMod(&resultantMods, &mods, NoFail, "No Fail")

	return resultantMods
}

func AddMod(array *[]string, remainingMods *int, mod int, modName string) {
	if mod <= *remainingMods {
		*remainingMods -= mod
		*array = append(*array, modName)
	}
}
<commit_msg>Changed naming to be proper.<commit_after>package GOsu

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
)

// Game Types which can be accessed via GOsu.<GAMETYPE>.
const (
	OSU   = "0"
	TAIKO = "1"
	CTB   = "2"
	MANIA = "3"
)

// Beatmap Identifier Types for use with GetBeatmaps.
const (
	BEATMAPSET = "s"
	BEATMAPID  = "b"
	USERID     = "u"
)

// Osu Mods which are accessed by the GetMod function.
// iota moves the 'binary 1' to the left.
// e.g. NoFail = 1, Easy = 10 in binary which is 2.
// NoVideo = 100 in binary which is 4.
// This is done in order for any combination of mods to be enabled at once.
const (
	None   = 0
	NoFail = 1 << (iota - 1)
	Easy
	NoVideo
	Hidden
	HardRock
	SuddenDeath
	DoubleTime
	Relax
	HalfTime
	Nightcore
	Flashlight
	Autoplay
	SpunOut
	Relax2
	Perfect
	Key4
	Key5
	Key6
	Key7
	Key8
	FadeIn
	Random
	LastMod
)

var (
	API_URL           string = "https://osu.ppy.sh/api/"
	API_RECENT_PLAYS  string = "get_user_recent"
	API_GET_BEATMAPS  string = "get_beatmaps"
	API_GET_USER      string = "get_user"
	API_GET_SCORES    string = "get_scores"
	API_GET_USER_BEST string = "get_user_best"
	API_GET_MATCH     string = "get_match"
)

type Database struct {
	API_KEY string
}

type Beatmap struct {
	Beatmapset_ID     string
	Beatmap_ID        string
	Approved          string
	Approved_Date     string
	Last_Update       string
	Total_Length      string
	Hit_Length        string
	Version           string
	Artist            string
	Title             string
	Creator           string
	Bpm               string
	Source            string
	Difficulty_Rating string
	Diff_Size         string
	Diff_Overall      string
	Diff_Approach     string
	Diff_Drain        string
	Mode              string
}

type Song struct {
	Beatmap_ID   string
	Score        string
	MaxCombo     string
	Count50      string
	Count100     string
	Count300     string
	CountMiss    string
	CountKatu    string
	CountGeki    string
	Perfect      string
	Enabled_Mods string
	User_ID      string
	Date         string
	Rank         string
}

type User struct {
	User_ID       string
	Username      string
	Count300      string
	Count100      string
	Count50       string
	PlayCount     string
	Ranked_Score  string
	Total_Score   string
	PP_Rank       string
	Level         string
	PP_Raw        string
	Accuracy      string
	Count_Rank_SS string
	Count_Rank_S  string
	Count_Rank_A  string
	Country       string
	PP_Country_Rank  string
	Events        []Event
}

type Event struct {
	Display_HTML  string
	Beatmap_ID    string
	Beatmapset_ID string
	Date          string
	EpicFactor    string
}

type Score struct {
	Score        string
	Username     string
	MaxCombo     string
	Count50      string
	Count100     string
	Count300     string
	CountMiss    string
	CountKatu    string
	CountGeki    string
	Perfect      string
	Enabled_Mods string
	User_ID      string
	Date         string
	Rank         string
	PP           string
}

type PPSong struct {
	Beatmap_ID   string
	Score        string
	MaxCombo     string
	Count50      string
	Count100     string
	Count300     string
	CountMiss    string
	CountKatu    string
	CountGeki    string
	Perfect      string
	Enabled_Mods string
	User_ID      string
	Date         string
	Rank         string
	PP           string
}

type Game struct {
	Match MPMatch
	Games []MPGame
}

type MPMatch struct {
	Match_ID   string
	Name       string
	Start_Time string
	End_Time   string
}

type MPGame struct {
	Game_ID      string
	Start_Time   string
	End_Time     string
	Beatmap_ID   string
	Play_Mode    string
	Match_Type   string
	Scoring_Type string
	Team_Type    string
	Mods         string
	Scores       []MPScore
}

type MPScore struct {
	Slot      string
	Team      string
	User_ID   string
	Score     string
	MaxCombo  string
	Rank      string
	Count50   string
	Count100  string
	Count300  string
	CountMiss string
	CountGeki string
	CountKatu string
	Perfect   string
	Pass      string
}

func (d *Database) SetAPIKey(API_KEY string) error {
	var err error
	if len(API_KEY) <= 1 {
		err = errors.New("API Key: invalid/non-existant API key.")
		return err
	} else {
		d.API_KEY = API_KEY
	}

	return err
}

func (d Database) BuildRecentURL(USER_ID string, GAME_TYPE string) string {
	return API_URL + API_RECENT_PLAYS + "?k=" + d.API_KEY + "&u=" + USER_ID + "&m=" + GAME_TYPE + "&limit=50"
}

func (d Database) BuildBeatmapURL(ID string, TYPE string) string {
	return API_URL + API_GET_BEATMAPS + "?k=" + d.API_KEY + "&" + TYPE + "=" + ID
}

func (d Database) BuildUserURL(USER_ID string, GAME_TYPE string, DAYS string) string {
	return API_URL + API_GET_USER + "?k=" + d.API_KEY + "&u=" + USER_ID + "&m=" + GAME_TYPE + "&event_days=" + DAYS
}

func (d Database) BuildUserBestURL(USER_ID string, GAME_TYPE string) string {
	return API_URL + API_GET_USER_BEST + "?k=" + d.API_KEY + "&u=" + USER_ID + "&m=" + GAME_TYPE
}

func (d Database) BuildScoreURL(BEATMAP_ID string, USER_ID string, GAME_TYPE string) string {
	return API_URL + API_GET_SCORES + "?k=" + d.API_KEY + "&b=" + BEATMAP_ID + "&m=" + GAME_TYPE + "&u=" + USER_ID
}

func (d Database) BuildMatchURL(MATCH_ID string) string {
	return API_URL + API_GET_MATCH + "?k=" + d.API_KEY + "&mp=" + MATCH_ID
}

func RetrieveHTML(URL string) ([]byte, error) {
	res, err := http.Get(URL)

	if err != nil {
		return nil, errors.New("HTTP: Could not open a connection to the Osu! API server.")
	}

	defer res.Body.Close()

	html, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return nil, errors.New("HTML: Could not read the HTML page grabbed.")
	}

	return html, err
}

func (d Database) GetUser(USER_ID string, GAME_TYPE string, DAYS string) ([]User, error) {
	var user []User
	url := d.BuildUserURL(USER_ID, GAME_TYPE, DAYS)
	html, err := RetrieveHTML(url)

	if err != nil {
		return user, err
	}

	err = json.Unmarshal(html, &user)

	if err != nil {
		return user, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return user, err
}

func (d Database) GetBeatmaps(ID string, BM_TYPE string) ([]Beatmap, error) {
	var beatmaps []Beatmap
	url := d.BuildBeatmapURL(ID, BM_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &beatmaps)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return beatmaps, err
}

func (d Database) GetRecentPlays(USER_ID string, GAME_TYPE string) ([]Song, error) {
	var songs []Song
	url := d.BuildRecentURL(USER_ID, GAME_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &songs)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return songs, err
}

func (d Database) GetScores(BEATMAP_ID string, USER_ID string, GAME_TYPE string) ([]Score, error) {
	var scores []Score
	url := d.BuildScoreURL(BEATMAP_ID, USER_ID, GAME_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &scores)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return scores, err
}

func (d Database) GetUserBest(USER_ID string, GAME_TYPE string) ([]PPSong, error) {
	var songs []PPSong
	url := d.BuildUserBestURL(USER_ID, GAME_TYPE)
	html, err := RetrieveHTML(url)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(html, &songs)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return songs, err
}

func (d Database) GetMatch(MATCH_ID string) (Game, error) {
	var game Game
	url := d.BuildMatchURL(MATCH_ID)
	html, err := RetrieveHTML(url)

	if err != nil {
		return game, err
	}

	err = json.Unmarshal(html, &game)

	if err != nil {
		return game, errors.New("JSON: Couldn't process the HTML into JSON. Possible wrong page/wrong API key/offline server.")
	}

	return game, err
}

// ONLY A TEMPORARY FUNCTION.
// Use this function if you are behind a proxy/corporate network and want to work off a local file.
// It will serve as a local HTML file for you to test the website.
func GetLocalPlays(path string) ([]Song, error) {
	var songs []Song

	html, err := ioutil.ReadFile(path)

	if err != nil {
		return nil, errors.New("HTML: Could not read the local HTML page properly.")
	}

	err = json.Unmarshal(html, &songs)

	if err != nil {
		return nil, errors.New("JSON: Couldn't process the local HTML page, most likely due to not being in the right format.")
	}

	return songs, err
}

func GetMods(mods int) []string {
	var resultantMods []string

	if mods == 0 {
		resultantMods = append(resultantMods, "None")
		return resultantMods
	}

	AddMod(&resultantMods, &mods, LastMod, "Last Mod")
	AddMod(&resultantMods, &mods, Random, "Random")
	AddMod(&resultantMods, &mods, FadeIn, "Fade In")
	AddMod(&resultantMods, &mods, Key8, "Key 8")
	AddMod(&resultantMods, &mods, Key7, "Key 7")
	AddMod(&resultantMods, &mods, Key6, "Key 6")
	AddMod(&resultantMods, &mods, Key5, "Key 5")
	AddMod(&resultantMods, &mods, Key4, "Key 4")
	AddMod(&resultantMods, &mods, Perfect, "Perfect")
	AddMod(&resultantMods, &mods, Relax2, "Relax 2")
	AddMod(&resultantMods, &mods, SpunOut, "Spun Out")
	AddMod(&resultantMods, &mods, Autoplay, "Autoplay")
	AddMod(&resultantMods, &mods, Flashlight, "Flashlight")
	AddMod(&resultantMods, &mods, Nightcore, "Nightcore")
	AddMod(&resultantMods, &mods, HalfTime, "Half Time")
	AddMod(&resultantMods, &mods, Relax, "Relax")
	AddMod(&resultantMods, &mods, DoubleTime, "Double Time")
	AddMod(&resultantMods, &mods, SuddenDeath, "Sudden Death")
	AddMod(&resultantMods, &mods, HardRock, "Hard Rock")
	AddMod(&resultantMods, &mods, Hidden, "Hidden")
	AddMod(&resultantMods, &mods, NoVideo, "No Video")
	AddMod(&resultantMods, &mods, Easy, "Easy")
	AddMod(&resultantMods, &mods, NoFail, "No Fail")

	return resultantMods
}

func AddMod(array *[]string, remainingMods *int, mod int, modName string) {
	if mod <= *remainingMods {
		*remainingMods -= mod
		*array = append(*array, modName)
	}
}
<|endoftext|>