You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: livestream_test.go
    path of file: ./repos/golang-samples/media/livestream
    
    the code of the file until where you have to start completion: // Copyright 2022 Google LLC
//
// 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
//
//     https://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 livestream

import (
	"bytes"
	"context"
	"fmt"
	"strconv"
	"strings"
	"testing"
	"time"

	livestream "cloud.google.com/go/video/livestream/apiv1"
	"cloud.google.com/go/video/livestream/apiv1/livestreampb"

	"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
	"google.golang.org/api/iterator"
)

const (
	deleteChannelEventResponse = "Deleted channel event"
	deleteChannelResponse      = "Deleted channel"
	deleteInputResponse        = "Deleted input"
	deleteAssetResponse        = "Deleted asset"
	startChannelResponse       = "Started channel"
	stopChannelResponse        = "Stopped channel"
	location                   = "us-central1"
	inputID                    = "my-go-test-input"
	backupInputID              = "my-go-test-backup-input"
	channelID                  = "my-go-test-channel"
	eventID                    = "my-go-test-channel-event"
	assetID                    = "my-go-test-asset"
	poolID                     = "default" // only 1 pool supported per location
)

var bucketName string
var outputURI string
var assetURI string

// To run the tests, do the following:
// Export the following env vars:
// *   GOOGLE_APPLICATION_CREDENTIALS
// *   GOLANG_SAMPLES_PROJECT_ID
// Enable the following API on the test project:
// *   Live Stream API

// TestMain tests major operations on inputs, channels, channel
// events, assets, and pools.
func TestMain(m *testing.M) {
	tc, _ := testutil.ContextMain(m)
	bucketName = tc.ProjectID + "-golang-samples-livestream-test"
	outputURI = "gs://" + bucketName + "/test-output-channel/"
	assetURI = "gs://cloud-samples-data/media/ForBiggerEscapes.mp4"
	m.Run()
	cleanStaleAssets(tc)
}

func cleanStaleAssets(tc testutil.Context) {
	ctx := context.Background()
	var threeHoursInSec int64 = 60 * 60 * 3
	timeNowSec := time.Now().Unix()

	client, err := livestream.NewClient(ctx)
	if err != nil {
		fmt.Printf("NewClient: %v", err)
	}
	defer client.Close()

	req := &livestreampb.ListAssetsRequest{
		Parent: fmt.Sprintf("projects/%s/locations/%s", tc.ProjectID, location),
	}

	it := client.ListAssets(ctx, req)
	for {
		response, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			fmt.Printf("ListAssets: %v", err)
			continue
		}
		req := &livestreampb.GetAssetRequest{
			Name: response.Name,
		}
		asset, err := client.GetAsset(ctx, req)
		if err != nil {
			fmt.Printf("GetAsset: %v", err)
			continue
		}
		if asset.GetCreateTime().GetSeconds() < timeNowSec-threeHoursInSec {
			fmt.Printf("%v - delete asset", asset.GetCreateTime().GetSeconds())
			req := &livestreampb.DeleteAssetRequest{
				Name: asset.GetName(),
			}
			// No need to wait for delete ops to finish, as this is a background
			// cleanup.
			_, err := client.DeleteAsset(ctx, req)
			if err != nil {
				fmt.Printf("DeleteAsset: %v", err)
				continue
			}
		}
	}
}

