<commit_before>package main

import (
	"fmt"
	"os/exec"
	"strings"
	"testing"
	"time"
)

// Regression test for https://github.com/docker/docker/issues/7843
func TestStartAttachReturnsOnError(t *testing.T) {
	defer deleteAllContainers()

	dockerCmd(t, "run", "-d", "--name", "test", "busybox")
	dockerCmd(t, "wait", "test")

	// Expect this to fail because the above container is stopped, this is what we want
	if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "--link", "test:test", "busybox")); err == nil {
		t.Fatal("Expected error but got none")
	}

	ch := make(chan struct{})
	go func() {
		// Attempt to start attached to the container that won't start
		// This should return an error immediately since the container can't be started
		if _, err := runCommand(exec.Command(dockerBinary, "start", "-a", "test2")); err == nil {
			t.Fatal("Expected error but got none")
		}
		close(ch)
	}()

	select {
	case <-ch:
	case <-time.After(time.Second):
		t.Fatalf("Attach did not exit properly")
	}

	logDone("start - error on start with attach exits")
}

// gh#8555: Exit code should be passed through when using start -a
func TestStartAttachCorrectExitCode(t *testing.T) {
	defer deleteAllContainers()

	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		t.Fatalf("failed to run container: %v, output: %q", err, out)
	}

	out = strings.TrimSpace(out)

	// make sure the container has exited before trying the "start -a"
	waitCmd := exec.Command(dockerBinary, "wait", out)
	if _, _, err = runCommandWithOutput(waitCmd); err != nil {
		t.Fatalf("Failed to wait on container: %v", err)
	}

	startCmd := exec.Command(dockerBinary, "start", "-a", out)
	startOut, exitCode, err := runCommandWithOutput(startCmd)
	if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) {
		t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
	}
	if exitCode != 1 {
		t.Fatalf("start -a did not respond with proper exit code: expected 1, got %d", exitCode)
	}

	logDone("start - correct exit code returned with -a")
}

func TestStartSilentAttach(t *testing.T) {
	defer deleteAllContainers()

	name := "teststartattachcorrectexitcode"
	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "echo", "test")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		t.Fatalf("failed to run container: %v, output: %q", err, out)
	}

	// make sure the container has exited before trying the "start -a"
	waitCmd := exec.Command(dockerBinary, "wait", name)
	if _, _, err = runCommandWithOutput(waitCmd); err != nil {
		t.Fatalf("wait command failed with error: %v", err)
	}

	startCmd := exec.Command(dockerBinary, "start", "-a", name)
	startOut, _, err := runCommandWithOutput(startCmd)
	if err != nil {
		t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
	}
	if expected := "test\n"; startOut != expected {
		t.Fatalf("start -a produced unexpected output: expected %q, got %q", expected, startOut)
	}

	logDone("start - don't echo container ID when attaching")
}

func TestStartRecordError(t *testing.T) {
	defer deleteAllContainers()

	// when container runs successfully, we should not have state.Error
	dockerCmd(t, "run", "-d", "-p", "9999:9999", "--name", "test", "busybox", "top")
	stateErr, err := inspectField("test", "State.Error")
	if err != nil {
		t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
	}
	if stateErr != "" {
		t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
	}

	// Expect this to fail and records error because of ports conflict
	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "-p", "9999:9999", "busybox", "top"))
	if err == nil {
		t.Fatalf("Expected error but got none, output %q", out)
	}
	stateErr, err = inspectField("test2", "State.Error")
	if err != nil {
		t.Fatalf("Failed to inspect %q state's error, got error %q", "test2", err)
	}
	expected := "port is already allocated"
	if stateErr == "" || !strings.Contains(stateErr, expected) {
		t.Fatalf("State.Error(%q) does not include %q", stateErr, expected)
	}

	// Expect the conflict to be resolved when we stop the initial container
	dockerCmd(t, "stop", "test")
	dockerCmd(t, "start", "test2")
	stateErr, err = inspectField("test2", "State.Error")
	if err != nil {
		t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
	}
	if stateErr != "" {
		t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
	}

	logDone("start - set state error when start is unsuccessful")
}

// gh#8726: a failed Start() breaks --volumes-from on subsequent Start()'s
func TestStartVolumesFromFailsCleanly(t *testing.T) {
	defer deleteAllContainers()

	// Create the first data volume
	dockerCmd(t, "run", "-d", "--name", "data_before", "-v", "/foo", "busybox")

	// Expect this to fail because the data test after contaienr doesn't exist yet
	if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "consumer", "--volumes-from", "data_before", "--volumes-from", "data_after", "busybox")); err == nil {
		t.Fatal("Expected error but got none")
	}

	// Create the second data volume
	dockerCmd(t, "run", "-d", "--name", "data_after", "-v", "/bar", "busybox")

	// Now, all the volumes should be there
	dockerCmd(t, "start", "consumer")

	// Check that we have the volumes we want
	out, _, _ := dockerCmd(t, "inspect", "--format='{{ len .Volumes }}'", "consumer")
	nVolumes := strings.Trim(out, " \r\n'")
	if nVolumes != "2" {
		t.Fatalf("Missing volumes: expected 2, got %s", nVolumes)
	}

	logDone("start - missing containers in --volumes-from did not affect subsequent runs")
}

func TestStartPausedContainer(t *testing.T) {
	defer deleteAllContainers()
	defer unpauseAllContainers()

	runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top")
	if out, _, err := runCommandWithOutput(runCmd); err != nil {
		t.Fatal(out, err)
	}

	runCmd = exec.Command(dockerBinary, "pause", "testing")
	if out, _, err := runCommandWithOutput(runCmd); err != nil {
		t.Fatal(out, err)
	}

	runCmd = exec.Command(dockerBinary, "start", "testing")
	if out, _, err := runCommandWithOutput(runCmd); err == nil || !strings.Contains(out, "Cannot start a paused container, try unpause instead.") {
		t.Fatalf("an error should have been shown that you cannot start paused container: %s\n%v", out, err)
	}

	logDone("start - error should show if trying to start paused container")
}

func TestStartMultipleContainers(t *testing.T) {
	defer deleteAllContainers()
	// run a container named 'parent' and create two container link to `parent`
	cmd := exec.Command(dockerBinary, "run", "-d", "--name", "parent", "busybox", "top")
	if out, _, err := runCommandWithOutput(cmd); err != nil {
		t.Fatal(out, err)
	}
	for _, container := range []string{"child_first", "child_second"} {
		cmd = exec.Command(dockerBinary, "create", "--name", container, "--link", "parent:parent", "busybox", "top")
		if out, _, err := runCommandWithOutput(cmd); err != nil {
			t.Fatal(out, err)
		}
	}

	// stop 'parent' container
	cmd = exec.Command(dockerBinary, "stop", "parent")
	if out, _, err := runCommandWithOutput(cmd); err != nil {
		t.Fatal(out, err)
	}
	cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", "parent")
	out, _, err := runCommandWithOutput(cmd)
	if err != nil {
		t.Fatal(out, err)
	}
	out = strings.Trim(out, "\r\n")
	if out != "false" {
		t.Fatal("Container should be stopped")
	}

	// start all the three containers, container `child_first` start first which should be faild
	// container 'parent' start second and then start container 'child_second'
	cmd = exec.Command(dockerBinary, "start", "child_first", "parent", "child_second")
	out, _, err = runCommandWithOutput(cmd)
	if !strings.Contains(out, "Cannot start container child_first") || err == nil {
		t.Fatal("Expected error but got none")
	}

	for container, expected := range map[string]string{"parent": "true", "child_first": "false", "child_second": "true"} {
		cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", container)
		out, _, err = runCommandWithOutput(cmd)
		if err != nil {
			t.Fatal(out, err)
		}
		out = strings.Trim(out, "\r\n")
		if out != expected {
			t.Fatal("Container running state wrong")
		}

	}

	logDone("start - start multiple containers continue on one failed")
}

func TestStartAttachMultipleContainers(t *testing.T) {

	var cmd *exec.Cmd

	defer deleteAllContainers()
	// run  multiple containers to test
	for _, container := range []string{"test1", "test2", "test3"} {
		cmd = exec.Command(dockerBinary, "run", "-d", "--name", container, "busybox", "top")
		if out, _, err := runCommandWithOutput(cmd); err != nil {
			t.Fatal(out, err)
		}
	}

	// stop all the containers
	for _, container := range []string{"test1", "test2", "test3"} {
		cmd = exec.Command(dockerBinary, "stop", container)
		if out, _, err := runCommandWithOutput(cmd); err != nil {
			t.Fatal(out, err)
		}
	}

	// test start and attach multiple containers at once, expected error
	for _, option := range []string{"-a", "-i", "-ai"} {
		cmd = exec.Command(dockerBinary, "start", option, "test1", "test2", "test3")
		out, _, err := runCommandWithOutput(cmd)
		if !strings.Contains(out, "You cannot start and attach multiple containers at once.") || err == nil {
			t.Fatal("Expected error but got none")
		}
	}

	// confirm the state of all the containers be stopped
	for container, expected := range map[string]string{"test1": "false", "test2": "false", "test3": "false"} {
		cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", container)
		out, _, err := runCommandWithOutput(cmd)
		if err != nil {
			t.Fatal(out, err)
		}
		out = strings.Trim(out, "\r\n")
		if out != expected {
			t.Fatal("Container running state wrong")
		}
	}

	logDone("start - error on start and attach multiple containers at once")
}
<commit_msg>Rename TestStartSilentAttach to TestStartAttachSilent<commit_after>package main

import (
	"fmt"
	"os/exec"
	"strings"
	"testing"
	"time"
)

// Regression test for https://github.com/docker/docker/issues/7843
func TestStartAttachReturnsOnError(t *testing.T) {
	defer deleteAllContainers()

	dockerCmd(t, "run", "-d", "--name", "test", "busybox")
	dockerCmd(t, "wait", "test")

	// Expect this to fail because the above container is stopped, this is what we want
	if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "--link", "test:test", "busybox")); err == nil {
		t.Fatal("Expected error but got none")
	}

	ch := make(chan struct{})
	go func() {
		// Attempt to start attached to the container that won't start
		// This should return an error immediately since the container can't be started
		if _, err := runCommand(exec.Command(dockerBinary, "start", "-a", "test2")); err == nil {
			t.Fatal("Expected error but got none")
		}
		close(ch)
	}()

	select {
	case <-ch:
	case <-time.After(time.Second):
		t.Fatalf("Attach did not exit properly")
	}

	logDone("start - error on start with attach exits")
}

// gh#8555: Exit code should be passed through when using start -a
func TestStartAttachCorrectExitCode(t *testing.T) {
	defer deleteAllContainers()

	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		t.Fatalf("failed to run container: %v, output: %q", err, out)
	}

	out = strings.TrimSpace(out)

	// make sure the container has exited before trying the "start -a"
	waitCmd := exec.Command(dockerBinary, "wait", out)
	if _, _, err = runCommandWithOutput(waitCmd); err != nil {
		t.Fatalf("Failed to wait on container: %v", err)
	}

	startCmd := exec.Command(dockerBinary, "start", "-a", out)
	startOut, exitCode, err := runCommandWithOutput(startCmd)
	if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) {
		t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
	}
	if exitCode != 1 {
		t.Fatalf("start -a did not respond with proper exit code: expected 1, got %d", exitCode)
	}

	logDone("start - correct exit code returned with -a")
}

func TestStartAttachSilent(t *testing.T) {
	defer deleteAllContainers()

	name := "teststartattachcorrectexitcode"
	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "echo", "test")
	out, _, _, err := runCommandWithStdoutStderr(runCmd)
	if err != nil {
		t.Fatalf("failed to run container: %v, output: %q", err, out)
	}

	// make sure the container has exited before trying the "start -a"
	waitCmd := exec.Command(dockerBinary, "wait", name)
	if _, _, err = runCommandWithOutput(waitCmd); err != nil {
		t.Fatalf("wait command failed with error: %v", err)
	}

	startCmd := exec.Command(dockerBinary, "start", "-a", name)
	startOut, _, err := runCommandWithOutput(startCmd)
	if err != nil {
		t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut)
	}
	if expected := "test\n"; startOut != expected {
		t.Fatalf("start -a produced unexpected output: expected %q, got %q", expected, startOut)
	}

	logDone("start - don't echo container ID when attaching")
}

