<commit_before>// Copyright (C) 2016 Kale Blankenship. All rights reserved.
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details

package trivialt

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"strings"
)

type opcode uint16

func (o opcode) String() string {
	name, ok := opcodeStrings[o]
	if ok {
		return name
	}
	return fmt.Sprintf("UNKNOWN_OPCODE_%v", uint16(o))
}

// ErrorCode is a TFTP error code as defined in RFC 1350
type ErrorCode uint16

func (e ErrorCode) String() string {
	name, ok := errorStrings[e]
	if ok {
		return name
	}
	return fmt.Sprintf("UNKNOWN_ERROR_%v", uint16(e))
}

const (
	opCodeRRQ   opcode = 0x1 // Read Request
	opCodeWRQ   opcode = 0x2 // Write Request
	opCodeDATA  opcode = 0x3 // Data
	opCodeACK   opcode = 0x4 // Acknowledgement
	opCodeERROR opcode = 0x5 // Error
	opCodeOACK  opcode = 0x6 // Option Acknowledgement

	// ErrCodeNotDefined - Not defined, see error message (if any).
	ErrCodeNotDefined ErrorCode = 0x0
	// ErrCodeFileNotFound - File not found.
	ErrCodeFileNotFound ErrorCode = 0x1
	// ErrCodeAccessViolation - Access violation.
	ErrCodeAccessViolation ErrorCode = 0x2
	// ErrCodeDiskFull - Disk full or allocation exceeded.
	ErrCodeDiskFull ErrorCode = 0x3
	// ErrCodeIllegalOperation - Illegal TFTP operation.
	ErrCodeIllegalOperation ErrorCode = 0x4
	// ErrCodeUnknownTransferID - Unknown transfer ID.
	ErrCodeUnknownTransferID ErrorCode = 0x5
	// ErrCodeFileAlreadyExists - File already exists.
	ErrCodeFileAlreadyExists ErrorCode = 0x6
	// ErrCodeNoSuchUser - No such user.
	ErrCodeNoSuchUser ErrorCode = 0x7

	// ModeNetASCII is the string for netascii transfer mode
	ModeNetASCII TransferMode = "netascii"
	// ModeOctet is the string for octet/binary transfer mode
	ModeOctet TransferMode = "octet"
	modeMail  TransferMode = "mail"

	optBlocksize    = "blksize"
	optTimeout      = "timeout"
	optTransferSize = "tsize"
	optWindowSize   = "windowsize"
)

// TransferMode is a TFTP transer mode
type TransferMode string

var (
	errorStrings = map[ErrorCode]string{
		ErrCodeNotDefined:        "NOT_DEFINED",
		ErrCodeFileNotFound:      "FILE_NOT_FOUND",
		ErrCodeAccessViolation:   "ACCESS_VIOLATION",
		ErrCodeDiskFull:          "DISK_FULL",
		ErrCodeIllegalOperation:  "ILLEGAL_OPERATION",
		ErrCodeUnknownTransferID: "UNKNOWN_TRANSFER_ID",
		ErrCodeFileAlreadyExists: "FILE_ALREADY_EXISTS",
		ErrCodeNoSuchUser:        "NO_SUCH_USER",
	}
	opcodeStrings = map[opcode]string{
		opCodeRRQ:   "READ_REQUEST",
		opCodeWRQ:   "WRITE_REQUEST",
		opCodeDATA:  "DATA",
		opCodeACK:   "ACK",
		opCodeERROR: "ERROR",
		opCodeOACK:  "OPTION_ACK",
	}
)

type datagram struct {
	buf    []byte
	offset int
}

func (d datagram) String() string {
	if err := d.validate(); err != nil {
		return fmt.Sprintf("INVALID_DATAGRAM[Error: %q]", err.Error())
	}

	switch o := d.opcode(); o {
	case opCodeRRQ, opCodeWRQ:
		return fmt.Sprintf("%s[Filename: %q; Mode: %q; Options: %s]", o, d.filename(), d.mode(), d.options())
	case opCodeDATA:
		return fmt.Sprintf("%s[Block: %d; Data Length: %d]", o, d.block(), len(d.data()))
	case opCodeOACK:
		return fmt.Sprintf("%s[Options: %s]", o, d.options())
	case opCodeACK:
		return fmt.Sprintf("%s[Block: %d]", o, d.block())
	case opCodeERROR:
		return fmt.Sprintf("%s[Code: %s; Message: %q]", o, d.errorCode(), d.errMsg())
	default:
		return o.String()
	}
}

// Sets the buffer from raw bytes
func (d *datagram) setBytes(b []byte) {
	d.buf = b
	d.offset = len(b)
}

// Returns the allocated bytes
func (d *datagram) bytes() []byte {
	return d.buf[:d.offset]
}

// Resets the byte buffer.
// If requested size is larger than allocated the buffer is reallocated.
func (d *datagram) reset(size int) {
	if len(d.buf) < size {
		d.buf = make([]byte, size)
	}
	d.offset = 0
}

// DATAGRAM CONSTRUCTORS
func (d *datagram) writeAck(block uint16) {
	d.reset(2 + 2)

	d.writeUint16(uint16(opCodeACK))
	d.writeUint16(block)
}

func (d *datagram) writeData(block uint16, data []byte) {
	d.reset(2 + 2 + len(data))

	d.writeUint16(uint16(opCodeDATA))
	d.writeUint16(block)
	d.writeBytes(data)
}

func (d *datagram) writeError(code ErrorCode, msg string) {
	d.reset(2 + 2 + len(msg) + 1)

	d.writeUint16(uint16(opCodeERROR))
	d.writeUint16(uint16(code))
	d.writeString(msg)
	d.writeNull()
}

func (d *datagram) writeReadReq(filename string, mode TransferMode, options map[string]string) {
	d.writeReq(opCodeRRQ, filename, mode, options)
}

func (d *datagram) writeWriteReq(filename string, mode TransferMode, options map[string]string) {
	d.writeReq(opCodeWRQ, filename, mode, options)
}

func (d *datagram) writeOptionAck(options map[string]string) {
	optLen := 0
	for opt, val := range options {
		optLen += len(opt) + 1 + len(val) + 1
	}
	d.reset(2 + optLen)

	d.writeUint16(uint16(opCodeOACK))

	for opt, val := range options {
		d.writeOption(opt, val)
	}
}

// Combines duplicate logic from RRQ and WRQ
func (d *datagram) writeReq(o opcode, filename string, mode TransferMode, options map[string]string) {
	// This is ugly, could just set buf to 512
	// or use a bytes buffer. Intend to switch to bytes buffer
	// after implementing all RFCs so that perf can be compared
	// with a reasonable block and window size
	optLen := 0
	for opt, val := range options {
		optLen += len(opt) + 1 + len(val) + 1
	}
	d.reset(2 + len(filename) + 1 + len(mode) + 1 + optLen)

	d.writeUint16(uint16(o))
	d.writeString(filename)
	d.writeNull()
	d.writeString(string(mode))
	d.writeNull()

	for opt, val := range options {
		d.writeOption(opt, val)
	}
}

// FIELD ACCESSORS

// Block # from DATA and ACK datagrams
func (d *datagram) block() uint16 {
	return binary.BigEndian.Uint16(d.buf[2:4])
}

// Data from DATA datagram
func (d *datagram) data() []byte {
	return d.buf[4:d.offset]
}

// ErrorCode from ERROR datagram
func (d *datagram) errorCode() ErrorCode {
	return ErrorCode(binary.BigEndian.Uint16(d.buf[2:4]))
}

// ErrMsg from ERROR datagram
func (d *datagram) errMsg() string {
	end := d.offset - 1
	return string(d.buf[4:end])
}

// Filename from RRQ and WRQ datagrams
func (d *datagram) filename() string {
	offset := bytes.IndexByte(d.buf[2:], 0x0) + 2
	return string(d.buf[2:offset])
}

// Mode from RRQ and WRQ datagrams
func (d *datagram) mode() TransferMode {
	fields := bytes.Split(d.buf[2:], []byte{0x0})
	return TransferMode(fields[1])
}

// Opcode from all datagrams
func (d *datagram) opcode() opcode {
	return opcode(binary.BigEndian.Uint16(d.buf[:2]))
}

type options map[string]string

func (o options) String() string {
	opts := make([]string, 0, len(o))
	for k, v := range o {
		opts = append(opts, fmt.Sprintf("%q: %q", k, v))
	}

	return "{" + strings.Join(opts, "; ") + "}"
}

func (d *datagram) options() options {
	options := make(options)

	optSlice := bytes.Split(d.buf[2:d.offset-1], []byte{0x0}) // d.buf[2:d.offset-1] = file -> just before final NULL
	if op := d.opcode(); op == opCodeRRQ || op == opCodeWRQ {
		optSlice = optSlice[2:] // Remove filename, mode
	}

	for i := 0; i < len(optSlice); i += 2 {
		options[string(optSlice[i])] = string(optSlice[i+1])
	}
	return options
}

// BUFFER WRITING FUNCTIONS
func (d *datagram) writeBytes(b []byte) {
	copy(d.buf[d.offset:], b)
	d.offset += len(b)
}

func (d *datagram) writeNull() {
	d.buf[d.offset] = 0x0
	d.offset++
}

func (d *datagram) writeString(str string) {
	d.writeBytes([]byte(str))
}

func (d *datagram) writeUint16(i uint16) {
	binary.BigEndian.PutUint16(d.buf[d.offset:], i)
	d.offset += 2
}

func (d *datagram) writeOption(o string, v string) {
	d.writeString(o)
	d.writeNull()
	d.writeString(v)
	d.writeNull()
}

// VALIDATION

func (d *datagram) validate() (err error) {
	switch {
	case d.offset < 2:
		err = errors.New("Datagram has no opcode")
	case d.opcode() > 6:
		err = errors.New("Invalid opcode")
	default:
		switch d.opcode() {
		case opCodeRRQ, opCodeWRQ:
			switch {
			case len(d.filename()) < 1:
				err = errors.New("No filename provided")
			case d.buf[d.offset-1] != 0x0: // End with NULL
				err = fmt.Errorf("Corrupt %v datagram", d.opcode())
			case bytes.Count(d.buf[2:d.offset], []byte{0x0})%2 != 0: // Number of NULL chars is not even
				err = fmt.Errorf("Corrupt %v datagram", d.opcode())
			default:
				switch d.mode() {
				case ModeNetASCII, ModeOctet:
					break
				case modeMail:
					err = errors.New("MAIL transfer mode is unsupported")
				default:
					err = errors.New("Invalid transfer mode")
				}
			}
		case opCodeACK, opCodeDATA:
			if d.offset < 4 {
				err = errors.New("Corrupt block number")
			}
		case opCodeERROR:
			switch {
			case d.offset < 5:
				err = errors.New("Corrupt ERROR datagram")
			case d.buf[d.offset-1] != 0x0:
				err = errors.New("Corrupt ERROR datagram")
			case bytes.Count(d.buf[4:d.offset], []byte{0x0}) > 1:
				err = errors.New("Corrupt ERROR datagram")
			}
		case opCodeOACK:
			switch {
			case d.buf[d.offset-1] != 0x0:
				err = errors.New("Corrupt OACK datagram")
			case bytes.Count(d.buf[2:d.offset], []byte{0x0})%2 != 0: // Number of NULL chars is not even
				err = errors.New("Corrupt OACK datagram")
			}
		}
	}
	return
}
<commit_msg>Improve dg.validate() readability<commit_after>// Copyright (C) 2016 Kale Blankenship. All rights reserved.
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details

package trivialt

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"strings"
)

type opcode uint16

func (o opcode) String() string {
	name, ok := opcodeStrings[o]
	if ok {
		return name
	}
	return fmt.Sprintf("UNKNOWN_OPCODE_%v", uint16(o))
}

// ErrorCode is a TFTP error code as defined in RFC 1350
type ErrorCode uint16

func (e ErrorCode) String() string {
	name, ok := errorStrings[e]
	if ok {
		return name
	}
	return fmt.Sprintf("UNKNOWN_ERROR_%v", uint16(e))
}

