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

package wrappers

import (
	"context"
	"errors"
	"log"
	"net/http"
	"syscall"

	"github.com/googlecloudplatform/gcsfuse/internal/logger"
	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/fuse/fuseutil"
	"google.golang.org/api/googleapi"
)

func errno(err error) error {
	if err == nil {
		return nil
	}

	// Use existing em errno
	var errno syscall.Errno
	if errors.As(err, &errno) {
		return errno
	}

	// em op is interrupted
	if errors.Is(err, context.Canceled) {
		return syscall.EINTR
	}

	// Translate API errors into an em errno
	var apiErr *googleapi.Error
	if errors.As(err, &apiErr) {
		switch apiErr.Code {
		case http.StatusForbidden:
			return syscall.EACCES
		}
	}

	// Unknown errors
	return syscall.EIO
}

// WithErrorMapping wraps a FileSystem, processing the returned errors, and
// mapping them into syscall.Errno that can be understood by FUSE.
func WithErrorMapping(wrapped fuseutil.FileSystem) fuseutil.FileSystem {
	return &errorMapping{
		wrapped: wrapped,
		logger:  logger.NewError(""),
	}
}

type errorMapping struct {
	wrapped fuseutil.FileSystem
	logger  *log.Logger
}

func (em *errorMapping) mapError(op string, err error) error {
	fsErr := errno(err)
	em.logger.Printf("%s: %v: %v", op, fsErr, err)
	return fsErr
}

func (em *errorMapping) Destroy() {
	em.wrapped.Destroy()
}

func (em *errorMapping) StatFS(
	ctx context.Context,
	op *fuseops.StatFSOp) error {
	err := em.wrapped.StatFS(ctx, op)
	return em.mapError("StatFS", err)
}

func (em *errorMapping) LookUpInode(
	ctx context.Context,
	op *fuseops.LookUpInodeOp) error {
	err := em.wrapped.LookUpInode(ctx, op)
	return em.mapError("LookUpInode", err)
}

func (em *errorMapping) GetInodeAttributes(
	ctx context.Context,
	op *fuseops.GetInodeAttributesOp) error {
	err := em.wrapped.GetInodeAttributes(ctx, op)
	return em.mapError("GetInodeAttributes", err)
}

func (em *errorMapping) SetInodeAttributes(
	ctx context.Context,
	op *fuseops.SetInodeAttributesOp) error {
	err := em.wrapped.SetInodeAttributes(ctx, op)
	return em.mapError("SetInodeAttributes", err)
}

func (em *errorMapping) ForgetInode(
	ctx context.Context,
	op *fuseops.ForgetInodeOp) error {
	err := em.wrapped.ForgetInode(ctx, op)
	return em.mapError("ForgetInode", err)
}

func (em *errorMapping) MkDir(
	ctx context.Context,
	op *fuseops.MkDirOp) error {
	err := em.wrapped.MkDir(ctx, op)
	return em.mapError("MkDir", err)
}

func (em *errorMapping) MkNode(
	ctx context.Context,
	op *fuseops.MkNodeOp) error {
	err := em.wrapped.MkNode(ctx, op)
	return em.mapError("MkNode", err)
}

func (em *errorMapping) CreateFile(
	ctx context.Context,
	op *fuseops.CreateFileOp) error {
	err := em.wrapped.CreateFile(ctx, op)
	return em.mapError("CreateFile", err)
}

func (em *errorMapping) CreateLink(
	ctx context.Context,
	op *fuseops.CreateLinkOp) error {
	err := em.wrapped.CreateLink(ctx, op)
	return em.mapError("CreateLink", err)
}

func (em *errorMapping) CreateSymlink(
	ctx context.Context,
	op *fuseops.CreateSymlinkOp) error {
	err := em.wrapped.CreateSymlink(ctx, op)
	return em.mapError("CreateSymlink", err)
}

func (em *errorMapping) Rename(
	ctx context.Context,
	op *fuseops.RenameOp) error {
	err := em.wrapped.Rename(ctx, op)
	return em.mapError("Rename", err)
}

func (em *errorMapping) RmDir(
	ctx context.Context,
	op *fuseops.RmDirOp) error {
	err := em.wrapped.RmDir(ctx, op)
	return em.mapError("RmDir", err)
}

func (em *errorMapping) Unlink(
	ctx context.Context,
	op *fuseops.UnlinkOp) error {
	err := em.wrapped.Unlink(ctx, op)
	return em.mapError("Unlink", err)
}

func (em *errorMapping) OpenDir(
	ctx context.Context,
	op *fuseops.OpenDirOp) error {
	err := em.wrapped.OpenDir(ctx, op)
	return em.mapError("OpenDir", err)
}

func (em *errorMapping) ReadDir(
	ctx context.Context,
	op *fuseops.ReadDirOp) error {
	err := em.wrapped.ReadDir(ctx, op)
	return em.mapError("ReadDir", err)
}

func (em *errorMapping) ReleaseDirHandle(
	ctx context.Context,
	op *fuseops.ReleaseDirHandleOp) error {
	err := em.wrapped.ReleaseDirHandle(ctx, op)
	return em.mapError("ReleaseDirHandle", err)
}

func (em *errorMapping) OpenFile(
	ctx context.Context,
	op *fuseops.OpenFileOp) error {
	err := em.wrapped.OpenFile(ctx, op)
	return em.mapError("OpenFile", err)
}

func (em *errorMapping) ReadFile(
	ctx context.Context,
	op *fuseops.ReadFileOp) error {
	err := em.wrapped.ReadFile(ctx, op)
	return em.mapError("ReadFile", err)
}

func (em *errorMapping) WriteFile(
	ctx context.Context,
	op *fuseops.WriteFileOp) error {
	err := em.wrapped.WriteFile(ctx, op)
	return em.mapError("WriteFile", err)
}

func (em *errorMapping) SyncFile(
	ctx context.Context,
	op *fuseops.SyncFileOp) error {
	err := em.wrapped.SyncFile(ctx, op)
	return em.mapError("SyncFile", err)
}

func (em *errorMapping) FlushFile(
	ctx context.Context,
	op *fuseops.FlushFileOp) error {
	err := em.wrapped.FlushFile(ctx, op)
	return em.mapError("FlushFile", err)
}

func (em *errorMapping) ReleaseFileHandle(
	ctx context.Context,
	op *fuseops.ReleaseFileHandleOp) error {
	err := em.wrapped.ReleaseFileHandle(ctx, op)
	return em.mapError("ReleaseFileHandle", err)
}

func (em *errorMapping) ReadSymlink(
	ctx context.Context,
	op *fuseops.ReadSymlinkOp) error {
	err := em.wrapped.ReadSymlink(ctx, op)
	return em.mapError("ReadSymlink", err)
}

func (em *errorMapping) RemoveXattr(
	ctx context.Context,
	op *fuseops.RemoveXattrOp) error {
	err := em.wrapped.RemoveXattr(ctx, op)
	return em.mapError("RemoveXattr", err)
}

func (em *errorMapping) GetXattr(
	ctx context.Context,
	op *fuseops.GetXattrOp) error {
	err := em.wrapped.GetXattr(ctx, op)
	return em.mapError("GetXattr", err)
}

func (em *errorMapping) ListXattr(
	ctx context.Context,
	op *fuseops.ListXattrOp) error {
	err := em.wrapped.ListXattr(ctx, op)
	return em.mapError("ListXattr", err)
}

func (em *errorMapping) SetXattr(
	ctx context.Context,
	op *fuseops.SetXattrOp) error {
	err := em.wrapped.SetXattr(ctx, op)
	return em.mapError("SetXattr", err)
}

func (em *errorMapping) Fallocate(
	ctx context.Context,
	op *fuseops.FallocateOp) error {
	err := em.wrapped.Fallocate(ctx, op)
	return em.mapError("Fallocate", err)
}
<commit_msg>Clean up the loggings from error mapping<commit_after>// Copyright 2021 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package wrappers

import (
	"context"
	"errors"
	"log"
	"net/http"
	"syscall"

	"github.com/googlecloudplatform/gcsfuse/internal/logger"
	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/fuse/fuseutil"
	"google.golang.org/api/googleapi"
)

func errno(err error) error {
	if err == nil {
		return nil
	}

	// Use existing em errno
	var errno syscall.Errno
	if errors.As(err, &errno) {
		return errno
	}

	// em op is interrupted
	if errors.Is(err, context.Canceled) {
		return syscall.EINTR
	}

	// Translate API errors into an em errno
	var apiErr *googleapi.Error
	if errors.As(err, &apiErr) {
		switch apiErr.Code {
		case http.StatusForbidden:
			return syscall.EACCES
		}
	}

	// Unknown errors
	return syscall.EIO
}

// WithErrorMapping wraps a FileSystem, processing the returned errors, and
// mapping them into syscall.Errno that can be understood by FUSE.
func WithErrorMapping(wrapped fuseutil.FileSystem) fuseutil.FileSystem {
	return &errorMapping{
		wrapped: wrapped,
		logger:  logger.NewError(""),
	}
}

type errorMapping struct {
	wrapped fuseutil.FileSystem
	logger  *log.Logger
}

func (em *errorMapping) mapError(op string, err error) error {
	fsErr := errno(err)
	if err != nil && fsErr != nil && err != fsErr {
		em.logger.Printf("%s: %v, %v", op, fsErr, err)
	}
	return fsErr
}

func (em *errorMapping) Destroy() {
	em.wrapped.Destroy()
}

func (em *errorMapping) StatFS(
	ctx context.Context,
	op *fuseops.StatFSOp) error {
	err := em.wrapped.StatFS(ctx, op)
	return em.mapError("StatFS", err)
}

func (em *errorMapping) LookUpInode(
	ctx context.Context,
	op *fuseops.LookUpInodeOp) error {
	err := em.wrapped.LookUpInode(ctx, op)
	return em.mapError("LookUpInode", err)
}

func (em *errorMapping) GetInodeAttributes(
	ctx context.Context,
	op *fuseops.GetInodeAttributesOp) error {
	err := em.wrapped.GetInodeAttributes(ctx, op)
	return em.mapError("GetInodeAttributes", err)
}

func (em *errorMapping) SetInodeAttributes(
	ctx context.Context,
	op *fuseops.SetInodeAttributesOp) error {
	err := em.wrapped.SetInodeAttributes(ctx, op)
	return em.mapError("SetInodeAttributes", err)
}

func (em *errorMapping) ForgetInode(
	ctx context.Context,
	op *fuseops.ForgetInodeOp) error {
	err := em.wrapped.ForgetInode(ctx, op)
	return em.mapError("ForgetInode", err)
}

func (em *errorMapping) MkDir(
	ctx context.Context,
	op *fuseops.MkDirOp) error {
	err := em.wrapped.MkDir(ctx, op)
	return em.mapError("MkDir", err)
}

func (em *errorMapping) MkNode(
	ctx context.Context,
	op *fuseops.MkNodeOp) error {
	err := em.wrapped.MkNode(ctx, op)
	return em.mapError("MkNode", err)
}

func (em *errorMapping) CreateFile(
	ctx context.Context,
	op *fuseops.CreateFileOp) error {
	err := em.wrapped.CreateFile(ctx, op)
	return em.mapError("CreateFile", err)
}

func (em *errorMapping) CreateLink(
	ctx context.Context,
	op *fuseops.CreateLinkOp) error {
	err := em.wrapped.CreateLink(ctx, op)
	return em.mapError("CreateLink", err)
}

func (em *errorMapping) CreateSymlink(
	ctx context.Context,
	op *fuseops.CreateSymlinkOp) error {
	err := em.wrapped.CreateSymlink(ctx, op)
	return em.mapError("CreateSymlink", err)
}

func (em *errorMapping) Rename(
	ctx context.Context,
	op *fuseops.RenameOp) error {
	err := em.wrapped.Rename(ctx, op)
	return em.mapError("Rename", err)
}

func (em *errorMapping) RmDir(
	ctx context.Context,
	op *fuseops.RmDirOp) error {
	err := em.wrapped.RmDir(ctx, op)
	return em.mapError("RmDir", err)
}

func (em *errorMapping) Unlink(
	ctx context.Context,
	op *fuseops.UnlinkOp) error {
	err := em.wrapped.Unlink(ctx, op)
	return em.mapError("Unlink", err)
}

func (em *errorMapping) OpenDir(
	ctx context.Context,
	op *fuseops.OpenDirOp) error {
	err := em.wrapped.OpenDir(ctx, op)
	return em.mapError("OpenDir", err)
}

func (em *errorMapping) ReadDir(
	ctx context.Context,
	op *fuseops.ReadDirOp) error {
	err := em.wrapped.ReadDir(ctx, op)
	return em.mapError("ReadDir", err)
}