func TestStartRecordError(t *testing.T) {
	defer deleteAllContainers()

	// when container runs successfully, we should not have state.Error
	dockerCmd(t, "run", "-d", "-p", "9999:9999", "--name", "test", "busybox", "top")
	stateErr, err := inspectField("test", "State.Error")
	if err != nil {
		t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
	}
	if stateErr != "" {
		t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
	}

	// Expect this to fail and records error because of ports conflict
	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "test2", "-p", "9999:9999", "busybox", "top"))
	if err == nil {
		t.Fatalf("Expected error but got none, output %q", out)
	}
	stateErr, err = inspectField("test2", "State.Error")
	if err != nil {
		t.Fatalf("Failed to inspect %q state's error, got error %q", "test2", err)
	}
	expected := "port is already allocated"
	if stateErr == "" || !strings.Contains(stateErr, expected) {
		t.Fatalf("State.Error(%q) does not include %q", stateErr, expected)
	}

	// Expect the conflict to be resolved when we stop the initial container
	dockerCmd(t, "stop", "test")
	dockerCmd(t, "start", "test2")
	stateErr, err = inspectField("test2", "State.Error")
	if err != nil {
		t.Fatalf("Failed to inspect %q state's error, got error %q", "test", err)
	}
	if stateErr != "" {
		t.Fatalf("Expected to not have state error but got state.Error(%q)", stateErr)
	}

	logDone("start - set state error when start is unsuccessful")
}

// gh#8726: a failed Start() breaks --volumes-from on subsequent Start()'s
func TestStartVolumesFromFailsCleanly(t *testing.T) {
	defer deleteAllContainers()

	// Create the first data volume
	dockerCmd(t, "run", "-d", "--name", "data_before", "-v", "/foo", "busybox")

	// Expect this to fail because the data test after contaienr doesn't exist yet
	if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "consumer", "--volumes-from", "data_before", "--volumes-from", "data_after", "busybox")); err == nil {
		t.Fatal("Expected error but got none")
	}

	// Create the second data volume
	dockerCmd(t, "run", "-d", "--name", "data_after", "-v", "/bar", "busybox")

	// Now, all the volumes should be there
	dockerCmd(t, "start", "consumer")

	// Check that we have the volumes we want
	out, _, _ := dockerCmd(t, "inspect", "--format='{{ len .Volumes }}'", "consumer")
	nVolumes := strings.Trim(out, " \r\n'")
	if nVolumes != "2" {
		t.Fatalf("Missing volumes: expected 2, got %s", nVolumes)
	}

	logDone("start - missing containers in --volumes-from did not affect subsequent runs")
}

func TestStartPausedContainer(t *testing.T) {
	defer deleteAllContainers()
	defer unpauseAllContainers()

	runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "testing", "busybox", "top")
	if out, _, err := runCommandWithOutput(runCmd); err != nil {
		t.Fatal(out, err)
	}

	runCmd = exec.Command(dockerBinary, "pause", "testing")
	if out, _, err := runCommandWithOutput(runCmd); err != nil {
		t.Fatal(out, err)
	}

	runCmd = exec.Command(dockerBinary, "start", "testing")
	if out, _, err := runCommandWithOutput(runCmd); err == nil || !strings.Contains(out, "Cannot start a paused container, try unpause instead.") {
		t.Fatalf("an error should have been shown that you cannot start paused container: %s\n%v", out, err)
	}

	logDone("start - error should show if trying to start paused container")
}

func TestStartMultipleContainers(t *testing.T) {
	defer deleteAllContainers()
	// run a container named 'parent' and create two container link to `parent`
	cmd := exec.Command(dockerBinary, "run", "-d", "--name", "parent", "busybox", "top")
	if out, _, err := runCommandWithOutput(cmd); err != nil {
		t.Fatal(out, err)
	}
	for _, container := range []string{"child_first", "child_second"} {
		cmd = exec.Command(dockerBinary, "create", "--name", container, "--link", "parent:parent", "busybox", "top")
		if out, _, err := runCommandWithOutput(cmd); err != nil {
			t.Fatal(out, err)
		}
	}

	// stop 'parent' container
	cmd = exec.Command(dockerBinary, "stop", "parent")
	if out, _, err := runCommandWithOutput(cmd); err != nil {
		t.Fatal(out, err)
	}
	cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", "parent")
	out, _, err := runCommandWithOutput(cmd)
	if err != nil {
		t.Fatal(out, err)
	}
	out = strings.Trim(out, "\r\n")
	if out != "false" {
		t.Fatal("Container should be stopped")
	}

	// start all the three containers, container `child_first` start first which should be faild
	// container 'parent' start second and then start container 'child_second'
	cmd = exec.Command(dockerBinary, "start", "child_first", "parent", "child_second")
	out, _, err = runCommandWithOutput(cmd)
	if !strings.Contains(out, "Cannot start container child_first") || err == nil {
		t.Fatal("Expected error but got none")
	}

	for container, expected := range map[string]string{"parent": "true", "child_first": "false", "child_second": "true"} {
		cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", container)
		out, _, err = runCommandWithOutput(cmd)
		if err != nil {
			t.Fatal(out, err)
		}
		out = strings.Trim(out, "\r\n")
		if out != expected {
			t.Fatal("Container running state wrong")
		}

	}

	logDone("start - start multiple containers continue on one failed")
}

func TestStartAttachMultipleContainers(t *testing.T) {

	var cmd *exec.Cmd

	defer deleteAllContainers()
	// run  multiple containers to test
	for _, container := range []string{"test1", "test2", "test3"} {
		cmd = exec.Command(dockerBinary, "run", "-d", "--name", container, "busybox", "top")
		if out, _, err := runCommandWithOutput(cmd); err != nil {
			t.Fatal(out, err)
		}
	}

	// stop all the containers
	for _, container := range []string{"test1", "test2", "test3"} {
		cmd = exec.Command(dockerBinary, "stop", container)
		if out, _, err := runCommandWithOutput(cmd); err != nil {
			t.Fatal(out, err)
		}
	}

	// test start and attach multiple containers at once, expected error
	for _, option := range []string{"-a", "-i", "-ai"} {
		cmd = exec.Command(dockerBinary, "start", option, "test1", "test2", "test3")
		out, _, err := runCommandWithOutput(cmd)
		if !strings.Contains(out, "You cannot start and attach multiple containers at once.") || err == nil {
			t.Fatal("Expected error but got none")
		}
	}

	// confirm the state of all the containers be stopped
	for container, expected := range map[string]string{"test1": "false", "test2": "false", "test3": "false"} {
		cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", container)
		out, _, err := runCommandWithOutput(cmd)
		if err != nil {
			t.Fatal(out, err)
		}
		out = strings.Trim(out, "\r\n")
		if out != expected {
			t.Fatal("Container running state wrong")
		}
	}

	logDone("start - error on start and attach multiple containers at once")
}
<|endoftext|>


<commit_before>// Copyright 2014 Hajime Hoshi
//
// 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 opengl

import (
	"fmt"
	"strings"

	"github.com/hajimehoshi/ebiten/internal/graphics"
)

type shaderID int

const (
	shaderVertexModelview shaderID = iota
	shaderFragmentColorMatrix
)

func shaderStr(id shaderID) string {
	switch id {
	case shaderVertexModelview:
		return shaderStrVertex
	case shaderFragmentColorMatrix:
		replaces := map[string]string{
			"{{.FilterNearest}}":      fmt.Sprintf("%d", graphics.FilterNearest),
			"{{.FilterLinear}}":       fmt.Sprintf("%d", graphics.FilterLinear),
			"{{.FilterScreen}}":       fmt.Sprintf("%d", graphics.FilterScreen),
			"{{.AddressClampToZero}}": fmt.Sprintf("%d", graphics.AddressClampToZero),
			"{{.AddressRepeat}}":      fmt.Sprintf("%d", graphics.AddressRepeat),
		}
		src := shaderStrFragment
		for k, v := range replaces {
			src = strings.Replace(src, k, v, -1)
		}
		return src
	default:
		panic("not reached")
	}
}

const (
	shaderStrVertex = `
uniform vec2 viewport_size;
attribute vec2 vertex;
attribute vec2 tex;
attribute vec4 tex_region;
attribute vec4 color_scale;
varying vec2 varying_tex;
varying vec4 varying_tex_region;
varying vec4 varying_color_scale;

void main(void) {
  varying_tex = tex;
  varying_tex_region = tex_region;
  varying_color_scale = color_scale;

  mat4 projection_matrix = mat4(
    vec4(2.0 / viewport_size.x, 0, 0, 0),
    vec4(0, 2.0 / viewport_size.y, 0, 0),
    vec4(0, 0, 1, 0),
    vec4(-1, -1, 0, 1)
  );
  gl_Position = projection_matrix * vec4(vertex, 0, 1);
}
`
	shaderStrFragment = `
#if defined(GL_ES)
precision mediump float;
#else
#define lowp
#define mediump
#define highp
#endif

#define FILTER_NEAREST ({{.FilterNearest}})
#define FILTER_LINEAR ({{.FilterLinear}})
#define FILTER_SCREEN ({{.FilterScreen}})
#define ADDRESS_CLAMP_TO_ZERO ({{.AddressClampToZero}})
#define ADDRESS_REPEAT ({{.AddressRepeat}})

uniform sampler2D texture;
uniform mat4 color_matrix_body;
uniform vec4 color_matrix_translation;

uniform int filter_type;
uniform highp vec2 source_size;
uniform int address;

#if defined(FILTER_SCREEN)
uniform highp float scale;
#endif

varying highp vec2 varying_tex;
varying highp vec4 varying_tex_region;
varying highp vec4 varying_color_scale;

// adjustTexel adjusts the two texels and returns the adjusted second texel.
// When p1 - p0 is exactly equal to the texel size, jaggy can happen on macOS (#669).
// In order to avoid this jaggy, subtract a little bit from the second texel.
highp vec2 adjustTexel(highp vec2 p0, highp vec2 p1) {
  highp vec2 texel_size = 1.0 / source_size;
  if (fract((p1.x-p0.x)*source_size.x) == 0.0) {
    p1.x -= texel_size.x / 512.0;
  }
  if (fract((p1.y-p0.y)*source_size.y) == 0.0) {
    p1.y -= texel_size.y / 512.0;
  }
  return p1;
}

highp float floorMod(highp float x, highp float y) {
  if (x < 0.0) {
    return y - (-x - y * floor(-x/y));
  }
  return x - y * floor(x/y);
}

highp vec2 adjustTexelByAddress(highp vec2 p, highp vec4 tex_region, int address) {
  if (address == ADDRESS_CLAMP_TO_ZERO) {
    return p;
  }
  if (address == ADDRESS_REPEAT) {
    highp vec2 o = vec2(tex_region[0], tex_region[1]);
    highp vec2 size = vec2(tex_region[2] - tex_region[0], tex_region[3] - tex_region[1]);
    return vec2(floorMod((p.x - o.x), size.x) + o.x, floorMod((p.y - o.y), size.y) + o.y);
  }
  // Not reached.
  return vec2(0.0);
}

void main(void) {
  highp vec2 pos = varying_tex;
  highp vec2 texel_size = 1.0 / source_size;

  vec4 color;

  if (filter_type == FILTER_NEAREST) {
    pos = adjustTexelByAddress(pos, varying_tex_region, address);
    color = texture2D(texture, pos);
    if (pos.x < varying_tex_region[0] ||
      pos.y < varying_tex_region[1] ||
      (varying_tex_region[2] - texel_size.x / 512.0) <= pos.x ||
      (varying_tex_region[3] - texel_size.y / 512.0) <= pos.y) {
      color = vec4(0, 0, 0, 0);
    }
  } else if (filter_type == FILTER_LINEAR) {
    highp vec2 p0 = pos - texel_size / 2.0;
    highp vec2 p1 = pos + texel_size / 2.0;

    p1 = adjustTexel(p0, p1);
    p0 = adjustTexelByAddress(p0, varying_tex_region, address);
    p1 = adjustTexelByAddress(p1, varying_tex_region, address);

    vec4 c0 = texture2D(texture, p0);
    vec4 c1 = texture2D(texture, vec2(p1.x, p0.y));
    vec4 c2 = texture2D(texture, vec2(p0.x, p1.y));
    vec4 c3 = texture2D(texture, p1);
    if (p0.x < varying_tex_region[0]) {
      c0 = vec4(0, 0, 0, 0);
      c2 = vec4(0, 0, 0, 0);
    }
    if (p0.y < varying_tex_region[1]) {
      c0 = vec4(0, 0, 0, 0);
      c1 = vec4(0, 0, 0, 0);
    }
    if ((varying_tex_region[2] - texel_size.x / 512.0) <= p1.x) {
      c1 = vec4(0, 0, 0, 0);
      c3 = vec4(0, 0, 0, 0);
    }
    if ((varying_tex_region[3] - texel_size.y / 512.0) <= p1.y) {
      c2 = vec4(0, 0, 0, 0);
      c3 = vec4(0, 0, 0, 0);
    }

    vec2 rate = fract(p0 * source_size);
    color = mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
  } else if (filter_type == FILTER_SCREEN) {
    highp vec2 p0 = pos - texel_size / 2.0 / scale;
    highp vec2 p1 = pos + texel_size / 2.0 / scale;

    p1 = adjustTexel(p0, p1);

    vec4 c0 = texture2D(texture, p0);
    vec4 c1 = texture2D(texture, vec2(p1.x, p0.y));
    vec4 c2 = texture2D(texture, vec2(p0.x, p1.y));
    vec4 c3 = texture2D(texture, p1);
    // Texels must be in the source rect, so it is not necessary to check that like linear filter.

    vec2 rateCenter = vec2(1.0, 1.0) - texel_size / 2.0 / scale;
    vec2 rate = clamp(((fract(p0 * source_size) - rateCenter) * scale) + rateCenter, 0.0, 1.0);
    color = mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
  } else {
    // Not reached.
    discard;
  }

  // Un-premultiply alpha
  if (0.0 < color.a) {
    color.rgb /= color.a;
  }
  // Apply the color matrix or scale.
  color = (color_matrix_body * color) + color_matrix_translation;
  color *= varying_color_scale;
  color = clamp(color, 0.0, 1.0);
  // Premultiply alpha
  color.rgb *= color.a;

  gl_FragColor = color;
}
`
)
<commit_msg>graphicsdriver/opengl: Check the reserved keyword<commit_after>// Copyright 2014 Hajime Hoshi
//
// 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 opengl

