e04ed9c211
CF: Deploy Dev Docs / deploy (push) Has been cancelled
Sync Labels / build (push) Has been cancelled
tests / unit tests (macos-latest) (push) Has been cancelled
tests / unit tests (windows-latest) (push) Has been cancelled
tests / unit tests (ubuntu-latest) (push) Has been cancelled
268 lines
10 KiB
Go
268 lines
10 KiB
Go
// Copyright 2026 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
|
|
//
|
|
// 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 serverlessspark_test
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"cloud.google.com/go/dataproc/v2/apiv1/dataprocpb"
|
|
"github.com/googleapis/mcp-toolbox/internal/sources/serverlessspark"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
)
|
|
|
|
func TestExtractBatchDetails_Success(t *testing.T) {
|
|
batchName := "projects/my-project/locations/us-central1/batches/my-batch"
|
|
projectID, location, batchID, err := serverlessspark.ExtractBatchDetails(batchName)
|
|
if err != nil {
|
|
t.Errorf("ExtractBatchDetails() error = %v, want no error", err)
|
|
return
|
|
}
|
|
wantProject := "my-project"
|
|
wantLocation := "us-central1"
|
|
wantBatchID := "my-batch"
|
|
if projectID != wantProject {
|
|
t.Errorf("ExtractBatchDetails() projectID = %v, want %v", projectID, wantProject)
|
|
}
|
|
if location != wantLocation {
|
|
t.Errorf("ExtractBatchDetails() location = %v, want %v", location, wantLocation)
|
|
}
|
|
if batchID != wantBatchID {
|
|
t.Errorf("ExtractBatchDetails() batchID = %v, want %v", batchID, wantBatchID)
|
|
}
|
|
}
|
|
|
|
func TestExtractBatchDetails_Failure(t *testing.T) {
|
|
batchName := "invalid-name"
|
|
_, _, _, err := serverlessspark.ExtractBatchDetails(batchName)
|
|
wantErr := "failed to parse batch name: invalid-name"
|
|
if err == nil || err.Error() != wantErr {
|
|
t.Errorf("ExtractBatchDetails() error = %v, want %v", err, wantErr)
|
|
}
|
|
}
|
|
|
|
func TestBatchConsoleURL(t *testing.T) {
|
|
got := serverlessspark.BatchConsoleURL("my-project", "us-central1", "my-batch")
|
|
want := "https://console.cloud.google.com/dataproc/batches/us-central1/my-batch/summary?project=my-project"
|
|
if got != want {
|
|
t.Errorf("BatchConsoleURL() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestBatchLogsURL(t *testing.T) {
|
|
startTime := time.Date(2025, 10, 1, 5, 0, 0, 0, time.UTC)
|
|
endTime := time.Date(2025, 10, 1, 6, 0, 0, 0, time.UTC)
|
|
got := serverlessspark.BatchLogsURL("my-project", "us-central1", "my-batch", startTime, endTime)
|
|
want := "https://console.cloud.google.com/logs/viewer?advancedFilter=" +
|
|
"resource.type%3D%22cloud_dataproc_batch%22" +
|
|
"%0Aresource.labels.project_id%3D%22my-project%22" +
|
|
"%0Aresource.labels.location%3D%22us-central1%22" +
|
|
"%0Aresource.labels.batch_id%3D%22my-batch%22" +
|
|
"%0Atimestamp%3E%3D%222025-10-01T04%3A59%3A00Z%22" + // Minus 1 minute
|
|
"%0Atimestamp%3C%3D%222025-10-01T06%3A10%3A00Z%22" + // Plus 10 minutes
|
|
"&project=my-project" +
|
|
"&resource=cloud_dataproc_batch%2Fbatch_id%2Fmy-batch"
|
|
if got != want {
|
|
t.Errorf("BatchLogsURL() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestBatchConsoleURLFromProto(t *testing.T) {
|
|
batchPb := &dataprocpb.Batch{
|
|
Name: "projects/my-project/locations/us-central1/batches/my-batch",
|
|
}
|
|
got, err := serverlessspark.BatchConsoleURLFromProto(batchPb)
|
|
if err != nil {
|
|
t.Fatalf("BatchConsoleURLFromProto() error = %v", err)
|
|
}
|
|
want := "https://console.cloud.google.com/dataproc/batches/us-central1/my-batch/summary?project=my-project"
|
|
if got != want {
|
|
t.Errorf("BatchConsoleURLFromProto() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestBatchLogsURLFromProto(t *testing.T) {
|
|
createTime := time.Date(2025, 10, 1, 5, 0, 0, 0, time.UTC)
|
|
stateTime := time.Date(2025, 10, 1, 6, 0, 0, 0, time.UTC)
|
|
batchPb := &dataprocpb.Batch{
|
|
Name: "projects/my-project/locations/us-central1/batches/my-batch",
|
|
CreateTime: timestamppb.New(createTime),
|
|
StateTime: timestamppb.New(stateTime),
|
|
}
|
|
got, err := serverlessspark.BatchLogsURLFromProto(batchPb)
|
|
if err != nil {
|
|
t.Fatalf("BatchLogsURLFromProto() error = %v", err)
|
|
}
|
|
want := "https://console.cloud.google.com/logs/viewer?advancedFilter=" +
|
|
"resource.type%3D%22cloud_dataproc_batch%22" +
|
|
"%0Aresource.labels.project_id%3D%22my-project%22" +
|
|
"%0Aresource.labels.location%3D%22us-central1%22" +
|
|
"%0Aresource.labels.batch_id%3D%22my-batch%22" +
|
|
"%0Atimestamp%3E%3D%222025-10-01T04%3A59%3A00Z%22" + // Minus 1 minute
|
|
"%0Atimestamp%3C%3D%222025-10-01T06%3A10%3A00Z%22" + // Plus 10 minutes
|
|
"&project=my-project" +
|
|
"&resource=cloud_dataproc_batch%2Fbatch_id%2Fmy-batch"
|
|
if got != want {
|
|
t.Errorf("BatchLogsURLFromProto() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestExtractSessionDetails_Success(t *testing.T) {
|
|
sessionName := "projects/my-project/locations/us-central1/sessions/my-session"
|
|
projectID, location, sessionID, err := serverlessspark.ExtractSessionDetails(sessionName)
|
|
if err != nil {
|
|
t.Errorf("ExtractSessionDetails() error = %v, want no error", err)
|
|
return
|
|
}
|
|
wantProject := "my-project"
|
|
wantLocation := "us-central1"
|
|
wantSessionID := "my-session"
|
|
if projectID != wantProject {
|
|
t.Errorf("ExtractSessionDetails() projectID = %v, want %v", projectID, wantProject)
|
|
}
|
|
if location != wantLocation {
|
|
t.Errorf("ExtractSessionDetails() location = %v, want %v", location, wantLocation)
|
|
}
|
|
if sessionID != wantSessionID {
|
|
t.Errorf("ExtractSessionDetails() sessionID = %v, want %v", sessionID, wantSessionID)
|
|
}
|
|
}
|
|
|
|
func TestExtractSessionDetails_Failure(t *testing.T) {
|
|
sessionName := "invalid-name"
|
|
_, _, _, err := serverlessspark.ExtractSessionDetails(sessionName)
|
|
wantErr := "failed to parse session name: invalid-name"
|
|
if err == nil || err.Error() != wantErr {
|
|
t.Errorf("ExtractSessionDetails() error = %v, want %v", err, wantErr)
|
|
}
|
|
}
|
|
|
|
func TestSessionConsoleURL(t *testing.T) {
|
|
got := serverlessspark.SessionConsoleURL("my-project", "us-central1", "my-session")
|
|
want := "https://console.cloud.google.com/dataproc/interactive/us-central1/my-session/details?project=my-project"
|
|
if got != want {
|
|
t.Errorf("SessionConsoleURL() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestSessionLogsURL(t *testing.T) {
|
|
startTime := time.Date(2025, 10, 1, 5, 0, 0, 0, time.UTC)
|
|
endTime := time.Date(2025, 10, 1, 6, 0, 0, 0, time.UTC)
|
|
got := serverlessspark.SessionLogsURL("my-project", "us-central1", "my-session", startTime, endTime)
|
|
want := "https://console.cloud.google.com/logs/viewer?advancedFilter=" +
|
|
"resource.type%3D%22cloud_dataproc_session%22" +
|
|
"%0Aresource.labels.session_id%3D%22my-session%22" +
|
|
"%0Aresource.labels.project_id%3D%22my-project%22" +
|
|
"%0Aresource.labels.location%3D%22us-central1%22" +
|
|
"%0Atimestamp%3E%3D%222025-10-01T04%3A59%3A00Z%22" + // Minus 1 minute
|
|
"%0Atimestamp%3C%3D%222025-10-01T06%3A10%3A00Z%22" + // Plus 10 minutes
|
|
"&project=my-project"
|
|
if got != want {
|
|
t.Errorf("SessionLogsURL() = \n%v\nwant \n%v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestSessionConsoleURLFromProto(t *testing.T) {
|
|
sessionPb := &dataprocpb.Session{
|
|
Name: "projects/my-project/locations/us-central1/sessions/my-session",
|
|
}
|
|
got, err := serverlessspark.SessionConsoleURLFromProto(sessionPb)
|
|
if err != nil {
|
|
t.Fatalf("SessionConsoleURLFromProto() error = %v", err)
|
|
}
|
|
want := "https://console.cloud.google.com/dataproc/interactive/us-central1/my-session/details?project=my-project"
|
|
if got != want {
|
|
t.Errorf("SessionConsoleURLFromProto() = %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestSessionLogsURLFromProto(t *testing.T) {
|
|
createTime := time.Date(2025, 10, 1, 5, 0, 0, 0, time.UTC)
|
|
stateTime := time.Date(2025, 10, 1, 6, 0, 0, 0, time.UTC)
|
|
sessionPb := &dataprocpb.Session{
|
|
Name: "projects/my-project/locations/us-central1/sessions/my-session",
|
|
CreateTime: timestamppb.New(createTime),
|
|
StateTime: timestamppb.New(stateTime),
|
|
}
|
|
got, err := serverlessspark.SessionLogsURLFromProto(sessionPb)
|
|
if err != nil {
|
|
t.Fatalf("SessionLogsURLFromProto() error = %v", err)
|
|
}
|
|
want := "https://console.cloud.google.com/logs/viewer?advancedFilter=" +
|
|
"resource.type%3D%22cloud_dataproc_session%22" +
|
|
"%0Aresource.labels.session_id%3D%22my-session%22" +
|
|
"%0Aresource.labels.project_id%3D%22my-project%22" +
|
|
"%0Aresource.labels.location%3D%22us-central1%22" +
|
|
"%0Atimestamp%3E%3D%222025-10-01T04%3A59%3A00Z%22" + // Minus 1 minute
|
|
"%0Atimestamp%3C%3D%222025-10-01T06%3A10%3A00Z%22" + // Plus 10 minutes
|
|
"&project=my-project"
|
|
if got != want {
|
|
t.Errorf("SessionLogsURLFromProto() = \n%v\nwant \n%v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestSessionLogsURL_Escaping(t *testing.T) {
|
|
startTime := time.Date(2025, 10, 1, 5, 0, 0, 0, time.UTC)
|
|
endTime := time.Date(2025, 10, 1, 6, 0, 0, 0, time.UTC)
|
|
|
|
// Input contains a double quote which should be escaped.
|
|
sessionID := `my-session" OR root`
|
|
got := serverlessspark.SessionLogsURL("my-project", "us-central1", sessionID, startTime, endTime)
|
|
|
|
want := "https://console.cloud.google.com/logs/viewer?advancedFilter=" +
|
|
"resource.type%3D%22cloud_dataproc_session%22" +
|
|
// "my-session\" OR root" encoded
|
|
"%0Aresource.labels.session_id%3D%22my-session%5C%22+OR+root%22" +
|
|
"%0Aresource.labels.project_id%3D%22my-project%22" +
|
|
"%0Aresource.labels.location%3D%22us-central1%22" +
|
|
"%0Atimestamp%3E%3D%222025-10-01T04%3A59%3A00Z%22" +
|
|
"%0Atimestamp%3C%3D%222025-10-01T06%3A10%3A00Z%22" +
|
|
"&project=my-project"
|
|
|
|
if got != want {
|
|
t.Errorf("SessionLogsURL_Escaping() = \n%v\nwant \n%v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestExtractSessionTemplateDetails_Success(t *testing.T) {
|
|
sessionTemplateName := "projects/my-project/locations/us-central1/sessionTemplates/my-session-template"
|
|
projectID, location, sessionTemplateID, err := serverlessspark.ExtractSessionTemplateDetails(sessionTemplateName)
|
|
if err != nil {
|
|
t.Errorf("ExtractSessionTemplateDetails() error = %v, want no error", err)
|
|
return
|
|
}
|
|
wantProject := "my-project"
|
|
wantLocation := "us-central1"
|
|
wantSessionTemplateID := "my-session-template"
|
|
if projectID != wantProject {
|
|
t.Errorf("ExtractSessionTemplateDetails() projectID = %v, want %v", projectID, wantProject)
|
|
}
|
|
if location != wantLocation {
|
|
t.Errorf("ExtractSessionTemplateDetails() location = %v, want %v", location, wantLocation)
|
|
}
|
|
if sessionTemplateID != wantSessionTemplateID {
|
|
t.Errorf("ExtractSessionTemplateDetails() sessionTemplateID = %v, want %v", sessionTemplateID, wantSessionTemplateID)
|
|
}
|
|
}
|
|
|
|
func TestExtractSessionTemplateDetails_Failure(t *testing.T) {
|
|
sessionTemplateName := "invalid-name"
|
|
_, _, _, err := serverlessspark.ExtractSessionTemplateDetails(sessionTemplateName)
|
|
wantErr := "failed to parse session template name: invalid-name"
|
|
if err == nil || err.Error() != wantErr {
|
|
t.Errorf("ExtractSessionTemplateDetails() error = %v, want %v", err, wantErr)
|
|
}
|
|
}
|