func (em *errorMapping) ReleaseDirHandle(
	ctx context.Context,
	op *fuseops.ReleaseDirHandleOp) error {
	err := em.wrapped.ReleaseDirHandle(ctx, op)
	return em.mapError("ReleaseDirHandle", err)
}

func (em *errorMapping) OpenFile(
	ctx context.Context,
	op *fuseops.OpenFileOp) error {
	err := em.wrapped.OpenFile(ctx, op)
	return em.mapError("OpenFile", err)
}

func (em *errorMapping) ReadFile(
	ctx context.Context,
	op *fuseops.ReadFileOp) error {
	err := em.wrapped.ReadFile(ctx, op)
	return em.mapError("ReadFile", err)
}

func (em *errorMapping) WriteFile(
	ctx context.Context,
	op *fuseops.WriteFileOp) error {
	err := em.wrapped.WriteFile(ctx, op)
	return em.mapError("WriteFile", err)
}

func (em *errorMapping) SyncFile(
	ctx context.Context,
	op *fuseops.SyncFileOp) error {
	err := em.wrapped.SyncFile(ctx, op)
	return em.mapError("SyncFile", err)
}

func (em *errorMapping) FlushFile(
	ctx context.Context,
	op *fuseops.FlushFileOp) error {
	err := em.wrapped.FlushFile(ctx, op)
	return em.mapError("FlushFile", err)
}

func (em *errorMapping) ReleaseFileHandle(
	ctx context.Context,
	op *fuseops.ReleaseFileHandleOp) error {
	err := em.wrapped.ReleaseFileHandle(ctx, op)
	return em.mapError("ReleaseFileHandle", err)
}

func (em *errorMapping) ReadSymlink(
	ctx context.Context,
	op *fuseops.ReadSymlinkOp) error {
	err := em.wrapped.ReadSymlink(ctx, op)
	return em.mapError("ReadSymlink", err)
}

func (em *errorMapping) RemoveXattr(
	ctx context.Context,
	op *fuseops.RemoveXattrOp) error {
	err := em.wrapped.RemoveXattr(ctx, op)
	return em.mapError("RemoveXattr", err)
}

func (em *errorMapping) GetXattr(
	ctx context.Context,
	op *fuseops.GetXattrOp) error {
	err := em.wrapped.GetXattr(ctx, op)
	return em.mapError("GetXattr", err)
}

func (em *errorMapping) ListXattr(
	ctx context.Context,
	op *fuseops.ListXattrOp) error {
	err := em.wrapped.ListXattr(ctx, op)
	return em.mapError("ListXattr", err)
}

func (em *errorMapping) SetXattr(
	ctx context.Context,
	op *fuseops.SetXattrOp) error {
	err := em.wrapped.SetXattr(ctx, op)
	return em.mapError("SetXattr", err)
}

func (em *errorMapping) Fallocate(
	ctx context.Context,
	op *fuseops.FallocateOp) error {
	err := em.wrapped.Fallocate(ctx, op)
	return em.mapError("Fallocate", err)
}
<|endoftext|>


<commit_before>// Copyright 2015 ISRG.  All rights reserved
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package ca

import (
	"testing"

	_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
	blog "github.com/letsencrypt/boulder/log"
	"github.com/letsencrypt/boulder/test"
)

const badDriver = "nothing"
const badFilename = "/doesnotexist/nofile"
const sqliteDriver = "sqlite3"
const sqliteName = ":memory:"

func TestConstruction(t *testing.T) {
	log, err := blog.Dial("", "", "tag")
	test.AssertNotError(t, err, "Could not construct audit logger")

	// Successful case
	_, err = NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	// Covers "sql.Open" error
	_, err = NewCertificateAuthorityDatabaseImpl(log, badDriver, sqliteName)
	test.AssertError(t, err, "Should have failed construction")

	// Covers "db.Ping" error
	_, err = NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, badFilename)
	test.AssertError(t, err, "Should have failed construction")

	// Ensures no nil pointer exception in logging
	_, err = NewCertificateAuthorityDatabaseImpl(nil, sqliteDriver, sqliteName)
	test.AssertError(t, err, "Should have failed construction")
}

func TestBeginCommit(t *testing.T) {
	log, err := blog.Dial("", "", "tag")
	test.AssertNotError(t, err, "Could not construct audit logger")

	cadb, err := NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	err = cadb.Begin()
	test.AssertNotError(t, err, "Could not begin")

	err = cadb.Begin()
	test.AssertError(t, err, "Should have already begun")

	err = cadb.Commit()
	test.AssertNotError(t, err, "Could not commit")

	err = cadb.Commit()
	test.AssertError(t, err, "Should have already committed")

}

func TestGetSetSequenceOutsideTx(t *testing.T) {
	log, err := blog.Dial("", "", "tag")
	test.AssertNotError(t, err, "Could not construct audit logger")

	cadb, err := NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	_, err = cadb.IncrementAndGetSerial()
	test.AssertError(t, err, "Not permitted")
}

func TestGetSetSequenceNumber(t *testing.T) {
	log, err := blog.Dial("", "", "tag")
	test.AssertNotError(t, err, "Could not construct audit logger")

	cadb, err := NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	err = cadb.Begin()
	test.AssertNotError(t, err, "Could not begin")

	num, err := cadb.IncrementAndGetSerial()
	test.AssertNotError(t, err, "Could not get number")

	num2, err := cadb.IncrementAndGetSerial()
	test.AssertNotError(t, err, "Could not get number")
	test.Assert(t, num+1 == num2, "Numbers should be incrementing")

	err = cadb.Commit()
	test.AssertNotError(t, err, "Could not commit")
}
<commit_msg>Fix test by updating log init.<commit_after>// Copyright 2015 ISRG.  All rights reserved
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package ca

import (
	"testing"

	"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
	_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
	blog "github.com/letsencrypt/boulder/log"
	"github.com/letsencrypt/boulder/test"
)

const badDriver = "nothing"
const badFilename = "/doesnotexist/nofile"
const sqliteDriver = "sqlite3"
const sqliteName = ":memory:"

func TestConstruction(t *testing.T) {
	stats, _ := statsd.NewNoopClient(nil)
	log, err := blog.Dial("", "", "tag", stats)
	test.AssertNotError(t, err, "Could not construct audit logger")

	// Successful case
	_, err = NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	// Covers "sql.Open" error
	_, err = NewCertificateAuthorityDatabaseImpl(log, badDriver, sqliteName)
	test.AssertError(t, err, "Should have failed construction")

	// Covers "db.Ping" error
	_, err = NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, badFilename)
	test.AssertError(t, err, "Should have failed construction")

	// Ensures no nil pointer exception in logging
	_, err = NewCertificateAuthorityDatabaseImpl(nil, sqliteDriver, sqliteName)
	test.AssertError(t, err, "Should have failed construction")
}

func TestBeginCommit(t *testing.T) {
	stats, _ := statsd.NewNoopClient(nil)
	log, err := blog.Dial("", "", "tag", stats)
	test.AssertNotError(t, err, "Could not construct audit logger")

	cadb, err := NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	err = cadb.Begin()
	test.AssertNotError(t, err, "Could not begin")

	err = cadb.Begin()
	test.AssertError(t, err, "Should have already begun")

	err = cadb.Commit()
	test.AssertNotError(t, err, "Could not commit")

	err = cadb.Commit()
	test.AssertError(t, err, "Should have already committed")

}

func TestGetSetSequenceOutsideTx(t *testing.T) {
	stats, _ := statsd.NewNoopClient(nil)
	log, err := blog.Dial("", "", "tag", stats)
	test.AssertNotError(t, err, "Could not construct audit logger")

	cadb, err := NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	_, err = cadb.IncrementAndGetSerial()
	test.AssertError(t, err, "Not permitted")
}

func TestGetSetSequenceNumber(t *testing.T) {
	stats, _ := statsd.NewNoopClient(nil)
	log, err := blog.Dial("", "", "tag", stats)
	test.AssertNotError(t, err, "Could not construct audit logger")

	cadb, err := NewCertificateAuthorityDatabaseImpl(log, sqliteDriver, sqliteName)
	test.AssertNotError(t, err, "Could not construct CA DB")

	err = cadb.Begin()
	test.AssertNotError(t, err, "Could not begin")

	num, err := cadb.IncrementAndGetSerial()
	test.AssertNotError(t, err, "Could not get number")

	num2, err := cadb.IncrementAndGetSerial()
	test.AssertNotError(t, err, "Could not get number")
	test.Assert(t, num+1 == num2, "Numbers should be incrementing")

	err = cadb.Commit()
	test.AssertNotError(t, err, "Could not commit")
}
<|endoftext|>


<commit_before>package gunfish

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"log"
	"math/rand"
	"net"
	"net/http"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"golang.org/x/net/http2"
)

// StartAPNSMockServer starts HTTP/2 server for mock
func StartAPNSMockServer(cert, key string) {
	// Create TLSlistener
	s := http.Server{}
	s.Addr = ":2195"
	http2.VerboseLogs = false
	http2.ConfigureServer(&s, nil)
	tlsConf := &tls.Config{}
	if s.TLSConfig != nil {
		*tlsConf = *s.TLSConfig
	}
	if tlsConf.NextProtos == nil {
		tlsConf.NextProtos = []string{"http/2.0"}
	}

	var err error
	tlsConf.Certificates = make([]tls.Certificate, 1)
	tlsConf.Certificates[0], err = tls.LoadX509KeyPair(cert, key)
	if err != nil {
		return
	}

	ln, err := net.Listen("tcp", s.Addr)
	if err != nil {
		return
	}

	tlsListener := tls.NewListener(ln, tlsConf)

	// Set Handlers
	LogWithFields(logrus.Fields{
		"type": "apns_mock",
	}).Info("Starts APNS mock server.")

	http.HandleFunc("/3/device/", func(w http.ResponseWriter, r *http.Request) {
		// sets the response time from apns server
		time.Sleep(time.Millisecond*200 + time.Millisecond*(time.Duration(rand.Int63n(90))-45))

		// only allow path which pattern is '/3/device/:token'
		splitPath := strings.Split(r.URL.Path, "/")
		if len(splitPath) != 4 {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "404 Not found")
			return
		}

		w.Header().Set("Content-Type", ApplicationJSON)

		token := splitPath[len(splitPath)-1]
		if len(([]byte(token))) > LimitApnsTokenByteSize {
			w.Header().Set("apns-id", "apns-id")
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, createErrorResponse(BadDeviceToken, http.StatusBadRequest))
		} else if token == "missingtopic" {
			// MissingDeviceToken
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, createErrorResponse(MissingTopic, http.StatusBadRequest))
		} else if token == "status410" {
			// If the value in the :status header is 410, the value of this key is
			// the last time at which APNs confirmed that the device token was
			// no longer valid for the topic.
			//
			// Stop pushing notifications until the device registers a token with
			// a later timestamp with your provider.
			w.WriteHeader(http.StatusGone)
			fmt.Fprint(w, createErrorResponse(TopicDisallowed, http.StatusGone))
		} else {
			w.Header().Set("apns-id", "apns-id")
			w.WriteHeader(http.StatusOK)
		}

		return
	})

	http.HandleFunc("/stop/", func(w http.ResponseWriter, r *http.Request) {
		tlsListener.Close()
		return
	})

	log.Fatal(s.Serve(tlsListener))
}

// StopAPNSServer stops APNS Mock server
func StopAPNSServer(cert, key string, insecure bool) error {
	client, err := NewConnection(cert, key, insecure)
	if err != nil {
		return err
	}

	client.Get("/stop")

	return nil
}

func createErrorResponse(ermsg ErrorResponseCode, status int) string {
	var er ErrorResponse
	if status == http.StatusGone {
		er = ErrorResponse{
			Reason:    ermsg.String(),
			Timestamp: time.Now().Unix(),
		}
	} else {
		er = ErrorResponse{
			Reason: ermsg.String(),
		}
	}
	der, _ := json.Marshal(er)
	return string(der)
}
<commit_msg>remove logrus<commit_after>package apns

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"log"
	"math/rand"
	"net"
	"net/http"
	"strings"
	"time"

	"golang.org/x/net/http2"
)

const (
	ApplicationJSON        = "application/json"
	LimitApnsTokenByteSize = 100 // Payload byte size.
)