import (
	"fmt"
	"regexp"
	"strings"

	"github.com/hajimehoshi/ebiten/internal/graphics"
)

type shaderID int

const (
	shaderVertexModelview shaderID = iota
	shaderFragmentColorMatrix
)

// glslReservedKeywords is a set of reserved keywords that cannot be used as an indentifier on some environments.
// See https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf.
var glslReservedKeywords = map[string]struct{}{
	"common": {}, "partition": {}, "active": {},
	"asm":   {},
	"class": {}, "union": {}, "enum": {}, "typedef": {}, "template": {}, "this": {},
	"resource": {},
	"goto":     {},
	"inline":   {}, "noinline": {}, "public": {}, "static": {}, "extern": {}, "external": {}, "interface": {},
	"long": {}, "short": {}, "half": {}, "fixed": {}, "unsigned": {}, "superp": {},
	"input": {}, "output": {},
	"hvec2": {}, "hvec3": {}, "hvec4": {}, "fvec2": {}, "fvec3": {}, "fvec4": {},
	"filter": {},
	"sizeof": {}, "cast": {},
	"namespace": {}, "using": {},
	"sampler3DRect": {},
}

var glslIdentifier = regexp.MustCompile(`[_a-zA-Z][_a-zA-Z0-9]*`)

func checkGLSL(src string) {
	for _, l := range strings.Split(src, "\n") {
		if strings.Contains(l, "//") {
			l = l[:strings.Index(l, "//")]
		}
		for _, token := range glslIdentifier.FindAllString(l, -1) {
			if _, ok := glslReservedKeywords[token]; ok {
				panic(fmt.Sprintf("opengl: %q is a reserved keyword", token))
			}
		}
	}
}

func shaderStr(id shaderID) string {
	src := ""
	switch id {
	case shaderVertexModelview:
		src = shaderStrVertex
	case shaderFragmentColorMatrix:
		replaces := map[string]string{
			"{{.FilterNearest}}":      fmt.Sprintf("%d", graphics.FilterNearest),
			"{{.FilterLinear}}":       fmt.Sprintf("%d", graphics.FilterLinear),
			"{{.FilterScreen}}":       fmt.Sprintf("%d", graphics.FilterScreen),
			"{{.AddressClampToZero}}": fmt.Sprintf("%d", graphics.AddressClampToZero),
			"{{.AddressRepeat}}":      fmt.Sprintf("%d", graphics.AddressRepeat),
		}
		src = shaderStrFragment
		for k, v := range replaces {
			src = strings.Replace(src, k, v, -1)
		}
	default:
		panic("not reached")
	}

	checkGLSL(src)
	return src
}

const (
	shaderStrVertex = `
uniform vec2 viewport_size;
attribute vec2 vertex;
attribute vec2 tex;
attribute vec4 tex_region;
attribute vec4 color_scale;
varying vec2 varying_tex;
varying vec4 varying_tex_region;
varying vec4 varying_color_scale;

void main(void) {
  varying_tex = tex;
  varying_tex_region = tex_region;
  varying_color_scale = color_scale;

  mat4 projection_matrix = mat4(
    vec4(2.0 / viewport_size.x, 0, 0, 0),
    vec4(0, 2.0 / viewport_size.y, 0, 0),
    vec4(0, 0, 1, 0),
    vec4(-1, -1, 0, 1)
  );
  gl_Position = projection_matrix * vec4(vertex, 0, 1);
}
`
	shaderStrFragment = `
#if defined(GL_ES)
precision mediump float;
#else
#define lowp
#define mediump
#define highp
#endif

#define FILTER_NEAREST ({{.FilterNearest}})
#define FILTER_LINEAR ({{.FilterLinear}})
#define FILTER_SCREEN ({{.FilterScreen}})
#define ADDRESS_CLAMP_TO_ZERO ({{.AddressClampToZero}})
#define ADDRESS_REPEAT ({{.AddressRepeat}})

uniform sampler2D texture;
uniform mat4 color_matrix_body;
uniform vec4 color_matrix_translation;

uniform int filter_type;
uniform highp vec2 source_size;
uniform int address;

#if defined(FILTER_SCREEN)
uniform highp float scale;
#endif

varying highp vec2 varying_tex;
varying highp vec4 varying_tex_region;
varying highp vec4 varying_color_scale;

// adjustTexel adjusts the two texels and returns the adjusted second texel.
// When p1 - p0 is exactly equal to the texel size, jaggy can happen on macOS (#669).
// In order to avoid this jaggy, subtract a little bit from the second texel.
highp vec2 adjustTexel(highp vec2 p0, highp vec2 p1) {
  highp vec2 texel_size = 1.0 / source_size;
  if (fract((p1.x-p0.x)*source_size.x) == 0.0) {
    p1.x -= texel_size.x / 512.0;
  }
  if (fract((p1.y-p0.y)*source_size.y) == 0.0) {
    p1.y -= texel_size.y / 512.0;
  }
  return p1;
}

highp float floorMod(highp float x, highp float y) {
  if (x < 0.0) {
    return y - (-x - y * floor(-x/y));
  }
  return x - y * floor(x/y);
}

highp vec2 adjustTexelByAddress(highp vec2 p, highp vec4 tex_region, int address) {
  if (address == ADDRESS_CLAMP_TO_ZERO) {
    return p;
  }
  if (address == ADDRESS_REPEAT) {
    highp vec2 o = vec2(tex_region[0], tex_region[1]);
    highp vec2 size = vec2(tex_region[2] - tex_region[0], tex_region[3] - tex_region[1]);
    return vec2(floorMod((p.x - o.x), size.x) + o.x, floorMod((p.y - o.y), size.y) + o.y);
  }
  // Not reached.
  return vec2(0.0);
}

void main(void) {
  highp vec2 pos = varying_tex;
  highp vec2 texel_size = 1.0 / source_size;

  vec4 color;

  if (filter_type == FILTER_NEAREST) {
    pos = adjustTexelByAddress(pos, varying_tex_region, address);
    color = texture2D(texture, pos);
    if (pos.x < varying_tex_region[0] ||
      pos.y < varying_tex_region[1] ||
      (varying_tex_region[2] - texel_size.x / 512.0) <= pos.x ||
      (varying_tex_region[3] - texel_size.y / 512.0) <= pos.y) {
      color = vec4(0, 0, 0, 0);
    }
  } else if (filter_type == FILTER_LINEAR) {
    highp vec2 p0 = pos - texel_size / 2.0;
    highp vec2 p1 = pos + texel_size / 2.0;

    p1 = adjustTexel(p0, p1);
    p0 = adjustTexelByAddress(p0, varying_tex_region, address);
    p1 = adjustTexelByAddress(p1, varying_tex_region, address);

    vec4 c0 = texture2D(texture, p0);
    vec4 c1 = texture2D(texture, vec2(p1.x, p0.y));
    vec4 c2 = texture2D(texture, vec2(p0.x, p1.y));
    vec4 c3 = texture2D(texture, p1);
    if (p0.x < varying_tex_region[0]) {
      c0 = vec4(0, 0, 0, 0);
      c2 = vec4(0, 0, 0, 0);
    }
    if (p0.y < varying_tex_region[1]) {
      c0 = vec4(0, 0, 0, 0);
      c1 = vec4(0, 0, 0, 0);
    }
    if ((varying_tex_region[2] - texel_size.x / 512.0) <= p1.x) {
      c1 = vec4(0, 0, 0, 0);
      c3 = vec4(0, 0, 0, 0);
    }
    if ((varying_tex_region[3] - texel_size.y / 512.0) <= p1.y) {
      c2 = vec4(0, 0, 0, 0);
      c3 = vec4(0, 0, 0, 0);
    }

    vec2 rate = fract(p0 * source_size);
    color = mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
  } else if (filter_type == FILTER_SCREEN) {
    highp vec2 p0 = pos - texel_size / 2.0 / scale;
    highp vec2 p1 = pos + texel_size / 2.0 / scale;

    p1 = adjustTexel(p0, p1);

    vec4 c0 = texture2D(texture, p0);
    vec4 c1 = texture2D(texture, vec2(p1.x, p0.y));
    vec4 c2 = texture2D(texture, vec2(p0.x, p1.y));
    vec4 c3 = texture2D(texture, p1);
    // Texels must be in the source rect, so it is not necessary to check that like linear filter.

    vec2 rateCenter = vec2(1.0, 1.0) - texel_size / 2.0 / scale;
    vec2 rate = clamp(((fract(p0 * source_size) - rateCenter) * scale) + rateCenter, 0.0, 1.0);
    color = mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
  } else {
    // Not reached.
    discard;
  }

  // Un-premultiply alpha
  if (0.0 < color.a) {
    color.rgb /= color.a;
  }
  // Apply the color matrix or scale.
  color = (color_matrix_body * color) + color_matrix_translation;
  color *= varying_color_scale;
  color = clamp(color, 0.0, 1.0);
  // Premultiply alpha
  color.rgb *= color.a;

  gl_FragColor = color;
}
`
)
<|endoftext|>


<commit_before>package regtest

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"golang.org/x/tools/internal/lsp/fake"
	"golang.org/x/tools/internal/testenv"
)

func TestIssue38815(t *testing.T) {
	const needs = `
-- go.mod --
module foo

-- a.go --
package main
func f() {}
`
	const ntest = `package main
func TestZ(t *testing.T) {
	f()
}
`
	const want = `package main

import "testing"

func TestZ(t *testing.T) {
	f()
}
`

	// it was returning
	// "package main\nimport \"testing\"\npackage main..."
	runner.Run(t, needs, func(t *testing.T, env *Env) {
		env.CreateBuffer("a_test.go", ntest)
		env.SaveBuffer("a_test.go")
		got := env.Editor.BufferText("a_test.go")
		if want != got {
			t.Errorf("got\n%q, wanted\n%q", got, want)
		}
	})
}

func TestVim1(t *testing.T) {
	const vim1 = `package main

import "fmt"

var foo = 1
var bar = 2

func main() {
	fmt.Printf("This is a test %v\n", foo)
	fmt.Printf("This is another test %v\n", foo)
	fmt.Printf("This is also a test %v\n", foo)
}
`

	// The file remains unchanged, but if there are any CodeActions returned, they confuse vim.
	// Therefore check for no CodeActions
	runner.Run(t, "", func(t *testing.T, env *Env) {
		env.CreateBuffer("main.go", vim1)
		env.OrganizeImports("main.go")
		actions := env.CodeAction("main.go")
		if len(actions) > 0 {
			got := env.Editor.BufferText("main.go")
			t.Errorf("unexpected actions %#v", actions)
			if got == vim1 {
				t.Errorf("no changes")
			} else {
				t.Errorf("got\n%q", got)
				t.Errorf("was\n%q", vim1)
			}
		}
	})
}