const (
	opCodeRRQ   opcode = 0x1 // Read Request
	opCodeWRQ   opcode = 0x2 // Write Request
	opCodeDATA  opcode = 0x3 // Data
	opCodeACK   opcode = 0x4 // Acknowledgement
	opCodeERROR opcode = 0x5 // Error
	opCodeOACK  opcode = 0x6 // Option Acknowledgement

	// ErrCodeNotDefined - Not defined, see error message (if any).
	ErrCodeNotDefined ErrorCode = 0x0
	// ErrCodeFileNotFound - File not found.
	ErrCodeFileNotFound ErrorCode = 0x1
	// ErrCodeAccessViolation - Access violation.
	ErrCodeAccessViolation ErrorCode = 0x2
	// ErrCodeDiskFull - Disk full or allocation exceeded.
	ErrCodeDiskFull ErrorCode = 0x3
	// ErrCodeIllegalOperation - Illegal TFTP operation.
	ErrCodeIllegalOperation ErrorCode = 0x4
	// ErrCodeUnknownTransferID - Unknown transfer ID.
	ErrCodeUnknownTransferID ErrorCode = 0x5
	// ErrCodeFileAlreadyExists - File already exists.
	ErrCodeFileAlreadyExists ErrorCode = 0x6
	// ErrCodeNoSuchUser - No such user.
	ErrCodeNoSuchUser ErrorCode = 0x7

	// ModeNetASCII is the string for netascii transfer mode
	ModeNetASCII TransferMode = "netascii"
	// ModeOctet is the string for octet/binary transfer mode
	ModeOctet TransferMode = "octet"
	modeMail  TransferMode = "mail"

	optBlocksize    = "blksize"
	optTimeout      = "timeout"
	optTransferSize = "tsize"
	optWindowSize   = "windowsize"
)

// TransferMode is a TFTP transer mode
type TransferMode string

var (
	errorStrings = map[ErrorCode]string{
		ErrCodeNotDefined:        "NOT_DEFINED",
		ErrCodeFileNotFound:      "FILE_NOT_FOUND",
		ErrCodeAccessViolation:   "ACCESS_VIOLATION",
		ErrCodeDiskFull:          "DISK_FULL",
		ErrCodeIllegalOperation:  "ILLEGAL_OPERATION",
		ErrCodeUnknownTransferID: "UNKNOWN_TRANSFER_ID",
		ErrCodeFileAlreadyExists: "FILE_ALREADY_EXISTS",
		ErrCodeNoSuchUser:        "NO_SUCH_USER",
	}
	opcodeStrings = map[opcode]string{
		opCodeRRQ:   "READ_REQUEST",
		opCodeWRQ:   "WRITE_REQUEST",
		opCodeDATA:  "DATA",
		opCodeACK:   "ACK",
		opCodeERROR: "ERROR",
		opCodeOACK:  "OPTION_ACK",
	}
)

type datagram struct {
	buf    []byte
	offset int
}

func (d datagram) String() string {
	if err := d.validate(); err != nil {
		return fmt.Sprintf("INVALID_DATAGRAM[Error: %q]", err.Error())
	}

	switch o := d.opcode(); o {
	case opCodeRRQ, opCodeWRQ:
		return fmt.Sprintf("%s[Filename: %q; Mode: %q; Options: %s]", o, d.filename(), d.mode(), d.options())
	case opCodeDATA:
		return fmt.Sprintf("%s[Block: %d; Data Length: %d]", o, d.block(), len(d.data()))
	case opCodeOACK:
		return fmt.Sprintf("%s[Options: %s]", o, d.options())
	case opCodeACK:
		return fmt.Sprintf("%s[Block: %d]", o, d.block())
	case opCodeERROR:
		return fmt.Sprintf("%s[Code: %s; Message: %q]", o, d.errorCode(), d.errMsg())
	default:
		return o.String()
	}
}

// Sets the buffer from raw bytes
func (d *datagram) setBytes(b []byte) {
	d.buf = b
	d.offset = len(b)
}

// Returns the allocated bytes
func (d *datagram) bytes() []byte {
	return d.buf[:d.offset]
}

// Resets the byte buffer.
// If requested size is larger than allocated the buffer is reallocated.
func (d *datagram) reset(size int) {
	if len(d.buf) < size {
		d.buf = make([]byte, size)
	}
	d.offset = 0
}

// DATAGRAM CONSTRUCTORS
func (d *datagram) writeAck(block uint16) {
	d.reset(2 + 2)

	d.writeUint16(uint16(opCodeACK))
	d.writeUint16(block)
}

func (d *datagram) writeData(block uint16, data []byte) {
	d.reset(2 + 2 + len(data))

	d.writeUint16(uint16(opCodeDATA))
	d.writeUint16(block)
	d.writeBytes(data)
}

func (d *datagram) writeError(code ErrorCode, msg string) {
	d.reset(2 + 2 + len(msg) + 1)

	d.writeUint16(uint16(opCodeERROR))
	d.writeUint16(uint16(code))
	d.writeString(msg)
	d.writeNull()
}

func (d *datagram) writeReadReq(filename string, mode TransferMode, options map[string]string) {
	d.writeReq(opCodeRRQ, filename, mode, options)
}

func (d *datagram) writeWriteReq(filename string, mode TransferMode, options map[string]string) {
	d.writeReq(opCodeWRQ, filename, mode, options)
}

func (d *datagram) writeOptionAck(options map[string]string) {
	optLen := 0
	for opt, val := range options {
		optLen += len(opt) + 1 + len(val) + 1
	}
	d.reset(2 + optLen)

	d.writeUint16(uint16(opCodeOACK))

	for opt, val := range options {
		d.writeOption(opt, val)
	}
}

// Combines duplicate logic from RRQ and WRQ
func (d *datagram) writeReq(o opcode, filename string, mode TransferMode, options map[string]string) {
	// This is ugly, could just set buf to 512
	// or use a bytes buffer. Intend to switch to bytes buffer
	// after implementing all RFCs so that perf can be compared
	// with a reasonable block and window size
	optLen := 0
	for opt, val := range options {
		optLen += len(opt) + 1 + len(val) + 1
	}
	d.reset(2 + len(filename) + 1 + len(mode) + 1 + optLen)

	d.writeUint16(uint16(o))
	d.writeString(filename)
	d.writeNull()
	d.writeString(string(mode))
	d.writeNull()

	for opt, val := range options {
		d.writeOption(opt, val)
	}
}

// FIELD ACCESSORS

// Block # from DATA and ACK datagrams
func (d *datagram) block() uint16 {
	return binary.BigEndian.Uint16(d.buf[2:4])
}

// Data from DATA datagram
func (d *datagram) data() []byte {
	return d.buf[4:d.offset]
}

// ErrorCode from ERROR datagram
func (d *datagram) errorCode() ErrorCode {
	return ErrorCode(binary.BigEndian.Uint16(d.buf[2:4]))
}

// ErrMsg from ERROR datagram
func (d *datagram) errMsg() string {
	end := d.offset - 1
	return string(d.buf[4:end])
}

// Filename from RRQ and WRQ datagrams
func (d *datagram) filename() string {
	offset := bytes.IndexByte(d.buf[2:], 0x0) + 2
	return string(d.buf[2:offset])
}

// Mode from RRQ and WRQ datagrams
func (d *datagram) mode() TransferMode {
	fields := bytes.Split(d.buf[2:], []byte{0x0})
	return TransferMode(fields[1])
}

// Opcode from all datagrams
func (d *datagram) opcode() opcode {
	return opcode(binary.BigEndian.Uint16(d.buf[:2]))
}

type options map[string]string

func (o options) String() string {
	opts := make([]string, 0, len(o))
	for k, v := range o {
		opts = append(opts, fmt.Sprintf("%q: %q", k, v))
	}

	return "{" + strings.Join(opts, "; ") + "}"
}

func (d *datagram) options() options {
	options := make(options)

	optSlice := bytes.Split(d.buf[2:d.offset-1], []byte{0x0}) // d.buf[2:d.offset-1] = file -> just before final NULL
	if op := d.opcode(); op == opCodeRRQ || op == opCodeWRQ {
		optSlice = optSlice[2:] // Remove filename, mode
	}

	for i := 0; i < len(optSlice); i += 2 {
		options[string(optSlice[i])] = string(optSlice[i+1])
	}
	return options
}

// BUFFER WRITING FUNCTIONS
func (d *datagram) writeBytes(b []byte) {
	copy(d.buf[d.offset:], b)
	d.offset += len(b)
}

func (d *datagram) writeNull() {
	d.buf[d.offset] = 0x0
	d.offset++
}

func (d *datagram) writeString(str string) {
	d.writeBytes([]byte(str))
}

func (d *datagram) writeUint16(i uint16) {
	binary.BigEndian.PutUint16(d.buf[d.offset:], i)
	d.offset += 2
}

func (d *datagram) writeOption(o string, v string) {
	d.writeString(o)
	d.writeNull()
	d.writeString(v)
	d.writeNull()
}

// VALIDATION

func (d *datagram) validate() error {
	switch {
	case d.offset < 2:
		return errors.New("Datagram has no opcode")
	case d.opcode() > 6:
		return errors.New("Invalid opcode")
	}

	switch d.opcode() {
	case opCodeRRQ, opCodeWRQ:
		switch {
		case len(d.filename()) < 1:
			return errors.New("No filename provided")
		case d.buf[d.offset-1] != 0x0: // End with NULL
			return fmt.Errorf("Corrupt %v datagram", d.opcode())
		case bytes.Count(d.buf[2:d.offset], []byte{0x0})%2 != 0: // Number of NULL chars is not even
			return fmt.Errorf("Corrupt %v datagram", d.opcode())
		default:
			switch d.mode() {
			case ModeNetASCII, ModeOctet:
				break
			case modeMail:
				return errors.New("MAIL transfer mode is unsupported")
			default:
				return errors.New("Invalid transfer mode")
			}
		}
	case opCodeACK, opCodeDATA:
		if d.offset < 4 {
			return errors.New("Corrupt block number")
		}
	case opCodeERROR:
		switch {
		case d.offset < 5:
			return errors.New("Corrupt ERROR datagram")
		case d.buf[d.offset-1] != 0x0:
			return errors.New("Corrupt ERROR datagram")
		case bytes.Count(d.buf[4:d.offset], []byte{0x0}) > 1:
			return errors.New("Corrupt ERROR datagram")
		}
	case opCodeOACK:
		switch {
		case d.buf[d.offset-1] != 0x0:
			return errors.New("Corrupt OACK datagram")
		case bytes.Count(d.buf[2:d.offset], []byte{0x0})%2 != 0: // Number of NULL chars is not even
			return errors.New("Corrupt OACK datagram")
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"path"
	"strings"
	"unicode"
)

const settingsFileName = "cfsubmit_settings.json"

var (
	contestId string
	problemId string
	langId    string
)

var (
	errNoSubmission    = errors.New("Submission file not specified")
	errUnkownExt       = errors.New("Unknown extension")
	errUnknownFilename = errors.New("Unknown filename format. Example: 123a.cpp")
)

var CFAuthData struct {
	XUser    string            `json:"X-User"`
	CSRF     string            `json:"CSRF-Token"`
	ExtId    map[string]string `json:"Ext-ID"`
	CFDomain string            `json:"CF-Domain"`
}

func init() {
	//load settings from json
	if jsonData, err := os.Open(settingsFileName); err != nil {
		log.Fatal(err)
	} else {
		if err := json.NewDecoder(jsonData).Decode(&CFAuthData); err != nil {
			log.Fatal(err)
		}
	}

	if len(os.Args) < 2 {
		log.Fatal(errNoSubmission)
	}

	//parse lang id
	if ext := path.Ext(os.Args[1]); len(ext) == 0 {
		log.Fatal(errUnkownExt)
	} else {
		if id, ok := CFAuthData.ExtId[strings.ToLower(ext[1:])]; !ok {
			log.Fatal(errUnkownExt)
		} else {
			langId = id
		}
	}

	//parse contest id & problem id
	filename := path.Base(os.Args[1])
	idx1 := strings.IndexFunc(filename, func(r rune) bool { return !unicode.IsDigit(r) })
	if idx1 == -1 {
		log.Fatal(errUnknownFilename)
	}
	idx2 := strings.Index(filename, ".")
	if idx2 == -1 {
		log.Fatal(errUnknownFilename)
	}

	problemId = strings.ToUpper(filename[:idx1])
	contestId = strings.ToUpper(filename[idx1:idx2])

	if len(problemId) == 0 || len(contestId) == 0 {
		log.Fatal(errUnknownFilename)
	}
}

func createMultipartForm() (io.Reader, string, error) {
	solutionText, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		return nil, "", err
	}

	//multipart form field: name - value
	formFields := [][]string{
		[]string{"csrf_token", CFAuthData.CSRF},
		[]string{"action", "submitSolutionFormSubmitted"},
		[]string{"submittedProblemIndex", problemId},
		[]string{"programTypeId", langId},
		[]string{"sourceFile", ""},
		[]string{"_tta", "222"},
		[]string{"source", string(solutionText)},
	}

	//cause butes.Buffer implements both io.Reader and io.Writer
	var b bytes.Buffer
	formWriter := multipart.NewWriter(&b)

	for _, field := range formFields {
		if err := formWriter.WriteField(field[0], field[1]); err != nil {
			return nil, "", err
		}
	}

	if err := formWriter.Close(); err != nil {
		return nil, "", err
	}

	return &b, formWriter.Boundary(), nil
}

func main() {

	//request url
	reqUrl := "http://codeforces." + CFAuthData.CFDomain +
		"/contest/" + contestId +
		"/problem/" + problemId +
		"?csrf_token=" + CFAuthData.CSRF

	//get request body data; boundary for header
	form, boundary, err := createMultipartForm()
	if err != nil {
		log.Fatal(err)
	}

	//ok, construct request
	req, err := http.NewRequest("POST", reqUrl, form)
	if err != nil {
		log.Fatal(err)
	}

	//add required headers and cookies
	req.Header.Set("Content-Type", "multipart/form-data; boundary="+boundary)
	req.AddCookie(&http.Cookie{Name: "X-User", Value: CFAuthData.XUser})

	//send request
	if _, err := http.DefaultClient.Do(req); err != nil {
		log.Fatal(err)
	}

	//maybe success
	log.Println("Solution sent. Check result in CF website")
}
<commit_msg>improved filename parsing<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"path"
	"regexp"
	"strings"
)