// StartAPNSMockServer starts HTTP/2 server for mock
func StartAPNSMockServer(cert, key string) {
	// Create TLSlistener
	s := http.Server{}
	s.Addr = ":2195"
	http2.VerboseLogs = false
	http2.ConfigureServer(&s, nil)
	tlsConf := &tls.Config{}
	if s.TLSConfig != nil {
		*tlsConf = *s.TLSConfig
	}
	if tlsConf.NextProtos == nil {
		tlsConf.NextProtos = []string{"http/2.0"}
	}

	var err error
	tlsConf.Certificates = make([]tls.Certificate, 1)
	tlsConf.Certificates[0], err = tls.LoadX509KeyPair(cert, key)
	if err != nil {
		return
	}

	ln, err := net.Listen("tcp", s.Addr)
	if err != nil {
		return
	}

	tlsListener := tls.NewListener(ln, tlsConf)

	http.HandleFunc("/3/device/", func(w http.ResponseWriter, r *http.Request) {
		// sets the response time from apns server
		time.Sleep(time.Millisecond*200 + time.Millisecond*(time.Duration(rand.Int63n(90))-45))

		// only allow path which pattern is '/3/device/:token'
		splitPath := strings.Split(r.URL.Path, "/")
		if len(splitPath) != 4 {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "404 Not found")
			return
		}

		w.Header().Set("Content-Type", ApplicationJSON)

		token := splitPath[len(splitPath)-1]
		if len(([]byte(token))) > LimitApnsTokenByteSize {
			w.Header().Set("apns-id", "apns-id")
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, createErrorResponse(BadDeviceToken, http.StatusBadRequest))
		} else if token == "missingtopic" {
			// MissingDeviceToken
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, createErrorResponse(MissingTopic, http.StatusBadRequest))
		} else if token == "status410" {
			// If the value in the :status header is 410, the value of this key is
			// the last time at which APNs confirmed that the device token was
			// no longer valid for the topic.
			//
			// Stop pushing notifications until the device registers a token with
			// a later timestamp with your provider.
			w.WriteHeader(http.StatusGone)
			fmt.Fprint(w, createErrorResponse(TopicDisallowed, http.StatusGone))
		} else {
			w.Header().Set("apns-id", "apns-id")
			w.WriteHeader(http.StatusOK)
		}

		return
	})

	http.HandleFunc("/stop/", func(w http.ResponseWriter, r *http.Request) {
		tlsListener.Close()
		return
	})

	log.Fatal(s.Serve(tlsListener))
}

// StopAPNSServer stops APNS Mock server
func StopAPNSServer(cert, key string, insecure bool) error {
	client, err := NewConnection(cert, key, insecure)
	if err != nil {
		return err
	}

	client.Get("/stop")

	return nil
}

func createErrorResponse(ermsg ErrorResponseCode, status int) string {
	var er ErrorResponse
	if status == http.StatusGone {
		er = ErrorResponse{
			Reason:    ermsg.String(),
			Timestamp: time.Now().Unix(),
		}
	} else {
		er = ErrorResponse{
			Reason: ermsg.String(),
		}
	}
	der, _ := json.Marshal(er)
	return string(der)
}
<|endoftext|>


<commit_before>package scheduler

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"sync"

	"github.com/winston-ci/prole/api/builds"
)

type Builder interface {
	Build(*builds.Build) (bool, error)
}

type Scheduler struct {
	builder       Builder
	runningBuilds *sync.WaitGroup

	httpClient *http.Client
}

func NewScheduler(builder Builder) *Scheduler {
	return &Scheduler{
		builder: builder,

		httpClient: &http.Client{
			Transport: &http.Transport{
				DisableKeepAlives: true,
			},
		},

		runningBuilds: new(sync.WaitGroup),
	}
}

func (scheduler *Scheduler) Schedule(build *builds.Build) error {
	scheduler.runningBuilds.Add(1)

	go func() {
		defer scheduler.runningBuilds.Done()

		log.Println("building", build.Guid)

		ok, err := scheduler.builder.Build(build)
		scheduler.completeBuild(*build, ok, err)
	}()

	return nil
}

func (scheduler *Scheduler) completeBuild(build builds.Build, succeeded bool, errored error) {
	if errored != nil {
		build.Status = "errored"
	} else if succeeded {
		build.Status = "succeeded"
	} else {
		build.Status = "failed"
	}

	log.Println("completed:", build.Guid, build.Status, errored)

	if build.Callback == "" {
		return
	}

	// this should always successfully parse (it's done via validation)
	destination, _ := url.ParseRequestURI(build.Callback)

	payload, _ := json.Marshal(build)

	scheduler.httpClient.Do(&http.Request{
		Method: "PUT",
		URL:    destination,

		ContentLength: int64(len(payload)),

		Header: map[string][]string{
			"Content-Type": {"application/json"},
		},

		Body: ioutil.NopCloser(bytes.NewBuffer(payload)),
	})
}
<commit_msg>close result callback response<commit_after>package scheduler

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"sync"

	"github.com/winston-ci/prole/api/builds"
)

type Builder interface {
	Build(*builds.Build) (bool, error)
}

type Scheduler struct {
	builder       Builder
	runningBuilds *sync.WaitGroup

	httpClient *http.Client
}

func NewScheduler(builder Builder) *Scheduler {
	return &Scheduler{
		builder: builder,

		httpClient: &http.Client{
			Transport: &http.Transport{
				DisableKeepAlives: true,
			},
		},

		runningBuilds: new(sync.WaitGroup),
	}
}

func (scheduler *Scheduler) Schedule(build *builds.Build) error {
	scheduler.runningBuilds.Add(1)

	go func() {
		defer scheduler.runningBuilds.Done()

		log.Println("building", build.Guid)

		ok, err := scheduler.builder.Build(build)
		scheduler.completeBuild(*build, ok, err)
	}()

	return nil
}

func (scheduler *Scheduler) completeBuild(build builds.Build, succeeded bool, errored error) {
	if errored != nil {
		build.Status = "errored"
	} else if succeeded {
		build.Status = "succeeded"
	} else {
		build.Status = "failed"
	}

	log.Println("completed:", build.Guid, build.Status, errored)

	if build.Callback == "" {
		return
	}

	// this should always successfully parse (it's done via validation)
	destination, _ := url.ParseRequestURI(build.Callback)

	payload, _ := json.Marshal(build)

	res, err := scheduler.httpClient.Do(&http.Request{
		Method: "PUT",
		URL:    destination,

		ContentLength: int64(len(payload)),

		Header: map[string][]string{
			"Content-Type": {"application/json"},
		},

		Body: ioutil.NopCloser(bytes.NewBuffer(payload)),
	})
	if err != nil {
		log.Println("failed to submit result:", err)
		return
	}

	res.Body.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"errors"
	"time"

	"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options"
	"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats"
	"github.com/Microsoft/hcsshim/internal/gcs"
	"github.com/Microsoft/hcsshim/internal/hcs"
	"github.com/Microsoft/hcsshim/internal/shimdiag"
	"github.com/containerd/containerd/errdefs"
	"github.com/containerd/containerd/runtime/v2/task"
	specs "github.com/opencontainers/runtime-spec/specs-go"
)

var errTaskNotIsolated = errors.New("task is not isolated")

// shimTaskPidPair groups a process pid to its execID if it was user generated.
type shimTaskPidPair struct {
	// Pid is the pid of the container process.
	Pid int
	// ExecID is the id of the exec if this container process was user
	// generated.
	ExecID string
}

type shimTask interface {
	// ID returns the original id used at `Create`.
	ID() string
	// CreateExec creates an additional exec within this task.
	//
	// If `req.ID==""` or `req.ID` is already a known exec this task MUST return
	// `errdefs.ErrAlreadyExists`
	//
	// If the init exec is no longer running this task MUST return
	// `errdefs.ErrFailedPrecondition`.
	CreateExec(ctx context.Context, req *task.ExecProcessRequest, s *specs.Process) error
	// GetExec returns an exec in this task that matches `eid`. If `eid == ""`
	// returns the init exec from the initial call to `Create`.
	//
	// If `eid` is not found this task MUST return `errdefs.ErrNotFound`.
	GetExec(eid string) (shimExec, error)
	// KillExec sends `signal` to the exec that matches `eid`. If `all==true`
	// `eid` MUST be empty and this task will send `signal` to all exec's in the
	// task and lastly send `signal` to the init exec.
	//
	// If `all == true && eid != ""` this task MUST return
	// `errdefs.ErrFailedPrecondition`.
	//
	// A call to `KillExec` is only valid when the exec is in the
	// `shimExecStateRunning, shimExecStateExited` states. If the exec is not in
	// this state this task MUST return `errdefs.ErrFailedPrecondition`. If
	// `eid=="" && all == false` all additional exec's must be in the
	// `shimExecStateExited` state.
	KillExec(ctx context.Context, eid string, signal uint32, all bool) error
	// DeleteExec deletes a `shimExec` in this `shimTask` that matches `eid`. If
	// `eid == ""` deletes the init `shimExec` AND this `shimTask`.
	//
	// If `eid` is not found `shimExec` MUST return `errdefs.ErrNotFound`.
	//
	// A call to `DeleteExec` is only valid in `shimExecStateCreated` and
	// `shimExecStateExited` states and MUST return
	// `errdefs.ErrFailedPrecondition` if not in these states. If `eid==""` all
	// additional exec's tracked by this task must also be in the
	// `shimExecStateExited` state.
	DeleteExec(ctx context.Context, eid string) (int, uint32, time.Time, error)
	// Pids returns all process pid's in this `shimTask` including ones not
	// created by the caller via a `CreateExec`.
	Pids(ctx context.Context) ([]options.ProcessDetails, error)
	// Waits for the the init task to complete.
	//
	// Note: If the `request.ExecID == ""` the caller should instead call `Wait`
	// rather than `exec.Wait` on the init exec. This is because  the lifetime
	// of the task is larger than just the init process and on shutdown we need
	// to wait for the container and potentially UVM before unblocking any event
	// based listeners or `Wait` based listeners.
	Wait() *task.StateResponse
	// ExecInHost execs a process in the host UVM. It is not tracked in the
	// other lifetimes of the task and is used only for diagnostics.
	//
	// If the host is not hypervisor isolated returns error.
	ExecInHost(ctx context.Context, req *shimdiag.ExecProcessRequest) (int, error)
	// DumpGuestStacks dumps the GCS stacks associated with this task host.
	//
	// If the host is not hypervisor isolated returns `""`.
	DumpGuestStacks(ctx context.Context) string
	// Share shares a directory/file into the host UVM.
	//
	// If the host is not hypervisor isolated returns error.
	Share(ctx context.Context, req *shimdiag.ShareRequest) error
	// Stats returns various metrics for the task.
	//
	// If the host is hypervisor isolated and this task owns the host additional
	// metrics on the UVM may be returned as well.
	Stats(ctx context.Context) (*stats.Statistics, error)
}

// isStatsNotFound returns true if the err corresponds to a scenario
// where statistics cannot be retrieved or found
func isStatsNotFound(err error) bool {
	return errdefs.IsNotFound(err) ||
		hcs.IsNotExist(err) ||
		hcs.IsOperationInvalidState(err) ||
		gcs.IsNotExist(err)
}
<commit_msg>Add Check for access denied when looking for stats<commit_after>package main

import (
	"context"
	"errors"
	"time"

	"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options"
	"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats"
	"github.com/Microsoft/hcsshim/internal/gcs"
	"github.com/Microsoft/hcsshim/internal/hcs"
	"github.com/Microsoft/hcsshim/internal/shimdiag"
	"github.com/containerd/containerd/errdefs"
	"github.com/containerd/containerd/runtime/v2/task"
	specs "github.com/opencontainers/runtime-spec/specs-go"
)

var errTaskNotIsolated = errors.New("task is not isolated")

// shimTaskPidPair groups a process pid to its execID if it was user generated.
type shimTaskPidPair struct {
	// Pid is the pid of the container process.
	Pid int
	// ExecID is the id of the exec if this container process was user
	// generated.
	ExecID string
}