func TestVim2(t *testing.T) {
	const vim2 = `package main

import (
	"fmt"

	"example.com/blah"

	"rubbish.com/useless"
)

func main() {
	fmt.Println(blah.Name, useless.Name)
}
`

	runner.Run(t, "", func(t *testing.T, env *Env) {
		env.CreateBuffer("main.go", vim2)
		env.OrganizeImports("main.go")
		actions := env.CodeAction("main.go")
		if len(actions) > 0 {
			t.Errorf("unexpected actions %#v", actions)
		}
	})
}

func TestGOMODCACHE(t *testing.T) {
	const proxy = `
-- example.com@v1.2.3/go.mod --
module example.com

go 1.12
-- example.com@v1.2.3/x/x.go --
package x

const X = 1
-- example.com@v1.2.3/y/y.go --
package y

const Y = 2
`
	const ws = `
-- go.mod --
module mod.com

require example.com v1.2.3

-- main.go --
package main

import "example.com/x"

var _, _ = x.X, y.Y
`
	testenv.NeedsGo1Point(t, 15)

	modcache, err := ioutil.TempDir("", "TestGOMODCACHE-modcache")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(modcache)

	runner.Run(t, ws, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		env.Await(env.DiagnosticAtRegexp("main.go", `y.Y`))
		env.SaveBuffer("main.go")
		env.Await(EmptyDiagnostics("main.go"))
		path, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `y.(Y)`))
		if !strings.HasPrefix(path, filepath.ToSlash(modcache)) {
			t.Errorf("found module dependency outside of GOMODCACHE: got %v, wanted subdir of %v", path, filepath.ToSlash(modcache))
		}
	}, WithProxy(proxy), WithEditorConfig(fake.EditorConfig{Env: []string{"GOMODCACHE=" + modcache}}), WithTimeout(5*time.Second))
}
<commit_msg>internal/lsp/regtest: remove stray short timeout<commit_after>package regtest

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"golang.org/x/tools/internal/lsp/fake"
	"golang.org/x/tools/internal/testenv"
)

func TestIssue38815(t *testing.T) {
	const needs = `
-- go.mod --
module foo

-- a.go --
package main
func f() {}
`
	const ntest = `package main
func TestZ(t *testing.T) {
	f()
}
`
	const want = `package main

import "testing"

func TestZ(t *testing.T) {
	f()
}
`

	// it was returning
	// "package main\nimport \"testing\"\npackage main..."
	runner.Run(t, needs, func(t *testing.T, env *Env) {
		env.CreateBuffer("a_test.go", ntest)
		env.SaveBuffer("a_test.go")
		got := env.Editor.BufferText("a_test.go")
		if want != got {
			t.Errorf("got\n%q, wanted\n%q", got, want)
		}
	})
}

func TestVim1(t *testing.T) {
	const vim1 = `package main

import "fmt"

var foo = 1
var bar = 2

func main() {
	fmt.Printf("This is a test %v\n", foo)
	fmt.Printf("This is another test %v\n", foo)
	fmt.Printf("This is also a test %v\n", foo)
}
`

	// The file remains unchanged, but if there are any CodeActions returned, they confuse vim.
	// Therefore check for no CodeActions
	runner.Run(t, "", func(t *testing.T, env *Env) {
		env.CreateBuffer("main.go", vim1)
		env.OrganizeImports("main.go")
		actions := env.CodeAction("main.go")
		if len(actions) > 0 {
			got := env.Editor.BufferText("main.go")
			t.Errorf("unexpected actions %#v", actions)
			if got == vim1 {
				t.Errorf("no changes")
			} else {
				t.Errorf("got\n%q", got)
				t.Errorf("was\n%q", vim1)
			}
		}
	})
}

func TestVim2(t *testing.T) {
	const vim2 = `package main

import (
	"fmt"

	"example.com/blah"

	"rubbish.com/useless"
)

func main() {
	fmt.Println(blah.Name, useless.Name)
}
`

	runner.Run(t, "", func(t *testing.T, env *Env) {
		env.CreateBuffer("main.go", vim2)
		env.OrganizeImports("main.go")
		actions := env.CodeAction("main.go")
		if len(actions) > 0 {
			t.Errorf("unexpected actions %#v", actions)
		}
	})
}

func TestGOMODCACHE(t *testing.T) {
	const proxy = `
-- example.com@v1.2.3/go.mod --
module example.com

go 1.12
-- example.com@v1.2.3/x/x.go --
package x

const X = 1
-- example.com@v1.2.3/y/y.go --
package y

const Y = 2
`
	const ws = `
-- go.mod --
module mod.com

require example.com v1.2.3

-- main.go --
package main

import "example.com/x"

var _, _ = x.X, y.Y
`
	testenv.NeedsGo1Point(t, 15)

	modcache, err := ioutil.TempDir("", "TestGOMODCACHE-modcache")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(modcache)

	runner.Run(t, ws, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		env.Await(env.DiagnosticAtRegexp("main.go", `y.Y`))
		env.SaveBuffer("main.go")
		env.Await(EmptyDiagnostics("main.go"))
		path, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `y.(Y)`))
		if !strings.HasPrefix(path, filepath.ToSlash(modcache)) {
			t.Errorf("found module dependency outside of GOMODCACHE: got %v, wanted subdir of %v", path, filepath.ToSlash(modcache))
		}
	}, WithProxy(proxy), WithEditorConfig(fake.EditorConfig{Env: []string{"GOMODCACHE=" + modcache}}))
}
<|endoftext|>


<commit_before>package core

import (
	"errors"
	"fmt"
	"github.com/MG-RAST/AWE/lib/acl"
	"github.com/MG-RAST/AWE/lib/conf"
	"github.com/MG-RAST/AWE/lib/core/uuid"
	"github.com/MG-RAST/golib/mgo/bson"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"
)

const (
	JOB_STAT_INIT       = "init"
	JOB_STAT_QUEUED     = "queued"
	JOB_STAT_INPROGRESS = "in-progress"
	JOB_STAT_COMPLETED  = "completed"
	JOB_STAT_SUSPEND    = "suspend"
	JOB_STAT_DELETED    = "deleted"
)

var JOB_STATS_ACTIVE = []string{JOB_STAT_QUEUED, JOB_STAT_INPROGRESS}
var JOB_STATS_REGISTERED = []string{JOB_STAT_QUEUED, JOB_STAT_INPROGRESS, JOB_STAT_SUSPEND}
var JOB_STATS_TO_RECOVER = []string{JOB_STAT_QUEUED, JOB_STAT_INPROGRESS, JOB_STAT_SUSPEND}

type Job struct {
	Id          string    `bson:"id" json:"id"`
	Jid         string    `bson:"jid" json:"jid"`
	Acl         acl.Acl   `bson:"acl" json:"-"`
	Info        *Info     `bson:"info" json:"info"`
	Tasks       []*Task   `bson:"tasks" json:"tasks"`
	Script      script    `bson:"script" json:"-"`
	State       string    `bson:"state" json:"state"`
	Registered  bool      `bson:"-" json:"registered"` //job in memory (not only in mongodb) (assigned on the fly, db value meaningless)
	RemainTasks int       `bson:"remaintasks" json:"remaintasks"`
	UpdateTime  time.Time `bson:"updatetime" json:"updatetime"`
	Notes       string    `bson:"notes" json:"notes"`
	LastFailed  string    `bson:"lastfailed" json:"lastfailed"`
	Resumed     int       `bson:"resumed" json:"resumed"`     //number of times the job has been resumed from suspension
	ShockHost   string    `bson:"shockhost" json:"shockhost"` // this is a fall-back default if not specified at a lower level
}

type JobMin struct {
	Id            string            `bson:"id" json:"id"`
	Name          string            `bson:"name" json:"name"`
	Size          int64             `bson:"size" json:"size"`
	SubmitTime    time.Time         `bson:"submittime" json:"submittime"`
	CompletedTime time.Time         `bson:"completedtime" json:"completedtime"`
	Task          []int             `bson:"task" json:"task"`
	State         []string          `bson:"state" json:"state"`
	UserAttr      map[string]string `bson:"userattr" json:"userattr"`
}

//set job's uuid
func (job *Job) setId() {
	job.Id = uuid.New()
	return
}

//set job's jid
func (job *Job) setJid(jid string) {
	job.Jid = jid
}

func (job *Job) initJob(jid string) {
	if job.Info == nil {
		job.Info = new(Info)
	}
	job.Info.SubmitTime = time.Now()
	job.Info.Priority = conf.BasePriority
	job.setId()     //uuid for the job
	job.setJid(jid) //an incremental id for the jobs within a AWE server domain
	job.State = JOB_STAT_INIT
	job.Registered = true
}

type script struct {
	Name string `bson:"name" json:"name"`
	Type string `bson:"type" json:"type"`
	Path string `bson:"path" json:"-"`
}

//---Script upload
func (job *Job) UpdateFile(params map[string]string, files FormFiles) (err error) {
	_, isRegularUpload := files["upload"]

	if isRegularUpload {
		if err = job.SetFile(files["upload"]); err != nil {
			return err
		}
		delete(files, "upload")
	}

	return
}

func (job *Job) Save() (err error) {
	job.UpdateTime = time.Now()
	bsonPath := fmt.Sprintf("%s/%s.bson", job.Path(), job.Id)
	os.Remove(bsonPath)
	nbson, err := bson.Marshal(job)
	if err != nil {
		err = errors.New("error in Marshal in job.Save(), error=" + err.Error())
		return
	}
	// this is incase job path does not exist, ignored if it does
	err = job.Mkdir()
	if err != nil {
		err = errors.New("error creating dir in job.Save(), error=" + err.Error())
		return
	}
	err = ioutil.WriteFile(bsonPath, nbson, 0644)
	if err != nil {
		err = errors.New("error writing file in job.Save(), error=" + err.Error())
		return
	}
	err = dbUpsert(job)
	if err != nil {
		err = errors.New("error in dbUpdate in job.Save(), error=" + err.Error())
		return
	}
	return
}

func (job *Job) Mkdir() (err error) {
	err = os.MkdirAll(job.Path(), 0777)
	if err != nil {
		return
	}
	return
}

func (job *Job) SetFile(file FormFile) (err error) {
	if err != nil { //?
		return
	}
	os.Rename(file.Path, job.FilePath())
	job.Script.Name = file.Name
	return
}

//---Path functions
func (job *Job) Path() string {
	return getPathByJobId(job.Id)
}

func (job *Job) FilePath() string {
	if job.Script.Path != "" {
		return job.Script.Path
	}
	return getPathByJobId(job.Id) + "/" + job.Id + ".script"
}

func getPathByJobId(id string) string {
	return fmt.Sprintf("%s/%s/%s/%s/%s", conf.DATA_PATH, id[0:2], id[2:4], id[4:6], id)
}

//---Task functions
func (job *Job) TaskList() []*Task {
	return job.Tasks
}

func (job *Job) NumTask() int {
	return len(job.Tasks)
}

//---Field update functions
func (job *Job) UpdateState(newState string, notes string) (err error) {
	job.State = newState
	if len(notes) > 0 {
		job.Notes = notes
	}
	return job.Save()
}

//invoked to modify job info in mongodb when a task in that job changed to the new status
func (job *Job) UpdateTask(task *Task) (remainTasks int, err error) {
	idx := -1
	for i, t := range job.Tasks {
		if t.Id == task.Id {
			idx = i
			break
		}
	}
	if idx == -1 {
		return job.RemainTasks, errors.New("job.UpdateTask: no task found with id=" + task.Id)
	}
	job.Tasks[idx] = task

	//if this task is complete, count remain tasks for the job
	if task.State == TASK_STAT_COMPLETED ||
		task.State == TASK_STAT_SKIPPED ||
		task.State == TASK_STAT_FAIL_SKIP {
		remain_tasks := len(job.Tasks)
		for _, t := range job.Tasks { //double check all task other than the one with state change
			if t.State == TASK_STAT_COMPLETED ||
				t.State == TASK_STAT_SKIPPED ||
				t.State == TASK_STAT_FAIL_SKIP {
				remain_tasks -= 1
			}
		}
		job.RemainTasks = remain_tasks
		if job.RemainTasks == 0 {
			job.State = JOB_STAT_COMPLETED
			job.Info.CompletedTime = time.Now()
		}
	}
	return job.RemainTasks, job.Save()
}