const settingsFileName = "cfsubmit_settings.json"

var (
	contestId string
	problemId string
	langId    string
)

var (
	errNoSubmission    = errors.New("Submission file not specified")
	errUnkownExt       = errors.New("Unknown extension. Ext must be in lowercase in your settings file")
	errUnknownFilename = errors.New("Unknown filename format. Example: 123a.cpp")
)

var (
	cfSubmissionFileRegex = regexp.MustCompile(`(\d+)(\w+)\.(\w+)`)
)

var CFAuthData struct {
	XUser    string            `json:"X-User"`
	CSRF     string            `json:"CSRF-Token"`
	ExtId    map[string]string `json:"Ext-ID"`
	CFDomain string            `json:"CF-Domain"`
}

func init() {
	//load settings from json
	if jsonData, err := os.Open(settingsFileName); err != nil {
		log.Fatal(err)
	} else {
		if err := json.NewDecoder(jsonData).Decode(&CFAuthData); err != nil {
			log.Fatal(err)
		}
	}

	if len(os.Args) < 2 {
		log.Fatal(errNoSubmission)
	}

	//matches: [0, contestId, problemId, extId]
	matches := cfSubmissionFileRegex.FindStringSubmatch(path.Base(os.Args[1]))
	if len(matches) < 4 {
		log.Fatal(errUnknownFilename)
	}
	contestId = matches[1]
	problemId = strings.ToUpper(matches[2])
	if l, ok := CFAuthData.ExtId[strings.ToLower(matches[3])]; !ok {
		log.Fatal(errUnkownExt)
	} else {
		langId = l
	}
}

func createMultipartForm() (io.Reader, string, error) {
	solutionText, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		return nil, "", err
	}

	//multipart form field: name - value
	formFields := [][]string{
		[]string{"csrf_token", CFAuthData.CSRF},
		[]string{"action", "submitSolutionFormSubmitted"},
		[]string{"submittedProblemIndex", problemId},
		[]string{"programTypeId", langId},
		[]string{"sourceFile", ""},
		[]string{"_tta", "222"},
		[]string{"source", string(solutionText)},
	}

	//cause bytes.Buffer implements both io.Reader and io.Writer
	var b bytes.Buffer
	formWriter := multipart.NewWriter(&b)

	for _, field := range formFields {
		if err := formWriter.WriteField(field[0], field[1]); err != nil {
			return nil, "", err
		}
	}

	if err := formWriter.Close(); err != nil {
		return nil, "", err
	}

	return &b, formWriter.Boundary(), nil
}

func main() {
	//request url
	reqUrl := "http://codeforces." + CFAuthData.CFDomain +
		"/contest/" + contestId +
		"/problem/" + problemId +
		"?csrf_token=" + CFAuthData.CSRF

	//get request body data; boundary for header
	form, boundary, err := createMultipartForm()
	if err != nil {
		log.Fatal(err)
	}

	//ok, construct request
	req, err := http.NewRequest("POST", reqUrl, form)
	if err != nil {
		log.Fatal(err)
	}

	//add required headers and cookies
	req.Header.Set("Content-Type", "multipart/form-data; boundary="+boundary)
	req.AddCookie(&http.Cookie{Name: "X-User", Value: CFAuthData.XUser})

	//send request
	if _, err := http.DefaultClient.Do(req); err != nil {
		log.Fatal(err)
	}

	//maybe success
	log.Println("Solution sent.")
}
<|endoftext|>


<commit_before>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

package cmd

import (
	"os"
	"path/filepath"

	"github.com/spf13/cobra"

	"github.com/admpub/log"
	"github.com/admpub/nging/v3/application/cmd/event"
	"github.com/admpub/nging/v3/application/handler/setup"
	"github.com/admpub/nging/v3/application/library/config"
	"github.com/admpub/nging/v3/application/library/service"
)

// 将Nging安装为系统服务的工具

// ServiceOptions 服务选项
var ServiceOptions = &service.Options{
	Name:        ``,
	DisplayName: ``,
	Description: ``,
}

var serviceCmd = &cobra.Command{
	Use:     "service",
	Short:   "Running as a service on major platforms.",
	Example: filepath.Base(os.Args[0]) + " service [install|uninstall|start|restart|stop]",
	RunE:    serviceRunE,
}

func serviceRunE(cmd *cobra.Command, args []string) error {
	conf, err := config.InitConfig()
	config.MustOK(err)
	conf.AsDefault()
	//application.DefaultConfigWatcher(false)
	if len(args) < 1 {
		return cmd.Usage()
	}
	if len(ServiceOptions.Name) == 0 {
		ServiceOptions.Name = event.SoftwareName
	}
	if len(ServiceOptions.DisplayName) == 0 {
		ServiceOptions.DisplayName = ServiceOptions.Name
	}
	if len(ServiceOptions.Name) == 0 {
		ServiceOptions.Description = ServiceOptions.DisplayName + ` Service`
	}

	if config.IsInstalled() {
		if err := setup.Upgrade(); err != nil && os.ErrNotExist != err {
			log.Error(`upgrade.sql: `, err)
		}
	}

	return service.Run(ServiceOptions, args[0])
}

func init() {
	rootCmd.AddCommand(serviceCmd)
}
<commit_msg>update<commit_after>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

package cmd

import (
	"os"
	"path/filepath"

	"github.com/spf13/cobra"

	"github.com/admpub/log"
	"github.com/admpub/nging/v3/application/cmd/event"
	"github.com/admpub/nging/v3/application/handler/setup"
	"github.com/admpub/nging/v3/application/library/config"
	"github.com/admpub/nging/v3/application/library/service"
)

// 将Nging安装为系统服务的工具

// ServiceOptions 服务选项
var ServiceOptions = &service.Options{
	Name:        ``,
	DisplayName: ``,
	Description: ``,
}

var serviceCmd = &cobra.Command{
	Use:     "service",
	Short:   "Running as a service on major platforms.",
	Example: filepath.Base(os.Args[0]) + " service [install|uninstall|start|restart|stop]",
	RunE:    serviceRunE,
}

func serviceRunE(cmd *cobra.Command, args []string) error {
	conf, err := config.InitConfig()
	config.MustOK(err)
	conf.AsDefault()
	if len(args) < 1 {
		return cmd.Usage()
	}
	if len(ServiceOptions.Name) == 0 {
		ServiceOptions.Name = event.SoftwareName
	}
	if len(ServiceOptions.DisplayName) == 0 {
		ServiceOptions.DisplayName = ServiceOptions.Name
	}
	if len(ServiceOptions.Name) == 0 {
		ServiceOptions.Description = ServiceOptions.DisplayName + ` Service`
	}

	if config.IsInstalled() {
		if err := setup.Upgrade(); err != nil && os.ErrNotExist != err {
			log.Error(`upgrade.sql: `, err)
		}
	}

	return service.Run(ServiceOptions, args[0])
}

func init() {
	rootCmd.AddCommand(serviceCmd)
}
<|endoftext|>


<commit_before>package amazon

import (
	"github.com/kris-nova/kubicorn/apis/cluster"
	"github.com/kris-nova/kubicorn/cloud"
	"github.com/kris-nova/kubicorn/cloud/amazon/awsSdkGo"
	"github.com/kris-nova/kubicorn/cloud/amazon/resources"
	"github.com/kris-nova/kubicorn/cutil/hang"
	"github.com/kris-nova/kubicorn/logger"
	"strings"
	"time"
	"os"
	"os/signal"
	"syscall"
)

type Reconciler struct {
	Known *cluster.Cluster
}

func NewReconciler(expected *cluster.Cluster) cloud.Reconciler {
	return &Reconciler{
		Known: expected,
	}
}

var model map[int]cloud.Resource

func (r *Reconciler) Init() error {
	sdk, err := awsSdkGo.NewSdk(r.Known.Location)
	if err != nil {
		return err
	}
	resources.Sdk = sdk
	model = ClusterModel(r.Known)
	return nil
}

func (r *Reconciler) GetActual() (*cluster.Cluster, error) {
	actualCluster := newClusterDefaults(r.Known)
	for i := 0; i < len(model); i++ {
		resource := model[i]
		actualResource, err := resource.Actual(r.Known)
		if err != nil {
			return nil, err
		}
		actualCluster, err = resource.Render(actualResource, actualCluster)
		if err != nil {
			return nil, err
		}
	}
	return actualCluster, nil
}

func (r *Reconciler) GetExpected() (*cluster.Cluster, error) {
	expectedCluster := newClusterDefaults(r.Known)
	for i := 0; i < len(model); i++ {
		resource := model[i]
		expectedResource, err := resource.Expected(r.Known)
		if err != nil {
			return nil, err
		}
		expectedCluster, err = resource.Render(expectedResource, expectedCluster)
		if err != nil {
			return nil, err
		}
	}
	return expectedCluster, nil
}

func cleanUp(cluster *cluster.Cluster, i int) error {
	logger.Warning("--------------------------------------")
	logger.Warning("Attempting to delete created resources!")
	logger.Warning("--------------------------------------")
	for j := i - 1; j >= 0; j-- {
		resource := model[j]
		createdResource := createdResources[j]
		err := resource.Delete(createdResource, cluster)
		if err != nil {
			err, j = destroyI(err, j)
			if err != nil {
				return err
			}
			continue
		}
	}
	return nil
}

var createdResources = make(map[int]cloud.Resource)

func (r *Reconciler) Reconcile(actualCluster, expectedCluster *cluster.Cluster) (*cluster.Cluster, error) {

	newCluster := newClusterDefaults(r.Known)

	errorOccured := false

	for i := 0; i < len(model); i++ {

		c := make(chan os.Signal, 2)
		signal.Notify(c, os.Interrupt, syscall.SIGTERM)
		go func() {
			<-c
			logger.Warning("SIGTERM Received while reconciling! Why in the world would you do that? Attempting to clean up!")
			errorOccured = true

			err := cleanUp(newCluster, i)
			if err != nil {
				logger.Critical("Failure during cleanup! Abandoned resources!")
			}
			os.Exit(1)
		}()

		if errorOccured == true {
			break
		}
		resource := model[i]
		expectedResource, err := resource.Expected(expectedCluster)
		if err != nil {
			return nil, err
		}
		actualResource, err := resource.Actual(actualCluster)
		if err != nil {
			return nil, err
		}
		appliedResource, err := resource.Apply(actualResource, expectedResource, newCluster)
		if err != nil {
			logger.Critical("Error during apply! Attempting cleaning: %v", err)
			err = cleanUp(newCluster, i)
			if err != nil {
				logger.Critical("Failure during cleanup! Abandoned resources!")
				return nil, err
			}
			return nil, nil
		}
		newCluster, err = resource.Render(appliedResource, newCluster)
		if err != nil {
			return nil, err
		}
		createdResources[i] = appliedResource
	}
	if errorOccured == true {
		os.Exit(1)
	}
	return newCluster, nil
}