// TestInputs tests major operations on inputs. Create, list, update,
// and get operations check if the input resource name is returned. The
// delete operation checks for a hard-coded string response.
func TestInputs(t *testing.T) {
	tc := testutil.SystemTest(t)
	buf := &bytes.Buffer{}

	// Test setup

	// Stop and delete the default channel if it exists
	if err := getChannel(buf, tc.ProjectID, location, channelID); err == nil {
		testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
			if err := stopChannel(buf, tc.ProjectID, location, channelID); err != nil {
				// Ignore the error when the channel is already stopped
			}
		})

		testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
			if err := deleteChannel(buf, tc.ProjectID, location, channelID); err != nil {
				r.Errorf("deleteChannel got err: %v", err)
			}
		})
	}

	// Delete the default input if it exists
	if err := getInput(buf, tc.ProjectID, location, inputID); err == nil {
		testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
			if err := 
    
func TestChannelEvents(t *testing.T) {
	tc := testutil.SystemTest(t)
	buf := &bytes.Buffer{}

	// Test setup

	// Stop and delete the default channel if it exists
	if err := getChannel(buf, tc.ProjectID, location, channelID); err == nil {
		testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
			if err := stopChannel(buf, tc.ProjectID, location, channelID); err != nil {
				// Ignore the error when the channel is already stopped.
			}
		})

		testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
			if err := deleteChannel(buf, tc.ProjectID, location, channelID); err != nil {
				r.Errorf("deleteChannel got err: %v", err)
			}
		})
	}

	// Delete the default input if it exists
	if err := getInput(buf, tc.ProjectID, location, inputID); err == nil {
		testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
			if err := deleteInput(buf, tc.ProjectID, location, inputID); err != nil {
				r.Errorf("deleteInput got err: %v", err)
			}
		})
	}

	// Create a new input.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		inputName := fmt.Sprintf("projects/%s/locations/%s/inputs/%s", tc.ProjectID, location, inputID)
		if err := createInput(buf, tc.ProjectID, location, inputID); err != nil {
			r.Errorf("createInput got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, inputName) {
			r.Errorf("createInput got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, inputName)
		}
	})

	// Create a new channel.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		channelName := fmt.Sprintf("projects/%s/locations/%s/channels/%s", tc.ProjectID, location, channelID)
		if err := createChannel(buf, tc.ProjectID, location, channelID, inputID, outputURI); err != nil {
			r.Errorf("createChannel got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, channelName) {
			r.Errorf("createChannel got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, channelName)
		}
	})

	// Start the channel.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		if err := startChannel(buf, tc.ProjectID, location, channelID); err != nil {
			r.Errorf("startChannel got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, startChannelResponse) {
			r.Errorf("startChannel got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, startChannelResponse)
		}
	})

	buf.Reset()

	// Tests

	// Create a new channel event.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		eventName := fmt.Sprintf("projects/%s/locations/%s/channels/%s/events/%s", tc.ProjectID, location, channelID, eventID)
		if err := createChannelEvent(buf, tc.ProjectID, location, channelID, eventID); err != nil {
			r.Errorf("createChannelEvent got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, eventName) {
			r.Errorf("createChannelEvent got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, eventName)
		}
	})
	buf.Reset()

	// List the channel events for a given channel.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		eventName := fmt.Sprintf("projects/%s/locations/%s/channels/%s/events/%s", tc.ProjectID, location, channelID, eventID)
		if err := listChannelEvents(buf, tc.ProjectID, location, channelID); err != nil {
			r.Errorf("listChannelEvents got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, eventName) {
			r.Errorf("listChannelEvents got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, eventName)
		}
	})
	buf.Reset()

	// Get the channel event.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		eventName := fmt.Sprintf("projects/%s/locations/%s/channels/%s/events/%s", tc.ProjectID, location, channelID, eventID)
		if err := getChannelEvent(buf, tc.ProjectID, location, channelID, eventID); err != nil {
			r.Errorf("getChannelEvent got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, eventName) {
			r.Errorf("getChannelEvent got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, eventName)
		}
	})
	buf.Reset()

	// Delete the channel event.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		if err := deleteChannelEvent(buf, tc.ProjectID, location, channelID, eventID); err != nil {
			r.Errorf("deleteChannelEvent got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, deleteChannelEventResponse) {
			r.Errorf("deleteChannelEvent got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, deleteChannelEventResponse)
		}
	})

	// Clean up

	// Stop the channel.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		if err := stopChannel(buf, tc.ProjectID, location, channelID); err != nil {
			r.Errorf("stopChannel got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, stopChannelResponse) {
			r.Errorf("stopChannel got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, stopChannelResponse)
		}
	})

	// Delete the channel.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		if err := deleteChannel(buf, tc.ProjectID, location, channelID); err != nil {
			r.Errorf("deleteChannel got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, deleteChannelResponse) {
			r.Errorf("deleteChannel got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, deleteChannelResponse)
		}
	})

	// Delete the input.
	testutil.Retry(t, 3, 2*time.Second, func(r *testutil.R) {
		if err := deleteInput(buf, tc.ProjectID, location, inputID); err != nil {
			r.Errorf("deleteInput got err: %v", err)
		}
		if got := buf.String(); !strings.Contains(got, deleteInputResponse) {
			r.Errorf("deleteInput got\n----\n%v\n----\nWant to contain:\n----\n%v\n----\n", got, deleteInputResponse)
		}
	})
	t.Logf("\nTestChannelEvents() completed\n")
}