//set token
func (job *Job) SetDataToken(token string) {
	job.Info.DataToken = token
	job.Info.Auth = true
	for _, task := range job.Tasks {
		task.Info.DataToken = token
		task.setTokenForIO()
	}
	job.Save()
}

func (job *Job) GetDataToken() (token string) {
	return job.Info.DataToken
}

func (job *Job) GetPrivateEnv(taskid string) (env map[string]string) {
	for _, task := range job.Tasks {
		if taskid == task.Id {
			return task.Cmd.Environ.Private
		}
	}
	return
}

func ReloadFromDisk(path string) (err error) {
	id := filepath.Base(path)
	jobbson, err := ioutil.ReadFile(path + "/" + id + ".bson")
	if err != nil {
		return
	}
	job := new(Job)
	err = bson.Unmarshal(jobbson, &job)
	if err == nil {
		if err = dbUpsert(job); err != nil {
			return err
		}
	}
	return
}
<commit_msg>Plan to start using this field in mongodb.<commit_after>package core

import (
	"errors"
	"fmt"
	"github.com/MG-RAST/AWE/lib/acl"
	"github.com/MG-RAST/AWE/lib/conf"
	"github.com/MG-RAST/AWE/lib/core/uuid"
	"github.com/MG-RAST/golib/mgo/bson"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"
)

const (
	JOB_STAT_INIT       = "init"
	JOB_STAT_QUEUED     = "queued"
	JOB_STAT_INPROGRESS = "in-progress"
	JOB_STAT_COMPLETED  = "completed"
	JOB_STAT_SUSPEND    = "suspend"
	JOB_STAT_DELETED    = "deleted"
)

var JOB_STATS_ACTIVE = []string{JOB_STAT_QUEUED, JOB_STAT_INPROGRESS}
var JOB_STATS_REGISTERED = []string{JOB_STAT_QUEUED, JOB_STAT_INPROGRESS, JOB_STAT_SUSPEND}
var JOB_STATS_TO_RECOVER = []string{JOB_STAT_QUEUED, JOB_STAT_INPROGRESS, JOB_STAT_SUSPEND}

type Job struct {
	Id          string    `bson:"id" json:"id"`
	Jid         string    `bson:"jid" json:"jid"`
	Acl         acl.Acl   `bson:"acl" json:"-"`
	Info        *Info     `bson:"info" json:"info"`
	Tasks       []*Task   `bson:"tasks" json:"tasks"`
	Script      script    `bson:"script" json:"-"`
	State       string    `bson:"state" json:"state"`
	Registered  bool      `bson:"registered" json:"registered"`
	RemainTasks int       `bson:"remaintasks" json:"remaintasks"`
	UpdateTime  time.Time `bson:"updatetime" json:"updatetime"`
	Notes       string    `bson:"notes" json:"notes"`
	LastFailed  string    `bson:"lastfailed" json:"lastfailed"`
	Resumed     int       `bson:"resumed" json:"resumed"`     //number of times the job has been resumed from suspension
	ShockHost   string    `bson:"shockhost" json:"shockhost"` // this is a fall-back default if not specified at a lower level
}

type JobMin struct {
	Id            string            `bson:"id" json:"id"`
	Name          string            `bson:"name" json:"name"`
	Size          int64             `bson:"size" json:"size"`
	SubmitTime    time.Time         `bson:"submittime" json:"submittime"`
	CompletedTime time.Time         `bson:"completedtime" json:"completedtime"`
	Task          []int             `bson:"task" json:"task"`
	State         []string          `bson:"state" json:"state"`
	UserAttr      map[string]string `bson:"userattr" json:"userattr"`
}

//set job's uuid
func (job *Job) setId() {
	job.Id = uuid.New()
	return
}

//set job's jid
func (job *Job) setJid(jid string) {
	job.Jid = jid
}

func (job *Job) initJob(jid string) {
	if job.Info == nil {
		job.Info = new(Info)
	}
	job.Info.SubmitTime = time.Now()
	job.Info.Priority = conf.BasePriority
	job.setId()     //uuid for the job
	job.setJid(jid) //an incremental id for the jobs within a AWE server domain
	job.State = JOB_STAT_INIT
	job.Registered = true
}

type script struct {
	Name string `bson:"name" json:"name"`
	Type string `bson:"type" json:"type"`
	Path string `bson:"path" json:"-"`
}

//---Script upload
func (job *Job) UpdateFile(params map[string]string, files FormFiles) (err error) {
	_, isRegularUpload := files["upload"]

	if isRegularUpload {
		if err = job.SetFile(files["upload"]); err != nil {
			return err
		}
		delete(files, "upload")
	}

	return
}

func (job *Job) Save() (err error) {
	job.UpdateTime = time.Now()
	bsonPath := fmt.Sprintf("%s/%s.bson", job.Path(), job.Id)
	os.Remove(bsonPath)
	nbson, err := bson.Marshal(job)
	if err != nil {
		err = errors.New("error in Marshal in job.Save(), error=" + err.Error())
		return
	}
	// this is incase job path does not exist, ignored if it does
	err = job.Mkdir()
	if err != nil {
		err = errors.New("error creating dir in job.Save(), error=" + err.Error())
		return
	}
	err = ioutil.WriteFile(bsonPath, nbson, 0644)
	if err != nil {
		err = errors.New("error writing file in job.Save(), error=" + err.Error())
		return
	}
	err = dbUpsert(job)
	if err != nil {
		err = errors.New("error in dbUpdate in job.Save(), error=" + err.Error())
		return
	}
	return
}

func (job *Job) Mkdir() (err error) {
	err = os.MkdirAll(job.Path(), 0777)
	if err != nil {
		return
	}
	return
}

func (job *Job) SetFile(file FormFile) (err error) {
	if err != nil { //?
		return
	}
	os.Rename(file.Path, job.FilePath())
	job.Script.Name = file.Name
	return
}

//---Path functions
func (job *Job) Path() string {
	return getPathByJobId(job.Id)
}

func (job *Job) FilePath() string {
	if job.Script.Path != "" {
		return job.Script.Path
	}
	return getPathByJobId(job.Id) + "/" + job.Id + ".script"
}

func getPathByJobId(id string) string {
	return fmt.Sprintf("%s/%s/%s/%s/%s", conf.DATA_PATH, id[0:2], id[2:4], id[4:6], id)
}

//---Task functions
func (job *Job) TaskList() []*Task {
	return job.Tasks
}

func (job *Job) NumTask() int {
	return len(job.Tasks)
}

//---Field update functions
func (job *Job) UpdateState(newState string, notes string) (err error) {
	job.State = newState
	if len(notes) > 0 {
		job.Notes = notes
	}
	return job.Save()
}

//invoked to modify job info in mongodb when a task in that job changed to the new status
func (job *Job) UpdateTask(task *Task) (remainTasks int, err error) {
	idx := -1
	for i, t := range job.Tasks {
		if t.Id == task.Id {
			idx = i
			break
		}
	}
	if idx == -1 {
		return job.RemainTasks, errors.New("job.UpdateTask: no task found with id=" + task.Id)
	}
	job.Tasks[idx] = task

	//if this task is complete, count remain tasks for the job
	if task.State == TASK_STAT_COMPLETED ||
		task.State == TASK_STAT_SKIPPED ||
		task.State == TASK_STAT_FAIL_SKIP {
		remain_tasks := len(job.Tasks)
		for _, t := range job.Tasks { //double check all task other than the one with state change
			if t.State == TASK_STAT_COMPLETED ||
				t.State == TASK_STAT_SKIPPED ||
				t.State == TASK_STAT_FAIL_SKIP {
				remain_tasks -= 1
			}
		}
		job.RemainTasks = remain_tasks
		if job.RemainTasks == 0 {
			job.State = JOB_STAT_COMPLETED
			job.Info.CompletedTime = time.Now()
		}
	}
	return job.RemainTasks, job.Save()
}

//set token
func (job *Job) SetDataToken(token string) {
	job.Info.DataToken = token
	job.Info.Auth = true
	for _, task := range job.Tasks {
		task.Info.DataToken = token
		task.setTokenForIO()
	}
	job.Save()
}

func (job *Job) GetDataToken() (token string) {
	return job.Info.DataToken
}

func (job *Job) GetPrivateEnv(taskid string) (env map[string]string) {
	for _, task := range job.Tasks {
		if taskid == task.Id {
			return task.Cmd.Environ.Private
		}
	}
	return
}

func ReloadFromDisk(path string) (err error) {
	id := filepath.Base(path)
	jobbson, err := ioutil.ReadFile(path + "/" + id + ".bson")
	if err != nil {
		return
	}
	job := new(Job)
	err = bson.Unmarshal(jobbson, &job)
	if err == nil {
		if err = dbUpsert(job); err != nil {
			return err
		}
	}
	return
}
<|endoftext|>


<commit_before>package auth