var destroyRetryStrings = []string{
	"DependencyViolation:",
	"does not exist in default VPC",
}

var hg = &hang.Hanger{
	Ratio: 1,
}

func destroyI(err error, i int) (error, int) {
	hg.Hang()
	for _, retryString := range destroyRetryStrings {
		if strings.Contains(err.Error(), retryString) {
			logger.Debug("Retry failed delete: %v", err)
			time.Sleep(1 * time.Second)
			return nil, i + 1
		}
	}
	return err, 0
}

func (r *Reconciler) Destroy() error {
	for i := len(model) - 1; i >= 0; i-- {
		resource := model[i]
		actualResource, err := resource.Actual(r.Known)
		if err != nil {
			err, i = destroyI(err, i)
			if err != nil {
				return err
			}
			continue
		}
		err = resource.Delete(actualResource, r.Known)
		if err != nil {
			err, i = destroyI(err, i)
			if err != nil {
				return err
			}
			continue
		}
	}
	return nil
}

func newClusterDefaults(base *cluster.Cluster) *cluster.Cluster {
	new := &cluster.Cluster{
		Name:     base.Name,
		Cloud:    base.Cloud,
		Location: base.Location,
		Network:  &cluster.Network{},
		Ssh:      &cluster.Ssh{},
		Values:   base.Values,
	}
	return new
}
<commit_msg>Intercepts SIGINT (ctrl-C) and attepts to clean up in a nice way<commit_after>package amazon

import (
	"github.com/kris-nova/kubicorn/apis/cluster"
	"github.com/kris-nova/kubicorn/cloud"
	"github.com/kris-nova/kubicorn/cloud/amazon/awsSdkGo"
	"github.com/kris-nova/kubicorn/cloud/amazon/resources"
	"github.com/kris-nova/kubicorn/cutil/hang"
	"github.com/kris-nova/kubicorn/logger"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

var sigCaught = false

type Reconciler struct {
	Known *cluster.Cluster
}

func NewReconciler(expected *cluster.Cluster) cloud.Reconciler {
	return &Reconciler{
		Known: expected,
	}
}

var model map[int]cloud.Resource

func (r *Reconciler) Init() error {
	sdk, err := awsSdkGo.NewSdk(r.Known.Location)
	if err != nil {
		return err
	}
	resources.Sdk = sdk
	model = ClusterModel(r.Known)
	return nil
}

func (r *Reconciler) GetActual() (*cluster.Cluster, error) {
	actualCluster := newClusterDefaults(r.Known)
	for i := 0; i < len(model); i++ {
		resource := model[i]
		actualResource, err := resource.Actual(r.Known)
		if err != nil {
			return nil, err
		}
		actualCluster, err = resource.Render(actualResource, actualCluster)
		if err != nil {
			return nil, err
		}
	}
	return actualCluster, nil
}

func (r *Reconciler) GetExpected() (*cluster.Cluster, error) {
	expectedCluster := newClusterDefaults(r.Known)
	for i := 0; i < len(model); i++ {
		resource := model[i]
		expectedResource, err := resource.Expected(r.Known)
		if err != nil {
			return nil, err
		}
		expectedCluster, err = resource.Render(expectedResource, expectedCluster)
		if err != nil {
			return nil, err
		}
	}
	return expectedCluster, nil
}

func cleanUp(cluster *cluster.Cluster, i int) error {
	logger.Warning("--------------------------------------")
	logger.Warning("Attempting to delete created resources!")
	logger.Warning("--------------------------------------")
	for j := i - 1; j >= 0; j-- {
		resource := model[j]
		createdResource := createdResources[j]
		err := resource.Delete(createdResource, cluster)
		if err != nil {
			err, j = destroyI(err, j)
			if err != nil {
				return err
			}
			continue
		}
	}
	return nil
}

var createdResources = make(map[int]cloud.Resource)

func (r *Reconciler) Reconcile(actualCluster, expectedCluster *cluster.Cluster) (*cluster.Cluster, error) {
	newCluster := newClusterDefaults(r.Known)

	for i := 0; i < len(model); i++ {
		if sigCaught {
			cleanUp(newCluster, i)
			os.Exit(1)
		}

		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)

		go handleCtrlC(c)

		resource := model[i]
		expectedResource, err := resource.Expected(expectedCluster)
		if err != nil {
			return nil, err
		}
		actualResource, err := resource.Actual(actualCluster)
		if err != nil {
			return nil, err
		}
		appliedResource, err := resource.Apply(actualResource, expectedResource, newCluster)
		if err != nil {
			logger.Critical("Error during apply! Attempting cleaning: %v", err)
			err = cleanUp(newCluster, i)
			if err != nil {
				logger.Critical("Failure during cleanup! Abandoned resources!")
				return nil, err
			}
			return nil, nil
		}
		newCluster, err = resource.Render(appliedResource, newCluster)
		if err != nil {
			return nil, err
		}
		createdResources[i] = appliedResource
	}

	return newCluster, nil
}

var destroyRetryStrings = []string{
	"DependencyViolation:",
	"does not exist in default VPC",
}

var hg = &hang.Hanger{
	Ratio: 1,
}

func destroyI(err error, i int) (error, int) {
	hg.Hang()
	for _, retryString := range destroyRetryStrings {
		if strings.Contains(err.Error(), retryString) {
			logger.Debug("Retry failed delete: %v", err)
			time.Sleep(1 * time.Second)
			return nil, i + 1
		}
	}
	return err, 0
}

func (r *Reconciler) Destroy() error {
	for i := len(model) - 1; i >= 0; i-- {
		resource := model[i]
		actualResource, err := resource.Actual(r.Known)
		if err != nil {
			err, i = destroyI(err, i)
			if err != nil {
				return err
			}
			continue
		}
		err = resource.Delete(actualResource, r.Known)
		if err != nil {
			err, i = destroyI(err, i)
			if err != nil {
				return err
			}
			continue
		}
	}
	return nil
}

func newClusterDefaults(base *cluster.Cluster) *cluster.Cluster {
	new := &cluster.Cluster{
		Name:     base.Name,
		Cloud:    base.Cloud,
		Location: base.Location,
		Network:  &cluster.Network{},
		Ssh:      &cluster.Ssh{},
		Values:   base.Values,
	}
	return new
}

func handleCtrlC(c chan os.Signal) {
	sig := <-c
	if sig == syscall.SIGINT {
		sigCaught = true
		logger.Warning("SIGINT! Why did you do that? Trying to rewind to clean up orphaned resources!")
	}
}
<|endoftext|>


<commit_before>package renderweb

import (
	"net/http"

	"github.com/rs/xhandler"
	"golang.org/x/net/context"

	"github.com/crackcomm/renderer/components"
	"github.com/crackcomm/renderer/middlewares"
)

// Handler - Web route handler.
type Handler struct {
	Component   *components.Component     `json:"component,omitempty" yaml:"component,omitempty"`
	Middlewares []*middlewares.Middleware `json:"middlewares,omitempty" yaml:"middlewares,omitempty"`
}

// Construct - Constructs http handler.
func (h *Handler) Construct(opts ...Option) (xhandler.HandlerC, error) {
	// Request initialization middleware
	opts = append(opts, WithMiddleware(ToMiddleware(initMiddleware)))

	// Set component-setting middleware with handler component
	opts = append(opts, WithComponentSetter(ComponentMiddleware(h.Component)))

	// Construct handler middlewares
	for _, md := range h.Middlewares {
		middleware, err := middlewares.Construct(md)
		if err != nil {
			return nil, err
		}
		opts = append(opts, WithMiddleware(middleware))
	}

	return New(opts...), nil
}

func initMiddleware(ctx context.Context, w http.ResponseWriter, r *http.Request, next xhandler.HandlerC) {
	ctx = NewRequestContext(ctx, r)
	ctx = components.WithTemplateKey(ctx, "request", r)
	next.ServeHTTPC(ctx, w, r)
}
<commit_msg>move params back to template context<commit_after>package renderweb

import (
	"net/http"

	"github.com/rs/xhandler"
	"github.com/rs/xmux"
	"golang.org/x/net/context"

	"github.com/crackcomm/renderer/components"
	"github.com/crackcomm/renderer/middlewares"
)

// Handler - Web route handler.
type Handler struct {
	Component   *components.Component     `json:"component,omitempty" yaml:"component,omitempty"`
	Middlewares []*middlewares.Middleware `json:"middlewares,omitempty" yaml:"middlewares,omitempty"`
}

// Construct - Constructs http handler.
func (h *Handler) Construct(opts ...Option) (xhandler.HandlerC, error) {
	// Request initialization middleware
	opts = append(opts, WithMiddleware(ToMiddleware(initMiddleware)))

	// Set component-setting middleware with handler component
	opts = append(opts, WithComponentSetter(ComponentMiddleware(h.Component)))

	// Construct handler middlewares
	for _, md := range h.Middlewares {
		middleware, err := middlewares.Construct(md)
		if err != nil {
			return nil, err
		}
		opts = append(opts, WithMiddleware(middleware))
	}

	return New(opts...), nil
}

func initMiddleware(ctx context.Context, w http.ResponseWriter, r *http.Request, next xhandler.HandlerC) {
	ctx = NewRequestContext(ctx, r)
	ctx = components.WithTemplateKey(ctx, "request", r)
	ctx = components.WithTemplateKey(ctx, "params", xmux.Params(ctx))
	next.ServeHTTPC(ctx, w, r)
}
<|endoftext|>


<commit_before><commit_msg>Don't send files.<commit_after><|endoftext|>


<commit_before>package main

import (
	"github.com/hillu/go-ntdll"

	"flag"
	"fmt"
	"os"
	"unsafe"
)

func query_vm(ph ntdll.Handle, base uintptr) (*ntdll.MemoryBasicInformationT, ntdll.NtStatus) {
	var mbi ntdll.MemoryBasicInformationT
	s := ntdll.NtQueryVirtualMemory(
		ph,
		(*uint8)(unsafe.Pointer(base)),
		ntdll.MemoryBasicInformation,
		(*uint8)(unsafe.Pointer(&mbi)),
		unsafe.Sizeof(mbi),
		nil,
	)
	if s.IsError() {
		return nil, s
	}
	return &mbi, s
}

func query_name (ph ntdll.Handle, base uintptr) (string, ntdll.NtStatus) {
	buf := [1024]byte{}
	s := ntdll.NtQueryVirtualMemory(
		ph,
		(*uint8)(unsafe.Pointer(base)),
		ntdll.MemoryMappedFilenameInformation,
		&buf[0],
		1024,
		nil,
	)
	if s.IsError() {
		return "", s
	}
	return (*ntdll.UnicodeString)(unsafe.Pointer(&buf[0])).String(), s
}

type memProtect uint32

func (p memProtect) String() string {
	r:= []byte("----")
	if p & ntdll.PAGE_NOACCESS != 0 { r[3] = '!' }
	if p & ntdll.PAGE_READONLY != 0 { r[0] = 'r' }
	if p & ntdll.PAGE_READWRITE != 0 { r[0] = 'r'; r[1] = 'w' }
	if p & ntdll.PAGE_WRITECOPY != 0 { r[1] = 'w'; r[3] = 'c' }
	if p & ntdll.PAGE_EXECUTE != 0 { r[2] = 'x' }
	if p & ntdll.PAGE_EXECUTE_READ != 0 { r[0] = 'r'; r[2] = 'x' }
	if p & ntdll.PAGE_EXECUTE_READWRITE != 0 { r[0] = 'r'; r[1] = 'w'; r[2] = 'x' }
	if p & ntdll.PAGE_EXECUTE_WRITECOPY != 0 { r[1] = 'x'; r[2] = 'x'; r[3] = 'c' }
	if p & ntdll.PAGE_GUARD!= 0 { r[3] = 'G' }
	if p & ntdll.PAGE_NOCACHE != 0 { r[3] = 'C' }
	return string(r)
}

type memState uint32
func (s memState) String() string {
	r := []byte("---")
	if s&ntdll.MEM_COMMIT != 0 {
		r[0] = 'c'
	}
	if s&ntdll.MEM_RESERVE != 0 {
		r[1] = 'r'
	}
	if s&ntdll.MEM_FREE != 0 {
		r[2] = 'f'
	}
	return string(r)
}