type shimTask interface {
	// ID returns the original id used at `Create`.
	ID() string
	// CreateExec creates an additional exec within this task.
	//
	// If `req.ID==""` or `req.ID` is already a known exec this task MUST return
	// `errdefs.ErrAlreadyExists`
	//
	// If the init exec is no longer running this task MUST return
	// `errdefs.ErrFailedPrecondition`.
	CreateExec(ctx context.Context, req *task.ExecProcessRequest, s *specs.Process) error
	// GetExec returns an exec in this task that matches `eid`. If `eid == ""`
	// returns the init exec from the initial call to `Create`.
	//
	// If `eid` is not found this task MUST return `errdefs.ErrNotFound`.
	GetExec(eid string) (shimExec, error)
	// KillExec sends `signal` to the exec that matches `eid`. If `all==true`
	// `eid` MUST be empty and this task will send `signal` to all exec's in the
	// task and lastly send `signal` to the init exec.
	//
	// If `all == true && eid != ""` this task MUST return
	// `errdefs.ErrFailedPrecondition`.
	//
	// A call to `KillExec` is only valid when the exec is in the
	// `shimExecStateRunning, shimExecStateExited` states. If the exec is not in
	// this state this task MUST return `errdefs.ErrFailedPrecondition`. If
	// `eid=="" && all == false` all additional exec's must be in the
	// `shimExecStateExited` state.
	KillExec(ctx context.Context, eid string, signal uint32, all bool) error
	// DeleteExec deletes a `shimExec` in this `shimTask` that matches `eid`. If
	// `eid == ""` deletes the init `shimExec` AND this `shimTask`.
	//
	// If `eid` is not found `shimExec` MUST return `errdefs.ErrNotFound`.
	//
	// A call to `DeleteExec` is only valid in `shimExecStateCreated` and
	// `shimExecStateExited` states and MUST return
	// `errdefs.ErrFailedPrecondition` if not in these states. If `eid==""` all
	// additional exec's tracked by this task must also be in the
	// `shimExecStateExited` state.
	DeleteExec(ctx context.Context, eid string) (int, uint32, time.Time, error)
	// Pids returns all process pid's in this `shimTask` including ones not
	// created by the caller via a `CreateExec`.
	Pids(ctx context.Context) ([]options.ProcessDetails, error)
	// Waits for the the init task to complete.
	//
	// Note: If the `request.ExecID == ""` the caller should instead call `Wait`
	// rather than `exec.Wait` on the init exec. This is because  the lifetime
	// of the task is larger than just the init process and on shutdown we need
	// to wait for the container and potentially UVM before unblocking any event
	// based listeners or `Wait` based listeners.
	Wait() *task.StateResponse
	// ExecInHost execs a process in the host UVM. It is not tracked in the
	// other lifetimes of the task and is used only for diagnostics.
	//
	// If the host is not hypervisor isolated returns error.
	ExecInHost(ctx context.Context, req *shimdiag.ExecProcessRequest) (int, error)
	// DumpGuestStacks dumps the GCS stacks associated with this task host.
	//
	// If the host is not hypervisor isolated returns `""`.
	DumpGuestStacks(ctx context.Context) string
	// Share shares a directory/file into the host UVM.
	//
	// If the host is not hypervisor isolated returns error.
	Share(ctx context.Context, req *shimdiag.ShareRequest) error
	// Stats returns various metrics for the task.
	//
	// If the host is hypervisor isolated and this task owns the host additional
	// metrics on the UVM may be returned as well.
	Stats(ctx context.Context) (*stats.Statistics, error)
}

// isStatsNotFound returns true if the err corresponds to a scenario
// where statistics cannot be retrieved or found
func isStatsNotFound(err error) bool {
	return errdefs.IsNotFound(err) ||
		hcs.IsNotExist(err) ||
		hcs.IsOperationInvalidState(err) ||
		gcs.IsNotExist(err) ||
		hcs.IsAccessIsDenied(err)
}
<|endoftext|>


<commit_before>package snapshot

import (
	gocontext "context"
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/containerd/containerd/cmd/ctr/commands"
	"github.com/containerd/containerd/log"
	"github.com/containerd/containerd/mount"
	"github.com/containerd/containerd/progress"
	"github.com/containerd/containerd/snapshot"
	digest "github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
)

// Command is the cli command for managing snapshots
var Command = cli.Command{
	Name:  "snapshot",
	Usage: "manage snapshots",
	Flags: commands.SnapshotterFlags,
	Subcommands: cli.Commands{
		commitCommand,
		infoCommand,
		listCommand,
		mountCommand,
		prepareCommand,
		removeCommand,
		setLabelCommand,
		treeCommand,
		unpackCommand,
		usageCommand,
		viewCommand,
	},
}

var listCommand = cli.Command{
	Name:    "list",
	Aliases: []string{"ls"},
	Usage:   "list snapshots",
	Action: func(context *cli.Context) error {
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		var (
			snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
			tw          = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
		)
		fmt.Fprintln(tw, "KEY\tPARENT\tKIND\t")
		if err := snapshotter.Walk(ctx, func(ctx gocontext.Context, info snapshot.Info) error {
			fmt.Fprintf(tw, "%v\t%v\t%v\t\n",
				info.Name,
				info.Parent,
				info.Kind)
			return nil
		}); err != nil {
			return err
		}

		return tw.Flush()
	},
}

var usageCommand = cli.Command{
	Name:      "usage",
	Usage:     "usage snapshots",
	ArgsUsage: "[flags] [<key>, ...]",
	Flags: []cli.Flag{
		cli.BoolFlag{
			Name:  "b",
			Usage: "display size in bytes",
		},
	},
	Action: func(context *cli.Context) error {
		var displaySize func(int64) string
		if context.Bool("b") {
			displaySize = func(s int64) string {
				return fmt.Sprintf("%d", s)
			}
		} else {
			displaySize = func(s int64) string {
				return progress.Bytes(s).String()
			}
		}
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		var (
			snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
			tw          = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
		)
		fmt.Fprintln(tw, "KEY\tSIZE\tINODES\t")
		if context.NArg() == 0 {
			if err := snapshotter.Walk(ctx, func(ctx gocontext.Context, info snapshot.Info) error {
				usage, err := snapshotter.Usage(ctx, info.Name)
				if err != nil {
					return err
				}
				fmt.Fprintf(tw, "%v\t%s\t%d\t\n", info.Name, displaySize(usage.Size), usage.Inodes)
				return nil
			}); err != nil {
				return err
			}
		} else {
			for _, id := range context.Args() {
				usage, err := snapshotter.Usage(ctx, id)
				if err != nil {
					return err
				}
				fmt.Fprintf(tw, "%v\t%s\t%d\t\n", id, displaySize(usage.Size), usage.Inodes)
			}
		}

		return tw.Flush()
	},
}

var removeCommand = cli.Command{
	Name:      "remove",
	Aliases:   []string{"rm"},
	ArgsUsage: "<key> [<key>, ...]",
	Usage:     "remove snapshots",
	Action: func(context *cli.Context) error {
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		for _, key := range context.Args() {
			err = snapshotter.Remove(ctx, key)
			if err != nil {
				return errors.Wrapf(err, "failed to remove %q", key)
			}
		}

		return nil
	},
}

var prepareCommand = cli.Command{
	Name:      "prepare",
	Usage:     "prepare a snapshot from a committed snapshot",
	ArgsUsage: "[flags] <key> [<parent>]",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "target, t",
			Usage: "mount target path, will print mount, if provided",
		},
	},
	Action: func(context *cli.Context) error {
		if context.NArg() != 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			target = context.String("target")
			key    = context.Args().Get(0)
			parent = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()

		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		mounts, err := snapshotter.Prepare(ctx, key, parent)
		if err != nil {
			return err
		}

		if target != "" {
			printMounts(target, mounts)
		}

		return nil
	},
}

var viewCommand = cli.Command{
	Name:      "view",
	Usage:     "create a read-only snapshot from a committed snapshot",
	ArgsUsage: "[flags] <key> [<parent>]",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "target, t",
			Usage: "mount target path, will print mount, if provided",
		},
	},
	Action: func(context *cli.Context) error {
		if context.NArg() != 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			target = context.String("target")
			key    = context.Args().Get(0)
			parent = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()

		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		mounts, err := snapshotter.View(ctx, key, parent)
		if err != nil {
			return err
		}

		if target != "" {
			printMounts(target, mounts)
		}

		return nil
	},
}

var mountCommand = cli.Command{
	Name:      "mounts",
	Aliases:   []string{"m", "mount"},
	Usage:     "mount gets mount commands for the snapshots",
	ArgsUsage: "<target> <key>",
	Action: func(context *cli.Context) error {
		if context.NArg() != 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			target = context.Args().Get(0)
			key    = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		mounts, err := snapshotter.Mounts(ctx, key)
		if err != nil {
			return err
		}

		printMounts(target, mounts)

		return nil
	},
}

var commitCommand = cli.Command{
	Name:      "commit",
	Usage:     "commit an active snapshot into the provided name",
	ArgsUsage: "<key> <active>",
	Action: func(context *cli.Context) error {
		if context.NArg() != 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			key    = context.Args().Get(0)
			active = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		return snapshotter.Commit(ctx, key, active)
	},
}

var treeCommand = cli.Command{
	Name:  "tree",
	Usage: "display tree view of snapshot branches",
	Action: func(context *cli.Context) error {
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		var (
			snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
			tree        = make(map[string]*snapshotTreeNode)
		)

		if err := snapshotter.Walk(ctx, func(ctx gocontext.Context, info snapshot.Info) error {
			// Get or create node and add node details
			node := getOrCreateTreeNode(info.Name, tree)
			if info.Parent != "" {
				node.Parent = info.Parent
				p := getOrCreateTreeNode(info.Parent, tree)
				p.Children = append(p.Children, info.Name)
			}

			return nil
		}); err != nil {
			return err
		}

		printTree(tree)

		return nil
	},
}

var infoCommand = cli.Command{
	Name:      "info",
	Usage:     "get info about a snapshot",
	ArgsUsage: "<key>",
	Action: func(context *cli.Context) error {
		if context.NArg() != 1 {
			return cli.ShowSubcommandHelp(context)
		}

		key := context.Args().Get(0)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		info, err := snapshotter.Stat(ctx, key)
		if err != nil {
			return err
		}

		commands.PrintAsJSON(info)

		return nil
	},
}

var setLabelCommand = cli.Command{
	Name:        "label",
	Usage:       "add labels to content",
	ArgsUsage:   "<name> [<label>=<value> ...]",
	Description: "labels snapshots in the snapshotter",
	Action: func(context *cli.Context) error {
		key, labels := commands.ObjectWithLabelArgs(context)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()

		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))

		info := snapshot.Info{
			Name:   key,
			Labels: map[string]string{},
		}

		var paths []string
		for k, v := range labels {
			paths = append(paths, fmt.Sprintf("labels.%s", k))
			if v != "" {
				info.Labels[k] = v
			}
		}

		// Nothing updated, do no clear
		if len(paths) == 0 {
			info, err = snapshotter.Stat(ctx, info.Name)
		} else {
			info, err = snapshotter.Update(ctx, info, paths...)
		}
		if err != nil {
			return err
		}

		var labelStrings []string
		for k, v := range info.Labels {
			labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v))
		}

		fmt.Println(strings.Join(labelStrings, ","))

		return nil
	},
}

var unpackCommand = cli.Command{
	Name:      "unpack",
	Usage:     "unpack applies layers from a manifest to a snapshot",
	ArgsUsage: "[flags] <digest>",
	Flags:     commands.SnapshotterFlags,
	Action: func(context *cli.Context) error {
		dgst, err := digest.Parse(context.Args().First())
		if err != nil {
			return err
		}
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		log.G(ctx).Debugf("unpacking layers from manifest %s", dgst.String())
		// TODO: Support unpack by name
		images, err := client.ListImages(ctx)
		if err != nil {
			return err
		}
		var unpacked bool
		for _, image := range images {
			if image.Target().Digest == dgst {
				fmt.Printf("unpacking %s (%s)...", dgst, image.Target().MediaType)
				if err := image.Unpack(ctx, context.String("snapshotter")); err != nil {
					fmt.Println()
					return err
				}
				fmt.Println("done")
				unpacked = true
				break
			}
		}
		if !unpacked {
			return errors.New("manifest not found")
		}
		// TODO: Get rootfs from Image
		//log.G(ctx).Infof("chain ID: %s", chainID.String())
		return nil
	},
}

type snapshotTreeNode struct {
	Name     string
	Parent   string
	Children []string
}

func getOrCreateTreeNode(name string, tree map[string]*snapshotTreeNode) *snapshotTreeNode {
	if node, ok := tree[name]; ok {
		return node
	}
	node := &snapshotTreeNode{
		Name: name,
	}
	tree[name] = node
	return node
}

func printTree(tree map[string]*snapshotTreeNode) {
	for _, node := range tree {
		// Print for root(parent-less) nodes only
		if node.Parent == "" {
			printNode(node.Name, tree, 0)
		}
	}
}

func printNode(name string, tree map[string]*snapshotTreeNode, level int) {
	node := tree[name]
	fmt.Printf("%s\\_ %s\n", strings.Repeat("  ", level), node.Name)
	level++
	for _, child := range node.Children {
		printNode(child, tree, level)
	}
}

func printMounts(target string, mounts []mount.Mount) {
	// FIXME: This is specific to Unix
	for _, m := range mounts {
		fmt.Printf("mount -t %s %s %s -o %s\n", m.Type, m.Source, target, strings.Join(m.Options, ","))
	}
}
<commit_msg>ctr: fix args<commit_after>package snapshot