import (
	"net/http"
	"testing"

	//"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

// 401 if no Authorization header is present
func TestAPIMiddlewareNoHeader(t *testing.T) {
	rw := new(responseWriterMock)
	request, _ := http.NewRequest("GET", "/api/v1/foo", nil)
	rw.On("Write", []byte("not authorized")).Once()
	rw.On("WriteHeader", 401).Once()

	APIMiddleware(rw, request, http.HandlerFunc(mockHTTPHandler))

	rw.AssertExpectations(t)
}

// header must be Authorization: Bearer xxx
func TestAPIMiddlewareInalidHeader(t *testing.T) {
	rw := new(responseWriterMock)
	request, _ := http.NewRequest("GET", "/api/v1/foo", nil)
	request.Header.Set("Authorization", "NotSupported token123")
	rw.On("Write", []byte("invalid authorization header")).Once()
	rw.On("WriteHeader", 401).Once()

	APIMiddleware(rw, request, http.HandlerFunc(mockHTTPHandler))

	rw.AssertExpectations(t)
}

func TestAPIMiddlewareValidJWTToken(t *testing.T) {
	rw := new(responseWriterMock)
	request, _ := http.NewRequest("GET", "/api/v1/foo", nil)
	request.Header.Set("Authorization", "Bearer token123")
	rw.On("Write", []byte("ok")).Once()
	rw.On("WriteHeader", 200).Once()

	APIMiddleware(rw, request, http.HandlerFunc(mockHTTPHandler))

	rw.AssertExpectations(t)
}

// mocks

func mockHTTPHandler(rw http.ResponseWriter, request *http.Request) {
	rw.Write([]byte("ok"))
	rw.WriteHeader(200)
}

type responseWriterMock struct {
	mock.Mock
}

func (r *responseWriterMock) Header() http.Header {
	return http.Header{}
}
func (r *responseWriterMock) Write(content []byte) (int, error) {
	r.Called(content)
	return 0, nil
}
func (r *responseWriterMock) WriteHeader(status int) {
	r.Called(status)
}
<commit_msg>spell check<commit_after>package auth

import (
	"net/http"
	"testing"

	//"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

// 401 if no Authorization header is present
func TestAPIMiddlewareNoHeader(t *testing.T) {
	rw := new(responseWriterMock)
	request, _ := http.NewRequest("GET", "/api/v1/foo", nil)
	rw.On("Write", []byte("not authorized")).Once()
	rw.On("WriteHeader", 401).Once()

	APIMiddleware(rw, request, http.HandlerFunc(mockHTTPHandler))

	rw.AssertExpectations(t)
}

// header must be Authorization: Bearer xxx
func TestAPIMiddlewareInvalidHeader(t *testing.T) {
	rw := new(responseWriterMock)
	request, _ := http.NewRequest("GET", "/api/v1/foo", nil)
	request.Header.Set("Authorization", "NotSupported token123")
	rw.On("Write", []byte("invalid authorization header")).Once()
	rw.On("WriteHeader", 401).Once()

	APIMiddleware(rw, request, http.HandlerFunc(mockHTTPHandler))

	rw.AssertExpectations(t)
}

func TestAPIMiddlewareValidJWTToken(t *testing.T) {
	rw := new(responseWriterMock)
	request, _ := http.NewRequest("GET", "/api/v1/foo", nil)
	request.Header.Set("Authorization", "Bearer token123")
	rw.On("Write", []byte("ok")).Once()
	rw.On("WriteHeader", 200).Once()

	APIMiddleware(rw, request, http.HandlerFunc(mockHTTPHandler))

	rw.AssertExpectations(t)
}

// mocks

func mockHTTPHandler(rw http.ResponseWriter, request *http.Request) {
	rw.Write([]byte("ok"))
	rw.WriteHeader(200)
}

type responseWriterMock struct {
	mock.Mock
}

func (r *responseWriterMock) Header() http.Header {
	return http.Header{}
}
func (r *responseWriterMock) Write(content []byte) (int, error) {
	r.Called(content)
	return 0, nil
}
func (r *responseWriterMock) WriteHeader(status int) {
	r.Called(status)
}
<|endoftext|>


<commit_before>// 25 january 2015
package main

import (
	"fmt"
	"os"
	"io"
	"encoding/xml"
	"strings"
	"text/template"
)

const outTemplate = `// generated by tools/ui2cdecl.go; do not edit
typedef struct {{.TypeName}} {{.TypeName}};
struct {{.TypeName}} {
{{range .Members}}	{{.Type}} *{{.Name}};
{{end}}};
static {{.TypeName}} *make{{.TypeName}}FromUIFile(void)
{
	{{.TypeName}} *instance;
	GError *err = NULL;
	GtkBuilder *builder;

	instance = g_new({{.TypeName}}, 1);
	builder = gtk_builder_new();
	if (gtk_builder_add_from_resource(builder, "{{.GResourcePath}}", &err) == 0)
		g_error("error loading {{.GResourcePath}}: %s", err->message);
{{$typename := .TypeName}}{{range .Members}}	instance->{{.Name}} = {{.CastTo}}(gtk_builder_get_object(builder, "{{.Name}}"));
	if (instance->{{.Name}} == NULL)
		g_error("error getting {{$typename}} member {{.Name}} (exact error unspecified)");
{{end}}	g_object_unref(builder);
	return instance;
}
`

type member struct {
	Name	string
	Type		string
	CastTo	string
}

type outParams struct {
	TypeName		string
	GResourcePath		string
	Members			[]*member
}

func die(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
	fmt.Fprintf(os.Stderr, "\n")
	os.Exit(1)
}

func main() {
	if len(os.Args) != 5 {
		die("usage: %s uifile cfile typename grespath", os.Args[0])
	}

	uifile, err := os.Open(os.Args[1])
	if err != nil {
		die("error opening .ui file %s: %v", os.Args[1], err)
	}
	defer uifile.Close()

	cfile, err := os.Create(os.Args[2])
	if err != nil {
		die("error creating .c file %s: %v", os.Args[2], err)
	}
	defer cfile.Close()

	typename := os.Args[3]
	grespath := os.Args[4]
	members := make([]*member, 0, 50)

	uireader := xml.NewDecoder(uifile)
	for {
		t, err := uireader.Token()
		if err == io.EOF {
			break
		} else if err != nil {
			die("error parsing .ui file: %v", err)
		}
		s, ok := t.(xml.StartElement)
		if !ok {
			continue
		}
		if strings.ToLower(s.Name.Local) != "object" {
			continue
		}
		id := ""
		ty := ""
		for _, a := range s.Attr {
			switch strings.ToLower(a.Name.Local) {
			case "id":
				id = a.Value
			case "class":
				ty = a.Value
			}
			if id != "" && ty != "" {
				break
			}
		}
		if ty == "GtkTreeSelection" {
			members = append(members, &member{
				Name:	id,
				Type:	"GtkTreeSelection",
				CastTo:	"GTK_TREE_SELECTION",
			})
		} else {
			members = append(members, &member{
				Name:	id,
				Type:	"GtkWidget",
				CastTo:	"GTK_WIDGET",
			})
		}
	}

	t, err := template.New("outTemplate").Parse(outTemplate)
	if err != nil {
		die("error parsing .c output template: %v", err)
	}
	err = t.Execute(cfile, &outParams{
		TypeName:		typename,
		GResourcePath:	grespath,
		Members:			members,
	})
	if err != nil {
		die("error generating .c output file: %v", err)
	}
}
<commit_msg>Adjusted ui2cdecl.go to take into account the extra GTK+ types that aren't GtkWidgets that are used here.<commit_after>// 25 january 2015
package main

import (
	"fmt"
	"os"
	"io"
	"encoding/xml"
	"strings"
	"text/template"
)

const outTemplate = `// generated by tools/ui2cdecl.go; do not edit
typedef struct {{.TypeName}} {{.TypeName}};
struct {{.TypeName}} {
{{range .Members}}	{{.Type}} *{{.Name}};
{{end}}};
static {{.TypeName}} *make{{.TypeName}}FromUIFile(void)
{
	{{.TypeName}} *instance;
	GError *err = NULL;
	GtkBuilder *builder;

	instance = g_new({{.TypeName}}, 1);
	builder = gtk_builder_new();
	if (gtk_builder_add_from_resource(builder, "{{.GResourcePath}}", &err) == 0)
		g_error("error loading {{.GResourcePath}}: %s", err->message);
{{$typename := .TypeName}}{{range .Members}}	instance->{{.Name}} = {{.CastTo}}(gtk_builder_get_object(builder, "{{.Name}}"));
	if (instance->{{.Name}} == NULL)
		g_error("error getting {{$typename}} member {{.Name}} (exact error unspecified)");
{{end}}	g_object_unref(builder);
	return instance;
}
`

type member struct {
	Name	string
	Type		string
	CastTo	string
}

type outParams struct {
	TypeName		string
	GResourcePath		string
	Members			[]*member
}

var knownTypes = map[string]string{
	"GtkTreeSelection":		"GTK_TREE_SELECTION",
	"GtkTextBuffer":		"GTK_TEXT_BUFFER",
	"GtkTextTag":			"GTK_TEXT_TAG",
	"GtkTextTagTable":		"GTK_TEXT_TAG_TABLE",
	"GtkAdjustment":		"GTK_ADJUSTMENT",
}

func die(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
	fmt.Fprintf(os.Stderr, "\n")
	os.Exit(1)
}

func main() {
	if len(os.Args) != 5 {
		die("usage: %s uifile cfile typename grespath", os.Args[0])
	}

	uifile, err := os.Open(os.Args[1])
	if err != nil {
		die("error opening .ui file %s: %v", os.Args[1], err)
	}
	defer uifile.Close()

	cfile, err := os.Create(os.Args[2])
	if err != nil {
		die("error creating .c file %s: %v", os.Args[2], err)
	}
	defer cfile.Close()

	typename := os.Args[3]
	grespath := os.Args[4]
	members := make([]*member, 0, 50)

	uireader := xml.NewDecoder(uifile)
	for {
		t, err := uireader.Token()
		if err == io.EOF {
			break
		} else if err != nil {
			die("error parsing .ui file: %v", err)
		}
		s, ok := t.(xml.StartElement)
		if !ok {
			continue
		}
		if strings.ToLower(s.Name.Local) != "object" {
			continue
		}
		id := ""
		ty := ""
		for _, a := range s.Attr {
			switch strings.ToLower(a.Name.Local) {
			case "id":
				id = a.Value
			case "class":
				ty = a.Value
			}
			if id != "" && ty != "" {
				break
			}
		}
		found := false
		for name, conv := range knownTypes {
			if ty == name {
				members = append(members, &member{
					Name:	id,
					Type:	name,
					CastTo:	conv,
				})
				found = true
				break
			}
		}
		if !found {
			members = append(members, &member{
				Name:	id,
				Type:	"GtkWidget",
				CastTo:	"GTK_WIDGET",
			})
		}
	}

	t, err := template.New("outTemplate").Parse(outTemplate)
	if err != nil {
		die("error parsing .c output template: %v", err)
	}
	err = t.Execute(cfile, &outParams{
		TypeName:		typename,
		GResourcePath:	grespath,
		Members:			members,
	})
	if err != nil {
		die("error generating .c output file: %v", err)
	}
}
<|endoftext|>


<commit_before>package storage

import (
	"fmt"
	"sort"
	"testing"

	"github.com/docker/distribution/context"
	"github.com/docker/distribution/registry/storage/driver"
	"github.com/docker/distribution/registry/storage/driver/inmemory"
)

func testFS(t *testing.T) (driver.StorageDriver, map[string]string, context.Context) {
	d := inmemory.New()
	c := []byte("")
	ctx := context.Background()
	if err := d.PutContent(ctx, "/a/b/c/d", c); err != nil {
		t.Fatalf("Unable to put to inmemory fs")
	}
	if err := d.PutContent(ctx, "/a/b/c/e", c); err != nil {
		t.Fatalf("Unable to put to inmemory fs")
	}

	expected := map[string]string{
		"/a":       "dir",
		"/a/b":     "dir",
		"/a/b/c":   "dir",
		"/a/b/c/d": "file",
		"/a/b/c/e": "file",
	}

	return d, expected, ctx
}

func TestWalkErrors(t *testing.T) {
	d, expected, ctx := testFS(t)
	fileCount := len(expected)
	err := Walk(ctx, d, "", func(fileInfo driver.FileInfo) error {
		return nil
	})
	if err == nil {
		t.Error("Expected invalid root err")
	}

	errEarlyExpected := fmt.Errorf("Early termination")

	err = Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error {
		// error on the 2nd file
		if fileInfo.Path() == "/a/b" {
			return errEarlyExpected
		}
		delete(expected, fileInfo.Path())
		return nil
	})
	if len(expected) != fileCount-1 {
		t.Error("Walk failed to terminate with error")
	}
	if err != errEarlyExpected {
		if err == nil {
			t.Fatalf("expected an error due to early termination")
		} else {
			t.Error(err.Error())
		}
	}

	err = Walk(ctx, d, "/nonexistant", func(fileInfo driver.FileInfo) error {
		return nil
	})
	if err == nil {
		t.Errorf("Expected missing file err")
	}

}

func TestWalk(t *testing.T) {
	d, expected, ctx := testFS(t)
	var traversed []string
	err := Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error {
		filePath := fileInfo.Path()
		filetype, ok := expected[filePath]
		if !ok {
			t.Fatalf("Unexpected file in walk: %q", filePath)
		}

		if fileInfo.IsDir() {
			if filetype != "dir" {
				t.Errorf("Unexpected file type: %q", filePath)
			}
		} else {
			if filetype != "file" {
				t.Errorf("Unexpected file type: %q", filePath)
			}
		}
		delete(expected, filePath)
		traversed = append(traversed, filePath)
		return nil
	})
	if len(expected) > 0 {
		t.Errorf("Missed files in walk: %q", expected)
	}

	if !sort.StringsAreSorted(traversed) {
		t.Errorf("result should be sorted: %v", traversed)
	}

	if err != nil {
		t.Fatalf(err.Error())
	}
}

func TestWalkSkipDir(t *testing.T) {
	d, expected, ctx := testFS(t)
	err := Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error {
		filePath := fileInfo.Path()
		if filePath == "/a/b" {
			// skip processing /a/b/c and /a/b/c/d
			return ErrSkipDir
		}
		delete(expected, filePath)
		return nil
	})
	if err != nil {
		t.Fatalf(err.Error())
	}
	if _, ok := expected["/a/b/c"]; !ok {
		t.Errorf("/a/b/c not skipped")
	}
	if _, ok := expected["/a/b/c/d"]; !ok {
		t.Errorf("/a/b/c/d not skipped")
	}
	if _, ok := expected["/a/b/c/e"]; !ok {
		t.Errorf("/a/b/c/e not skipped")
	}

}
<commit_msg>storage: add further tests for Walk implementation<commit_after>package storage

import (
	"fmt"
	"sort"
	"testing"

	"github.com/docker/distribution/context"
	"github.com/docker/distribution/registry/storage/driver"
	"github.com/docker/distribution/registry/storage/driver/inmemory"
)

func testFS(t *testing.T) (driver.StorageDriver, map[string]string, context.Context) {
	d := inmemory.New()
	ctx := context.Background()

	expected := map[string]string{
		"/a":       "dir",
		"/a/b":     "dir",
		"/a/b/c":   "dir",
		"/a/b/c/d": "file",
		"/a/b/c/e": "file",
		"/a/b/f":   "dir",
		"/a/b/f/g": "file",
		"/a/b/f/h": "file",
		"/a/b/f/i": "file",
		"/z":       "dir",
		"/z/y":     "file",
	}

	for p, typ := range expected {
		if typ != "file" {
			continue
		}

		if err := d.PutContent(ctx, p, []byte(p)); err != nil {
			t.Fatalf("unable to put content into fixture: %v", err)
		}
	}

	return d, expected, ctx
}