type memType uint32
func (s memType) String() string {
	r := []byte("---")
	if s&ntdll.MEM_MAPPED != 0 {
		r[0] = 'm'
	}
	if s&ntdll.MEM_PRIVATE != 0 {
		r[1] = 'p'
	}
	if s&ntdll.MEM_IMAGE != 0 {
		r[2] = 'i'
	}
	return string(r)
}

func main() {
	var pid uint
	flag.UintVar(&pid, "pid", 0, "target process id")
	flag.Parse()
	if pid == 0 {
		fmt.Printf("usage: %s -pid <pid>\n", os.Args[0])
		os.Exit(1)
	}

	var ph ntdll.Handle
	oa := ntdll.NewObjectAttributes("", 0, 0, nil)
	client := ntdll.ClientId{ ntdll.Handle(pid), 0}
	s := ntdll.NtOpenProcess(&ph, ntdll.PROCESS_QUERY_INFORMATION, oa, &client)
	if s.IsError() {
		fmt.Printf("NtOpenProcess: %s", s)
		os.Exit(1)
	}

	addr := uintptr(0)
	for {
		mbi, s := query_vm(ph, addr)
		if s.IsError() {
			if s != ntdll.STATUS_INVALID_PARAMETER {
				fmt.Printf("NtQueryVirtualMemory: %08x: %s", addr, s.Error())
			}
			break
		}
		name, _ := query_name(ph, addr)
		if mbi.AllocationBase != nil {
			fmt.Printf("%12x %12x + %12x ty:%s st:%s pr:=%s %s\n",
				uintptr(unsafe.Pointer(mbi.AllocationBase)),
				uintptr(unsafe.Pointer(mbi.BaseAddress)),
				mbi.RegionSize,
				memType(mbi.Type),
				memState(mbi.State),
				memProtect(mbi.Protect),
				name,
			)
		}
		addr = uintptr(unsafe.Pointer(mbi.BaseAddress)) + mbi.RegionSize
	}
}
<commit_msg>gofmt ls-proc-vm example<commit_after>package main

import (
	"github.com/hillu/go-ntdll"

	"flag"
	"fmt"
	"os"
	"unsafe"
)

func query_vm(ph ntdll.Handle, base uintptr) (*ntdll.MemoryBasicInformationT, ntdll.NtStatus) {
	var mbi ntdll.MemoryBasicInformationT
	s := ntdll.NtQueryVirtualMemory(
		ph,
		(*uint8)(unsafe.Pointer(base)),
		ntdll.MemoryBasicInformation,
		(*uint8)(unsafe.Pointer(&mbi)),
		unsafe.Sizeof(mbi),
		nil,
	)
	if s.IsError() {
		return nil, s
	}
	return &mbi, s
}

func query_name(ph ntdll.Handle, base uintptr) (string, ntdll.NtStatus) {
	buf := [1024]byte{}
	s := ntdll.NtQueryVirtualMemory(
		ph,
		(*uint8)(unsafe.Pointer(base)),
		ntdll.MemoryMappedFilenameInformation,
		&buf[0],
		1024,
		nil,
	)
	if s.IsError() {
		return "", s
	}
	return (*ntdll.UnicodeString)(unsafe.Pointer(&buf[0])).String(), s
}

type memProtect uint32

func (p memProtect) String() string {
	r := []byte("----")
	if p&ntdll.PAGE_NOACCESS != 0 {
		r[3] = '!'
	}
	if p&ntdll.PAGE_READONLY != 0 {
		r[0] = 'r'
	}
	if p&ntdll.PAGE_READWRITE != 0 {
		r[0] = 'r'
		r[1] = 'w'
	}
	if p&ntdll.PAGE_WRITECOPY != 0 {
		r[1] = 'w'
		r[3] = 'c'
	}
	if p&ntdll.PAGE_EXECUTE != 0 {
		r[2] = 'x'
	}
	if p&ntdll.PAGE_EXECUTE_READ != 0 {
		r[0] = 'r'
		r[2] = 'x'
	}
	if p&ntdll.PAGE_EXECUTE_READWRITE != 0 {
		r[0] = 'r'
		r[1] = 'w'
		r[2] = 'x'
	}
	if p&ntdll.PAGE_EXECUTE_WRITECOPY != 0 {
		r[1] = 'x'
		r[2] = 'x'
		r[3] = 'c'
	}
	if p&ntdll.PAGE_GUARD != 0 {
		r[3] = 'G'
	}
	if p&ntdll.PAGE_NOCACHE != 0 {
		r[3] = 'C'
	}
	return string(r)
}

type memState uint32

func (s memState) String() string {
	r := []byte("---")
	if s&ntdll.MEM_COMMIT != 0 {
		r[0] = 'c'
	}
	if s&ntdll.MEM_RESERVE != 0 {
		r[1] = 'r'
	}
	if s&ntdll.MEM_FREE != 0 {
		r[2] = 'f'
	}
	return string(r)
}

type memType uint32

func (s memType) String() string {
	r := []byte("---")
	if s&ntdll.MEM_MAPPED != 0 {
		r[0] = 'm'
	}
	if s&ntdll.MEM_PRIVATE != 0 {
		r[1] = 'p'
	}
	if s&ntdll.MEM_IMAGE != 0 {
		r[2] = 'i'
	}
	return string(r)
}

func main() {
	var pid uint
	flag.UintVar(&pid, "pid", 0, "target process id")
	flag.Parse()
	if pid == 0 {
		fmt.Printf("usage: %s -pid <pid>\n", os.Args[0])
		os.Exit(1)
	}

	var ph ntdll.Handle
	oa := ntdll.NewObjectAttributes("", 0, 0, nil)
	client := ntdll.ClientId{ntdll.Handle(pid), 0}
	s := ntdll.NtOpenProcess(&ph, ntdll.PROCESS_QUERY_INFORMATION, oa, &client)
	if s.IsError() {
		fmt.Printf("NtOpenProcess: %s", s)
		os.Exit(1)
	}

	addr := uintptr(0)
	for {
		mbi, s := query_vm(ph, addr)
		if s.IsError() {
			if s != ntdll.STATUS_INVALID_PARAMETER {
				fmt.Printf("NtQueryVirtualMemory: %08x: %s", addr, s.Error())
			}
			break
		}
		name, _ := query_name(ph, addr)
		if mbi.AllocationBase != nil {
			fmt.Printf("%12x %12x + %12x ty:%s st:%s pr:=%s %s\n",
				uintptr(unsafe.Pointer(mbi.AllocationBase)),
				uintptr(unsafe.Pointer(mbi.BaseAddress)),
				mbi.RegionSize,
				memType(mbi.Type),
				memState(mbi.State),
				memProtect(mbi.Protect),
				name,
			)
		}
		addr = uintptr(unsafe.Pointer(mbi.BaseAddress)) + mbi.RegionSize
	}
}
<|endoftext|>


<commit_before>package restpc

import (
	"io"
	"net/url"
	"testing"

	"github.com/golang/mock/gomock"
)

func Test_RequestMock(t *testing.T) {
	ctrl := gomock.NewController(t)
	mockReq := NewMockRequest(ctrl)
	{
		mockReq.EXPECT().RemoteIP().Return("192.168.100.100", nil)
		mockReq.RemoteIP()
	}
	{
		testUrl, err := url.Parse("http://127.0.0.1/test")
		if err != nil {
			panic(err)
		}
		mockReq.EXPECT().URL().Return(testUrl)
		mockReq.URL()
	}
	{
		mockReq.EXPECT().Host().Return("localhost")
		mockReq.Host()
	}
	{
		mockReq.EXPECT().HandlerName().Return("TestHandler")
		mockReq.HandlerName()
	}
	{
		mockReq.EXPECT().Body().Return(nil, io.EOF)
		mockReq.Body()
	}
	{
		mockReq.EXPECT().BodyTo(gomock.Any()).Return(nil)
		m := map[string]interface{}{}
		mockReq.BodyTo(&m)
	}
	{
		mockReq.EXPECT().GetHeader("test").Return("bar")
		mockReq.GetHeader("test")
	}
	{
		mockReq.EXPECT().GetString("test").Return(nil, nil)
		mockReq.GetString("test")
	}
	{
		mockReq.EXPECT().GetStringList("test").Return(nil, nil)
		mockReq.GetStringList("test")
	}
	{
		mockReq.EXPECT().GetInt("test").Return(nil, nil)
		mockReq.GetInt("test")
	}
	{
		mockReq.EXPECT().GetIntDefault("test", 0).Return(0, nil)
		mockReq.GetIntDefault("test", 0)
	}
	{
		mockReq.EXPECT().GetFloat("test").Return(nil, nil)
		mockReq.GetFloat("test")
	}
	{
		mockReq.EXPECT().GetBool("test").Return(nil, nil)
		mockReq.GetBool("test")
	}
	{
		mockReq.EXPECT().GetTime("test").Return(nil, nil)
		mockReq.GetTime("test")
	}
	{
		mockReq.EXPECT().FullMap().Return(nil)
		mockReq.FullMap()
	}

}
<commit_msg>cover %100 of mock_request.go<commit_after>package restpc

import (
	"io"
	"net/url"
	"testing"

	"github.com/golang/mock/gomock"
)

func Test_RequestMock(t *testing.T) {
	ctrl := gomock.NewController(t)
	mockReq := NewMockRequest(ctrl)
	{
		mockReq.EXPECT().RemoteIP().Return("192.168.100.100", nil)
		mockReq.RemoteIP()
	}
	{
		testUrl, err := url.Parse("http://127.0.0.1/test")
		if err != nil {
			panic(err)
		}
		mockReq.EXPECT().URL().Return(testUrl)
		mockReq.URL()
	}
	{
		mockReq.EXPECT().Host().Return("localhost")
		mockReq.Host()
	}
	{
		mockReq.EXPECT().HandlerName().Return("TestHandler")
		mockReq.HandlerName()
	}
	{
		mockReq.EXPECT().Body().Return(nil, io.EOF)
		mockReq.Body()
	}
	{
		mockReq.EXPECT().BodyTo(gomock.Any()).Return(nil)
		m := map[string]interface{}{}
		mockReq.BodyTo(&m)
	}
	{
		mockReq.EXPECT().GetHeader("test").Return("bar")
		mockReq.GetHeader("test")
	}
	{
		mockReq.EXPECT().GetString("test", FromForm).Return(nil, nil)
		mockReq.GetString("test", FromForm)
	}
	{
		mockReq.EXPECT().GetStringList("test", FromBody).Return(nil, nil)
		mockReq.GetStringList("test", FromBody)
	}
	{
		mockReq.EXPECT().GetInt("test", FromBody).Return(nil, nil)
		mockReq.GetInt("test", FromBody)
	}
	{
		mockReq.EXPECT().GetIntDefault("test", 0, FromContext).Return(0, nil)
		mockReq.GetIntDefault("test", 0, FromContext)
	}
	{
		mockReq.EXPECT().GetFloat("test", FromBody).Return(nil, nil)
		mockReq.GetFloat("test", FromBody)
	}
	{
		mockReq.EXPECT().GetBool("test", FromForm).Return(nil, nil)
		mockReq.GetBool("test", FromForm)
	}
	{
		mockReq.EXPECT().GetTime("test", FromBody).Return(nil, nil)
		mockReq.GetTime("test", FromBody)
	}
	{
		mockReq.EXPECT().FullMap().Return(nil)
		mockReq.FullMap()
	}

}
<|endoftext|>


<commit_before>package user

type User struct {
	Name string
}
<commit_msg>think about how to use redis, finially give up only using redis. First use postgresql for features<commit_after>package user

type User struct {
	Name     string
	password string
}
<|endoftext|>


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

package expvar

import (
	"bytes"
	"encoding/json"
	"net"
	"net/http/httptest"
	"runtime"
	"strconv"
	"sync"
	"testing"
)

// RemoveAll removes all exported variables.
// This is for tests only.
func RemoveAll() {
	mutex.Lock()
	defer mutex.Unlock()
	vars = make(map[string]Var)
	varKeys = nil
}