import (
	gocontext "context"
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/containerd/containerd/cmd/ctr/commands"
	"github.com/containerd/containerd/log"
	"github.com/containerd/containerd/mount"
	"github.com/containerd/containerd/progress"
	"github.com/containerd/containerd/snapshot"
	digest "github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
)

// Command is the cli command for managing snapshots
var Command = cli.Command{
	Name:  "snapshot",
	Usage: "manage snapshots",
	Flags: commands.SnapshotterFlags,
	Subcommands: cli.Commands{
		commitCommand,
		infoCommand,
		listCommand,
		mountCommand,
		prepareCommand,
		removeCommand,
		setLabelCommand,
		treeCommand,
		unpackCommand,
		usageCommand,
		viewCommand,
	},
}

var listCommand = cli.Command{
	Name:    "list",
	Aliases: []string{"ls"},
	Usage:   "list snapshots",
	Action: func(context *cli.Context) error {
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		var (
			snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
			tw          = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
		)
		fmt.Fprintln(tw, "KEY\tPARENT\tKIND\t")
		if err := snapshotter.Walk(ctx, func(ctx gocontext.Context, info snapshot.Info) error {
			fmt.Fprintf(tw, "%v\t%v\t%v\t\n",
				info.Name,
				info.Parent,
				info.Kind)
			return nil
		}); err != nil {
			return err
		}

		return tw.Flush()
	},
}

var usageCommand = cli.Command{
	Name:      "usage",
	Usage:     "usage snapshots",
	ArgsUsage: "[flags] [<key>, ...]",
	Flags: []cli.Flag{
		cli.BoolFlag{
			Name:  "b",
			Usage: "display size in bytes",
		},
	},
	Action: func(context *cli.Context) error {
		var displaySize func(int64) string
		if context.Bool("b") {
			displaySize = func(s int64) string {
				return fmt.Sprintf("%d", s)
			}
		} else {
			displaySize = func(s int64) string {
				return progress.Bytes(s).String()
			}
		}
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		var (
			snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
			tw          = tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
		)
		fmt.Fprintln(tw, "KEY\tSIZE\tINODES\t")
		if context.NArg() == 0 {
			if err := snapshotter.Walk(ctx, func(ctx gocontext.Context, info snapshot.Info) error {
				usage, err := snapshotter.Usage(ctx, info.Name)
				if err != nil {
					return err
				}
				fmt.Fprintf(tw, "%v\t%s\t%d\t\n", info.Name, displaySize(usage.Size), usage.Inodes)
				return nil
			}); err != nil {
				return err
			}
		} else {
			for _, id := range context.Args() {
				usage, err := snapshotter.Usage(ctx, id)
				if err != nil {
					return err
				}
				fmt.Fprintf(tw, "%v\t%s\t%d\t\n", id, displaySize(usage.Size), usage.Inodes)
			}
		}

		return tw.Flush()
	},
}

var removeCommand = cli.Command{
	Name:      "remove",
	Aliases:   []string{"rm"},
	ArgsUsage: "<key> [<key>, ...]",
	Usage:     "remove snapshots",
	Action: func(context *cli.Context) error {
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		for _, key := range context.Args() {
			err = snapshotter.Remove(ctx, key)
			if err != nil {
				return errors.Wrapf(err, "failed to remove %q", key)
			}
		}

		return nil
	},
}

var prepareCommand = cli.Command{
	Name:      "prepare",
	Usage:     "prepare a snapshot from a committed snapshot",
	ArgsUsage: "[flags] <key> [<parent>]",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "target, t",
			Usage: "mount target path, will print mount, if provided",
		},
	},
	Action: func(context *cli.Context) error {
		if narg := context.NArg(); narg < 1 || narg > 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			target = context.String("target")
			key    = context.Args().Get(0)
			parent = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()

		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		mounts, err := snapshotter.Prepare(ctx, key, parent)
		if err != nil {
			return err
		}

		if target != "" {
			printMounts(target, mounts)
		}

		return nil
	},
}

var viewCommand = cli.Command{
	Name:      "view",
	Usage:     "create a read-only snapshot from a committed snapshot",
	ArgsUsage: "[flags] <key> [<parent>]",
	Flags: []cli.Flag{
		cli.StringFlag{
			Name:  "target, t",
			Usage: "mount target path, will print mount, if provided",
		},
	},
	Action: func(context *cli.Context) error {
		if narg := context.NArg(); narg < 1 || narg > 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			target = context.String("target")
			key    = context.Args().Get(0)
			parent = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()

		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		mounts, err := snapshotter.View(ctx, key, parent)
		if err != nil {
			return err
		}

		if target != "" {
			printMounts(target, mounts)
		}

		return nil
	},
}

var mountCommand = cli.Command{
	Name:      "mounts",
	Aliases:   []string{"m", "mount"},
	Usage:     "mount gets mount commands for the snapshots",
	ArgsUsage: "<target> <key>",
	Action: func(context *cli.Context) error {
		if context.NArg() != 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			target = context.Args().Get(0)
			key    = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		mounts, err := snapshotter.Mounts(ctx, key)
		if err != nil {
			return err
		}

		printMounts(target, mounts)

		return nil
	},
}

var commitCommand = cli.Command{
	Name:      "commit",
	Usage:     "commit an active snapshot into the provided name",
	ArgsUsage: "<key> <active>",
	Action: func(context *cli.Context) error {
		if context.NArg() != 2 {
			return cli.ShowSubcommandHelp(context)
		}
		var (
			key    = context.Args().Get(0)
			active = context.Args().Get(1)
		)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		return snapshotter.Commit(ctx, key, active)
	},
}

var treeCommand = cli.Command{
	Name:  "tree",
	Usage: "display tree view of snapshot branches",
	Action: func(context *cli.Context) error {
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		var (
			snapshotter = client.SnapshotService(context.GlobalString("snapshotter"))
			tree        = make(map[string]*snapshotTreeNode)
		)

		if err := snapshotter.Walk(ctx, func(ctx gocontext.Context, info snapshot.Info) error {
			// Get or create node and add node details
			node := getOrCreateTreeNode(info.Name, tree)
			if info.Parent != "" {
				node.Parent = info.Parent
				p := getOrCreateTreeNode(info.Parent, tree)
				p.Children = append(p.Children, info.Name)
			}

			return nil
		}); err != nil {
			return err
		}

		printTree(tree)

		return nil
	},
}

var infoCommand = cli.Command{
	Name:      "info",
	Usage:     "get info about a snapshot",
	ArgsUsage: "<key>",
	Action: func(context *cli.Context) error {
		if context.NArg() != 1 {
			return cli.ShowSubcommandHelp(context)
		}

		key := context.Args().Get(0)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))
		info, err := snapshotter.Stat(ctx, key)
		if err != nil {
			return err
		}

		commands.PrintAsJSON(info)

		return nil
	},
}

var setLabelCommand = cli.Command{
	Name:        "label",
	Usage:       "add labels to content",
	ArgsUsage:   "<name> [<label>=<value> ...]",
	Description: "labels snapshots in the snapshotter",
	Action: func(context *cli.Context) error {
		key, labels := commands.ObjectWithLabelArgs(context)
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()

		snapshotter := client.SnapshotService(context.GlobalString("snapshotter"))

		info := snapshot.Info{
			Name:   key,
			Labels: map[string]string{},
		}

		var paths []string
		for k, v := range labels {
			paths = append(paths, fmt.Sprintf("labels.%s", k))
			if v != "" {
				info.Labels[k] = v
			}
		}

		// Nothing updated, do no clear
		if len(paths) == 0 {
			info, err = snapshotter.Stat(ctx, info.Name)
		} else {
			info, err = snapshotter.Update(ctx, info, paths...)
		}
		if err != nil {
			return err
		}

		var labelStrings []string
		for k, v := range info.Labels {
			labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v))
		}

		fmt.Println(strings.Join(labelStrings, ","))

		return nil
	},
}

var unpackCommand = cli.Command{
	Name:      "unpack",
	Usage:     "unpack applies layers from a manifest to a snapshot",
	ArgsUsage: "[flags] <digest>",
	Flags:     commands.SnapshotterFlags,
	Action: func(context *cli.Context) error {
		dgst, err := digest.Parse(context.Args().First())
		if err != nil {
			return err
		}
		client, ctx, cancel, err := commands.NewClient(context)
		if err != nil {
			return err
		}
		defer cancel()
		log.G(ctx).Debugf("unpacking layers from manifest %s", dgst.String())
		// TODO: Support unpack by name
		images, err := client.ListImages(ctx)
		if err != nil {
			return err
		}
		var unpacked bool
		for _, image := range images {
			if image.Target().Digest == dgst {
				fmt.Printf("unpacking %s (%s)...", dgst, image.Target().MediaType)
				if err := image.Unpack(ctx, context.String("snapshotter")); err != nil {
					fmt.Println()
					return err
				}
				fmt.Println("done")
				unpacked = true
				break
			}
		}
		if !unpacked {
			return errors.New("manifest not found")
		}
		// TODO: Get rootfs from Image
		//log.G(ctx).Infof("chain ID: %s", chainID.String())
		return nil
	},
}

type snapshotTreeNode struct {
	Name     string
	Parent   string
	Children []string
}

func getOrCreateTreeNode(name string, tree map[string]*snapshotTreeNode) *snapshotTreeNode {
	if node, ok := tree[name]; ok {
		return node
	}
	node := &snapshotTreeNode{
		Name: name,
	}
	tree[name] = node
	return node
}

func printTree(tree map[string]*snapshotTreeNode) {
	for _, node := range tree {
		// Print for root(parent-less) nodes only
		if node.Parent == "" {
			printNode(node.Name, tree, 0)
		}
	}
}

func printNode(name string, tree map[string]*snapshotTreeNode, level int) {
	node := tree[name]
	fmt.Printf("%s\\_ %s\n", strings.Repeat("  ", level), node.Name)
	level++
	for _, child := range node.Children {
		printNode(child, tree, level)
	}
}

func printMounts(target string, mounts []mount.Mount) {
	// FIXME: This is specific to Unix
	for _, m := range mounts {
		fmt.Printf("mount -t %s %s %s -o %s\n", m.Type, m.Source, target, strings.Join(m.Options, ","))
	}
}
<|endoftext|>


<commit_before>package db

import (
	"bytes"
	"encoding/gob"
	"path"
	"sort"
	"strconv"
	"strings"
	"sync"
	"unsafe"
)

const (
	ManifestPrefix = "manifest_"
)

// In-memory representation of each nsst file.
// File may be deleted if refcnt reaches 0 (i.e. no iterator
// refers to it, and there is no explicit snapshot request
// that needs it)
type FileInfo struct {
	Location string
	BeginKey []byte
	EndKey   []byte
	Refcnt   int
}

// Each time a new file is created or an old file is deleted,
// the system creates a new snapshot. Old snapshot will be
// deleted if its refcnt becomes 0 (i.e. no iterator refers
// to it, and there is no explicit snapshot request for it)
type FileSnapshotInfo struct {
	Levels [][]int64
	Refcnt int
}

// In memory representation of a manifest file. Each manifest
// file consist of an initial snapshot and logs of subsequent
// modifying request. On startup, old manifest file is read,
// logs in the file are replayed, and the resulting Manifest
// data structure is serialized to a new file as the base
// for next manifest file.
type ManifestData struct {
	FileMap          map[int64]FileInfo
	NextId           uint64
	FileSnapshotMap  map[int64]FileSnapshotInfo
	NextFileSnapshot int64
}

type Manifest struct {
	ManifestData
	env   Env
	rwMux sync.RWMutex
}

// Parse base file name, return its manifest number. If the base
// name does not fit into manifest file pattern, return -1 instead
func ParseManifestName(fname string) int64 {
	numPart := strings.TrimPrefix(fname, ManifestPrefix)
	if len(numPart) == len(fname) {
		return -1
	}

	numVal, err := strconv.ParseInt(numPart, 10, 64)
	if err != nil {
		return -1
	} else {
		return numVal
	}
}

// Helper type to sort slice of int64
type int64Sortee []int64

func (x int64Sortee) Len() int           { return len(x) }
func (x int64Sortee) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
func (x int64Sortee) Less(i, j int) bool { return x[i] < x[j] }

// Return all manifest files in given directory @path. Then return
// full pathes of those files in ascending time order.
func ListAllManifestFiles(e Env, parent string) []string {
	lists, status := e.GetChildren(parent)
	if !status.Ok() {
		return []string{}
	}

	fileMap := make(map[int64]string)
	numList := make([]int64, 0, len(lists))

	for _, name := range lists {
		numVal := ParseManifestName(name)
		if numVal >= 0 {
			fileMap[numVal] = name
			numList = append(numList, numVal)
		}
	}

	sort.Sort(int64Sortee(numList))

	ret := make([]string, 0, len(numList))
	for _, num := range numList {
		val, ok := fileMap[num]
		if ok == true {
			ret = append(ret, path.Join(parent, val))
		}
	}

	return ret
}