func TestWalkErrors(t *testing.T) {
	d, expected, ctx := testFS(t)
	fileCount := len(expected)
	err := Walk(ctx, d, "", func(fileInfo driver.FileInfo) error {
		return nil
	})
	if err == nil {
		t.Error("Expected invalid root err")
	}

	errEarlyExpected := fmt.Errorf("Early termination")

	err = Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error {
		// error on the 2nd file
		if fileInfo.Path() == "/a/b" {
			return errEarlyExpected
		}

		delete(expected, fileInfo.Path())
		return nil
	})
	if len(expected) != fileCount-1 {
		t.Error("Walk failed to terminate with error")
	}
	if err != errEarlyExpected {
		if err == nil {
			t.Fatalf("expected an error due to early termination")
		} else {
			t.Error(err.Error())
		}
	}

	err = Walk(ctx, d, "/nonexistant", func(fileInfo driver.FileInfo) error {
		return nil
	})
	if err == nil {
		t.Errorf("Expected missing file err")
	}

}

func TestWalk(t *testing.T) {
	d, expected, ctx := testFS(t)
	var traversed []string
	err := Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error {
		filePath := fileInfo.Path()
		filetype, ok := expected[filePath]
		if !ok {
			t.Fatalf("Unexpected file in walk: %q", filePath)
		}

		if fileInfo.IsDir() {
			if filetype != "dir" {
				t.Errorf("Unexpected file type: %q", filePath)
			}
		} else {
			if filetype != "file" {
				t.Errorf("Unexpected file type: %q", filePath)
			}

			// each file has its own path as the contents. If the length
			// doesn't match the path length, fail.
			if fileInfo.Size() != int64(len(fileInfo.Path())) {
				t.Fatalf("unexpected size for %q: %v != %v",
					fileInfo.Path(), fileInfo.Size(), len(fileInfo.Path()))
			}
		}
		delete(expected, filePath)
		traversed = append(traversed, filePath)
		return nil
	})
	if len(expected) > 0 {
		t.Errorf("Missed files in walk: %q", expected)
	}

	if !sort.StringsAreSorted(traversed) {
		t.Errorf("result should be sorted: %v", traversed)
	}

	if err != nil {
		t.Fatalf(err.Error())
	}
}

func TestWalkSkipDir(t *testing.T) {
	d, expected, ctx := testFS(t)
	err := Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error {
		filePath := fileInfo.Path()
		if filePath == "/a/b" {
			// skip processing /a/b/c and /a/b/c/d
			return ErrSkipDir
		}
		delete(expected, filePath)
		return nil
	})
	if err != nil {
		t.Fatalf(err.Error())
	}
	if _, ok := expected["/a/b/c"]; !ok {
		t.Errorf("/a/b/c not skipped")
	}
	if _, ok := expected["/a/b/c/d"]; !ok {
		t.Errorf("/a/b/c/d not skipped")
	}
	if _, ok := expected["/a/b/c/e"]; !ok {
		t.Errorf("/a/b/c/e not skipped")
	}

}
<|endoftext|>


<commit_before>package relationships

import (
	"errors"
	"github.com/bor3ham/reja/format"
	"github.com/bor3ham/reja/instances"
	"github.com/bor3ham/reja/context"
)

type Pointer struct {
	Data *instances.InstancePointer `json:"data"`
}

type PointerSet struct {
	Data []instances.InstancePointer `json:"data"`
}

type RelationshipStub struct {}
func (stub RelationshipStub) GetSelectDirectColumns() []string {
	return []string{}
}
func (stub RelationshipStub) GetSelectDirectVariables() []interface{} {
	return []interface{}{}
}
func (stub RelationshipStub) GetSelectExtraColumns() []string {
	return []string{}
}
func (stub RelationshipStub) GetSelectExtraVariables() []interface{} {
	return []interface{}{}
}
func (stub RelationshipStub) ValidateNew(c context.Context, val interface{}) (interface{}, error) {
	return val, nil
}

func AssertPointerSet(val interface{}) PointerSet {
	pageVal, ok := val.(PointerSet)
	if !ok {
		panic("Bad pointer page value")
	}
	return pageVal
}

func ParsePagePointerSet(val interface{}) (PointerSet, error) {
	pageVal, ok := val.(format.Page)
	if !ok {
		panic("Invalid pointer set")
	}
	pointersVal := PointerSet{}
	for _, stringPointer := range pageVal.Data {
		pointer, ok := stringPointer.(map[string]interface{})
		if !ok {
			return PointerSet{}, errors.New("Invalid pointer in pointer set.")
		}

		// parse the id
		pointerId, exists := pointer["id"]
		if !exists {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (missing ID).")
		}
		parsedId, ok := pointerId.(string)
		if !ok {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (bad ID).")
		}

		// parse the type
		pointerType, exists := pointer["type"]
		if !exists {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (missing Type).")
		}
		parsedType, ok := pointerType.(string)
		if !ok {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (bad Type).")
		}

		// valid pointer
		pointersVal.Data = append(pointersVal.Data, instances.InstancePointer{
			Type: parsedType,
			ID:   &parsedId,
		})
	}
	return pointersVal, nil
}
<commit_msg>Go fmt<commit_after>package relationships

import (
	"errors"
	"github.com/bor3ham/reja/context"
	"github.com/bor3ham/reja/format"
	"github.com/bor3ham/reja/instances"
)

type Pointer struct {
	Data *instances.InstancePointer `json:"data"`
}

type PointerSet struct {
	Data []instances.InstancePointer `json:"data"`
}

type RelationshipStub struct{}

func (stub RelationshipStub) GetSelectDirectColumns() []string {
	return []string{}
}
func (stub RelationshipStub) GetSelectDirectVariables() []interface{} {
	return []interface{}{}
}
func (stub RelationshipStub) GetSelectExtraColumns() []string {
	return []string{}
}
func (stub RelationshipStub) GetSelectExtraVariables() []interface{} {
	return []interface{}{}
}
func (stub RelationshipStub) ValidateNew(c context.Context, val interface{}) (interface{}, error) {
	return val, nil
}

func AssertPointerSet(val interface{}) PointerSet {
	pageVal, ok := val.(PointerSet)
	if !ok {
		panic("Bad pointer page value")
	}
	return pageVal
}

func ParsePagePointerSet(val interface{}) (PointerSet, error) {
	pageVal, ok := val.(format.Page)
	if !ok {
		panic("Invalid pointer set")
	}
	pointersVal := PointerSet{}
	for _, stringPointer := range pageVal.Data {
		pointer, ok := stringPointer.(map[string]interface{})
		if !ok {
			return PointerSet{}, errors.New("Invalid pointer in pointer set.")
		}

		// parse the id
		pointerId, exists := pointer["id"]
		if !exists {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (missing ID).")
		}
		parsedId, ok := pointerId.(string)
		if !ok {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (bad ID).")
		}

		// parse the type
		pointerType, exists := pointer["type"]
		if !exists {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (missing Type).")
		}
		parsedType, ok := pointerType.(string)
		if !ok {
			return PointerSet{}, errors.New("Invalid pointer in pointer set (bad Type).")
		}

		// valid pointer
		pointersVal.Data = append(pointersVal.Data, instances.InstancePointer{
			Type: parsedType,
			ID:   &parsedId,
		})
	}
	return pointersVal, nil
}
<|endoftext|>


<commit_before>// Copyright 2012 Apcera Inc. All rights reserved.

package test

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"github.com/apcera/gnatsd/server"
)

const natsServerExe = "../gnatsd"

type natsServer struct {
	args []string
	cmd  *exec.Cmd
}

// So we can pass tests and benchmarks..
type tLogger interface {
	Fatalf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
}

var DefaultTestOptions = server.Options{
	Host:   "localhost",
	Port:   4222,
	NoSigs: true,
}

func runDefaultServer() *server.Server {
	return RunServer(&DefaultTestOptions)
}

// New Go Routine based server
func RunServer(opts *server.Options) *server.Server {
	if opts == nil {
		opts = &DefaultTestOptions
	}
	s := server.New(opts)
	if s == nil {
		panic("No nats server object returned.")
	}

	go s.AcceptLoop()

	// Make sure we are running and can bind before returning.
	addr := fmt.Sprintf("%s:%d", opts.Host, opts.Port)
	end := time.Now().Add(10 * time.Second)
	for time.Now().Before(end) {
		conn, err := net.Dial("tcp", addr)
		if err != nil {
			time.Sleep(50 * time.Millisecond)
			// Retry
			continue
		}
		conn.Close()
		return s
	}
	panic("Unable to start NATs Server in Go Routine")
}

func startServer(t tLogger, port int, other string) *natsServer {
	var s natsServer
	args := fmt.Sprintf("-p %d %s", port, other)
	s.args = strings.Split(args, " ")
	s.cmd = exec.Command(natsServerExe, s.args...)
	err := s.cmd.Start()
	if err != nil {
		s.cmd = nil
		t.Errorf("Could not start <%s> [%s], is NATS installed and in path?", natsServerExe, err)
		return &s
	}
	// Give it time to start up
	start := time.Now()
	for {
		addr := fmt.Sprintf("localhost:%d", port)
		c, err := net.Dial("tcp", addr)
		if err != nil {
			time.Sleep(50 * time.Millisecond)
			if time.Since(start) > (5 * time.Second) {
				t.Fatalf("Timed out trying to connect to %s", natsServerExe)
				return nil
			}
		} else {
			c.Close()
			break
		}
	}
	return &s
}

func (s *natsServer) stopServer() {
	if s.cmd != nil && s.cmd.Process != nil {
		s.cmd.Process.Kill()
		s.cmd.Process.Wait()
	}
}

func createClientConn(t tLogger, host string, port int) net.Conn {
	addr := fmt.Sprintf("%s:%d", host, port)
	c, err := net.DialTimeout("tcp", addr, 1*time.Second)
	if err != nil {
		t.Fatalf("Could not connect to server: %v\n", err)
	}
	return c
}

func doConnect(t tLogger, c net.Conn, verbose, pedantic, ssl bool) {
	buf := expectResult(t, c, infoRe)
	js := infoRe.FindAllSubmatch(buf, 1)[0][1]
	var sinfo server.Info
	err := json.Unmarshal(js, &sinfo)
	if err != nil {
		t.Fatalf("Could not unmarshal INFO json: %v\n", err)
	}
	cs := fmt.Sprintf("CONNECT {\"verbose\":%v,\"pedantic\":%v,\"ssl_required\":%v}\r\n", verbose, pedantic, ssl)
	sendProto(t, c, cs)
}

func doDefaultConnect(t tLogger, c net.Conn) {
	// Basic Connect
	doConnect(t, c, false, false, false)
}

func setupConn(t tLogger, c net.Conn) (sendFun, expectFun) {
	doDefaultConnect(t, c)
	send := sendCommand(t, c)
	expect := expectCommand(t, c)
	return send, expect
}

type sendFun func(string)
type expectFun func(*regexp.Regexp) []byte

// Closure version for easier reading
func sendCommand(t tLogger, c net.Conn) sendFun {
	return func(op string) {
		sendProto(t, c, op)
	}
}

// Closure version for easier reading
func expectCommand(t tLogger, c net.Conn) expectFun {
	return func(re *regexp.Regexp) []byte {
		return expectResult(t, c, re)
	}
}

// Send the protocol command to the server.
func sendProto(t tLogger, c net.Conn, op string) {
	n, err := c.Write([]byte(op))
	if err != nil {
		t.Fatalf("Error writing command to conn: %v\n", err)
	}
	if n != len(op) {
		t.Fatalf("Partial write: %d vs %d\n", n, len(op))
	}
}

var (
	infoRe = regexp.MustCompile(`\AINFO\s+([^\r\n]+)\r\n`)
	pingRe = regexp.MustCompile(`\APING\r\n`)
	pongRe = regexp.MustCompile(`\APONG\r\n`)
	msgRe  = regexp.MustCompile(`(?:(?:MSG\s+([^\s]+)\s+([^\s]+)\s+(([^\s]+)[^\S\r\n]+)?(\d+)\r\n([^\\r\\n]*?)\r\n)+?)`)
	okRe   = regexp.MustCompile(`\A\+OK\r\n`)
	errRe  = regexp.MustCompile(`\A\-ERR\s+([^\r\n]+)\r\n`)
)

const (
	SUB_INDEX   = 1
	SID_INDEX   = 2
	REPLY_INDEX = 4
	LEN_INDEX   = 5
	MSG_INDEX   = 6
)

// Reuse expect buffer
var expBuf = make([]byte, 32768)