func TestInt(t *testing.T) {
	RemoveAll()
	reqs := NewInt("requests")
	if reqs.i != 0 {
		t.Errorf("reqs.i = %v, want 0", reqs.i)
	}
	if reqs != Get("requests").(*Int) {
		t.Errorf("Get() failed.")
	}

	reqs.Add(1)
	reqs.Add(3)
	if reqs.i != 4 {
		t.Errorf("reqs.i = %v, want 4", reqs.i)
	}

	if s := reqs.String(); s != "4" {
		t.Errorf("reqs.String() = %q, want \"4\"", s)
	}

	reqs.Set(-2)
	if reqs.i != -2 {
		t.Errorf("reqs.i = %v, want -2", reqs.i)
	}
}

func BenchmarkIntAdd(b *testing.B) {
	var v Int

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			v.Add(1)
		}
	})
}

func BenchmarkIntSet(b *testing.B) {
	var v Int

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			v.Set(1)
		}
	})
}

func TestFloat(t *testing.T) {
	RemoveAll()
	reqs := NewFloat("requests-float")
	if reqs.f != 0.0 {
		t.Errorf("reqs.f = %v, want 0", reqs.f)
	}
	if reqs != Get("requests-float").(*Float) {
		t.Errorf("Get() failed.")
	}

	reqs.Add(1.5)
	reqs.Add(1.25)
	if reqs.f != 2.75 {
		t.Errorf("reqs.f = %v, want 2.75", reqs.f)
	}

	if s := reqs.String(); s != "2.75" {
		t.Errorf("reqs.String() = %q, want \"4.64\"", s)
	}

	reqs.Add(-2)
	if reqs.f != 0.75 {
		t.Errorf("reqs.f = %v, want 0.75", reqs.f)
	}
}

func BenchmarkFloatAdd(b *testing.B) {
	var f Float

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			f.Add(1.0)
		}
	})
}

func BenchmarkFloatSet(b *testing.B) {
	var f Float

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			f.Set(1.0)
		}
	})
}

func TestString(t *testing.T) {
	RemoveAll()
	name := NewString("my-name")
	if name.s != "" {
		t.Errorf("name.s = %q, want \"\"", name.s)
	}

	name.Set("Mike")
	if name.s != "Mike" {
		t.Errorf("name.s = %q, want \"Mike\"", name.s)
	}

	if s := name.String(); s != "\"Mike\"" {
		t.Errorf("reqs.String() = %q, want \"\"Mike\"\"", s)
	}
}

func BenchmarkStringSet(b *testing.B) {
	var s String

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			s.Set("red")
		}
	})
}

func TestMapCounter(t *testing.T) {
	RemoveAll()
	colors := NewMap("bike-shed-colors")

	colors.Add("red", 1)
	colors.Add("red", 2)
	colors.Add("blue", 4)
	colors.AddFloat(`green "midori"`, 4.125)
	if x := colors.m["red"].(*Int).i; x != 3 {
		t.Errorf("colors.m[\"red\"] = %v, want 3", x)
	}
	if x := colors.m["blue"].(*Int).i; x != 4 {
		t.Errorf("colors.m[\"blue\"] = %v, want 4", x)
	}
	if x := colors.m[`green "midori"`].(*Float).f; x != 4.125 {
		t.Errorf("colors.m[`green \"midori\"] = %v, want 3.14", x)
	}

	// colors.String() should be '{"red":3, "blue":4}',
	// though the order of red and blue could vary.
	s := colors.String()
	var j interface{}
	err := json.Unmarshal([]byte(s), &j)
	if err != nil {
		t.Errorf("colors.String() isn't valid JSON: %v", err)
	}
	m, ok := j.(map[string]interface{})
	if !ok {
		t.Error("colors.String() didn't produce a map.")
	}
	red := m["red"]
	x, ok := red.(float64)
	if !ok {
		t.Error("red.Kind() is not a number.")
	}
	if x != 3 {
		t.Errorf("red = %v, want 3", x)
	}
}

func BenchmarkMapSet(b *testing.B) {
	m := new(Map).Init()

	v := new(Int)

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			m.Set("red", v)
		}
	})
}

func BenchmarkMapAddSame(b *testing.B) {
	for i := 0; i < b.N; i++ {
		m := new(Map).Init()
		m.Add("red", 1)
		m.Add("red", 1)
		m.Add("red", 1)
		m.Add("red", 1)
	}
}

func BenchmarkMapAddDifferent(b *testing.B) {
	for i := 0; i < b.N; i++ {
		m := new(Map).Init()
		m.Add("red", 1)
		m.Add("blue", 1)
		m.Add("green", 1)
		m.Add("yellow", 1)
	}
}

func TestFunc(t *testing.T) {
	RemoveAll()
	var x interface{} = []string{"a", "b"}
	f := Func(func() interface{} { return x })
	if s, exp := f.String(), `["a","b"]`; s != exp {
		t.Errorf(`f.String() = %q, want %q`, s, exp)
	}

	x = 17
	if s, exp := f.String(), `17`; s != exp {
		t.Errorf(`f.String() = %q, want %q`, s, exp)
	}
}

func TestHandler(t *testing.T) {
	RemoveAll()
	m := NewMap("map1")
	m.Add("a", 1)
	m.Add("z", 2)
	m2 := NewMap("map2")
	for i := 0; i < 9; i++ {
		m2.Add(strconv.Itoa(i), int64(i))
	}
	rr := httptest.NewRecorder()
	rr.Body = new(bytes.Buffer)
	expvarHandler(rr, nil)
	want := `{
"map1": {"a": 1, "z": 2},
"map2": {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8}
}
`
	if got := rr.Body.String(); got != want {
		t.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got, want)
	}
}

func BenchmarkRealworldExpvarUsage(b *testing.B) {
	var (
		bytesSent Int
		bytesRead Int
	)

	// The benchmark creates GOMAXPROCS client/server pairs.
	// Each pair creates 4 goroutines: client reader/writer and server reader/writer.
	// The benchmark stresses concurrent reading and writing to the same connection.
	// Such pattern is used in net/http and net/rpc.

	b.StopTimer()

	P := runtime.GOMAXPROCS(0)
	N := b.N / P
	W := 1000

	// Setup P client/server connections.
	clients := make([]net.Conn, P)
	servers := make([]net.Conn, P)
	ln, err := net.Listen("tcp", laddr)
	if err != nil {
		b.Fatalf("Listen failed: %v", err)
	}
	defer ln.Close()
	done := make(chan bool)
	go func() {
		for p := 0; p < P; p++ {
			s, err := ln.Accept()
			if err != nil {
				b.Errorf("Accept failed: %v", err)
				return
			}
			servers[p] = s
		}
		done <- true
	}()
	for p := 0; p < P; p++ {
		c, err := net.Dial("tcp", ln.Addr().String())
		if err != nil {
			b.Fatalf("Dial failed: %v", err)
		}
		clients[p] = c
	}
	<-done

	b.StartTimer()

	var wg sync.WaitGroup
	wg.Add(4 * P)
	for p := 0; p < P; p++ {
		// Client writer.
		go func(c net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				v := byte(i)
				for w := 0; w < W; w++ {
					v *= v
				}
				buf[0] = v
				n, err := c.Write(buf[:])
				if err != nil {
					b.Errorf("Write failed: %v", err)
					return
				}

				bytesSent.Add(int64(n))
			}
		}(clients[p])

		// Pipe between server reader and server writer.
		pipe := make(chan byte, 128)

		// Server reader.
		go func(s net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				n, err := s.Read(buf[:])

				if err != nil {
					b.Errorf("Read failed: %v", err)
					return
				}

				bytesRead.Add(int64(n))
				pipe <- buf[0]
			}
		}(servers[p])

		// Server writer.
		go func(s net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				v := <-pipe
				for w := 0; w < W; w++ {
					v *= v
				}
				buf[0] = v
				n, err := s.Write(buf[:])
				if err != nil {
					b.Errorf("Write failed: %v", err)
					return
				}

				bytesSent.Add(int64(n))
			}
			s.Close()
		}(servers[p])

		// Client reader.
		go func(c net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				n, err := c.Read(buf[:])

				if err != nil {
					b.Errorf("Read failed: %v", err)
					return
				}

				bytesRead.Add(int64(n))
			}
			c.Close()
		}(clients[p])
	}
	wg.Wait()
}
<commit_msg>expvar: fix build<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package expvar

import (
	"bytes"
	"encoding/json"
	"net"
	"net/http/httptest"
	"runtime"
	"strconv"
	"sync"
	"testing"
)

// RemoveAll removes all exported variables.
// This is for tests only.
func RemoveAll() {
	mutex.Lock()
	defer mutex.Unlock()
	vars = make(map[string]Var)
	varKeys = nil
}

func TestInt(t *testing.T) {
	RemoveAll()
	reqs := NewInt("requests")
	if reqs.i != 0 {
		t.Errorf("reqs.i = %v, want 0", reqs.i)
	}
	if reqs != Get("requests").(*Int) {
		t.Errorf("Get() failed.")
	}

	reqs.Add(1)
	reqs.Add(3)
	if reqs.i != 4 {
		t.Errorf("reqs.i = %v, want 4", reqs.i)
	}

	if s := reqs.String(); s != "4" {
		t.Errorf("reqs.String() = %q, want \"4\"", s)
	}

	reqs.Set(-2)
	if reqs.i != -2 {
		t.Errorf("reqs.i = %v, want -2", reqs.i)
	}
}

func BenchmarkIntAdd(b *testing.B) {
	var v Int

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			v.Add(1)
		}
	})
}

func BenchmarkIntSet(b *testing.B) {
	var v Int

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			v.Set(1)
		}
	})
}

func TestFloat(t *testing.T) {
	RemoveAll()
	reqs := NewFloat("requests-float")
	if reqs.f != 0.0 {
		t.Errorf("reqs.f = %v, want 0", reqs.f)
	}
	if reqs != Get("requests-float").(*Float) {
		t.Errorf("Get() failed.")
	}

	reqs.Add(1.5)
	reqs.Add(1.25)
	if reqs.f != 2.75 {
		t.Errorf("reqs.f = %v, want 2.75", reqs.f)
	}

	if s := reqs.String(); s != "2.75" {
		t.Errorf("reqs.String() = %q, want \"4.64\"", s)
	}

	reqs.Add(-2)
	if reqs.f != 0.75 {
		t.Errorf("reqs.f = %v, want 0.75", reqs.f)
	}
}

func BenchmarkFloatAdd(b *testing.B) {
	var f Float

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			f.Add(1.0)
		}
	})
}

func BenchmarkFloatSet(b *testing.B) {
	var f Float

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			f.Set(1.0)
		}
	})
}

func TestString(t *testing.T) {
	RemoveAll()
	name := NewString("my-name")
	if name.s != "" {
		t.Errorf("name.s = %q, want \"\"", name.s)
	}

	name.Set("Mike")
	if name.s != "Mike" {
		t.Errorf("name.s = %q, want \"Mike\"", name.s)
	}

	if s := name.String(); s != "\"Mike\"" {
		t.Errorf("reqs.String() = %q, want \"\"Mike\"\"", s)
	}
}

func BenchmarkStringSet(b *testing.B) {
	var s String

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			s.Set("red")
		}
	})
}

func TestMapCounter(t *testing.T) {
	RemoveAll()
	colors := NewMap("bike-shed-colors")

	colors.Add("red", 1)
	colors.Add("red", 2)
	colors.Add("blue", 4)
	colors.AddFloat(`green "midori"`, 4.125)
	if x := colors.m["red"].(*Int).i; x != 3 {
		t.Errorf("colors.m[\"red\"] = %v, want 3", x)
	}
	if x := colors.m["blue"].(*Int).i; x != 4 {
		t.Errorf("colors.m[\"blue\"] = %v, want 4", x)
	}
	if x := colors.m[`green "midori"`].(*Float).f; x != 4.125 {
		t.Errorf("colors.m[`green \"midori\"] = %v, want 3.14", x)
	}

	// colors.String() should be '{"red":3, "blue":4}',
	// though the order of red and blue could vary.
	s := colors.String()
	var j interface{}
	err := json.Unmarshal([]byte(s), &j)
	if err != nil {
		t.Errorf("colors.String() isn't valid JSON: %v", err)
	}
	m, ok := j.(map[string]interface{})
	if !ok {
		t.Error("colors.String() didn't produce a map.")
	}
	red := m["red"]
	x, ok := red.(float64)
	if !ok {
		t.Error("red.Kind() is not a number.")
	}
	if x != 3 {
		t.Errorf("red = %v, want 3", x)
	}
}

