func init() {
	logLevel := Session.Config.LogLevel
	if os.Getenv("DEBUG") != "" {
		logLevel = aws.LogLevel(aws.LogDebug)
	}
	if os.Getenv("DEBUG_SIGNING") != "" {
		logLevel = aws.LogLevel(aws.LogDebugWithSigning)
	}
	if os.Getenv("DEBUG_BODY") != "" {
		logLevel = aws.LogLevel(aws.LogDebugWithHTTPBody)
	}
	Session.Config.LogLevel = logLevel

	gucumber.When(`^I call the "(.+?)" API$`, func(op string) {
		call(op, nil, false)
	})

	gucumber.When(`^I call the "(.+?)" API with:$`, func(op string, args [][]string) {
		call(op, args, false)
	})

	gucumber.Then(`^the value at "(.+?)" should be a list$`, func(member string) {
		vals, _ := awsutil.ValuesAtPath(gucumber.World["response"], member)
		assert.NotNil(gucumber.T, vals)
	})

	gucumber.Then(`^the response should contain a "(.+?)"$`, func(member string) {
		vals, _ := awsutil.ValuesAtPath(gucumber.World["response"], member)
		assert.NotEmpty(gucumber.T, vals)
	})

	gucumber.When(`^I attempt to call the "(.+?)" API with:$`, func(op string, args [][]string) {
		call(op, args, true)
	})

	gucumber.Then(`^I expect the response error code to be "(.+?)"$`, func(code string) {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.True(gucumber.T, ok, "no error returned")
		if ok {
			assert.Equal(gucumber.T, code, err.Code(), "Error: %v", err)
		}
	})

	gucumber.And(`^I expect the response error message to include:$`, func(data string) {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.True(gucumber.T, ok, "no error returned")
		if ok {
			assert.Contains(gucumber.T, err.Error(), data)
		}
	})

	gucumber.And(`^I expect the response error message to include one of:$`, func(table [][]string) {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.True(gucumber.T, ok, "no error returned")
		if ok {
			found := false
			for _, row := range table {
				if strings.Contains(err.Error(), row[0]) {
					found = true
					break
				}
			}

			assert.True(gucumber.T, found, fmt.Sprintf("no error messages matched: \"%s\"", err.Error()))
		}
	})

	gucumber.And(`^I expect the response error message not be empty$`, func() {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.True(gucumber.T, ok, "no error returned")
		assert.NotEmpty(gucumber.T, err.Message())
	})

	gucumber.When(`^I call the "(.+?)" API with JSON:$`, func(s1 string, data string) {
		callWithJSON(s1, data, false)
	})

	gucumber.When(`^I attempt to call the "(.+?)" API with JSON:$`, func(s1 string, data string) {
		callWithJSON(s1, data, true)
	})

	gucumber.Then(`^the error code should be "(.+?)"$`, func(s1 string) {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.True(gucumber.T, ok, "no error returned")
		assert.Equal(gucumber.T, s1, err.Code())
	})

	gucumber.And(`^the error message should contain:$`, func(data string) {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.True(gucumber.T, ok, "no error returned")
		assert.Contains(gucumber.T, err.Error(), data)
	})

	gucumber.Then(`^the request should fail$`, func() {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.True(gucumber.T, ok, "no error returned")
		assert.Error(gucumber.T, err)
	})

	gucumber.Then(`^the request should be successful$`, func() {
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.False(gucumber.T, ok, "error returned")
		assert.NoError(gucumber.T, err)
	})
}
func init() {
	// Go loads all of its dependecies on compile
	gucumber.Given(`^I have loaded my SDK and its dependencies$`, func() {
	})

	// Performance
	gucumber.When(`^I create and discard (\d+) clients for each service$`, func(i1 int) {
		services := gucumber.World["services"].([]func())
		err := benchmarkTask(fmt.Sprintf("%d_create_and_discard_clients", i1), services, i1)
		gucumber.World["error"] = err
	})

	gucumber.Then(`^I should not have leaked any resources$`, func() {
		runtime.GC()
		err, ok := gucumber.World["error"].(awserr.Error)
		assert.False(gucumber.T, ok, "error returned")
		assert.NoError(gucumber.T, err)
	})

	gucumber.And(`^I have a list of services$`, func() {
		mapCreateClients()
	})

	gucumber.And(`^I take a snapshot of my resources$`, func() {
		// Can't take a memory snapshot here, because gucumber does some
		// allocation between each instruction leading to unreliable numbers
	})

	gucumber.When(`^I create a client for each service$`, func() {
		buildAnArrayOfClients()
	})

	gucumber.And("^I execute (\\d+) command\\(s\\) on each client$", func(i1 int) {
		clientFns := gucumber.World["clientFns"].([]func())
		err := benchmarkTask(fmt.Sprintf("%d_commands_on_clients", i1), clientFns, i1)
		gucumber.World["error"] = err
	})

	gucumber.And(`^I destroy all the clients$`, func() {
		delete(gucumber.World, "clientFns")
		runtime.GC()
	})

	gucumber.Given(`^I have a (\d+) byte file$`, func(i1 int) {
		gucumber.World["file"] = make([]byte, i1)
	})

	gucumber.When(`^I upload the file$`, func() {
		svc := s3.New(mock.Session)
		memStatStart := &runtime.MemStats{}
		runtime.ReadMemStats(memStatStart)
		gucumber.World["start"] = memStatStart

		svc.PutObjectRequest(&s3.PutObjectInput{
			Bucket: aws.String("bucketmesilly"),
			Key:    aws.String("testKey"),
			Body:   bytes.NewReader(gucumber.World["file"].([]byte)),
		})
	})

	gucumber.And(`then download the file$`, func() {
		svc := s3.New(mock.Session)
		svc.GetObjectRequest(&s3.GetObjectInput{
			Bucket: aws.String("bucketmesilly"),
			Key:    aws.String("testKey"),
		})
		memStatEnd := &runtime.MemStats{}
		runtime.ReadMemStats(memStatEnd)
		memStatStart := gucumber.World["start"].(*runtime.MemStats)
		if memStatStart.Alloc < memStatEnd.Alloc {
			gucumber.World["error"] = errors.New("Leaked memory")
		}
	})
}
Exemple #3
0
func init() {
	gucumber.When(`^I get all fixtures for "(.+?)" from "(.+?)"$`,
		func(cekAlg, bucket string) {
			prefix := "plaintext_test_case_"
			baseFolder := "crypto_tests/" + cekAlg
			s3Client := gucumber.World["client"].(*s3.S3)

			out, err := s3Client.ListObjects(&s3.ListObjectsInput{
				Bucket: aws.String(bucket),
				Prefix: aws.String(baseFolder + "/" + prefix),
			})
			assert.NoError(gucumber.T, err)

			plaintexts := make(map[string][]byte)
			for _, obj := range out.Contents {
				plaintextKey := obj.Key
				ptObj, err := s3Client.GetObject(&s3.GetObjectInput{
					Bucket: aws.String(bucket),
					Key:    plaintextKey,
				})
				assert.NoError(gucumber.T, err)
				caseKey := strings.TrimPrefix(*plaintextKey, baseFolder+"/"+prefix)
				plaintext, err := ioutil.ReadAll(ptObj.Body)
				assert.NoError(gucumber.T, err)

				plaintexts[caseKey] = plaintext
			}
			gucumber.World["baseFolder"] = baseFolder
			gucumber.World["bucket"] = bucket
			gucumber.World["plaintexts"] = plaintexts
		})

	gucumber.Then(`^I decrypt each fixture against "(.+?)" "(.+?)"$`, func(lang, version string) {
		plaintexts := gucumber.World["plaintexts"].(map[string][]byte)
		baseFolder := gucumber.World["baseFolder"].(string)
		bucket := gucumber.World["bucket"].(string)
		prefix := "ciphertext_test_case_"
		s3Client := gucumber.World["client"].(*s3.S3)
		s3CryptoClient := gucumber.World["decryptionClient"].(*s3crypto.DecryptionClient)
		language := "language_" + lang

		ciphertexts := make(map[string][]byte)
		for caseKey := range plaintexts {
			cipherKey := baseFolder + "/" + version + "/" + language + "/" + prefix + caseKey

			// To get metadata for encryption key
			ctObj, err := s3Client.GetObject(&s3.GetObjectInput{
				Bucket: aws.String(bucket),
				Key:    &cipherKey,
			})
			if err != nil {
				continue
			}

			// We don't support wrap, so skip it
			if *ctObj.Metadata["X-Amz-Wrap-Alg"] != "kms" {
				continue
			}
			//masterkeyB64 := ctObj.Metadata["Masterkey"]
			//masterkey, err := base64.StdEncoding.DecodeString(*masterkeyB64)
			//assert.NoError(T, err)

			//s3CryptoClient.Config.MasterKey = masterkey
			ctObj, err = s3CryptoClient.GetObject(&s3.GetObjectInput{
				Bucket: aws.String(bucket),
				Key:    &cipherKey,
			},
			)
			assert.NoError(gucumber.T, err)

			ciphertext, err := ioutil.ReadAll(ctObj.Body)
			assert.NoError(gucumber.T, err)
			ciphertexts[caseKey] = ciphertext
		}
		gucumber.World["ciphertexts"] = ciphertexts
	})

	gucumber.And(`^I compare the decrypted ciphertext to the plaintext$`, func() {
		plaintexts := gucumber.World["plaintexts"].(map[string][]byte)
		ciphertexts := gucumber.World["ciphertexts"].(map[string][]byte)
		for caseKey, ciphertext := range ciphertexts {
			assert.Equal(gucumber.T, len(plaintexts[caseKey]), len(ciphertext))
			assert.True(gucumber.T, bytes.Equal(plaintexts[caseKey], ciphertext))
		}
	})

	gucumber.Then(`^I encrypt each fixture with "(.+?)" "(.+?)" "(.+?)" and "(.+?)"$`, func(kek, v1, v2, cek string) {
		var handler s3crypto.CipherDataGenerator
		var builder s3crypto.ContentCipherBuilder
		switch kek {
		case "kms":
			arn, err := getAliasInformation(v1, v2)
			assert.Nil(gucumber.T, err)

			b64Arn := base64.StdEncoding.EncodeToString([]byte(arn))
			assert.Nil(gucumber.T, err)
			gucumber.World["Masterkey"] = b64Arn

			handler = s3crypto.NewKMSKeyGenerator(kms.New(session.New(&aws.Config{
				Region: &v2,
			})), arn)
			assert.Nil(gucumber.T, err)
		default:
			gucumber.T.Skip()
		}

		switch cek {
		case "aes_gcm":
			builder = s3crypto.AESGCMContentCipherBuilder(handler)
		default:
			gucumber.T.Skip()
		}

		sess := session.New(&aws.Config{
			Region: aws.String("us-west-2"),
		})
		c := s3crypto.NewEncryptionClient(sess, builder, func(c *s3crypto.EncryptionClient) {
		})
		gucumber.World["encryptionClient"] = c
		gucumber.World["cek"] = cek
	})

	gucumber.And(`^upload "(.+?)" data with folder "(.+?)"$`, func(language, folder string) {
		c := gucumber.World["encryptionClient"].(*s3crypto.EncryptionClient)
		cek := gucumber.World["cek"].(string)
		bucket := gucumber.World["bucket"].(string)
		plaintexts := gucumber.World["plaintexts"].(map[string][]byte)
		key := gucumber.World["Masterkey"].(string)
		for caseKey, plaintext := range plaintexts {
			input := &s3.PutObjectInput{
				Bucket: &bucket,
				Key:    aws.String("crypto_tests/" + cek + "/" + folder + "/language_" + language + "/ciphertext_test_case_" + caseKey),
				Body:   bytes.NewReader(plaintext),
				Metadata: map[string]*string{
					"Masterkey": &key,
				},
			}

			_, err := c.PutObject(input)
			assert.Nil(gucumber.T, err)
		}
	})
}