// Test result from server against regexp
func expectResult(t tLogger, c net.Conn, re *regexp.Regexp) []byte {
	// Wait for commands to be processed and results queued for read
	// time.Sleep(10 * time.Millisecond)
	c.SetReadDeadline(time.Now().Add(1 * time.Second))
	defer c.SetReadDeadline(time.Time{})

	n, err := c.Read(expBuf)
	if n <= 0 && err != nil {
		t.Fatalf("Error reading from conn: %v\n", err)
	}
	buf := expBuf[:n]

	if !re.Match(buf) {
		buf = bytes.Replace(buf, []byte("\r\n"), []byte("\\r\\n"), -1)
		t.Fatalf("Response did not match expected: \n\tReceived:'%s'\n\tExpected:'%s'\n", buf, re)
	}
	return buf
}

// This will check that we got what we expected.
func checkMsg(t tLogger, m [][]byte, subject, sid, reply, len, msg string) {
	if string(m[SUB_INDEX]) != subject {
		t.Fatalf("Did not get correct subject: expected '%s' got '%s'\n", subject, m[SUB_INDEX])
	}
	if string(m[SID_INDEX]) != sid {
		t.Fatalf("Did not get correct sid: exepected '%s' got '%s'\n", sid, m[SID_INDEX])
	}
	if string(m[REPLY_INDEX]) != reply {
		t.Fatalf("Did not get correct reply: exepected '%s' got '%s'\n", reply, m[REPLY_INDEX])
	}
	if string(m[LEN_INDEX]) != len {
		t.Fatalf("Did not get correct msg length: expected '%s' got '%s'\n", len, m[LEN_INDEX])
	}
	if string(m[MSG_INDEX]) != msg {
		t.Fatalf("Did not get correct msg: expected '%s' got '%s'\n", msg, m[MSG_INDEX])
	}
}

// Closure for expectMsgs
func expectMsgsCommand(t tLogger, ef expectFun) func(int) [][][]byte {
	return func(expected int) [][][]byte {
		buf := ef(msgRe)
		matches := msgRe.FindAllSubmatch(buf, -1)
		if len(matches) != expected {
			t.Fatalf("Did not get correct # msgs: %d vs %d\n", len(matches), expected)
		}
		return matches
	}
}
<commit_msg>Suppress logs in default test server<commit_after>// Copyright 2012 Apcera Inc. All rights reserved.

package test

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"os/exec"
	"regexp"
	"strings"
	"time"

	"github.com/apcera/gnatsd/server"
)

const natsServerExe = "../gnatsd"

type natsServer struct {
	args []string
	cmd  *exec.Cmd
}

// So we can pass tests and benchmarks..
type tLogger interface {
	Fatalf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
}

var DefaultTestOptions = server.Options{
	Host:   "localhost",
	Port:   4222,
	NoLog:  true,
	NoSigs: true,
}

func runDefaultServer() *server.Server {
	return RunServer(&DefaultTestOptions)
}

// New Go Routine based server
func RunServer(opts *server.Options) *server.Server {
	if opts == nil {
		opts = &DefaultTestOptions
	}
	s := server.New(opts)
	if s == nil {
		panic("No nats server object returned.")
	}

	go s.AcceptLoop()

	// Make sure we are running and can bind before returning.
	addr := fmt.Sprintf("%s:%d", opts.Host, opts.Port)
	end := time.Now().Add(10 * time.Second)
	for time.Now().Before(end) {
		conn, err := net.Dial("tcp", addr)
		if err != nil {
			time.Sleep(50 * time.Millisecond)
			// Retry
			continue
		}
		conn.Close()
		return s
	}
	panic("Unable to start NATs Server in Go Routine")
}

func startServer(t tLogger, port int, other string) *natsServer {
	var s natsServer
	args := fmt.Sprintf("-p %d %s", port, other)
	s.args = strings.Split(args, " ")
	s.cmd = exec.Command(natsServerExe, s.args...)
	err := s.cmd.Start()
	if err != nil {
		s.cmd = nil
		t.Errorf("Could not start <%s> [%s], is NATS installed and in path?", natsServerExe, err)
		return &s
	}
	// Give it time to start up
	start := time.Now()
	for {
		addr := fmt.Sprintf("localhost:%d", port)
		c, err := net.Dial("tcp", addr)
		if err != nil {
			time.Sleep(50 * time.Millisecond)
			if time.Since(start) > (5 * time.Second) {
				t.Fatalf("Timed out trying to connect to %s", natsServerExe)
				return nil
			}
		} else {
			c.Close()
			break
		}
	}
	return &s
}

func (s *natsServer) stopServer() {
	if s.cmd != nil && s.cmd.Process != nil {
		s.cmd.Process.Kill()
		s.cmd.Process.Wait()
	}
}

func createClientConn(t tLogger, host string, port int) net.Conn {
	addr := fmt.Sprintf("%s:%d", host, port)
	c, err := net.DialTimeout("tcp", addr, 1*time.Second)
	if err != nil {
		t.Fatalf("Could not connect to server: %v\n", err)
	}
	return c
}

func doConnect(t tLogger, c net.Conn, verbose, pedantic, ssl bool) {
	buf := expectResult(t, c, infoRe)
	js := infoRe.FindAllSubmatch(buf, 1)[0][1]
	var sinfo server.Info
	err := json.Unmarshal(js, &sinfo)
	if err != nil {
		t.Fatalf("Could not unmarshal INFO json: %v\n", err)
	}
	cs := fmt.Sprintf("CONNECT {\"verbose\":%v,\"pedantic\":%v,\"ssl_required\":%v}\r\n", verbose, pedantic, ssl)
	sendProto(t, c, cs)
}

func doDefaultConnect(t tLogger, c net.Conn) {
	// Basic Connect
	doConnect(t, c, false, false, false)
}

func setupConn(t tLogger, c net.Conn) (sendFun, expectFun) {
	doDefaultConnect(t, c)
	send := sendCommand(t, c)
	expect := expectCommand(t, c)
	return send, expect
}

type sendFun func(string)
type expectFun func(*regexp.Regexp) []byte

// Closure version for easier reading
func sendCommand(t tLogger, c net.Conn) sendFun {
	return func(op string) {
		sendProto(t, c, op)
	}
}

// Closure version for easier reading
func expectCommand(t tLogger, c net.Conn) expectFun {
	return func(re *regexp.Regexp) []byte {
		return expectResult(t, c, re)
	}
}

// Send the protocol command to the server.
func sendProto(t tLogger, c net.Conn, op string) {
	n, err := c.Write([]byte(op))
	if err != nil {
		t.Fatalf("Error writing command to conn: %v\n", err)
	}
	if n != len(op) {
		t.Fatalf("Partial write: %d vs %d\n", n, len(op))
	}
}

var (
	infoRe = regexp.MustCompile(`\AINFO\s+([^\r\n]+)\r\n`)
	pingRe = regexp.MustCompile(`\APING\r\n`)
	pongRe = regexp.MustCompile(`\APONG\r\n`)
	msgRe  = regexp.MustCompile(`(?:(?:MSG\s+([^\s]+)\s+([^\s]+)\s+(([^\s]+)[^\S\r\n]+)?(\d+)\r\n([^\\r\\n]*?)\r\n)+?)`)
	okRe   = regexp.MustCompile(`\A\+OK\r\n`)
	errRe  = regexp.MustCompile(`\A\-ERR\s+([^\r\n]+)\r\n`)
)

const (
	SUB_INDEX   = 1
	SID_INDEX   = 2
	REPLY_INDEX = 4
	LEN_INDEX   = 5
	MSG_INDEX   = 6
)

// Reuse expect buffer
var expBuf = make([]byte, 32768)

// Test result from server against regexp
func expectResult(t tLogger, c net.Conn, re *regexp.Regexp) []byte {
	// Wait for commands to be processed and results queued for read
	// time.Sleep(10 * time.Millisecond)
	c.SetReadDeadline(time.Now().Add(1 * time.Second))
	defer c.SetReadDeadline(time.Time{})

	n, err := c.Read(expBuf)
	if n <= 0 && err != nil {
		t.Fatalf("Error reading from conn: %v\n", err)
	}
	buf := expBuf[:n]

	if !re.Match(buf) {
		buf = bytes.Replace(buf, []byte("\r\n"), []byte("\\r\\n"), -1)
		t.Fatalf("Response did not match expected: \n\tReceived:'%s'\n\tExpected:'%s'\n", buf, re)
	}
	return buf
}

// This will check that we got what we expected.
func checkMsg(t tLogger, m [][]byte, subject, sid, reply, len, msg string) {
	if string(m[SUB_INDEX]) != subject {
		t.Fatalf("Did not get correct subject: expected '%s' got '%s'\n", subject, m[SUB_INDEX])
	}
	if string(m[SID_INDEX]) != sid {
		t.Fatalf("Did not get correct sid: exepected '%s' got '%s'\n", sid, m[SID_INDEX])
	}
	if string(m[REPLY_INDEX]) != reply {
		t.Fatalf("Did not get correct reply: exepected '%s' got '%s'\n", reply, m[REPLY_INDEX])
	}
	if string(m[LEN_INDEX]) != len {
		t.Fatalf("Did not get correct msg length: expected '%s' got '%s'\n", len, m[LEN_INDEX])
	}
	if string(m[MSG_INDEX]) != msg {
		t.Fatalf("Did not get correct msg: expected '%s' got '%s'\n", msg, m[MSG_INDEX])
	}
}

// Closure for expectMsgs
func expectMsgsCommand(t tLogger, ef expectFun) func(int) [][][]byte {
	return func(expected int) [][][]byte {
		buf := ef(msgRe)
		matches := msgRe.FindAllSubmatch(buf, -1)
		if len(matches) != expected {
			t.Fatalf("Did not get correct # msgs: %d vs %d\n", len(matches), expected)
		}
		return matches
	}
}
<|endoftext|>


<commit_before>// This package contains utility methos for testing
package test

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

func GetTestCasePath() string {
	//TODO: Right now the command is hardcoded. We should decide how to fix this.
	dirPath, err := filepath.Abs("../test/tools")

	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	path, err := filepath.EvalSymlinks(filepath.Join(dirPath, "test"))
	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	return path
}

func PrintSoftErrors(softerrors []error) {
	for _, err := range softerrors {
		fmt.Fprintln(os.Stderr, err.Error())
	}
}

// this method redirects the process's stdout to the test stdout
func LaunchTestCase() (*exec.Cmd, error) {
	cmd := exec.Command(GetTestCasePath())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Start()
	return cmd, err
}

func LaunchTestCaseAndWaitForInitialization() (*exec.Cmd, error) {
	return launchProcessAndWaitInitialization(GetTestCasePath())
}

// starts a process and waits until it writes everythin to stdout: that way we know it has been initialized.
// the process launched should close stdout once it has been fully initialized.
// this method redirects the process's stdout to the test stdout
func launchProcessAndWaitInitialization(file string) (*exec.Cmd, error) {
	cmd := exec.Command(file)

	childout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer childout.Close()

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	io.Copy(os.Stdout, childout)

	return cmd, nil
}
<commit_msg>[test/windows] add workaround for .exe executables<commit_after>// This package contains utility methos for testing
package test

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
)

func GetTestCasePath() string {
	//TODO: Right now the command is hardcoded. We should decide how to fix this.
	dirPath, err := filepath.Abs("../test/tools")
	testFileName := "test"

	// Ugly hack for windows: The testFileName must end in .exe
	if runtime.GOOS == "windows" {
		testFileName = "test.exe"
	}

	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	path, err := filepath.EvalSymlinks(filepath.Join(dirPath, testFileName))
	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	return path
}

func PrintSoftErrors(softerrors []error) {
	for _, err := range softerrors {
		fmt.Fprintln(os.Stderr, err.Error())
	}
}

// this method redirects the process's stdout to the test stdout
func LaunchTestCase() (*exec.Cmd, error) {
	cmd := exec.Command(GetTestCasePath())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Start()
	return cmd, err
}

func LaunchTestCaseAndWaitForInitialization() (*exec.Cmd, error) {
	return launchProcessAndWaitInitialization(GetTestCasePath())
}

// starts a process and waits until it writes everythin to stdout: that way we know it has been initialized.
// the process launched should close stdout once it has been fully initialized.
// this method redirects the process's stdout to the test stdout
func launchProcessAndWaitInitialization(file string) (*exec.Cmd, error) {
	cmd := exec.Command(file)

	childout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer childout.Close()

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	io.Copy(os.Stdout, childout)

	return cmd, nil
}
<|endoftext|>