func BenchmarkMapSet(b *testing.B) {
	m := new(Map).Init()

	v := new(Int)

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			m.Set("red", v)
		}
	})
}

func BenchmarkMapAddSame(b *testing.B) {
	for i := 0; i < b.N; i++ {
		m := new(Map).Init()
		m.Add("red", 1)
		m.Add("red", 1)
		m.Add("red", 1)
		m.Add("red", 1)
	}
}

func BenchmarkMapAddDifferent(b *testing.B) {
	for i := 0; i < b.N; i++ {
		m := new(Map).Init()
		m.Add("red", 1)
		m.Add("blue", 1)
		m.Add("green", 1)
		m.Add("yellow", 1)
	}
}

func TestFunc(t *testing.T) {
	RemoveAll()
	var x interface{} = []string{"a", "b"}
	f := Func(func() interface{} { return x })
	if s, exp := f.String(), `["a","b"]`; s != exp {
		t.Errorf(`f.String() = %q, want %q`, s, exp)
	}

	x = 17
	if s, exp := f.String(), `17`; s != exp {
		t.Errorf(`f.String() = %q, want %q`, s, exp)
	}
}

func TestHandler(t *testing.T) {
	RemoveAll()
	m := NewMap("map1")
	m.Add("a", 1)
	m.Add("z", 2)
	m2 := NewMap("map2")
	for i := 0; i < 9; i++ {
		m2.Add(strconv.Itoa(i), int64(i))
	}
	rr := httptest.NewRecorder()
	rr.Body = new(bytes.Buffer)
	expvarHandler(rr, nil)
	want := `{
"map1": {"a": 1, "z": 2},
"map2": {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8}
}
`
	if got := rr.Body.String(); got != want {
		t.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got, want)
	}
}

func BenchmarkRealworldExpvarUsage(b *testing.B) {
	var (
		bytesSent Int
		bytesRead Int
	)

	// The benchmark creates GOMAXPROCS client/server pairs.
	// Each pair creates 4 goroutines: client reader/writer and server reader/writer.
	// The benchmark stresses concurrent reading and writing to the same connection.
	// Such pattern is used in net/http and net/rpc.

	b.StopTimer()

	P := runtime.GOMAXPROCS(0)
	N := b.N / P
	W := 1000

	// Setup P client/server connections.
	clients := make([]net.Conn, P)
	servers := make([]net.Conn, P)
	ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		b.Fatalf("Listen failed: %v", err)
	}
	defer ln.Close()
	done := make(chan bool)
	go func() {
		for p := 0; p < P; p++ {
			s, err := ln.Accept()
			if err != nil {
				b.Errorf("Accept failed: %v", err)
				return
			}
			servers[p] = s
		}
		done <- true
	}()
	for p := 0; p < P; p++ {
		c, err := net.Dial("tcp", ln.Addr().String())
		if err != nil {
			b.Fatalf("Dial failed: %v", err)
		}
		clients[p] = c
	}
	<-done

	b.StartTimer()

	var wg sync.WaitGroup
	wg.Add(4 * P)
	for p := 0; p < P; p++ {
		// Client writer.
		go func(c net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				v := byte(i)
				for w := 0; w < W; w++ {
					v *= v
				}
				buf[0] = v
				n, err := c.Write(buf[:])
				if err != nil {
					b.Errorf("Write failed: %v", err)
					return
				}

				bytesSent.Add(int64(n))
			}
		}(clients[p])

		// Pipe between server reader and server writer.
		pipe := make(chan byte, 128)

		// Server reader.
		go func(s net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				n, err := s.Read(buf[:])

				if err != nil {
					b.Errorf("Read failed: %v", err)
					return
				}

				bytesRead.Add(int64(n))
				pipe <- buf[0]
			}
		}(servers[p])

		// Server writer.
		go func(s net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				v := <-pipe
				for w := 0; w < W; w++ {
					v *= v
				}
				buf[0] = v
				n, err := s.Write(buf[:])
				if err != nil {
					b.Errorf("Write failed: %v", err)
					return
				}

				bytesSent.Add(int64(n))
			}
			s.Close()
		}(servers[p])

		// Client reader.
		go func(c net.Conn) {
			defer wg.Done()
			var buf [1]byte
			for i := 0; i < N; i++ {
				n, err := c.Read(buf[:])

				if err != nil {
					b.Errorf("Read failed: %v", err)
					return
				}

				bytesRead.Add(int64(n))
			}
			c.Close()
		}(clients[p])
	}
	wg.Wait()
}
<|endoftext|>


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

package main

import (
	"fmt"
	"github.com/jacobsa/aws/exp/sdb"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"math/rand"
	"sort"
	"sync"
)

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type integrationTest struct {
	db sdb.SimpleDB
}

func (t *integrationTest) SetUp(i *TestInfo) {
	var err error

	// Open a connection.
	t.db, err = sdb.NewSimpleDB(g_region, g_accessKey)
	AssertEq(nil, err)
}

// Generate an item name likely to be unique.
func (t *integrationTest) makeItemName() sdb.ItemName {
	return sdb.ItemName(fmt.Sprintf("item.%16x", uint64(rand.Int63())))
}

type nameSortedAttrList []sdb.Attribute

func (l nameSortedAttrList) Len() int           { return len(l) }
func (l nameSortedAttrList) Less(i, j int) bool { return l[i].Name < l[j].Name }
func (l nameSortedAttrList) Swap(i, j int)      { l[j], l[i] = l[i], l[j] }

func sortByName(attrs []sdb.Attribute) []sdb.Attribute {
	res := make(nameSortedAttrList, len(attrs))
	copy(res, attrs)
	sort.Sort(res)
	return res
}

////////////////////////////////////////////////////////////////////////
// Domains
////////////////////////////////////////////////////////////////////////

var g_domainsTestDb sdb.SimpleDB
var g_domainsTestDomain0 sdb.Domain
var g_domainsTestDomain1 sdb.Domain

type DomainsTest struct {
	integrationTest

	mutex           sync.Mutex
	domainsToDelete []sdb.Domain  // Protected by mutex
}

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

func (t *DomainsTest) SetUpTestSuite() {
	var err error

	// Open a connection.
	g_domainsTestDb, err = sdb.NewSimpleDB(g_region, g_accessKey)
	if err != nil {
		panic(err)
	}

	// Create domain 0.
	g_domainsTestDomain0, err = g_domainsTestDb.OpenDomain("DomainsTest.domain0")
	if err != nil {
		panic(err)
	}

	// Create domain 1.
	g_domainsTestDomain1, err = g_domainsTestDb.OpenDomain("DomainsTest.domain1")
	if err != nil {
		panic(err)
	}
}

func (t *DomainsTest) TearDownTestSuite() {
	// Delete both domains.
	if err := g_domainsTestDb.DeleteDomain(g_domainsTestDomain0); err != nil {
		panic(err)
	}

	if err := g_domainsTestDb.DeleteDomain(g_domainsTestDomain1); err != nil {
		panic(err)
	}

	// Clear variables.
	g_domainsTestDb = nil
	g_domainsTestDomain0 = nil
	g_domainsTestDomain1 = nil
}

func (t *DomainsTest) TearDown() {
	t.mutex.Lock()
	defer t.mutex.Unlock()

	// Delete each of the domains created during the test.
	for _, d := range t.domainsToDelete {
		ExpectEq(nil, t.db.DeleteDomain(d), "Domain: %s", d.Name())
	}
}

func (t *DomainsTest) InvalidAccessKey() {
	// Open a connection with an unknown key ID.
	wrongKey := g_accessKey
	wrongKey.Id += "taco"

	db, err := sdb.NewSimpleDB(g_region, wrongKey)
	AssertEq(nil, err)

	// Attempt to create a domain.
	_, err = db.OpenDomain("some_domain")

	ExpectThat(err, Error(HasSubstr("403")))
	ExpectThat(err, Error(HasSubstr("Key Id")))
	ExpectThat(err, Error(HasSubstr("exist")))
}

func (t *DomainsTest) SeparatelyNamedDomainsHaveIndependentItems() {
	var err error

	// Set up an item in the first domain.
	itemName := t.makeItemName()
	err = g_domainsTestDomain0.PutAttributes(
		itemName,
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "enchilada", Value: "queso"},
		},
		[]sdb.Precondition{},
	)

	AssertEq(nil, err)

	// Get attributes for the same name in the other domain. There should be
	// none.
	attrs, err := g_domainsTestDomain1.GetAttributes(itemName, true, []string{})
	AssertEq(nil, err)

	ExpectThat(attrs, ElementsAre())
}

func (t *DomainsTest) IdenticallyNamedDomainsHaveIdenticalItems() {
	var err error

	// Set up an item in the first domain.
	itemName := t.makeItemName()
	err = g_domainsTestDomain0.PutAttributes(
		itemName,
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "enchilada", Value: "queso"},
		},
		[]sdb.Precondition{},
	)

	AssertEq(nil, err)

	// Get attributes for the same name in another domain object opened with the
	// same name.
	domain1, err := t.db.OpenDomain(g_domainsTestDomain0.Name())
	AssertEq(nil, err)

	attrs, err := domain1.GetAttributes(itemName, true, []string{})
	AssertEq(nil, err)

	ExpectThat(
		attrs,
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "enchilada", Value: "queso"}),
		),
	)
}

func (t *DomainsTest) Delete() {
	var err error
	domainName := "DomainsTest.Delete"

	// Create a domain, then delete it.
	domain, err := t.db.OpenDomain(domainName)
	AssertEq(nil, err)

	err = t.db.DeleteDomain(domain)
	AssertEq(nil, err)

	// Delete again; nothing should go wrong.
	err = t.db.DeleteDomain(domain)
	AssertEq(nil, err)

	// Attempt to write to the domain.
	err = domain.PutAttributes(
		"some_item",
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "foo", Value: "bar"},
		},
		[]sdb.Precondition{},
	)

	ExpectThat(err, Error(HasSubstr("NoSuchDomain")))
	ExpectThat(err, Error(HasSubstr("domain")))
	ExpectThat(err, Error(HasSubstr("exist")))
}

////////////////////////////////////////////////////////////////////////
// Items
////////////////////////////////////////////////////////////////////////

var g_itemsTestDb     sdb.SimpleDB
var g_itemsTestDomain sdb.Domain

type ItemsTest struct {
	integrationTest
}

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

func (t *ItemsTest) SetUpTestSuite() {
	var err error

	// Open a connection.
	g_itemsTestDb, err = sdb.NewSimpleDB(g_region, g_accessKey)
	if err != nil {
		panic(err)
	}

	// Create a domain.
	g_itemsTestDomain, err = g_itemsTestDb.OpenDomain("ItemsTest.domain")
	if err != nil {
		panic(err)
	}
}

func (t *ItemsTest) TearDownTestSuite() {
	// Delete the domain.
	if err := g_itemsTestDb.DeleteDomain(g_itemsTestDomain); err != nil {
		panic(err)
	}

	// Clear variables.
	g_itemsTestDb = nil
	g_itemsTestDomain = nil
}

func (t *ItemsTest) PutThenGet() {
	var err error
	item := t.makeItemName()

	// Put
	err = g_itemsTestDomain.PutAttributes(
		item,
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "foo", Value: "taco"},
			sdb.PutUpdate{Name: "bar", Value: "burrito"},
			sdb.PutUpdate{Name: "baz", Value: "enchilada"},
		},
		[]sdb.Precondition{},
	)

	AssertEq(nil, err)

	// Get
	attrs, err := g_itemsTestDomain.GetAttributes(item, true, nil)

	AssertEq(nil, err)
	ExpectThat(
		sortByName(attrs),
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "bar", Value: "burrito"}),
			DeepEquals(sdb.Attribute{Name: "baz", Value: "enchilada"}),
			DeepEquals(sdb.Attribute{Name: "foo", Value: "taco"}),
		),
	)
}

