Repository: open-telemetry/opentelemetry-swift (swift)

Issue:
InstrumentBuilder incorrectly marked as internal
https://github.com/open-telemetry/opentelemetry-swift/blob/main/Sources/OpenTelemetrySdk/Metrics/Stable/InstrumentBuilder.swift

This is a little more complicated than just making this public, as some member vars are internal only.

Pull request description:
Fixes #721 
a 'virtual' protocol is not viable in this situation because the member variables and extension functions need variable visibility, both internal and public

Patch:
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleCounterMeterBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleCounterMeterBuilderSdk.swift
index fd166f994..0c8792c0a 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleCounterMeterBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleCounterMeterBuilderSdk.swift
@@ -6,31 +6,21 @@
 import Foundation
 import OpenTelemetryApi
 
-public class DoubleCounterMeterBuilderSdk: DoubleCounterBuilder, InstrumentBuilder {
-  var meterSharedState: StableMeterSharedState
-
-  var meterProviderSharedState: MeterProviderSharedState
-
-  let type: InstrumentType = .counter
-
-  let valueType: InstrumentValueType = .double
-
-  var instrumentName: String
-
-  var description: String
-
-  var unit: String
-
-  init(meterProviderSharedState: MeterProviderSharedState,
-       meterSharedState: StableMeterSharedState,
+public class DoubleCounterMeterBuilderSdk: InstrumentBuilder, DoubleCounterBuilder {
+  init(meterProviderSharedState: inout MeterProviderSharedState,
+       meterSharedState: inout StableMeterSharedState,
        name: String,
        description: String,
        unit: String) {
-    self.meterProviderSharedState = meterProviderSharedState
-    self.meterSharedState = meterSharedState
-    self.unit = unit
-    self.description = description
-    instrumentName = name
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .counter,
+      valueType: .double,
+      description: description,
+      unit: unit,
+      instrumentName: name
+    )
   }
 
   public func build() -> OpenTelemetryApi.DoubleCounter {
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleGaugeBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleGaugeBuilderSdk.swift
index 239128984..231d2b7c3 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleGaugeBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleGaugeBuilderSdk.swift
@@ -6,25 +6,17 @@
 import Foundation
 import OpenTelemetryApi
 
-public class DoubleGaugeBuilderSdk: DoubleGaugeBuilder, InstrumentBuilder {
-  var meterProviderSharedState: MeterProviderSharedState
-
-  var meterSharedState: StableMeterSharedState
-
-  var type: InstrumentType = .observableGauge
-
-  var valueType: InstrumentValueType = .double
-
-  var description: String = ""
-
-  var unit: String = ""
-
-  var instrumentName: String
-
+public class DoubleGaugeBuilderSdk: InstrumentBuilder, DoubleGaugeBuilder {
   init(meterProviderSharedState: inout MeterProviderSharedState, meterSharedState: inout StableMeterSharedState, name: String) {
-    self.meterProviderSharedState = meterProviderSharedState
-    self.meterSharedState = meterSharedState
-    instrumentName = name
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .observableGauge,
+      valueType: .double,
+      description: "",
+      unit: "",
+      instrumentName: name
+    )
   }
 
   public func ofLongs() -> OpenTelemetryApi.LongGaugeBuilder {
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleHistogramMeterBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleHistogramMeterBuilderSdk.swift
index 080537edb..2dfc9ff4c 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleHistogramMeterBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleHistogramMeterBuilderSdk.swift
@@ -6,31 +6,21 @@
 import Foundation
 import OpenTelemetryApi
 
-public class DoubleHistogramMeterBuilderSdk: DoubleHistogramBuilder, InstrumentBuilder {
-  var meterProviderSharedState: MeterProviderSharedState
-
-  var meterSharedState: StableMeterSharedState
-
-  let type: InstrumentType = .histogram
-
-  let valueType: InstrumentValueType = .double
-
-  let instrumentName: String
-
-  var description: String
-
-  var unit: String
-
+public class DoubleHistogramMeterBuilderSdk: InstrumentBuilder, DoubleHistogramBuilder {
   init(meterProviderSharedState: inout MeterProviderSharedState,
        meterSharedState: inout StableMeterSharedState,
        name: String,
        description: String = "",
        unit: String = "") {
-    self.meterProviderSharedState = meterProviderSharedState
-    self.meterSharedState = meterSharedState
-    instrumentName = name
-    self.description = description
-    self.unit = unit
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .histogram,
+      valueType: .double,
+      description: description,
+      unit: unit,
+      instrumentName: name
+    )
   }
 
   public func ofLongs() -> OpenTelemetryApi.LongHistogramBuilder {
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleUpDownCounterBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleUpDownCounterBuilderSdk.swift
index bf56eebab..981f90b7f 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleUpDownCounterBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/DoubleUpDownCounterBuilderSdk.swift
@@ -6,31 +6,21 @@
 import Foundation
 import OpenTelemetryApi
 
-public class DoubleUpDownCounterBuilderSdk: DoubleUpDownCounterBuilder, InstrumentBuilder {
-  var meterSharedState: StableMeterSharedState
-
-  var meterProviderSharedState: MeterProviderSharedState
-
-  let type: InstrumentType = .upDownCounter
-
-  let valueType: InstrumentValueType = .double
-
-  var instrumentName: String
-
-  var description: String
-
-  var unit: String
-
-  init(meterProviderSharedState: MeterProviderSharedState,
-       meterSharedState: StableMeterSharedState,
+public class DoubleUpDownCounterBuilderSdk: InstrumentBuilder, DoubleUpDownCounterBuilder {
+  init(meterProviderSharedState: inout MeterProviderSharedState,
+       meterSharedState: inout StableMeterSharedState,
        name: String,
        description: String,
        unit: String) {
-    self.meterProviderSharedState = meterProviderSharedState
-    self.meterSharedState = meterSharedState
-    self.unit = unit
-    self.description = description
-    instrumentName = name
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .upDownCounter,
+      valueType: .double,
+      description: description,
+      unit: unit,
+      instrumentName: name
+    )
   }
 
   public func build() -> OpenTelemetryApi.DoubleUpDownCounter {
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/InstrumentBuilder.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/InstrumentBuilder.swift
index d945d868d..295c5211c 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/InstrumentBuilder.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/InstrumentBuilder.swift
@@ -6,40 +6,49 @@
 import Foundation
 import OpenTelemetryApi
 
-protocol InstrumentBuilder: AnyObject {
-  var meterProviderSharedState: MeterProviderSharedState { get }
-  var meterSharedState: StableMeterSharedState { get set }
-  var type: InstrumentType { get }
-  var valueType: InstrumentValueType { get }
-  var description: String { get set }
-  var unit: String { get set }
-  var instrumentName: String { get }
+public class InstrumentBuilder {
+  private var meterProviderSharedState: MeterProviderSharedState
+  private var meterSharedState: StableMeterSharedState
+  internal var type: InstrumentType
+  internal var valueType: InstrumentValueType
+  internal var description: String
+  internal var unit: String
+  internal var instrumentName: String
+  internal init(meterProviderSharedState: inout MeterProviderSharedState, meterSharedState: inout StableMeterSharedState, type: InstrumentType, valueType: InstrumentValueType, description: String, unit: String, instrumentName: String) {
+    self.meterProviderSharedState = meterProviderSharedState
+    self.meterSharedState = meterSharedState
+    self.type = type
+    self.valueType = valueType
+    self.description = description
+    self.unit = unit
+    self.instrumentName = instrumentName
+  }
 }
 
-extension InstrumentBuilder {
-  public func setUnit(_ units: String) -> Self {
+public extension InstrumentBuilder {
+  func setUnit(_ units: String) -> Self {
     // todo : validate unit
-    unit = unit
+    unit = units
     return self
   }
 
-  public func setDescription(_ description: String) -> Self {
+  func setDescription(_ description: String) -> Self {
     self.description = description
     return self
   }
 
-  func swapBuilder<T: InstrumentBuilder>(_ builder: (MeterProviderSharedState, StableMeterSharedState, String, String, String) -> T) -> T {
-    return builder(meterProviderSharedState, meterSharedState, instrumentName, description, unit)
+  internal func swapBuilder<T: InstrumentBuilder>(_ builder: (inout MeterProviderSharedState, inout StableMeterSharedState, String, String, String) -> T) -> T {
+    return builder(&meterProviderSharedState, &meterSharedState, instrumentName, description, unit)
   }
 
   // todo : Is it necessary to use inout for writableMetricStorage?
-  public func buildSynchronousInstrument<T: Instrument>(_ instrumentFactory: (InstrumentDescriptor, WritableMetricStorage) -> T) -> T {
+  func buildSynchronousInstrument<T: Instrument>(_ instrumentFactory: (InstrumentDescriptor, WritableMetricStorage) -> T) -> T {
     let descriptor = InstrumentDescriptor(name: instrumentName, description: description, unit: unit, type: type, valueType: valueType)
     let storage = meterSharedState.registerSynchronousMetricStorage(instrument: descriptor, meterProviderSharedState: meterProviderSharedState)
     return instrumentFactory(descriptor, storage)
   }
 
-  public func registerDoubleAsynchronousInstrument(type: InstrumentType, updater: @escaping (ObservableDoubleMeasurement) -> Void) -> ObservableInstrumentSdk {
+  func registerDoubleAsynchronousInstrument(type: InstrumentType, updater: @escaping (ObservableDoubleMeasurement) -> Void) -> ObservableInstrumentSdk {
     let sdkObservableMeasurement = buildObservableMeasurement(type: type)
     let callbackRegistration = CallbackRegistration(observableMeasurements: [sdkObservableMeasurement]) {
       updater(sdkObservableMeasurement)
@@ -48,7 +57,7 @@ extension InstrumentBuilder {
     return ObservableInstrumentSdk(meterSharedState: meterSharedState, callbackRegistration: callbackRegistration)
   }
 
-  public func registerLongAsynchronousInstrument(type: InstrumentType, updater: @escaping (ObservableLongMeasurement) -> Void) -> ObservableInstrumentSdk {
+  func registerLongAsynchronousInstrument(type: InstrumentType, updater: @escaping (ObservableLongMeasurement) -> Void) -> ObservableInstrumentSdk {
     let sdkObservableMeasurement = buildObservableMeasurement(type: type)
     let callbackRegistration = CallbackRegistration(observableMeasurements: [sdkObservableMeasurement], callback: {
       updater(sdkObservableMeasurement)
@@ -57,7 +66,7 @@ extension InstrumentBuilder {
     return ObservableInstrumentSdk(meterSharedState: meterSharedState, callbackRegistration: callbackRegistration)
   }
 
-  public func buildObservableMeasurement(type: InstrumentType) -> StableObservableMeasurementSdk {
+  func buildObservableMeasurement(type: InstrumentType) -> StableObservableMeasurementSdk {
     let descriptor = InstrumentDescriptor(name: instrumentName, description: description, unit: unit, type: type, valueType: valueType)
     return meterSharedState.registerObservableMeasurement(instrumentDescriptor: descriptor)
   }
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/LongCounterMeterBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/LongCounterMeterBuilderSdk.swift
index bb8d1b80a..86b4413f4 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/LongCounterMeterBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/LongCounterMeterBuilderSdk.swift
@@ -6,27 +6,19 @@
 import Foundation
 import OpenTelemetryApi
 
-public class LongCounterMeterBuilderSdk: LongCounterBuilder, InstrumentBuilder {
-  var meterProviderSharedState: MeterProviderSharedState
-
-  var meterSharedState: StableMeterSharedState
-
-  let type: InstrumentType = .counter
-
-  let valueType: InstrumentValueType = .long
-
-  var instrumentName: String
-
-  var description: String = ""
-
-  var unit: String = ""
-
+public class LongCounterMeterBuilderSdk: InstrumentBuilder, LongCounterBuilder {
   init(meterProviderSharedState: inout MeterProviderSharedState,
        meterSharedState: inout StableMeterSharedState,
        name: String) {
-    self.meterProviderSharedState = meterProviderSharedState
-    self.meterSharedState = meterSharedState
-    instrumentName = name
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .counter,
+      valueType: .long,
+      description: "",
+      unit: "",
+      instrumentName: name
+    )
   }
 
   public func ofDoubles() -> OpenTelemetryApi.DoubleCounterBuilder {
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/LongGaugeBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/LongGaugeBuilderSdk.swift
index b27feb2f5..5d463afa1 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/LongGaugeBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/LongGaugeBuilderSdk.swift
@@ -6,27 +6,17 @@
 import Foundation
 import OpenTelemetryApi
 
-public class LongGaugeBuilderSdk: LongGaugeBuilder, InstrumentBuilder {
-  var meterProviderSharedState: MeterProviderSharedState
-
-  var meterSharedState: StableMeterSharedState
-
-  var type: InstrumentType = .observableGauge
-
-  var valueType: InstrumentValueType = .long
-
-  var description: String = ""
-
-  var unit: String = ""
-
-  var instrumentName: String
-
-  init(meterProviderSharedState: MeterProviderSharedState, meterSharedState: StableMeterSharedState, name: String, description: String, unit: String) {
-    instrumentName = name
-    self.unit = unit
-    self.description = description
-    self.meterSharedState = meterSharedState
-    self.meterProviderSharedState = meterProviderSharedState
+public class LongGaugeBuilderSdk: InstrumentBuilder, LongGaugeBuilder {
+  init(meterProviderSharedState: inout MeterProviderSharedState, meterSharedState: inout StableMeterSharedState, name: String, description: String, unit: String) {
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .observableGauge,
+      valueType: .long,
+      description: description,
+      unit: unit,
+      instrumentName: name
+    )
   }
 
   public func build() -> OpenTelemetryApi.LongGauge {
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/LongHistogramMeterBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/LongHistogramMeterBuilderSdk.swift
index 2253be213..e93f3dc9d 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/LongHistogramMeterBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/LongHistogramMeterBuilderSdk.swift
@@ -6,31 +6,21 @@
 import Foundation
 import OpenTelemetryApi
 
-public class LongHistogramMeterBuilderSdk: LongHistogramBuilder, InstrumentBuilder {
-  var meterProviderSharedState: MeterProviderSharedState
-
-  var meterSharedState: StableMeterSharedState
-
-  let type: InstrumentType = .histogram
-
-  let valueType: InstrumentValueType = .long
-
-  var description: String
-
-  var unit: String
-
-  var instrumentName: String
-
-  init(meterProviderSharedState: MeterProviderSharedState,
-       meterSharedState: StableMeterSharedState,
+public class LongHistogramMeterBuilderSdk: InstrumentBuilder, LongHistogramBuilder {
+  init(meterProviderSharedState: inout MeterProviderSharedState,
+       meterSharedState: inout StableMeterSharedState,
        instrumentName: String,
        description: String,
        unit: String) {
-    self.meterProviderSharedState = meterProviderSharedState
-    self.meterSharedState = meterSharedState
-    self.instrumentName = instrumentName
-    self.description = description
-    self.unit = unit
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .histogram,
+      valueType: .long,
+      description: description,
+      unit: unit,
+      instrumentName: instrumentName
+    )
   }
 
   public func build() -> OpenTelemetryApi.LongHistogram {
diff --git a/Sources/OpenTelemetrySdk/Metrics/Stable/LongUpDownCounterBuilderSdk.swift b/Sources/OpenTelemetrySdk/Metrics/Stable/LongUpDownCounterBuilderSdk.swift
index 349fc11c3..7d4f196e3 100644
--- a/Sources/OpenTelemetrySdk/Metrics/Stable/LongUpDownCounterBuilderSdk.swift
+++ b/Sources/OpenTelemetrySdk/Metrics/Stable/LongUpDownCounterBuilderSdk.swift
@@ -6,27 +6,19 @@
 import Foundation
 import OpenTelemetryApi
 
-public class LongUpDownCounterBuilderSdk: LongUpDownCounterBuilder, InstrumentBuilder {
-  var meterSharedState: StableMeterSharedState
-
-  var meterProviderSharedState: MeterProviderSharedState
-
-  let type: InstrumentType = .upDownCounter
-
-  let valueType: InstrumentValueType = .long
-
-  var instrumentName: String
-
-  var description: String = ""
-
-  var unit: String = ""
-
+public class LongUpDownCounterBuilderSdk: InstrumentBuilder, LongUpDownCounterBuilder {
   init(meterProviderSharedState: inout MeterProviderSharedState,
        meterSharedState: inout StableMeterSharedState,
        name: String) {
-    self.meterSharedState = meterSharedState
-    self.meterProviderSharedState = meterProviderSharedState
-    instrumentName = name
+    super.init(
+      meterProviderSharedState: &meterProviderSharedState,
+      meterSharedState: &meterSharedState,
+      type: .upDownCounter,
+      valueType: .long,
+      description: "",
+      unit: "",
+      instrumentName: name
+    )
   }
 
   public func ofDoubles() -> OpenTelemetryApi.DoubleUpDownCounterBuilder {


Test patch:
diff --git a/Tests/OpenTelemetrySdkTests/Metrics/StableMetrics/BuilderTests.swift b/Tests/OpenTelemetrySdkTests/Metrics/StableMetrics/BuilderTests.swift
index 3c2965570..4e4db6ce4 100644
--- a/Tests/OpenTelemetrySdkTests/Metrics/StableMetrics/BuilderTests.swift
+++ b/Tests/OpenTelemetrySdkTests/Metrics/StableMetrics/BuilderTests.swift
@@ -24,4 +24,240 @@ class BuilderTests: XCTestCase {
     XCTAssertNotNil(meter.upDownCounterBuilder(name: "updown").ofDoubles().build())
     XCTAssertNotNil(meter.upDownCounterBuilder(name: "updown").buildWithCallback { _ in })
   }
+
+  func testCounterofLongs() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .registerView(
+        selector: InstrumentSelector.builder().setMeter(name: "*").build(),
+        view: StableView
+          .builder().build()
+      )
+      .build()
+
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (
+      meter
+        .counterBuilder(
+          name: "longCounter"
+        ) as! LongCounterMeterBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as! LongCounterSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "longCounter")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.long)
+    XCTAssertEqual(
+      instrument.instrumentDescriptor.type,
+      InstrumentType.counter
+    )
+  }
+
+  func testCounterOfDoubles() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .registerView(
+        selector: InstrumentSelector.builder().setMeter(name: "*").build(),
+        view: StableView
+          .builder().build()
+      )
+      .build()
+
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (
+      meter
+        .counterBuilder(
+          name: "doubleCounter"
+        ).ofDoubles() as! DoubleCounterMeterBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as! DoubleCounterSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "doubleCounter")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.double)
+    XCTAssertEqual(
+      instrument.instrumentDescriptor.type,
+      InstrumentType.counter
+    )
+  }
+
+  func testGuageOfDoubles() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .registerView(
+        selector: InstrumentSelector.builder().setMeter(name: "*").build(),
+        view: StableView
+          .builder().build()
+      )
+      .build()
+
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (
+      meter
+        .gaugeBuilder(
+          name: "doubleGauge"
+        ) as! DoubleGaugeBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as! DoubleGaugeSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "doubleGauge")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.double)
+    XCTAssertEqual(
+      instrument.instrumentDescriptor.type,
+      InstrumentType.observableGauge
+    )
+
+  }
+
+  func testGaugeOfLongs() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .registerView(
+        selector: InstrumentSelector.builder().setMeter(name: "*").build(),
+        view: StableView
+          .builder().build()
+      )
+      .build()
+
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (
+      meter
+        .gaugeBuilder(
+          name: "longGauge"
+        ).ofLongs () as! LongGaugeBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as!LongGaugeSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "longGauge")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.long)
+    XCTAssertEqual(
+      instrument.instrumentDescriptor.type,
+      InstrumentType.observableGauge
+    )
+  }
+
+  func testHistogramOfLongs() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .registerView(
+        selector: InstrumentSelector.builder().setMeter(name: "*").build(),
+        view: StableView
+          .builder().build()
+      )
+      .build()
+
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (
+      meter
+        .histogramBuilder(
+          name: "longHistogram"
+        ).ofLongs() as! LongHistogramMeterBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as!LongHistogramMeterSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "longHistogram")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.long)
+    XCTAssertEqual(instrument.instrumentDescriptor.type, InstrumentType.histogram)
+  }
+
+  func testHistogramOfDoubles() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .build()
+
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (
+      meter
+        .histogramBuilder(
+          name: "doubleHistogram"
+        ) as! DoubleHistogramMeterBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as! DoubleHistogramMeterSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "doubleHistogram")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.double)
+    XCTAssertEqual(instrument.instrumentDescriptor.type, InstrumentType.histogram)
+  }
+
+  func testLongUpDownInstrument() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .build()
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (meter.upDownCounterBuilder(name: "updown") as! LongUpDownCounterBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as! LongUpDownCounterSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.type, InstrumentType.upDownCounter)
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "updown")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.long)
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+  }
+  func testDoubleUpDownInstrument() {
+    let myReader = StablePeriodicMetricReaderBuilder(
+      exporter: MockStableMetricExporter()
+    ).build()
+    
+    let meterProvider = StableMeterProviderBuilder()
+      .registerMetricReader(reader:myReader)
+      .build()
+
+    let meter = meterProvider.meterBuilder(name: "meter").build() as! StableMeterSdk
+    let instrument = (meter.upDownCounterBuilder(name: "doubleUpdown").ofDoubles() as! DoubleUpDownCounterBuilderSdk)
+      .setUnit("unit")
+      .setDescription("description")
+      .build() as! DoubleUpDownCounterSdk
+
+    XCTAssertEqual(instrument.instrumentDescriptor.name, "doubleUpdown")
+    XCTAssertEqual(instrument.instrumentDescriptor.unit, "unit")
+    XCTAssertEqual(instrument.instrumentDescriptor.description, "description")
+    XCTAssertEqual(instrument.instrumentDescriptor.valueType, InstrumentValueType.double)
+    XCTAssertEqual(instrument.instrumentDescriptor.type, InstrumentType.upDownCounter)
+  }
 }