func recoverSingleManifest(e Env, fullPath string) *Manifest {
	// first try to open the file
	ret := Manifest{env: e}
	file, status := e.NewSequentialFile(fullPath)
	if !status.Ok() {
		return nil
	}

	// read snapshot size from the file
	sizeBuf := make([]byte, 4)
	var dataReads []byte
	dataReads, status = file.Read(sizeBuf)
	if !status.Ok() {
		return nil
	}

	// read snapshot into buffer
	snapshotSize := *(*int32)(unsafe.Pointer(&dataReads[0]))
	dataSnapshot := make([]byte, snapshotSize)

	// use gob to decode it
	buffer := bytes.NewBuffer(dataSnapshot)
	dec := gob.NewDecoder(buffer)
	err := dec.Decode(&ret)
	if err != nil {
		return nil
	}

	return &ret
}

func initNewManifest(e Env, parent string) *Manifest {
	ret := Manifest{
		ManifestData: ManifestData{
			FileMap:         make(map[int64]FileInfo),
			FileSnapshotMap: make(map[int64]FileSnapshotInfo),
		},
		env: e,
	}

	return &ret
}

func RecoverManifest(e Env, parent string, createIfMissing bool) *Manifest {
	paths := ListAllManifestFiles(e, parent)
	var ret *Manifest
	for i := len(paths) - 1; i >= 0; i-- {
		fullPath := paths[i]
		if ret == nil {
			tmp := recoverSingleManifest(e, fullPath)
			if tmp != nil {
				ret = tmp
				continue
			}
		}

		// remove corrupted or old manifest files
		e.DeleteFile(fullPath)
	}

	if ret == nil && createIfMissing {
		ret = initNewManifest(e, parent)
	}

	return ret
}
<commit_msg>More manifest implementation<commit_after>package db

import (
	"bytes"
	"encoding/gob"
	"path"
	"sort"
	"strconv"
	"strings"
	"sync"
	"unsafe"
)

const (
	ManifestPrefix = "manifest_"
)

// A list of requests
const (
	ManifestCreateFile byte = iota
	ManifestNewSnapshot
)

// In-memory representation of each nsst file.
// File may be deleted if refcnt reaches 0 (i.e. no iterator
// refers to it, and there is no explicit snapshot request
// that needs it)
type FileInfo struct {
	Location string
	BeginKey []byte
	EndKey   []byte
	Refcnt   int
}

// Each time a new file is created or an old file is deleted,
// the system creates a new snapshot. Old snapshot will be
// deleted if its refcnt becomes 0 (i.e. no iterator refers
// to it, and there is no explicit snapshot request for it)
type FileSnapshotInfo struct {
	Levels [][]int64
	Refcnt int
}

// In memory representation of a manifest file. Each manifest
// file consist of an initial snapshot and logs of subsequent
// modifying request. On startup, old manifest file is read,
// logs in the file are replayed, and the resulting Manifest
// data structure is serialized to a new file as the base
// for next manifest file.
type ManifestData struct {
	FileMap          map[int64]FileInfo
	NextId           int64
	FileSnapshotMap  map[int64]FileSnapshotInfo
	NextFileSnapshot int64
}

type Manifest struct {
	ManifestData
	env    Env
	rwMux  sync.RWMutex
	writer *LogWriter
}

// Parse base file name, return its manifest number. If the base
// name does not fit into manifest file pattern, return -1 instead
func ParseManifestName(fname string) int64 {
	numPart := strings.TrimPrefix(fname, ManifestPrefix)
	if len(numPart) == len(fname) {
		return -1
	}

	numVal, err := strconv.ParseInt(numPart, 10, 64)
	if err != nil {
		return -1
	} else {
		return numVal
	}
}

// Helper type to sort slice of int64
type int64Sortee []int64

func (x int64Sortee) Len() int           { return len(x) }
func (x int64Sortee) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
func (x int64Sortee) Less(i, j int) bool { return x[i] < x[j] }

// Return all manifest files in given directory @path. Then return
// full pathes of those files in ascending time order.
func ListAllManifestFiles(e Env, parent string) []string {
	lists, status := e.GetChildren(parent)
	if !status.Ok() {
		return []string{}
	}

	fileMap := make(map[int64]string)
	numList := make([]int64, 0, len(lists))

	for _, name := range lists {
		numVal := ParseManifestName(name)
		if numVal >= 0 {
			fileMap[numVal] = name
			numList = append(numList, numVal)
		}
	}

	sort.Sort(int64Sortee(numList))

	ret := make([]string, 0, len(numList))
	for _, num := range numList {
		val, ok := fileMap[num]
		if ok == true {
			ret = append(ret, path.Join(parent, val))
		}
	}

	return ret
}

func recoverSingleManifest(e Env, fullPath string) *Manifest {
	// first try to open the file
	ret := Manifest{env: e}
	file, status := e.NewSequentialFile(fullPath)
	if !status.Ok() {
		return nil
	}

	// read snapshot size from the file
	sizeBuf := make([]byte, 4)
	var dataReads []byte
	dataReads, status = file.Read(sizeBuf)
	if !status.Ok() {
		return nil
	}

	// read snapshot into buffer
	snapshotSize := *(*int32)(unsafe.Pointer(&dataReads[0]))
	dataSnapshot := make([]byte, snapshotSize)

	// use gob to decode it
	buffer := bytes.NewBuffer(dataSnapshot)
	dec := gob.NewDecoder(buffer)
	err := dec.Decode(&ret)
	if err != nil {
		return nil
	}

	return &ret
}

func initNewManifest(e Env, parent string) *Manifest {
	ret := Manifest{
		ManifestData: ManifestData{
			FileMap:         make(map[int64]FileInfo),
			FileSnapshotMap: make(map[int64]FileSnapshotInfo),
		},
		env: e,
	}

	return &ret
}

func RecoverManifest(e Env, parent string, createIfMissing bool) *Manifest {
	paths := ListAllManifestFiles(e, parent)
	var ret *Manifest
	for i := len(paths) - 1; i >= 0; i-- {
		fullPath := paths[i]
		if ret == nil {
			tmp := recoverSingleManifest(e, fullPath)
			if tmp != nil {
				ret = tmp
				continue
			}
		}

		// remove corrupted or old manifest files
		e.DeleteFile(fullPath)
	}

	if ret == nil && createIfMissing {
		ret = initNewManifest(e, parent)
	}

	return ret
}

// create a new nsst file, return the file number.
func (m *Manifest) CreateFile(replay bool) int64 {
	m.rwMux.Lock()
	defer m.rwMux.Unlock()

	ret := m.NextId
	m.NextId++

	// If this is not replay, write a log record.
	if !replay {
		var buf bytes.Buffer
		enc := gob.NewEncoder(&buf)
		enc.Encode(ManifestCreateFile)
		m.writer.AddRecord(buf.Bytes())
	}

	return ret
}

type NewSnapshotRequest struct {
	Levels [][]int64
	Files  map[int64]FileInfo
}

// Create a most recent snapshot. Return snapshot Id back. This is usually called
// after a merge (compaction)
func (m *Manifest) NewSnapshot(req *NewSnapshotRequest, replay bool) int64 {
	m.rwMux.Lock()
	defer m.rwMux.Unlock()

	ret := m.NextFileSnapshot
	m.NextFileSnapshot++

	m.FileSnapshotMap[ret] = FileSnapshotInfo{Levels: req.Levels}

	// Add new files
	for id, info := range req.Files {
		_, ok := m.FileMap[id]
		if !ok {
			m.FileMap[id] = info
		}
	}

	if !replay {
		var buf bytes.Buffer
		enc := gob.NewEncoder(&buf)
		enc.Encode(ManifestNewSnapshot)
		enc.Encode(req)
		m.writer.AddRecord(buf.Bytes())
	}

	return ret
}
<|endoftext|>


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

package safe

import (
	"sync"
	"testing"
)

func TestNewLinkedList(t *testing.T) {
	linked := NewLinkedList()
	if linked.Len() != 0 {
		t.Errorf("NewLinkedList(): Want 0. Got %d.", linked.Len())
	}
}

func TestLinkedListInsert(t *testing.T) {
	values := []int{10, 15, 18}
	linked := NewLinkedList()
	for _, v := range values {
		linked.Insert(v)
	}
	n := linked.Head
	if n == nil {
		t.Fatal("Got unexpected <nil> on LinkedList.Head")
	}
	for i := len(values) - 1; n != nil; i-- {
		if n.Value != values[i] {
			t.Errorf("LinkedList.Insert(). Want %d. Got %d.", values[i], n.Value)
		}
		n = n.Next
	}
	if linked.Len() != 3 {
		t.Errorf("LinkedList.Len(): Want 3. Got %d.", linked.Len())
	}
}

func TestLinkedListRemove(t *testing.T) {
	values := []int{10, 15, 18}
	linked := NewLinkedList()
	for _, v := range values {
		linked.Insert(v)
	}
	for i := len(values) - 1; i >= 0; i-- {
		v, err := linked.Remove()
		if err != nil {
			t.Fatal(err)
		}
		if v != values[i] {
			t.Errorf("LinkedList.Remove(). Want %d. Got %d.", values[i], v)
		}
		if linked.Len() != i {
			t.Errorf("LinkedList.Len(): Want %d. Got %d.", i, linked.Len())
		}
	}
}

func TestLinkedListRemoveEmpty(t *testing.T) {
	l := NewLinkedList()
	_, err := l.Remove()
	if err == nil {
		t.Error("Want non-nil error, got <nil>.")
	}
}

// Cannot fail with -race.
func TestIsSafe(t *testing.T) {
	linked := NewLinkedList()
	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(i int) {
			linked.Insert(i)
			wg.Done()
		}(i)
	}
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			linked.Remove()
			wg.Done()
		}()
	}
	wg.Wait()
}

<commit_msg>concurrency/safe: added benchmarks for LinkedList<commit_after>// Copyright 2013 Francisco Souza. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package safe

import (
	"sync"
	"testing"
)

func TestNewLinkedList(t *testing.T) {
	linked := NewLinkedList()
	if linked.Len() != 0 {
		t.Errorf("NewLinkedList(): Want 0. Got %d.", linked.Len())
	}
}

func TestLinkedListInsert(t *testing.T) {
	values := []int{10, 15, 18}
	linked := NewLinkedList()
	for _, v := range values {
		linked.Insert(v)
	}
	n := linked.Head
	if n == nil {
		t.Fatal("Got unexpected <nil> on LinkedList.Head")
	}
	for i := len(values) - 1; n != nil; i-- {
		if n.Value != values[i] {
			t.Errorf("LinkedList.Insert(). Want %d. Got %d.", values[i], n.Value)
		}
		n = n.Next
	}
	if linked.Len() != 3 {
		t.Errorf("LinkedList.Len(): Want 3. Got %d.", linked.Len())
	}
}

func TestLinkedListRemove(t *testing.T) {
	values := []int{10, 15, 18}
	linked := NewLinkedList()
	for _, v := range values {
		linked.Insert(v)
	}
	for i := len(values) - 1; i >= 0; i-- {
		v, err := linked.Remove()
		if err != nil {
			t.Fatal(err)
		}
		if v != values[i] {
			t.Errorf("LinkedList.Remove(). Want %d. Got %d.", values[i], v)
		}
		if linked.Len() != i {
			t.Errorf("LinkedList.Len(): Want %d. Got %d.", i, linked.Len())
		}
	}
}

func TestLinkedListRemoveEmpty(t *testing.T) {
	l := NewLinkedList()
	_, err := l.Remove()
	if err == nil {
		t.Error("Want non-nil error, got <nil>.")
	}
}

// Cannot fail with -race.
func TestIsSafe(t *testing.T) {
	linked := NewLinkedList()
	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(i int) {
			linked.Insert(i)
			wg.Done()
		}(i)
	}
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			linked.Remove()
			wg.Done()
		}()
	}
	wg.Wait()
}

func BenchmarkInsert(b *testing.B) {
	linked := NewLinkedList()
	for i := 0; i < b.N; i++ {
		linked.Insert(i*100)
	}
}

func BenchmarkRemove(b *testing.B) {
	b.StopTimer()
	linked := NewLinkedList()
	for i := 0; i < 1e6; i++ {
		linked.Insert(i*100)
	}
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		linked.Remove()
	}
}
<|endoftext|>


