Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/soong/android/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 5 kB image not shown  

Quelle  onceper_test.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2019 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 android

import (
 "testing"
 "time"
)

func TestOncePer_Once(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 a := once.Once(key, func() interface{} { return "a" }).(string)
 b := once.Once(key, func() interface{} { return "b" }).(string)

 if a != "a" {
  t.Errorf(`first call to Once should return "a": %q`, a)
 }

 if b != "a" {
  t.Errorf(`second call to Once with the same key should return "a": %q`, b)
 }
}

func TestOncePer_Once_wait(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 ch := make(chan bool)

 go once.Once(key, func() interface{} { close(ch); time.Sleep(100 * time.Millisecond); return "foo" })
 <-ch
 a := once.Once(key, func() interface{} { return "bar" }).(string)

 if a != "foo" {
  t.Errorf("expect %q, got %q", "foo", a)
 }
}

func TestOncePer_Get(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 a := once.Once(key, func() interface{} { return "a" }).(string)
 b := once.Get(key).(string)

 if a != "a" {
  t.Errorf(`first call to Once should return "a": %q`, a)
 }

 if b != "a" {
  t.Errorf(`Get with the same key should return "a": %q`, b)
 }
}

func TestOncePer_Get_panic(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 defer func() {
  p := recover()

  if p == nil {
   t.Error("call to Get for unused key should panic")
  }
 }()

 once.Get(key)
}

func TestOncePer_Get_wait(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 ch := make(chan bool)

 go once.Once(key, func() interface{} { close(ch); time.Sleep(100 * time.Millisecond); return "foo" })
 <-ch
 a := once.Get(key).(string)

 if a != "foo" {
  t.Errorf("expect %q, got %q", "foo", a)
 }
}

func TestOncePer_OnceStringSlice(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 a := once.OnceStringSlice(key, func() []string { return []string{"a"} })
 b := once.OnceStringSlice(key, func() []string { return []string{"a"} })

 if a[0] != "a" {
  t.Errorf(`first call to OnceStringSlice should return ["a"]: %q`, a)
 }

 if b[0] != "a" {
  t.Errorf(`second call to OnceStringSlice with the same key should return ["a"]: %q`, b)
 }
}

func TestOncePer_Once2StringSlice(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 a, b := once.Once2StringSlice(key, func() ([]string, []string) { return []string{"a"}, []string{"b"} })
 c, d := once.Once2StringSlice(key, func() ([]string, []string) { return []string{"c"}, []string{"d"} })

 if a[0] != "a" || b[0] != "b" {
  t.Errorf(`first call to Once2StringSlice should return ["a"], ["b"]: %q, %q`, a, b)
 }

 if c[0] != "a" || d[0] != "b" {
  t.Errorf(`second call to Once2StringSlice with the same key should return ["a"], ["b"]: %q, %q`, c, d)
 }
}

func TestNewOnceKey(t *testing.T) {
 once := OncePer{}
 key1 := NewOnceKey("key")
 key2 := NewOnceKey("key")

 a := once.Once(key1, func() interface{} { return "a" }).(string)
 b := once.Once(key2, func() interface{} { return "b" }).(string)

 if a != "a" {
  t.Errorf(`first call to Once should return "a": %q`, a)
 }

 if b != "b" {
  t.Errorf(`second call to Once with the NewOnceKey from same string should return "b": %q`, b)
 }
}

func TestNewCustomOnceKey(t *testing.T) {
 type key struct {
  key string
 }
 once := OncePer{}
 key1 := NewCustomOnceKey(key{"key"})
 key2 := NewCustomOnceKey(key{"key"})

 a := once.Once(key1, func() interface{} { return "a" }).(string)
 b := once.Once(key2, func() interface{} { return "b" }).(string)

 if a != "a" {
  t.Errorf(`first call to Once should return "a": %q`, a)
 }

 if b != "a" {
  t.Errorf(`second call to Once with the NewCustomOnceKey from equal key should return "a": %q`, b)
 }
}

func TestOncePerReentrant(t *testing.T) {
 once := OncePer{}
 key1 := NewOnceKey("key")
 key2 := NewOnceKey("key")

 a := once.Once(key1, func() interface{} { return once.Once(key2, func() interface{} { return "a" }) })
 if a != "a" {
  t.Errorf(`reentrant Once should return "a": %q`, a)
 }
}

// Test that a recovered panic in a Once function doesn't deadlock
func TestOncePerPanic(t *testing.T) {
 once := OncePer{}
 key := NewOnceKey("key")

 ch := make(chan interface{})

 var a interface{}

 go func() {
  defer func() {
   ch <- recover()
  }()

  a = once.Once(key, func() interface{} {
   panic("foo")
  })
 }()

 p := <-ch

 if p.(string) != "foo" {
  t.Errorf(`expected panic with "foo", got %#v`, p)
 }

 if a != nil {
  t.Errorf(`expected a to be nil, got %#v`, a)
 }

 // If the call to Once that panicked leaves the key in a bad state this will deadlock
 b := once.Once(key, func() interface{} {
  return "bar"
 })

 // The second call to Once should return nil inserted by the first call that panicked.
 if b != nil {
  t.Errorf(`expected b to be nil, got %#v`, b)
 }
}

[Dauer der Verarbeitung: 0.23 Sekunden, vorverarbeitet 2026-06-28]