func (t *ItemsTest) BatchPutThenGet() {
	var err error
	item0 := t.makeItemName()
	item1 := t.makeItemName()

	// Batch put
	err = g_itemsTestDomain.BatchPutAttributes(
		map[sdb.ItemName][]sdb.PutUpdate{
			item0: []sdb.PutUpdate{
				sdb.PutUpdate{Name: "foo", Value: "taco"},
				sdb.PutUpdate{Name: "bar", Value: "burrito"},
			},
			item1: []sdb.PutUpdate{
			sdb.PutUpdate{Name: "baz", Value: "enchilada"},
			},
		},
	)

	AssertEq(nil, err)

	// Get for item 0
	attrs, err := g_itemsTestDomain.GetAttributes(item0, true, nil)

	AssertEq(nil, err)
	ExpectThat(
		sortByName(attrs),
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "bar", Value: "burrito"}),
			DeepEquals(sdb.Attribute{Name: "foo", Value: "taco"}),
		),
	)

	// Get for item 1
	attrs, err = g_itemsTestDomain.GetAttributes(item1, true, nil)

	AssertEq(nil, err)
	ExpectThat(
		sortByName(attrs),
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "baz", Value: "enchilada"}),
		),
	)
}

func (t *ItemsTest) GetForNonExistentItem() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) GetParticularAttributes() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) GetNonExistentAttributeName() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) FailedValuePrecondition() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) FailedExistencePrecondition() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) FailedNonExistencePrecondition() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SuccessfulPreconditions() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) DeleteParticularAttributes() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) DeleteAllAttributes() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) BatchDelete() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) InvalidSelectQuery() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectAll() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectItemName() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectCount() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectWithPredicates() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectWithSortOrder() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectWithLimit() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectEmptyResultSet() {
	ExpectEq("TODO", "")
}

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

package main

import (
	"fmt"
	"github.com/jacobsa/aws/exp/sdb"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"math/rand"
	"sort"
	"sync"
)

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type integrationTest struct {
	db sdb.SimpleDB
}

func (t *integrationTest) SetUp(i *TestInfo) {
	var err error

	// Open a connection.
	t.db, err = sdb.NewSimpleDB(g_region, g_accessKey)
	AssertEq(nil, err)
}

// Generate an item name likely to be unique.
func (t *integrationTest) makeItemName() sdb.ItemName {
	return sdb.ItemName(fmt.Sprintf("item.%16x", uint64(rand.Int63())))
}

type nameSortedAttrList []sdb.Attribute

func (l nameSortedAttrList) Len() int           { return len(l) }
func (l nameSortedAttrList) Less(i, j int) bool { return l[i].Name < l[j].Name }
func (l nameSortedAttrList) Swap(i, j int)      { l[j], l[i] = l[i], l[j] }

func sortByName(attrs []sdb.Attribute) []sdb.Attribute {
	res := make(nameSortedAttrList, len(attrs))
	copy(res, attrs)
	sort.Sort(res)
	return res
}

////////////////////////////////////////////////////////////////////////
// Domains
////////////////////////////////////////////////////////////////////////

var g_domainsTestDb sdb.SimpleDB
var g_domainsTestDomain0 sdb.Domain
var g_domainsTestDomain1 sdb.Domain

type DomainsTest struct {
	integrationTest

	mutex           sync.Mutex
	domainsToDelete []sdb.Domain  // Protected by mutex
}

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

func (t *DomainsTest) SetUpTestSuite() {
	var err error

	// Open a connection.
	g_domainsTestDb, err = sdb.NewSimpleDB(g_region, g_accessKey)
	if err != nil {
		panic(err)
	}

	// Create domain 0.
	g_domainsTestDomain0, err = g_domainsTestDb.OpenDomain("DomainsTest.domain0")
	if err != nil {
		panic(err)
	}

	// Create domain 1.
	g_domainsTestDomain1, err = g_domainsTestDb.OpenDomain("DomainsTest.domain1")
	if err != nil {
		panic(err)
	}
}

func (t *DomainsTest) TearDownTestSuite() {
	// Delete both domains.
	if err := g_domainsTestDb.DeleteDomain(g_domainsTestDomain0); err != nil {
		panic(err)
	}

	if err := g_domainsTestDb.DeleteDomain(g_domainsTestDomain1); err != nil {
		panic(err)
	}

	// Clear variables.
	g_domainsTestDb = nil
	g_domainsTestDomain0 = nil
	g_domainsTestDomain1 = nil
}

func (t *DomainsTest) TearDown() {
	t.mutex.Lock()
	defer t.mutex.Unlock()

	// Delete each of the domains created during the test.
	for _, d := range t.domainsToDelete {
		ExpectEq(nil, t.db.DeleteDomain(d), "Domain: %s", d.Name())
	}
}

func (t *DomainsTest) InvalidAccessKey() {
	// Open a connection with an unknown key ID.
	wrongKey := g_accessKey
	wrongKey.Id += "taco"

	db, err := sdb.NewSimpleDB(g_region, wrongKey)
	AssertEq(nil, err)

	// Attempt to create a domain.
	_, err = db.OpenDomain("some_domain")

	ExpectThat(err, Error(HasSubstr("403")))
	ExpectThat(err, Error(HasSubstr("Key Id")))
	ExpectThat(err, Error(HasSubstr("exist")))
}

func (t *DomainsTest) SeparatelyNamedDomainsHaveIndependentItems() {
	var err error

	// Set up an item in the first domain.
	itemName := t.makeItemName()
	err = g_domainsTestDomain0.PutAttributes(
		itemName,
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "enchilada", Value: "queso"},
		},
		[]sdb.Precondition{},
	)

	AssertEq(nil, err)

	// Get attributes for the same name in the other domain. There should be
	// none.
	attrs, err := g_domainsTestDomain1.GetAttributes(itemName, true, []string{})
	AssertEq(nil, err)

	ExpectThat(attrs, ElementsAre())
}

func (t *DomainsTest) IdenticallyNamedDomainsHaveIdenticalItems() {
	var err error

	// Set up an item in the first domain.
	itemName := t.makeItemName()
	err = g_domainsTestDomain0.PutAttributes(
		itemName,
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "enchilada", Value: "queso"},
		},
		[]sdb.Precondition{},
	)

	AssertEq(nil, err)

	// Get attributes for the same name in another domain object opened with the
	// same name.
	domain1, err := t.db.OpenDomain(g_domainsTestDomain0.Name())
	AssertEq(nil, err)

	attrs, err := domain1.GetAttributes(itemName, true, []string{})
	AssertEq(nil, err)

	ExpectThat(
		attrs,
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "enchilada", Value: "queso"}),
		),
	)
}

func (t *DomainsTest) Delete() {
	var err error
	domainName := "DomainsTest.Delete"

	// Create a domain, then delete it.
	domain, err := t.db.OpenDomain(domainName)
	AssertEq(nil, err)

	err = t.db.DeleteDomain(domain)
	AssertEq(nil, err)

	// Delete again; nothing should go wrong.
	err = t.db.DeleteDomain(domain)
	AssertEq(nil, err)

	// Attempt to write to the domain.
	err = domain.PutAttributes(
		"some_item",
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "foo", Value: "bar"},
		},
		[]sdb.Precondition{},
	)

	ExpectThat(err, Error(HasSubstr("NoSuchDomain")))
	ExpectThat(err, Error(HasSubstr("domain")))
	ExpectThat(err, Error(HasSubstr("exist")))
}

////////////////////////////////////////////////////////////////////////
// Items
////////////////////////////////////////////////////////////////////////

var g_itemsTestDb     sdb.SimpleDB
var g_itemsTestDomain sdb.Domain

type ItemsTest struct {
	integrationTest
}

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

func (t *ItemsTest) SetUpTestSuite() {
	var err error

	// Open a connection.
	g_itemsTestDb, err = sdb.NewSimpleDB(g_region, g_accessKey)
	if err != nil {
		panic(err)
	}

	// Create a domain.
	g_itemsTestDomain, err = g_itemsTestDb.OpenDomain("ItemsTest.domain")
	if err != nil {
		panic(err)
	}
}

func (t *ItemsTest) TearDownTestSuite() {
	// Delete the domain.
	if err := g_itemsTestDb.DeleteDomain(g_itemsTestDomain); err != nil {
		panic(err)
	}

	// Clear variables.
	g_itemsTestDb = nil
	g_itemsTestDomain = nil
}

func (t *ItemsTest) PutThenGet() {
	var err error
	item := t.makeItemName()

	// Put
	err = g_itemsTestDomain.PutAttributes(
		item,
		[]sdb.PutUpdate{
			sdb.PutUpdate{Name: "foo", Value: "taco"},
			sdb.PutUpdate{Name: "bar", Value: "burrito"},
			sdb.PutUpdate{Name: "baz", Value: "enchilada"},
		},
		[]sdb.Precondition{},
	)

	AssertEq(nil, err)

	// Get
	attrs, err := g_itemsTestDomain.GetAttributes(item, true, nil)

	AssertEq(nil, err)
	ExpectThat(
		sortByName(attrs),
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "bar", Value: "burrito"}),
			DeepEquals(sdb.Attribute{Name: "baz", Value: "enchilada"}),
			DeepEquals(sdb.Attribute{Name: "foo", Value: "taco"}),
		),
	)
}

func (t *ItemsTest) BatchPutThenGet() {
	var err error
	item0 := t.makeItemName()
	item1 := t.makeItemName()

	// Batch put
	err = g_itemsTestDomain.BatchPutAttributes(
		map[sdb.ItemName][]sdb.PutUpdate{
			item0: []sdb.PutUpdate{
				sdb.PutUpdate{Name: "foo", Value: "taco"},
				sdb.PutUpdate{Name: "bar", Value: "burrito"},
			},
			item1: []sdb.PutUpdate{
			sdb.PutUpdate{Name: "baz", Value: "enchilada"},
			},
		},
	)

	AssertEq(nil, err)

	// Get for item 0
	attrs, err := g_itemsTestDomain.GetAttributes(item0, true, nil)

	AssertEq(nil, err)
	ExpectThat(
		sortByName(attrs),
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "bar", Value: "burrito"}),
			DeepEquals(sdb.Attribute{Name: "foo", Value: "taco"}),
		),
	)

	// Get for item 1
	attrs, err = g_itemsTestDomain.GetAttributes(item1, true, nil)

	AssertEq(nil, err)
	ExpectThat(
		sortByName(attrs),
		ElementsAre(
			DeepEquals(sdb.Attribute{Name: "baz", Value: "enchilada"}),
		),
	)
}

func (t *ItemsTest) GetForNonExistentItem() {
	var err error
	itemName := t.makeItemName()

	// Get
	attrs, err := g_itemsTestDomain.GetAttributes(itemName, true, nil)

	AssertEq(nil, err)
	ExpectThat(attrs, ElementsAre())
}

func (t *ItemsTest) GetParticularAttributes() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) GetNonExistentAttributeName() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) FailedValuePrecondition() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) FailedExistencePrecondition() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) FailedNonExistencePrecondition() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SuccessfulPreconditions() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) DeleteParticularAttributes() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) DeleteAllAttributes() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) BatchDelete() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) InvalidSelectQuery() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectAll() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectItemName() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectCount() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectWithPredicates() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectWithSortOrder() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectWithLimit() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectEmptyResultSet() {
	ExpectEq("TODO", "")
}

func (t *ItemsTest) SelectLargeResultSet() {
	ExpectEq("TODO", "")
}
<|endoftext|>


<commit_before>package registry

import (
	"reflect"
	"testing"
)

func TestRegistry(t *testing.T) {
	name := "test"
	json := `{"aliases": ["test"]}`
	Register(name, json)

	if jsonOut := languages[name]; jsonOut != json {
		t.Fatalf("Register(%q, %q); languages[%q] = %q; not %q", name, json, name, jsonOut, json)
	}

	lang, err := Lookup(name)
	if err != nil {
		t.Fatal(err)
	}
	expectedLang := Language{
		Aliases: []string{"test"},
	}
	if !reflect.DeepEqual(lang, expectedLang) {
		t.Fatalf("Lookup(%q) = %+v; not %+v", name, lang, expectedLang)
	}
}
<commit_msg>registry: fixed test<commit_after>package registry

import (
	"reflect"
	"testing"
)

func TestRegistry(t *testing.T) {
	name := "test"
	json := `{"aliases": ["test"]}`
	Register([]string{name}, json)

	if jsonOut := languages[name]; jsonOut != json {
		t.Fatalf("Register(%q, %q); languages[%q] = %q; not %q", name, json, name, jsonOut, json)
	}

	lang, err := Lookup(name)
	if err != nil {
		t.Fatal(err)
	}
	expectedLang := Language{
		Aliases: []string{"test"},
	}
	if !reflect.DeepEqual(lang, expectedLang) {
		t.Fatalf("Lookup(%q) = %+v; not %+v", name, lang, expectedLang)
	}
}
<|endoftext|>