<commit_before>package format // import "eriol.xyz/piken/format"
import (
	"strconv"
	"testing"

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

func TestCodePointToGlyph(t *testing.T) {
	glyph, err := CodePointToGlyph("1F602")
	assert.Nil(t, err)
	assert.Equal(t, glyph, "😂")

	glyph, err = CodePointToGlyph("1000000000")
	assert.Equal(t, glyph, "")
	if assert.Error(t, err) {
		assert.Equal(t, err.(*strconv.NumError).Err, strconv.ErrRange)
	}
}
<commit_msg>Add tests for TextFormatter<commit_after>package format // import "eriol.xyz/piken/format"
import (
	"strconv"
	"testing"

	"eriol.xyz/piken/sql"

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

func TestCodePointToGlyph(t *testing.T) {
	glyph, err := CodePointToGlyph("1F602")
	assert.Nil(t, err)
	assert.Equal(t, glyph, "😂")

	glyph, err = CodePointToGlyph("1000000000")
	assert.Equal(t, glyph, "")
	if assert.Error(t, err) {
		assert.Equal(t, err.(*strconv.NumError).Err, strconv.ErrRange)
	}
}

func TestFormat(t *testing.T) {

	s := sql.UnicodeData{CodePoint: "1F602",
		Name: "FACE WITH TEARS OF JOY"}

	formatter := NewTextFormatter(
		[]string{"CodePoint", "Name"}, " -- ", true)
	b, _ := formatter.Format(&s)
	assert.Equal(t, b, "1F602 -- FACE WITH TEARS OF JOY -- 😂")

	formatter = NewTextFormatter(
		[]string{"CodePoint", "Name"}, " ## ", true)
	b, _ = formatter.Format(&s)
	assert.Equal(t, b, "1F602 ## FACE WITH TEARS OF JOY ## 😂")

	formatter = NewTextFormatter(
		[]string{"Name"}, " -- ", true)
	b, _ = formatter.Format(&s)
	assert.Equal(t, b, "FACE WITH TEARS OF JOY -- 😂")

	formatter = NewTextFormatter(
		[]string{"Name"}, " -- ", false)
	b, _ = formatter.Format(&s)
	assert.Equal(t, b, "FACE WITH TEARS OF JOY")

}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type SimpleChaincode struct {
}

func main() {
	fmt.Println("started logging in main()")
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Println("failed in function main()")
	}
}

var projectName string
var projectRate int
var projectPeriod int
var projectGoal int
var projectTimes int
var projectBenifary string
var projectState string
var currentPrice float64
var projectSummary int
var userList []string
var shareList map[string]int
var availableList map[string]int

//Init comment
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("started logging in Init()")

	//started to initialize the projectState
	//step1: check whether args == 5
	if len(args) != 5 {
		return nil, errors.New("failed in args")
	}

	//step 2, intialize the project properties
	projectName = args[0]
	projectRate, _ = strconv.Atoi(args[1])
	if projectRate <= 0 {
		return nil, errors.New("errors in args[1], it cannot be negative")
	}

	projectPeriod, _ = strconv.Atoi(args[2])
	if projectPeriod <= 0 {
		return nil, errors.New("errors in args[2], it cannot be negative")
	}

	projectGoal, _ = strconv.Atoi(args[3])
	if projectGoal <= 0 {
		return nil, errors.New("errors in args[3], it cannot be negative")
	}

	projectTimes = 1
	projectBenifary = args[4]
	projectState = "draft"
	currentPrice = 1.0
	projectSummary = 0

	return nil, nil
} //end of Init()

// Invoke comment
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("started logging in Invoke()")
	switch function {
	case "goPublic":
		fmt.Println("started logging in goPublic")
		if len(args) != 0 {
			return nil, errors.New("failed in args")
		}
		projectState = "public"
		return nil, nil //end of goPublic
	case "pay":
		fmt.Println("started logging in pay()")

		if len(args) != 2 {
			return nil, errors.New("failed in args")
		}
		//step1 : get args
		user := args[0]
		amount, _ := strconv.Atoi(args[1])
		if amount <= 0 {
			return nil, errors.New("errors in args[1],it is negative")
		}

		//step2 : check if the userList[user] exist
		//if exist, then userList[user] += amount
		//if not exists, then userList[user] = amount
		if shareList[user] == 0 {
			fmt.Printf("the user [%v] does not exit \n", user)
			userList = append(userList, user)
			shareList[user] = amount

		} else {
			fmt.Printf("the user [%v] exist", user)
			if !GoalReached() {
				shareList[user] += amount
			}
		}

		// step3: raise amount

		//// TODO: write code for pay
		return nil, nil
	case "checkGoalReached":
		fmt.Println("started logging in checkGoalReached()")
		// TODO: write code for checkGoalReached
		return nil, nil
	case "checkDaoqi":
		fmt.Println("started logging in checkDaoqi()")
		// TODO: write code for checkDaoqi
		return nil, nil
	case "calculatePrice":
		fmt.Println("started logging in calculatePrice")
		return nil, nil
	case "calculateResult":
		fmt.Println("started logging in calculateResult")
		return nil, nil
	default:
		fmt.Println("no function found")
		return nil, errors.New("no function found, recheck your function name")
	}
}

// Query comment
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("started logging in Query()")
	switch function {
	case "getProjectState":
		fmt.Println("started logging in getProjectState()")
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result := projectName + "/"
		result += strconv.Itoa(projectRate) + "/"
		result += strconv.Itoa(projectPeriod) + "/"
		result += strconv.Itoa(projectGoal) + "/"
		result += strconv.Itoa(projectTimes) + "/"
		result += projectBenifary + "/"
		result += projectState + "/"
		result += strconv.FormatFloat(currentPrice, 'E', -1, 64) + "/"
		result += strconv.Itoa(projectSummary) + "/"

		return []byte(result), nil //end of getProjectState
	case "getUserList":
		fmt.Println("started logging in getUserList")
		var result string
		for i, value := range userList {
			result += fmt.Sprintf("userList[%v] is %v ****", strconv.Itoa(i), value)
		}
		return []byte(result), nil
	case "getShareList":
		fmt.Println("started logging in getShareList")
		return nil, nil
	case "getAvailableList":
		fmt.Println("started logging in getAvailableList")
		return nil, nil
	default:
		fmt.Println("no function found")
		return nil, errors.New("no function found, recheck your function name")
	}
}

func GoalReached() bool {
	return false
}
<commit_msg>demo7.go<commit_after>package main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type SimpleChaincode struct {
}

func main() {
	fmt.Println("started logging in main()")
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Println("failed in function main()")
	}
}

var projectName string
var projectRate int
var projectPeriod int
var projectGoal int
var projectTimes int
var projectBenifary string
var projectState string
var currentPrice float64
var projectSummary int
var userList []string
var shareList map[string]int
var availableList map[string]int

//Init comment
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("started logging in Init()")

	//started to initialize the projectState
	//step1: check whether args == 5
	if len(args) != 5 {
		return nil, errors.New("failed in args")
	}

	//step 2, intialize the project properties
	projectName = args[0]
	stub.PutState("projectName", projectName)

	projectRate, _ = strconv.Atoi(args[1])
	if projectRate <= 0 {
		return nil, errors.New("errors in args[1], it cannot be negative")
	}
	stub.PutState("projectRate", projectRate)

	projectPeriod, _ = strconv.Atoi(args[2])
	if projectPeriod <= 0 {
		return nil, errors.New("errors in args[2], it cannot be negative")
	}
	stub.PutState("projectPeriod", projectPeriod)

	projectGoal, _ = strconv.Atoi(args[3])
	if projectGoal <= 0 {
		return nil, errors.New("errors in args[3], it cannot be negative")
	}
	stub.PutState("projectGoal", projectGoal)

	projectTimes = 1
	stub.PutState("projectTimes", projectTimes)

	projectBenifary = args[4]
	stub.PutState("projectBenifary", projectBenifary)

	projectState = "draft"
	stub.PutState("projectState", projectState)

	currentPrice = 1.0
	stub.PutState("currentPrice", currentPrice)

	projectSummary = 0
	stub.PutState("projectSummary", projectSummary)

	return nil, nil
} //end of Init()

// Invoke comment
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("started logging in Invoke()")
	switch function {
	case "goPublic":
		fmt.Println("started logging in goPublic")
		if len(args) != 0 {
			return nil, errors.New("failed in args")
		}
		projectState = "public"
		return nil, nil //end of goPublic
	case "pay":
		fmt.Println("started logging in pay()")

		if len(args) != 2 {
			return nil, errors.New("failed in args")
		}

		//step1 : get args
		user := args[0]
		amount, _ := strconv.Atoi(args[1])
		if amount <= 0 {
			return nil, errors.New("errors in args[1],it is negative")
		}

		//step2 : check if the userList[user] exist
		//if exist, then userList[user] += amount
		//if not exists, then userList[user] = amount
		if shareList[user] == 0 {
			fmt.Printf("the user [%v] does not exit \n", user)
			userList = append(userList, user)
			shareList[user] = amount

		} else {
			fmt.Printf("the user [%v] exist", user)
			if !GoalReached() {
				shareList[user] += amount
			}
		}

		// step3: raise amount

		//// TODO: write code for pay
		return nil, nil
	case "checkGoalReached":
		fmt.Println("started logging in checkGoalReached()")
		// TODO: write code for checkGoalReached
		return nil, nil
	case "checkDaoqi":
		fmt.Println("started logging in checkDaoqi()")
		// TODO: write code for checkDaoqi
		return nil, nil
	case "calculatePrice":
		fmt.Println("started logging in calculatePrice")
		return nil, nil
	case "calculateResult":
		fmt.Println("started logging in calculateResult")
		return nil, nil
	default:
		fmt.Println("no function found")
		return nil, errors.New("no function found, recheck your function name")
	}
}

// Query comment
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("started logging in Query()")
	switch function {
	case "getProjectName":
		result := stub.GetState("projectName")
		return []byte(result), nil
	// case "getProjectState":
	// 	fmt.Println("started logging in getProjectState()")
	// 	if len(args) != 0 {
	// 		return nil, errors.New("incorrect args")
	// 	}
	// 	result := projectName + "/"
	// 	result += strconv.Itoa(projectRate) + "/"
	// 	result += strconv.Itoa(projectPeriod) + "/"
	// 	result += strconv.Itoa(projectGoal) + "/"
	// 	result += strconv.Itoa(projectTimes) + "/"
	// 	result += projectBenifary + "/"
	// 	result += projectState + "/"
	// 	result += strconv.FormatFloat(currentPrice, 'E', -1, 64) + "/"
	// 	result += strconv.Itoa(projectSummary) + "/"
	//
	// 	return []byte(result), nil //end of getProjectState
	case "getUserList":
		fmt.Println("started logging in getUserList")
		var result string
		for i, value := range userList {
			result += fmt.Sprintf("userList[%v] is %v ****", strconv.Itoa(i), value)
		}
		return []byte(result), nil
	case "getShareList":
		fmt.Println("started logging in getShareList")
		return nil, nil
	case "getAvailableList":
		fmt.Println("started logging in getAvailableList")
		return nil, nil
	default:
		fmt.Println("no function found")
		return nil, errors.New("no function found, recheck your function name")
	}
}

func GoalReached() bool {
	return false
}
<|endoftext|>


<commit_before>package core

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

	"github.com/af83/edwig/audit"
	"github.com/af83/edwig/model"
	"github.com/af83/edwig/siri"
)

func Test_SIRICheckStatusServer_CheckStatus(t *testing.T) {
	referentials := NewMemoryReferentials()
	referential := referentials.New("referential")
	referential.Start()
	referential.Stop()
	partner := referential.Partners().New("partner")
	partner.Settings["local_url"] = "http://edwig"
	partner.Settings["generators.response_message_identifier"] = "Edwig:ResponseMessage::%{uuid}:LOC"
	connector := NewSIRICheckStatusServer(partner)
	connector.SIRIPartner().SetUUIDGenerator(model.NewFakeUUIDGenerator())
	connector.SetClock(model.NewFakeClock())

	file, err := os.Open("testdata/checkstatus_request.xml")
	if err != nil {
		t.Fatal(err)
	}
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	if err != nil {
		t.Fatal(err)
	}
	request, err := siri.NewXMLCheckStatusRequestFromContent(content)
	if err != nil {
		t.Fatal(err)
	}

	response, err := connector.CheckStatus(request)

	time := model.DefaultClock().Now()
	if response.Address != "http://edwig" {
		t.Errorf("Wrong Address in response:\n got: %v\n want: http://edwig", response.Address)
	}
	if response.ProducerRef != "Edwig" {
		t.Errorf("Wrong ProducerRef in response:\n got: %v\n want: Edwig", response.ProducerRef)
	}
	if response.RequestMessageRef != "CheckStatus:Test:0" {
		t.Errorf("Wrong RequestMessageRef in response:\n got: %v\n want: CheckStatus:Test:0", response.RequestMessageRef)
	}
	if response.ResponseMessageIdentifier != "Edwig:ResponseMessage::6ba7b814-9dad-11d1-0-00c04fd430c8:LOC" {
		t.Errorf("Wrong ResponseMessageIdentifier in response:\n got: %v\n want: Edwig:Message::6ba7b814-9dad-11d1-0-00c04fd430c8:LOC", response.ResponseMessageIdentifier)
	}
	if !response.Status {
		t.Errorf("Wrong Status in response:\n got: %v\n want: true", response.Status)
	}
	if response.ResponseTimestamp != time {
		t.Errorf("Wrong Address in response:\n got: %v\n want: %v", response.ResponseTimestamp, time)
	}
	if response.ServiceStartedTime != time {
		t.Errorf("Wrong ServiceStartedTime in response:\n got: %v\n want: %v", response.ServiceStartedTime, time)
	}
}

func Test_SIRICheckStatusServerFactory_Validate(t *testing.T) {
	partner := &Partner{
		slug:           "partner",
		Settings:       make(map[string]string),
		ConnectorTypes: []string{"siri-check-status-server"},
		connectors:     make(map[string]Connector),
		manager:        NewPartnerManager(nil),
	}
	apiPartner := partner.Definition()
	apiPartner.Validate()
	if apiPartner.Errors.Empty() {
		t.Errorf("apiPartner should have an error when local_credential isn't set, got: %v", apiPartner.Errors)
	}

	apiPartner.Settings = map[string]string{
		"local_credential": "local_credential",
	}
	apiPartner.Validate()
	if !apiPartner.Errors.Empty() {
		t.Errorf("apiPartner shouldn't have any error when local_credential is set, got: %v", apiPartner.Errors)
	}
}

func Test_SIRICheckStatusServer_LogCheckStatusRequest(t *testing.T) {
	logStashEvent := make(audit.LogStashEvent)

	file, err := os.Open("testdata/checkstatus_request.xml")
	if err != nil {
		t.Fatal(err)
	}
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	if err != nil {
		t.Fatal(err)
	}
	request, err := siri.NewXMLCheckStatusRequestFromContent(content)
	if err != nil {
		t.Fatal(err)
	}

	logXMLCheckStatusRequest(logStashEvent, request)

	if logStashEvent["requestorRef"] != "NINOXE:default" {
		t.Errorf("Wrong requestorRef logged:\n got: %v\n expected: NINOXE:default", logStashEvent["requestorRef"])
	}
	if logStashEvent["messageIdentifier"] != "CheckStatus:Test:0" {
		t.Errorf("Wrong messageIdentifier logged:\n got: %v\n expected: CheckStatus:Test:0", logStashEvent["messageIdentifier"])
	}
	if logStashEvent["requestTimestamp"] != "2016-09-07 09:11:25.174 +0000 UTC" {
		t.Errorf("Wrong requestTimestamp logged:\n got: %v\n expected: 2016-09-22 07:58:34 +0200 CEST", logStashEvent["requestTimestamp"])
	}
}

func Test_SIRICheckStatusServer_LogCheckStatusResponse(t *testing.T) {
	logStashEvent := make(audit.LogStashEvent)
	time := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
	response := &siri.SIRICheckStatusResponse{
		Status:             true,
		ServiceStartedTime: time,
	}
	response.Address = "Address"
	response.ProducerRef = "ProducerRef"
	response.RequestMessageRef = "RequestMessageRef"
	response.ResponseMessageIdentifier = "ResponseMessageIdentifier"
	response.ResponseTimestamp = time

	logSIRICheckStatusResponse(logStashEvent, response)

	if logStashEvent["address"] != "Address" {
		t.Errorf("Wrong Address logged:\n got: %v\n expected: Address", logStashEvent["address"])
	}
	if logStashEvent["producerRef"] != "ProducerRef" {
		t.Errorf("Wrong ProducerRef logged:\n got: %v\n expected: ProducerRef", logStashEvent["producerRef"])
	}
	if logStashEvent["requestMessageRef"] != "RequestMessageRef" {
		t.Errorf("Wrong RequestMessageRef logged:\n got: %v\n expected: RequestMessageRef", logStashEvent["requestMessageRef"])
	}
	if logStashEvent["responseMessageIdentifier"] != "ResponseMessageIdentifier" {
		t.Errorf("Wrong ResponseMessageIdentifier logged:\n got: %v\n expected: ResponseMessageIdentifier", logStashEvent["responseMessageIdentifier"])
	}
	if logStashEvent["status"] != "true" {
		t.Errorf("Wrong Status logged:\n got: %v\n expected: true", logStashEvent["status"])
	}
	if expected := time.String(); logStashEvent["responseTimestamp"] != expected {
		t.Errorf("Wrong ResponseTimestamp logged:\n got: %v\n expected: %v", logStashEvent["responseTimestamp"], expected)
	}
	if expected := time.String(); logStashEvent["serviceStartedTime"] != expected {
		t.Errorf("Wrong ServiceStartedTime logged:\n got: %v\n expected: %v", logStashEvent["serviceStartedTime"], expected)
	}
	xml, err := response.BuildXML()
	if err != nil {
		t.Fatal(err)
	}
	if logStashEvent["responseXML"] != xml {
		t.Errorf("Wrong responseXML logged:\n got: %v\n expected: %v", logStashEvent["responseXML"], xml)
	}
}
<commit_msg>Correctly handle an error in test<commit_after>package core

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

	"github.com/af83/edwig/audit"
	"github.com/af83/edwig/model"
	"github.com/af83/edwig/siri"
)

func Test_SIRICheckStatusServer_CheckStatus(t *testing.T) {
	referentials := NewMemoryReferentials()
	referential := referentials.New("referential")
	referential.Start()
	referential.Stop()
	partner := referential.Partners().New("partner")
	partner.Settings["local_url"] = "http://edwig"
	partner.Settings["generators.response_message_identifier"] = "Edwig:ResponseMessage::%{uuid}:LOC"
	connector := NewSIRICheckStatusServer(partner)
	connector.SIRIPartner().SetUUIDGenerator(model.NewFakeUUIDGenerator())
	connector.SetClock(model.NewFakeClock())

	file, err := os.Open("testdata/checkstatus_request.xml")
	if err != nil {
		t.Fatal(err)
	}
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	if err != nil {
		t.Fatal(err)
	}
	request, err := siri.NewXMLCheckStatusRequestFromContent(content)
	if err != nil {
		t.Fatal(err)
	}

	response, err := connector.CheckStatus(request)
	if err != nil {
		t.Fatal(err)
	}

	time := model.DefaultClock().Now()
	if response.Address != "http://edwig" {
		t.Errorf("Wrong Address in response:\n got: %v\n want: http://edwig", response.Address)
	}
	if response.ProducerRef != "Edwig" {
		t.Errorf("Wrong ProducerRef in response:\n got: %v\n want: Edwig", response.ProducerRef)
	}
	if response.RequestMessageRef != "CheckStatus:Test:0" {
		t.Errorf("Wrong RequestMessageRef in response:\n got: %v\n want: CheckStatus:Test:0", response.RequestMessageRef)
	}
	if response.ResponseMessageIdentifier != "Edwig:ResponseMessage::6ba7b814-9dad-11d1-0-00c04fd430c8:LOC" {
		t.Errorf("Wrong ResponseMessageIdentifier in response:\n got: %v\n want: Edwig:Message::6ba7b814-9dad-11d1-0-00c04fd430c8:LOC", response.ResponseMessageIdentifier)
	}
	if !response.Status {
		t.Errorf("Wrong Status in response:\n got: %v\n want: true", response.Status)
	}
	if response.ResponseTimestamp != time {
		t.Errorf("Wrong Address in response:\n got: %v\n want: %v", response.ResponseTimestamp, time)
	}
	if response.ServiceStartedTime != time {
		t.Errorf("Wrong ServiceStartedTime in response:\n got: %v\n want: %v", response.ServiceStartedTime, time)
	}
}

func Test_SIRICheckStatusServerFactory_Validate(t *testing.T) {
	partner := &Partner{
		slug:           "partner",
		Settings:       make(map[string]string),
		ConnectorTypes: []string{"siri-check-status-server"},
		connectors:     make(map[string]Connector),
		manager:        NewPartnerManager(nil),
	}
	apiPartner := partner.Definition()
	apiPartner.Validate()
	if apiPartner.Errors.Empty() {
		t.Errorf("apiPartner should have an error when local_credential isn't set, got: %v", apiPartner.Errors)
	}

	apiPartner.Settings = map[string]string{
		"local_credential": "local_credential",
	}
	apiPartner.Validate()
	if !apiPartner.Errors.Empty() {
		t.Errorf("apiPartner shouldn't have any error when local_credential is set, got: %v", apiPartner.Errors)
	}
}

func Test_SIRICheckStatusServer_LogCheckStatusRequest(t *testing.T) {
	logStashEvent := make(audit.LogStashEvent)

	file, err := os.Open("testdata/checkstatus_request.xml")
	if err != nil {
		t.Fatal(err)
	}
	defer file.Close()
	content, err := ioutil.ReadAll(file)
	if err != nil {
		t.Fatal(err)
	}
	request, err := siri.NewXMLCheckStatusRequestFromContent(content)
	if err != nil {
		t.Fatal(err)
	}

	logXMLCheckStatusRequest(logStashEvent, request)

	if logStashEvent["requestorRef"] != "NINOXE:default" {
		t.Errorf("Wrong requestorRef logged:\n got: %v\n expected: NINOXE:default", logStashEvent["requestorRef"])
	}
	if logStashEvent["messageIdentifier"] != "CheckStatus:Test:0" {
		t.Errorf("Wrong messageIdentifier logged:\n got: %v\n expected: CheckStatus:Test:0", logStashEvent["messageIdentifier"])
	}
	if logStashEvent["requestTimestamp"] != "2016-09-07 09:11:25.174 +0000 UTC" {
		t.Errorf("Wrong requestTimestamp logged:\n got: %v\n expected: 2016-09-22 07:58:34 +0200 CEST", logStashEvent["requestTimestamp"])
	}
}

func Test_SIRICheckStatusServer_LogCheckStatusResponse(t *testing.T) {
	logStashEvent := make(audit.LogStashEvent)
	time := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
	response := &siri.SIRICheckStatusResponse{
		Status:             true,
		ServiceStartedTime: time,
	}
	response.Address = "Address"
	response.ProducerRef = "ProducerRef"
	response.RequestMessageRef = "RequestMessageRef"
	response.ResponseMessageIdentifier = "ResponseMessageIdentifier"
	response.ResponseTimestamp = time

	logSIRICheckStatusResponse(logStashEvent, response)

	if logStashEvent["address"] != "Address" {
		t.Errorf("Wrong Address logged:\n got: %v\n expected: Address", logStashEvent["address"])
	}
	if logStashEvent["producerRef"] != "ProducerRef" {
		t.Errorf("Wrong ProducerRef logged:\n got: %v\n expected: ProducerRef", logStashEvent["producerRef"])
	}
	if logStashEvent["requestMessageRef"] != "RequestMessageRef" {
		t.Errorf("Wrong RequestMessageRef logged:\n got: %v\n expected: RequestMessageRef", logStashEvent["requestMessageRef"])
	}
	if logStashEvent["responseMessageIdentifier"] != "ResponseMessageIdentifier" {
		t.Errorf("Wrong ResponseMessageIdentifier logged:\n got: %v\n expected: ResponseMessageIdentifier", logStashEvent["responseMessageIdentifier"])
	}
	if logStashEvent["status"] != "true" {
		t.Errorf("Wrong Status logged:\n got: %v\n expected: true", logStashEvent["status"])
	}
	if expected := time.String(); logStashEvent["responseTimestamp"] != expected {
		t.Errorf("Wrong ResponseTimestamp logged:\n got: %v\n expected: %v", logStashEvent["responseTimestamp"], expected)
	}
	if expected := time.String(); logStashEvent["serviceStartedTime"] != expected {
		t.Errorf("Wrong ServiceStartedTime logged:\n got: %v\n expected: %v", logStashEvent["serviceStartedTime"], expected)
	}
	xml, err := response.BuildXML()
	if err != nil {
		t.Fatal(err)
	}
	if logStashEvent["responseXML"] != xml {
		t.Errorf("Wrong responseXML logged:\n got: %v\n expected: %v", logStashEvent["responseXML"], xml)
	}
}
<|endoftext|>